Bagaimana kami bertahan dari peningkatan beban kerja x10 dari jarak jauh dan kesimpulan apa yang kami buat

Hei Habr! Beberapa bulan terakhir ini kami hidup dalam situasi yang sangat menarik, dan saya ingin berbagi cerita tentang peningkatan infrastruktur. Selama ini, SberMarket telah melipatgandakan pesanan dan meluncurkan layanan di 4 kota baru. Ledakan pertumbuhan permintaan pengiriman bahan makanan mengharuskan kami untuk meningkatkan infrastruktur kami. Baca tentang kesimpulan paling menarik dan berguna di bawah potongan.

Bagaimana kami bertahan dari peningkatan beban kerja x10 dari jarak jauh dan kesimpulan apa yang kami buat

Nama saya Dima Bobylev, saya direktur teknis SberMarket. Karena ini adalah posting pertama di blog kami, saya akan menyampaikan beberapa patah kata tentang diri saya dan perusahaan. Musim gugur yang lalu, saya berpartisipasi dalam kompetisi untuk pemimpin muda Runet. Untuk Lomba I menulis sedikit cerita tentang bagaimana kami melihat budaya internal dan pendekatan pengembangan layanan di SberMarket. Dan meskipun saya tidak berhasil memenangkan persaingan, saya merumuskan sendiri prinsip-prinsip dasar pengembangan ekosistem TI.

Saat mengelola tim, penting untuk memahami dan menemukan keseimbangan antara kebutuhan bisnis dan kebutuhan masing-masing pengembang. Sekarang SberMarket tumbuh 13 kali setahun, dan ini memengaruhi produk, membutuhkan peningkatan volume dan kecepatan pengembangan yang konstan. Meskipun demikian, kami mengalokasikan cukup waktu untuk pengembang untuk analisis awal dan pengkodean berkualitas tinggi. Pendekatan yang terbentuk membantu tidak hanya dalam menciptakan produk yang berfungsi, tetapi juga dalam penskalaan dan pengembangan lebih lanjut. Sebagai hasil dari pertumbuhan ini, SberMarket telah menjadi pemimpin di antara layanan pengiriman bahan makanan: kami mengirimkan sekitar 18 pesanan sehari, meskipun pada awal Februari ada sekitar 3500 pesanan.

Bagaimana kami bertahan dari peningkatan beban kerja x10 dari jarak jauh dan kesimpulan apa yang kami buat
Suatu hari, seorang klien meminta kurir SberMarket untuk mengantarkan bahan makanan kepadanya tanpa kontak β€” tepat di balkon.

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

Budak dalam kesiapan tempur penuh

Bahkan sebelum dimulainya pandemi, kami dihadapkan pada peningkatan jumlah permintaan ke server backend kami. Tren memesan makanan dengan pengiriman ke rumah mulai mendapatkan momentumnya, dan dengan diperkenalkannya langkah-langkah isolasi diri pertama sehubungan dengan COVID-19, beban meningkat secara dramatis di depan mata kita sepanjang hari. Ada kebutuhan untuk membongkar server master dari database utama dengan cepat dan mentransfer beberapa permintaan baca ke server replika (budak).

Kami sedang mempersiapkan langkah ini sebelumnya, dan 2 server budak sudah berjalan untuk manuver seperti itu. Mereka terutama mengerjakan tugas batch untuk menghasilkan umpan informasi untuk bertukar data dengan mitra. Proses-proses ini menciptakan beban tambahan dan dengan tepat dikeluarkan dari kurung beberapa bulan sebelumnya. 

Karena replikasi terjadi pada Slave, kami menganut konsep bahwa aplikasi hanya dapat bekerja dengannya dalam mode hanya baca. Rencana Pemulihan Bencana mengasumsikan bahwa jika terjadi bencana, kita dapat dengan mudah memasang Slave sebagai pengganti Master dan mengalihkan semua permintaan tulis dan baca ke Slave. Namun, kami juga ingin menggunakan replika untuk kebutuhan departemen analitik, sehingga server tidak sepenuhnya disetel ke status hanya baca, dan setiap host memiliki kumpulan penggunanya sendiri, dan beberapa memiliki izin menulis untuk menyimpan hasil perhitungan menengah.

