Bagaimana kami bisa selamat dari peningkatan tajam pada beban x10 di situs jarak jauh dan apa kesimpulannya

Halo, Habr! Beberapa bulan terakhir kami hidup dalam situasi yang sangat menarik, dan saya ingin berbagi sejarah tentang penskalaan infrastruktur. Selama waktu ini, SberMarket tumbuh 4 kali lipat dalam pesanan dan meluncurkan layanan di 17 kota baru. Pertumbuhan permintaan pengiriman makanan yang eksplosif mengharuskan kami meningkatkan skala infrastruktur kami. Baca temuan paling menarik dan bermanfaat di bawah kucing.



Nama saya Dima Bobylev, saya adalah Direktur Teknis SberMarket. Karena ini adalah posting pertama di blog kami, saya akan mengatakan beberapa kata tentang diri saya dan tentang perusahaan. Musim gugur yang lalu, saya berpartisipasi dalam kontes pemimpin muda Runet. Untuk kontes, saya menulis cerita pendek tentang bagaimana kami di SberMarket melihat budaya internal dan pendekatan untuk pengembangan layanan. Dan meskipun tidak mungkin untuk memenangkan persaingan, saya merumuskan sendiri prinsip-prinsip dasar untuk pengembangan ekosistem IT.

Saat mengelola tim, penting untuk memahami dan menemukan keseimbangan antara apa yang dibutuhkan bisnis dan kebutuhan masing-masing pengembang spesifik. Sekarang SberMarket tumbuh 13 kali dari tahun ke tahun, dan ini memengaruhi produk, membutuhkan peningkatan volume dan kecepatan pengembangan yang konstan. Meskipun demikian, kami mencurahkan cukup waktu bagi pengembang untuk analisis awal dan penulisan kode berkualitas tinggi. Pendekatan yang dibentuk membantu tidak hanya dalam menciptakan produk yang bekerja, tetapi juga dalam penskalaan dan pengembangan lebih lanjut. Sebagai hasil dari pertumbuhan ini, SberMarket telah menjadi pemimpin di antara layanan pengiriman makanan: kami mengirimkan sekitar 18 ribu pesanan sehari setiap hari, meskipun pada awal Februari ada sekitar 3.500 dari mereka.


Suatu kali seorang klien meminta kurir SberMarket untuk mengirimkan produk kepadanya tanpa kontak - langsung ke balkon

Tapi mari kita beralih ke spesifik. Selama beberapa bulan terakhir, kami telah secara aktif meningkatkan infrastruktur perusahaan kami. Kebutuhan seperti itu dijelaskan oleh faktor-faktor eksternal dan internal. Bersamaan dengan perluasan basis pelanggan, jumlah toko yang terhubung meningkat dari 90 pada awal tahun menjadi lebih dari 200 pada pertengahan Mei. Tentu saja, kami menyiapkan, memesan infrastruktur utama, dan mengandalkan kemungkinan penskalaan vertikal dan horizontal semua mesin virtual yang terletak di cloud Yandex. Namun, latihan telah menunjukkan: "Segala sesuatu yang salah bisa salah." Dan hari ini saya ingin berbagi situasi paling menarik yang telah terjadi dalam beberapa minggu ini. Semoga pengalaman kami bermanfaat bagi Anda.

Budak dalam peringatan penuh


Bahkan sebelum pandemi dimulai, kami dihadapkan dengan peningkatan jumlah permintaan ke server backend kami. Kecenderungan untuk memesan produk dengan pengiriman rumah mulai mendapatkan momentum, dan dengan diperkenalkannya langkah-langkah isolasi diri sendiri sehubungan dengan COVID-19, beban tumbuh secara dramatis di depan mata kita sepanjang hari. Ada kebutuhan untuk dengan cepat menurunkan server master dari database utama dan mentransfer bagian dari permintaan baca ke server replika (budak).

Kami sedang mempersiapkan sebelumnya untuk langkah ini, dan untuk manuver 2 server slave telah diluncurkan. Mereka terutama bekerja pada tugas batch menghasilkan umpan informasi untuk bertukar data dengan mitra. Proses-proses ini menciptakan beban tambahan dan cukup tepat ditempatkan "di luar kurung" beberapa bulan sebelumnya. 

Karena ada replikasi pada Slave, kami berpegang pada konsep bahwa aplikasi hanya dapat bekerja dengannya dalam mode read only. Rencana Pemulihan Bencana menyarankan bahwa jika terjadi bencana, kita bisa dengan mudah memasang Budak di tempat Master dan mengalihkan semua permintaan tulis dan baca ke Budak. Namun, kami juga ingin menggunakan replika untuk kebutuhan departemen analitik, sehingga server tidak sepenuhnya ditransfer untuk hanya membaca status, dan setiap host memiliki set pengguna sendiri, dan beberapa memiliki izin menulis untuk menyimpan hasil perhitungan menengah.

Hingga tingkat pemuatan tertentu, kami memiliki cukup penyihir untuk menulis dan membaca saat memproses permintaan http. Pada pertengahan Maret, tepat ketika Sbermarket memutuskan untuk sepenuhnya beralih ke situs jarak jauh, kami memulai beberapa peningkatan dalam RPS. Semakin banyak pelanggan kami pergi ke tempat terpencil atau bekerja dari rumah, yang tercermin dalam indikator beban.

Performa "master" tidak lagi cukup, jadi kami mulai menanggung beberapa permintaan baca replika terberat. Untuk mengirim permintaan untuk menulis kepada master secara transparan, dan membaca ke budak, kami menggunakan permata ruby, “ Gurita". Kami menciptakan pengguna khusus dengan postfix _readonly tanpa izin tulis. Tetapi karena kesalahan dalam konfigurasi salah satu host, sebagian dari permintaan tulis dikirim ke server slave atas nama pengguna yang memiliki hak yang sesuai.

Masalahnya tidak terwujud dengan segera, karena peningkatan beban meningkatkan lag budak. Ketidakkonsistenan data terungkap di pagi hari ketika, setelah impor malam hari, para budak tidak “mengejar ketinggalan” dengan tuannya. Kami mengaitkan hal ini dengan tingginya beban pada layanan itu sendiri dan impor yang terkait dengan peluncuran toko baru. Tetapi untuk memberikan informasi kepada banyak jam penundaan itu tidak dapat diterima, dan kita beralih ke proses analisis kedua budak, karena ia telah menggunakan pada sumber daya lshie dan tidak dimuat permintaan membaca (dan kami telah menjelaskan diri untuk tidak adanya replikasi lag).

Ketika kami menemukan alasan untuk "merayap" budak utama, analitik sudah gagal karena alasan yang sama. Meskipun ada dua server tambahan, yang kami rencanakan untuk mentransfer beban jika terjadi kerusakan utama, karena kesalahan yang tidak menguntungkan, ternyata pada saat kritis tidak ada.

Tetapi karena kami tidak hanya membuang database (sisanya pada waktu itu sekitar 5 jam), tetapi juga server master snapshot, kami berhasil memulai replika dalam waktu 2 jam. Benar, setelah itu kami diharapkan untuk menggulung log replikasi untuk waktu yang lama (karena prosesnya dalam mode single-threaded, tetapi ini adalah cerita yang sama sekali berbeda).

: , readonly . , .

« »


Meskipun kami terus-menerus memperbarui katalog di situs, permintaan yang kami buat ke server Slave memungkinkan sedikit keterlambatan dari Master. Waktu di mana kami menemukan dan menghilangkan masalah budak "yang tiba-tiba keluar dari kejauhan" lebih dari sekadar "penghalang psikologis" (selama waktu ini harga bisa diperbarui, dan pelanggan akan melihat data yang ketinggalan zaman), dan kami harus mengalihkan semua permintaan ke server database utama . Hasilnya, situs itu bekerja lambat ... tapi setidaknya berhasil. Dan sementara Slave pulih, kami tidak punya pilihan selain mengoptimalkan. 

Sementara server Slave pulih, menit demi menit berjalan lambat, Master tetap kelebihan beban, dan kami mencurahkan semua upaya kami untuk mengoptimalkan tugas aktif sesuai dengan Aturan Pareto: kami memilih permintaan TOP yang memberikan sebagian besar beban dan mulai menyetel. Ini dilakukan secara langsung "dengan cepat."