Hingga tingkat beban tertentu, kami memiliki cukup master untuk menulis dan membaca saat memproses permintaan http. Pada pertengahan Maret, tepat ketika Sbermarket memutuskan untuk sepenuhnya beralih ke pekerjaan jarak jauh, kami mulai melipatgandakan pertumbuhan RPS. Semakin banyak klien kami yang melakukan isolasi mandiri atau bekerja dari rumah, yang tercermin dari indikator beban.

Performa "master" tidak lagi cukup, jadi kami mulai mentransfer beberapa permintaan baca terberat ke replika. Untuk mengarahkan permintaan tulis secara transparan ke master, dan membaca permintaan ke budak, kami menggunakan permata ruby ​​\uXNUMXb\uXNUMXb"gurita". Kami telah membuat pengguna khusus dengan postfix _readonly tanpa izin menulis. Tetapi karena kesalahan dalam konfigurasi salah satu host, sebagian dari permintaan tulis dikirim ke server budak atas nama pengguna yang memiliki hak yang sesuai.

Masalahnya tidak segera terwujud, karena. peningkatan beban meningkatkan backlog para budak. Inkonsistensi data ditemukan di pagi hari, ketika setelah impor malam, para budak tidak "mengejar" tuannya. Kami menghubungkan ini dengan beban tinggi pada layanan itu sendiri dan impor yang terkait dengan peluncuran toko baru. Tetapi tidak dapat diterima untuk memberikan data dengan penundaan berjam-jam, dan kami mengalihkan proses ke budak analitik kedua, karena memang demikianΠΎSumber daya yang lebih besar dan tidak dimuat dengan permintaan baca (begitulah cara kami menjelaskan kepada diri kami sendiri tentang kurangnya jeda replikasi).

Ketika kami menemukan alasan "penyebaran" budak utama, analitis telah gagal karena alasan yang sama. Meskipun ada dua server tambahan, yang kami rencanakan untuk mentransfer beban jika master crash, karena kesalahan yang tidak menguntungkan, ternyata tidak ada satu pun pada saat kritis.

Tetapi karena kami tidak hanya membuang database (pemulihan pada waktu itu sekitar 5 jam), tetapi juga snapshot dari server master, kami berhasil meluncurkan replika dalam waktu 2 jam. Benar, setelah itu, kami diharapkan untuk memutar log replikasi untuk waktu yang lama (karena prosesnya dalam mode utas tunggal, tetapi itu adalah cerita yang sama sekali berbeda).

Kesimpulan: Setelah kejadian seperti itu, menjadi jelas bahwa praktik membatasi penulisan untuk pengguna harus ditinggalkan dan seluruh server harus dinyatakan hanya dapat dibaca. Dengan pendekatan ini, Anda dapat yakin bahwa replika akan tersedia pada saat kritis.

Mengoptimalkan bahkan satu kueri berat dapat menghidupkan kembali database

Meskipun kami terus memperbarui katalog di situs, permintaan yang kami buat ke server Slave memungkinkan sedikit keterlambatan di belakang Master. Waktu di mana kami menemukan dan menghilangkan masalah budak yang "tiba-tiba keluar jalur" lebih dari sekadar "penghalang psikologis" (selama ini, harga dapat diperbarui, dan klien akan melihat data yang sudah ketinggalan zaman), dan kami terpaksa beralih semua query ke server database utama. Akibatnya, situs menjadi lambat... tapi setidaknya berhasil. Dan saat Budak pulih, tidak ada yang tersisa bagi kami selain pengoptimalan. 

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