Efek yang menarik adalah bahwa MySQL yang dimuat ke bola mata merespon bahkan sedikit perbaikan dalam proses. Optimalisasi sepasang permintaan, yang hanya memberi 5% dari total beban, sudah menunjukkan pembongkaran CPU nyata. Sebagai hasilnya, kami dapat menyediakan pasokan sumber daya yang dapat diterima bagi Guru untuk bekerja dengan database dan mendapatkan waktu yang diperlukan untuk memulihkan replika. 

Kesimpulan: Bahkan optimasi kecil memungkinkan Anda untuk "bertahan" selama overload selama beberapa jam. Ini cukup bagi kami selama pemulihan server dengan replika. Ngomong-ngomong, kita akan membahas sisi teknis optimasi kueri di salah satu posting berikut. Jadi berlangganan ke blog kami jika ini mungkin bermanfaat bagi Anda.

Atur pemantauan kinerja layanan mitra


Kami terlibat dalam pemrosesan pesanan dari pelanggan, dan oleh karena itu layanan kami terus berinteraksi dengan API pihak ketiga - ini adalah gateway untuk mengirim SMS, platform pembayaran, sistem perutean, geocoder, Layanan Pajak Federal dan banyak sistem lainnya. Dan ketika beban mulai tumbuh dengan cepat, kami mulai bersandar pada keterbatasan API mitra layanan kami, yang bahkan belum kami pikirkan sebelumnya.

Kelebihan kuota yang tak terduga untuk layanan afiliasi dapat menyebabkan waktu henti Anda sendiri. Banyak API memblokir klien yang melebihi batas, dan dalam beberapa kasus, kelebihan permintaan dapat membebani produksi dengan mitra. 

Misalnya, pada saat meningkatkan jumlah pengiriman, layanan yang menyertainya tidak dapat mengatasi tugas distribusi mereka, penentuan rute. Akibatnya, ternyata pesanan dibuat, dan layanan membuat rute tidak berfungsi. Saya harus mengatakan bahwa ahli logistik kami membuatnya hampir tidak mungkin dalam kondisi ini, dan interaksi tim yang jelas membantu untuk mengkompensasi kegagalan layanan sementara. Tetapi volume aplikasi seperti itu tidak mungkin diproses secara manual, dan setelah beberapa waktu kami akan menemukan celah yang tidak dapat diterima antara pesanan dan pelaksanaannya. 

Sejumlah langkah organisasi diambil dan kerja tim yang terkoordinasi membantu untuk mendapatkan waktu sementara kami menyetujui kondisi baru dan menunggu modernisasi layanan dari beberapa mitra. Ada API lain yang menyenangkan Anda dengan daya tahan tinggi dan tarif tak bertuhan dalam hal lalu lintas tinggi. Misalnya, pada awalnya kami menggunakan satu API pemetaan terkenal untuk menentukan alamat titik pengiriman. Tetapi pada akhir bulan mereka menerima tagihan hampir 2 juta rubel. Setelah itu, mereka memutuskan untuk segera menggantinya. Saya tidak akan terlibat dalam periklanan, tetapi saya akan mengatakan bahwa pengeluaran kami telah menurun secara signifikan.

: . , « », , . , ,   . 

, « » ()


Kami terbiasa "mencolokkan" di database utama atau server aplikasi, tetapi ketika meningkatkan, masalah dapat muncul di mana mereka tidak diharapkan. Untuk pencarian teks lengkap di situs, kami menggunakan mesin Apache Solr. Dengan peningkatan beban, kami mencatat penurunan waktu respons, dan beban prosesor server mencapai 100%. Apa yang bisa lebih sederhana - kami akan memberikan lebih banyak sumber daya ke wadah bersama Solr.

Alih-alih kenaikan kinerja yang diharapkan, server hanya "mati". Segera memuat 100% dan merespons lebih lambat. Awalnya, kami memiliki 2 core dan 2 GB RAM. Kami memutuskan untuk melakukan apa yang biasanya membantu - kami memberikan server 8 core dan 32 GB. Semuanya menjadi jauh lebih buruk (persis bagaimana dan mengapa - kami akan kirim di pos terpisah). 

Selama beberapa hari, kami menemukan seluk-beluk masalah ini, dan mencapai kinerja optimal dengan 8 core dan 32 GB. Konfigurasi ini memungkinkan kami untuk terus meningkatkan beban hari ini, yang sangat penting, karena pertumbuhan tidak hanya pada pelanggan, tetapi juga dalam jumlah toko yang terhubung - lebih dari 2 bulan jumlah mereka telah berlipat ganda. 

Kesimpulan: Metode standar seperti "tambah lebih banyak zat besi" tidak selalu berhasil. Jadi ketika meningkatkan layanan apa pun, Anda perlu memahami dengan baik bagaimana ia menggunakan sumber daya dan melakukan pra-tes operasinya dalam kondisi baru. 

Stateless - kunci untuk penskalaan horizontal yang mudah


Secara umum, tim kami menganut pendekatan terkenal: layanan tidak boleh memiliki status stateless dan harus independen dari lingkungan runtime. Ini memungkinkan kami untuk bertahan dari pertumbuhan beban dengan penskalaan horisontal sederhana. Tapi kami memiliki satu pengecualian layanan - penangan untuk tugas latar belakang yang panjang. Dia terlibat dalam mengirim email dan sms, memproses acara, menghasilkan feed, mengimpor harga dan stok, dan memproses gambar. Kebetulan itu tergantung pada penyimpanan file lokal dan dalam satu salinan. 

Ketika jumlah tugas dalam antrian prosesor meningkat (dan ini terjadi secara alami dengan peningkatan jumlah pesanan), kinerja host yang menampung prosesor dan penyimpanan file menjadi faktor pembatas. Akibatnya, pembaruan bermacam-macam dan harga, pengiriman pemberitahuan kepada pengguna dan banyak fungsi penting lainnya yang terjebak dalam antrian berhenti. Tim Ops dengan cepat memigrasikan penyimpanan file ke penyimpanan jaringan mirip S3, dan ini memungkinkan kami untuk meningkatkan beberapa mesin yang kuat untuk skala penangan tugas latar belakang.

Kesimpulan: Aturan Stateless harus dihormati untuk semua komponen, tanpa terkecuali, bahkan jika tampaknya "bahwa kita pasti tidak mengganggu". Lebih baik menghabiskan sedikit waktu pada organisasi yang benar dari semua sistem kerja daripada menulis ulang kode dengan tergesa-gesa dan memperbaiki layanan yang mengalami kelebihan beban.

7 prinsip untuk pertumbuhan yang intens


Terlepas dari ketersediaan kapasitas tambahan, dalam proses pertumbuhan kami menginjak beberapa garu. Selama waktu ini, jumlah pesanan meningkat lebih dari 4 kali. Sekarang kami telah mengirimkan lebih dari 17.000 pesanan per hari di 62 kota dan berencana untuk memperluas geografi kami lebih jauh lagi - pada paruh pertama tahun 2020, layanan diharapkan akan diluncurkan di seluruh Rusia. Untuk mengatasi meningkatnya beban, dengan memperhitungkan tonjolan yang sudah penuh, kami telah mengembangkan sendiri 7 prinsip dasar kerja dalam kondisi pertumbuhan konstan:

  1. -. Jira,   . . — . , , , , .
  2. . « » . , , . , .
  3. . -, . -, , .
  4. stateless. , . . , , S3. https://12factor.net. , .
  5. . , . , , - . , . 
  6. . , . , SMS . , .
  7. . , . , , . API, -. .


Bukan tanpa kehilangan, tapi kami selamat dari tahap ini, dan hari ini kami mencoba untuk mematuhi semua prinsip yang ditemukan, dan setiap mesin memiliki kemampuan untuk dengan mudah meningkatkan kinerja x4 untuk mengatasi kejutan apa pun. 

Dalam posting berikut, kami akan berbagi pengalaman kami dalam menyelidiki penurunan kinerja di Apache Solr, serta berbicara tentang optimasi kueri dan bagaimana interaksi dengan Layanan Pajak Federal membantu perusahaan menghemat uang. Berlangganan ke blog kami agar Anda tidak kehilangan apa pun, dan beri tahu kami di komentar jika Anda memiliki masalah seperti itu selama pertumbuhan lalu lintas.


All Articles