Efek yang menarik adalah MySQL, dimuat ke bola mata, merespons bahkan sedikit peningkatan dalam proses. Optimalisasi beberapa kueri yang hanya memberikan 5% dari total beban telah menunjukkan penurunan beban CPU yang nyata. Hasilnya, kami dapat menyediakan cadangan sumber daya yang dapat diterima agar Master dapat bekerja dengan database dan mendapatkan waktu yang diperlukan untuk memulihkan replika. 

Kesimpulan: Bahkan pengoptimalan kecil memungkinkan Anda untuk "bertahan" dari kelebihan beban selama beberapa jam. Ini cukup bagi kami untuk memulihkan server dengan replika. Omong-omong, kami akan membahas sisi teknis pengoptimalan kueri di salah satu postingan berikut. Jadi berlangganan blog kami jika itu dapat bermanfaat bagi Anda.

Menyelenggarakan pemantauan kesehatan layanan mitra

Kami memproses 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 bertambah dengan cepat, kami mulai menghadapi batasan API layanan mitra kami, yang bahkan tidak pernah kami pikirkan sebelumnya.

Pelebihan tak terduga dari kuota layanan mitra dapat mengakibatkan downtime Anda sendiri. Banyak API memblokir klien yang melebihi batas, dan dalam beberapa kasus, kelebihan permintaan dapat membebani produksi mitra. 

Misalnya, pada saat pertumbuhan jumlah pengiriman, layanan pendamping tidak dapat mengatasi tugas distribusi dan penentuan rute mereka. Alhasil, ternyata pesanan sudah dibuat, namun layanan yang membuat rute tersebut tidak berfungsi. Saya harus mengatakan bahwa ahli logistik kami melakukan hal yang hampir mustahil dalam kondisi ini, dan interaksi yang jelas dari tim membantu mengkompensasi kegagalan layanan sementara. Tetapi tidak realistis untuk memproses volume permintaan seperti itu secara manual sepanjang waktu, dan setelah beberapa saat kami akan menemukan celah yang tidak dapat diterima antara pesanan dan pelaksanaannya. 

Sejumlah tindakan organisasi telah diambil dan kerja tim yang terkoordinasi dengan baik membantu mengulur waktu sementara kami menyepakati kondisi baru dan menunggu modernisasi layanan dari beberapa mitra. Ada API lain yang menawarkan daya tahan tinggi dan tingkat yang tidak baik jika lalu lintas tinggi. Misalnya, pada awalnya kami menggunakan satu API pemetaan terkenal untuk menentukan alamat titik pengiriman. Tetapi pada akhir bulan, mereka menerima tagihan bulat hampir 2 juta rubel. Setelah itu, kami memutuskan untuk segera menggantinya. Saya tidak akan terlibat dalam periklanan, tetapi saya akan mengatakan bahwa pengeluaran kami telah menurun secara signifikan.
Bagaimana kami bertahan dari peningkatan beban kerja x10 dari jarak jauh dan kesimpulan apa yang kami buat

Kesimpulan: Sangat penting untuk memantau kondisi kerja semua layanan mitra dan mengingatnya. Bahkan jika hari ini tampaknya "dengan margin besar" untuk Anda, ini tidak berarti bahwa besok mereka tidak akan menjadi penghambat pertumbuhan. Dan, tentu saja, lebih baik untuk menyetujui persyaratan keuangan dari peningkatan permintaan layanan terlebih dahulu. 

Terkadang ternyata begituButuh lebih banyak emas"(c) tidak membantu

Kami terbiasa "meludah" di database utama atau di server aplikasi, tetapi saat menskalakan, masalah dapat muncul di tempat yang tidak diharapkan.Untuk pencarian teks lengkap di situs, kami menggunakan mesin Apache Solr. Saat beban meningkat, kami melihat penurunan waktu respons, dan beban CPU server mencapai 100%. Apa yang bisa lebih sederhana - berikan wadah Solr lebih banyak sumber daya.

Alih-alih peningkatan kinerja yang diharapkan, server hanya "mati". Itu 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 memberi server 8 core dan 32 GB. Semuanya menjadi jauh lebih buruk (kami akan memberi tahu Anda bagaimana dan mengapa tepatnya di pos terpisah). 

Dalam beberapa hari, kami menemukan seluk-beluk masalah ini, dan mencapai kinerja optimal dengan 8 core dan 32 GB. Konfigurasi ini memungkinkan kami untuk terus menambah beban hari ini, yang sangat penting, karena pertumbuhan tidak hanya dalam hal pelanggan, tetapi juga dalam jumlah toko yang terhubung - dalam 2 bulan jumlahnya menjadi dua kali lipat. 

Kesimpulan: Metode standar seperti "tambahkan lebih banyak zat besi" tidak selalu berhasil. Jadi saat menskalakan layanan apa pun, Anda harus memiliki pemahaman yang baik tentang cara menggunakan sumber daya dan mengujinya terlebih dahulu, berfungsi dalam kondisi baru. 

Stateless adalah kunci untuk penskalaan horizontal sederhana

Secara umum, tim kami menganut pendekatan yang terkenal: layanan tidak boleh memiliki status internal (stateless) dan harus independen dari lingkungan runtime. Ini memungkinkan kami bertahan dari peningkatan beban dengan penskalaan horizontal sederhana. Tapi kami memiliki satu pengecualian layanan - penangan untuk tugas latar belakang yang panjang. Dia terlibat dalam pengiriman 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 secara alami terjadi dengan peningkatan jumlah pesanan), kinerja host yang menghosting prosesor dan penyimpanan file menjadi faktor pembatas. Akibatnya, pembaruan kisaran dan harga, pengiriman pemberitahuan ke pengguna, dan banyak fungsi penting lainnya yang terjebak dalam antrean terhenti. Tim Ops dengan cepat memigrasikan penyimpanan file ke penyimpanan jaringan mirip S3, dan ini memungkinkan kami meningkatkan beberapa mesin canggih untuk menskalakan penangan tugas latar belakang.

Kesimpulan: Aturan Stateless harus diperhatikan untuk semua komponen tanpa kecuali, bahkan jika tampaknya "kita pasti tidak akan beristirahat di sini". Lebih baik menghabiskan sedikit waktu untuk mengatur pekerjaan semua sistem dengan benar daripada terburu-buru menulis ulang kode dan memperbaiki layanan yang kelebihan beban.

7 Prinsip Pertumbuhan Intensif

Terlepas dari tersedianya kapasitas tambahan, dalam proses pertumbuhan, kami menginjak beberapa penggaruk. Selama ini, jumlah pesanan meningkat lebih dari 4 kali lipat. Sekarang kami telah mengirimkan lebih dari 17 pesanan per hari di 000 kota dan berencana untuk memperluas geografi lebih lanjut - pada paruh pertama tahun 62, layanan ini diharapkan akan diluncurkan di seluruh Rusia. Untuk mengatasi beban kerja yang bertambah, dengan mempertimbangkan gundukan yang sudah penuh, kami telah memperoleh 2020 prinsip dasar untuk bekerja di lingkungan dengan pertumbuhan konstan:

  1. Manajemen insiden. Kami telah membuat papan di Jira, di mana setiap kejadian tercermin dalam bentuk tiket. Ini akan membantu Anda benar-benar memprioritaskan dan menyelesaikan tugas terkait insiden. Memang, pada dasarnya, membuat kesalahan itu tidak buruk - membuat kesalahan dua kali pada kesempatan yang sama itu mengerikan. Untuk kasus-kasus ketika insiden berulang sebelum penyebabnya dapat diperbaiki, instruksi tindakan harus disiapkan, karena selama beban berat penting untuk bereaksi secepat kilat.
  2. Pemantauan diperlukan untuk semua elemen infrastruktur tanpa terkecuali. Berkat dia, kami dapat memprediksi pertumbuhan beban dan memilih "kemacetan" dengan benar untuk memprioritaskan eliminasi. Kemungkinan besar, di bawah beban tinggi, segala sesuatu yang bahkan tidak Anda pikirkan akan rusak atau mulai melambat. Oleh karena itu, yang terbaik adalah membuat peringatan baru segera setelah timbulnya insiden pertama untuk memantau dan mengantisipasinya.
  3. Lansiran yang benar hanya dibutuhkan dengan peningkatan beban yang tajam. Pertama, mereka harus melaporkan dengan tepat apa yang rusak. Kedua, tidak boleh ada banyak peringatan, karena banyaknya peringatan non-kritis mengarah pada pengabaian semua peringatan secara umum.
  4. Aplikasi harus tanpa kewarganegaraan. Kami telah memastikan bahwa tidak boleh ada pengecualian untuk aturan ini. Anda membutuhkan kebebasan penuh dari lingkungan runtime. Untuk melakukannya, Anda dapat menyimpan data bersama di database atau, misalnya, langsung di S3. Lebih baik lagi, ikuti aturan. https://12factor.net. Selama peningkatan tajam dalam waktu, tidak ada cara untuk mengoptimalkan kode, dan Anda harus mengatasi beban dengan meningkatkan sumber daya komputasi dan penskalaan horizontal secara langsung.
  5. Kuota dan kinerja layanan eksternal. Dengan pertumbuhan yang cepat, masalah mungkin muncul tidak hanya pada infrastruktur Anda, tetapi juga pada layanan eksternal. Hal yang paling menyebalkan adalah ketika hal ini terjadi bukan karena kegagalan, melainkan karena mencapai kuota atau limit. Jadi, layanan eksternal harus berskala sebaik Anda sendiri. 
  6. Pisahkan proses dan antrian. Ini sangat membantu ketika steker terjadi di salah satu gateway. Kami tidak akan mengalami keterlambatan transmisi data jika antrian penuh untuk pengiriman SMS tidak mengganggu pertukaran notifikasi antar sistem informasi. Dan akan lebih mudah menambah jumlah pekerja jika mereka bekerja secara terpisah.
  7. realitas keuangan. Ketika terjadi ledakan pertumbuhan arus data, tidak ada waktu untuk memikirkan tarif dan langganan. Tetapi mereka harus diingat, terutama jika Anda adalah perusahaan kecil. Tagihan besar dapat diatur oleh pemilik API apa pun, serta penyedia hosting Anda. Jadi baca kontrak dengan hati-hati.

Kesimpulan

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

Dalam posting berikut, kami akan membagikan pengalaman kami menyelidiki kemerosotan kinerja di Apache Solr, serta berbicara tentang pengoptimalan kueri dan bagaimana interaksi dengan Layanan Pajak Federal membantu perusahaan menghemat uang. Berlangganan ke blog kami agar tidak ketinggalan apa pun, dan beri tahu kami di komentar jika Anda mengalami masalah serupa selama pertumbuhan lalu lintas.

Bagaimana kami bertahan dari peningkatan beban kerja x10 dari jarak jauh dan kesimpulan apa yang kami buat

Hanya pengguna terdaftar yang dapat berpartisipasi dalam survei. Masuk, silakan.

Pernahkah Anda mengalami pelambatan/penurunan layanan karena peningkatan beban yang tajam karena:

  • 55,6%Ketidakmampuan untuk menambahkan sumber daya komputasi dengan cepat10

  • 16,7%Batas infrastruktur penyedia hosting3

  • 33,3%Batasan API6 pihak ketiga

  • 27,8%Pelanggaran prinsip stateless aplikasi mereka5

  • 88,9%Kode layanan sendiri yang tidak optimal16

18 pengguna memilih. 6 pengguna abstain.

Sumber: www.habr.com

Tambah komentar