Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Halo, nama saya Evgeniy. Saya bekerja di infrastruktur pencarian Yandex.Market. Saya ingin memberi tahu komunitas Habr tentang dapur bagian dalam Pasar - dan banyak hal yang ingin saya ceritakan. Pertama-tama, cara kerja pencarian Pasar, proses dan arsitektur. Bagaimana kita menghadapi situasi darurat: apa yang terjadi jika satu server mati? Bagaimana jika ada 100 server seperti itu?

Anda juga akan mempelajari cara kami mengimplementasikan fungsionalitas baru di beberapa server sekaligus. Dan bagaimana kami menguji layanan kompleks secara langsung dalam produksi, tanpa menimbulkan ketidaknyamanan bagi pengguna. Secara umum, cara kerja Pencarian Pasar sehingga semua orang bersenang-senang.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Sedikit tentang kami: masalah apa yang kami pecahkan

Saat Anda memasukkan teks, mencari produk berdasarkan parameter, atau membandingkan harga di toko yang berbeda, semua permintaan dikirim ke layanan pencarian. Pencarian adalah layanan terbesar di Pasar.

Kami memproses semua permintaan pencarian: dari situs market.yandex.ru, beru.ru, layanan Supercheck, Yandex.Advisor, aplikasi seluler. Kami juga menyertakan penawaran produk dalam hasil pencarian di yandex.ru.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Yang saya maksud dengan layanan pencarian bukan hanya pencarian itu sendiri, tetapi juga database dengan semua penawaran di Pasar. Skalanya begini: lebih dari satu miliar permintaan pencarian diproses setiap hari. Dan semuanya harus berjalan cepat, tanpa gangguan dan selalu membuahkan hasil yang diinginkan.

Apa itu: Arsitektur pasar

Saya akan menjelaskan secara singkat arsitektur Pasar saat ini. Secara kasar dapat dijelaskan melalui diagram di bawah ini:
Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal
Katakanlah toko mitra mendatangi kita. Dia bilang aku ingin menjual mainan: kucing jahat dengan alat mencicit. Dan satu lagi kucing marah tanpa bunyi mencicit. Dan hanya seekor kucing. Kemudian toko perlu menyiapkan penawaran yang dicari oleh Pasar. Toko menghasilkan xml khusus dengan penawaran dan mengomunikasikan jalur ke xml ini melalui antarmuka afiliasi. Pengindeks kemudian mengunduh xml ini secara berkala, memeriksa kesalahan dan menyimpan semua informasi ke dalam database besar.

Ada banyak xml yang disimpan. Indeks pencarian dibuat dari database ini. Indeks disimpan dalam format internal. Setelah membuat indeks, layanan Layout mengunggahnya ke server pencarian.

Akibatnya, kucing yang marah dengan squeaker muncul di database, dan indeks kucing tersebut muncul di server.

Saya akan memberi tahu Anda cara kami menelusuri kucing di bagian arsitektur penelusuran.

Arsitektur pencarian pasar

Kita hidup di dunia layanan mikro: setiap permintaan masuk pasar.yandex.ru menyebabkan banyak subkueri, dan lusinan layanan terlibat dalam pemrosesannya. Diagram hanya menunjukkan beberapa:

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal
Skema pemrosesan permintaan yang disederhanakan

Setiap layanan memiliki hal yang luar biasa - penyeimbangnya sendiri dengan nama unik:

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Penyeimbang memberi kami fleksibilitas lebih besar dalam mengelola layanan: Anda dapat, misalnya, mematikan server, yang sering kali diperlukan untuk pembaruan. Penyeimbang melihat bahwa server tidak tersedia dan secara otomatis mengalihkan permintaan ke server atau pusat data lain. Saat menambah atau menghapus server, beban secara otomatis didistribusikan kembali antar server.

Nama unik penyeimbang tidak bergantung pada pusat data. Ketika layanan A membuat permintaan ke B, maka secara default penyeimbang B mengalihkan permintaan tersebut ke pusat data saat ini. Jika layanan tidak tersedia atau tidak ada di pusat data saat ini, maka permintaan dialihkan ke pusat data lain.

FQDN tunggal untuk semua pusat data memungkinkan layanan A sepenuhnya abstrak dari lokasi. Permintaannya ke layanan B akan selalu diproses. Pengecualiannya adalah ketika layanan berlokasi di semua pusat data.

Namun tidak semuanya berjalan baik dengan penyeimbang ini: kami memiliki komponen perantara tambahan. Penyeimbang mungkin tidak stabil, dan masalah ini diselesaikan dengan server redundan. Ada juga penundaan tambahan antara layanan A dan B. Namun dalam praktiknya, penundaan ini kurang dari 1 ms dan untuk sebagian besar layanan, hal ini tidak penting.

Menghadapi Hal Tak Terduga: Keseimbangan dan Ketahanan Layanan Pencarian

Bayangkan ada keruntuhan: Anda perlu menemukan kucing dengan squeaker, tetapi server mogok. Atau 100 server. Bagaimana cara keluar? Apakah kita benar-benar akan meninggalkan pengguna tanpa kucing?

Situasinya menakutkan, tapi kami siap menghadapinya. Aku akan memberitahumu secara berurutan.

Infrastruktur pencarian terletak di beberapa pusat data:

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Saat mendesain, kami menyertakan kemungkinan mematikan satu pusat data. Hidup ini penuh kejutan - misalnya, sebuah ekskavator dapat memotong kabel bawah tanah (ya, itu memang terjadi). Kapasitas pusat data lainnya harus cukup untuk menahan beban puncak.

Mari kita pertimbangkan satu pusat data. Setiap pusat data memiliki skema operasi penyeimbang yang sama:

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal
Satu penyeimbang setidaknya adalah tiga server fisik. Redundansi ini dibuat untuk keandalan. Penyeimbang berjalan di HAProx.

Kami memilih HAProx karena kinerjanya yang tinggi, kebutuhan sumber daya yang rendah, dan fungsionalitas yang luas. Perangkat lunak pencarian kami berjalan di dalam setiap server.

Kemungkinan kegagalan satu server rendah. Namun jika Anda memiliki banyak server, kemungkinan setidaknya satu server akan down meningkat.

Inilah yang terjadi dalam kenyataan: server mogok. Oleh karena itu, perlu untuk terus memantau status semua server. Jika server berhenti merespons, maka secara otomatis terputus dari lalu lintas. Untuk tujuan ini, HAProxy memiliki pemeriksaan kesehatan bawaan. Ini masuk ke semua server sekali dalam satu detik dengan permintaan HTTP β€œ/ping”.

Fitur lain dari HAProxy: pemeriksaan agen memungkinkan Anda memuat semua server secara merata. Untuk melakukan ini, HAProxy terhubung ke semua server, dan mereka mengembalikan bobotnya tergantung pada beban saat ini dari 1 hingga 100. Bobot dihitung berdasarkan jumlah permintaan dalam antrian pemrosesan dan beban pada prosesor.

Sekarang tentang menemukan kucing itu. Hasil pencarian dalam permintaan seperti: /search?text=marah+kucing. Agar pencarian menjadi cepat, seluruh indeks cat harus masuk ke dalam RAM. Bahkan membaca dari SSD saja tidak cukup cepat.

Dahulu kala, basis data penawaran kecil, dan RAM satu server cukup untuk itu. Seiring bertambahnya basis penawaran, semuanya tidak lagi sesuai dengan RAM ini, dan data dibagi menjadi dua bagian: shard 1 dan shard 2.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal
Namun hal ini selalu terjadi: solusi apa pun, bahkan solusi yang baik sekalipun, akan menimbulkan masalah lain.

Penyeimbang masih masuk ke server mana pun. Namun pada mesin tempat permintaan datang, hanya ada setengah dari indeks. Sisanya ada di server lain. Oleh karena itu, server harus berpindah ke mesin tetangga. Setelah menerima data dari kedua server, hasilnya digabungkan dan diurutkan ulang.

Karena penyeimbang mendistribusikan permintaan secara merata, semua server terlibat dalam pemeringkatan ulang, dan tidak hanya mengirim data.

Masalah terjadi jika server tetangga tidak tersedia. Solusinya adalah dengan menetapkan beberapa server dengan prioritas berbeda sebagai server β€œtetangga”. Pertama, permintaan dikirim ke server di rak saat ini. Jika tidak ada respon, permintaan dikirim ke seluruh server di pusat data ini. Dan terakhir, permintaan tersebut ditujukan ke pusat data lainnya.
Seiring bertambahnya jumlah proposal, data dibagi menjadi empat bagian. Tapi ini bukanlah batasnya.

Saat ini, konfigurasi delapan pecahan digunakan. Selain itu, untuk menghemat lebih banyak memori, indeks dibagi menjadi bagian pencarian (yang digunakan untuk pencarian) dan bagian cuplikan (yang tidak terlibat dalam pencarian).

Satu server hanya berisi informasi untuk satu pecahan. Oleh karena itu, untuk mencari indeks lengkap, Anda perlu mencari di delapan server yang berisi pecahan berbeda.

Server dikelompokkan ke dalam cluster. Setiap cluster berisi delapan mesin pencari dan satu server cuplikan.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal
Server cuplikan menjalankan database nilai kunci dengan data statis. Mereka diperlukan untuk mengeluarkan dokumen, misalnya deskripsi kucing yang mencicit. Data tersebut secara khusus ditransfer ke server terpisah agar tidak memuat memori server pencarian.

Karena ID dokumen bersifat unik hanya dalam satu indeks, situasi dapat muncul ketika tidak ada dokumen dalam cuplikan. Nah, atau itu untuk satu ID akan berbeda isinya. Oleh karena itu, agar pencarian dapat berfungsi dan hasilnya dapat diperoleh, diperlukan konsistensi di seluruh cluster. Saya akan memberi tahu Anda di bawah ini bagaimana kami memantau konsistensi.

Pencarian itu sendiri disusun sebagai berikut: permintaan pencarian dapat datang ke salah satu dari delapan server. Katakanlah dia datang ke server 1. Server ini memproses semua argumen dan memahami apa dan bagaimana mencarinya. Tergantung pada permintaan yang masuk, server dapat membuat permintaan tambahan ke layanan eksternal untuk informasi yang diperlukan. Satu permintaan dapat diikuti hingga sepuluh permintaan ke layanan eksternal.

Setelah mengumpulkan informasi yang diperlukan, pencarian di database penawaran dimulai. Untuk melakukan hal ini, subkueri dibuat ke kedelapan server di cluster.

Setelah tanggapan diterima, hasilnya digabungkan. Pada akhirnya, beberapa subkueri lagi ke server cuplikan mungkin diperlukan untuk menghasilkan hasilnya.

Kueri pencarian dalam cluster terlihat seperti: /shard1?text=marah+kucing. Selain itu, subkueri formulir terus-menerus dibuat antara semua server dalam cluster satu kali dalam satu detik: /status.

Minta /status mendeteksi situasi di mana server tidak tersedia.

Ini juga mengontrol bahwa versi mesin pencari dan versi indeks sama di semua server, jika tidak maka akan ada data yang tidak konsisten di dalam cluster.

Meskipun satu server cuplikan memproses permintaan dari delapan mesin pencari, prosesornya memuat sangat sedikit. Oleh karena itu, kami sekarang mentransfer data cuplikan ke layanan terpisah.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Untuk mentransfer data, kami memperkenalkan kunci universal untuk dokumen. Sekarang tidak mungkin terjadi situasi di mana konten dari dokumen lain dikembalikan menggunakan satu kunci.

Namun transisi ke arsitektur lain belum selesai. Sekarang kami ingin menyingkirkan server cuplikan khusus. Dan kemudian menjauh dari struktur cluster sama sekali. Hal ini akan memungkinkan kami untuk terus melakukan penskalaan dengan mudah. Bonus tambahannya adalah penghematan zat besi yang signifikan.

Dan sekarang ke cerita seram dengan akhir yang bahagia. Mari kita pertimbangkan beberapa kasus tidak tersedianya server.

Sesuatu yang buruk terjadi: satu server tidak tersedia

Katakanlah satu server tidak tersedia. Kemudian server yang tersisa di cluster dapat terus merespons, namun hasil pencariannya tidak lengkap.

Melalui pemeriksaan status /status server tetangga memahami bahwa server tersebut tidak tersedia. Oleh karena itu, untuk menjaga kelengkapan, semua server di cluster per permintaan /ping mereka mulai merespons penyeimbang bahwa mereka juga tidak tersedia. Ternyata semua server di cluster mati (yang tidak benar). Ini adalah kelemahan utama skema klaster kami - itulah sebabnya kami ingin menghindarinya.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Permintaan yang gagal karena kesalahan dikirim ulang oleh penyeimbang di server lain.
Penyeimbang juga berhenti mengirimkan lalu lintas pengguna ke server mati, namun terus memeriksa statusnya.

Ketika server tersedia, ia mulai merespons /ping. Segera setelah respons normal terhadap ping dari server mati mulai tiba, penyeimbang mulai mengirimkan lalu lintas pengguna ke sana. Operasi cluster dipulihkan, hore.

Lebih buruk lagi: banyak server tidak tersedia

Sebagian besar server di pusat data ditebang. Apa yang harus dilakukan, ke mana harus lari? Penyeimbang datang untuk menyelamatkan lagi. Setiap penyeimbang secara konstan menyimpan dalam memori jumlah server aktif saat ini. Ini secara konstan menghitung jumlah lalu lintas maksimum yang dapat diproses oleh pusat data saat ini.

Ketika banyak server di sebuah pusat data mati, penyeimbang menyadari bahwa pusat data ini tidak dapat memproses semua lalu lintas.

Kemudian kelebihan lalu lintas mulai didistribusikan secara acak ke pusat data lainnya. Semuanya berfungsi, semua orang senang.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Bagaimana kami melakukannya: menerbitkan rilis

Sekarang mari kita bahas tentang cara kami memublikasikan perubahan yang dilakukan pada layanan. Di sini kami telah mengambil jalur penyederhanaan proses: peluncuran rilis baru hampir sepenuhnya dilakukan secara otomatis.
Ketika sejumlah perubahan terakumulasi dalam proyek, rilis baru secara otomatis dibuat dan pembangunannya dimulai.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Layanan kemudian diluncurkan ke pengujian, di mana stabilitas operasi diperiksa.

Pada saat yang sama, pengujian kinerja otomatis diluncurkan. Ini ditangani oleh layanan khusus. Saya tidak akan membicarakannya sekarang - uraiannya layak untuk artikel terpisah.

Jika publikasi dalam pengujian berhasil, publikasi rilis dalam prestable secara otomatis dimulai. Prestable adalah cluster khusus tempat lalu lintas pengguna normal diarahkan. Jika menghasilkan kesalahan, penyeimbang membuat permintaan ulang ke produksi.

Dalam prestabil, waktu respons diukur dan dibandingkan dengan rilis produksi sebelumnya. Jika semuanya baik-baik saja, maka seseorang akan terhubung: memeriksa grafik dan hasil pengujian beban dan kemudian mulai meluncurkan ke produksi.

Semua yang terbaik diberikan kepada pengguna: pengujian A/B

Tidak selalu jelas apakah perubahan pada suatu layanan akan membawa manfaat nyata. Untuk mengukur manfaat perubahan, orang-orang melakukan pengujian A/B. Saya akan memberi tahu Anda sedikit tentang cara kerjanya di pencarian Yandex.Market.

Semuanya dimulai dengan menambahkan parameter CGI baru yang memungkinkan fungsionalitas baru. Biarkan parameter kita menjadi: pasar_fungsi_baru=1. Kemudian dalam kode kami mengaktifkan fungsi ini jika ada tanda:

If (cgi.experiments.market_new_functionality) {
// enable new functionality
}

Fungsionalitas baru sedang diluncurkan ke produksi.

Untuk mengotomatiskan pengujian A/B, ada layanan khusus yang menyediakan informasi mendetail dijelaskan di sini. Eksperimen dibuat di layanan. Pembagian lalu lintas ditetapkan, misalnya, 15%. Persentase ditetapkan bukan untuk kueri, tetapi untuk pengguna. Durasi percobaan juga ditunjukkan, misalnya seminggu.

Beberapa eksperimen dapat dijalankan secara bersamaan. Dalam pengaturan, Anda dapat menentukan apakah persimpangan dengan eksperimen lain dimungkinkan.

Hasilnya, layanan secara otomatis menambahkan argumen pasar_fungsi_baru=1 hingga 15% pengguna. Ini juga secara otomatis menghitung metrik yang dipilih. Setelah percobaan selesai, analis melihat hasilnya dan menarik kesimpulan. Berdasarkan temuan tersebut, keputusan dibuat untuk meluncurkan ke produksi atau penyempurnaan.

Tangan cekatan pasar: pengujian dalam produksi

Sering terjadi bahwa Anda perlu menguji pengoperasian fungsi baru dalam produksi, tetapi Anda tidak yakin bagaimana perilakunya dalam kondisi "pertempuran" di bawah beban berat.

Ada solusinya: flag dalam parameter CGI dapat digunakan tidak hanya untuk pengujian A/B, tetapi juga untuk menguji fungsionalitas baru.

Kami membuat alat yang memungkinkan Anda mengubah konfigurasi secara instan di ribuan server tanpa membuat layanan terkena risiko. Ini disebut Berhenti Ketuk. Ide awalnya adalah untuk dapat dengan cepat menonaktifkan beberapa fungsi tanpa tata letak. Kemudian alat tersebut berkembang dan menjadi lebih kompleks.

Diagram alur layanan disajikan di bawah ini:

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Nilai bendera ditetapkan melalui API. Layanan manajemen menyimpan nilai-nilai ini dalam database. Semua server masuk ke database setiap sepuluh detik sekali, mengeluarkan nilai tanda dan menerapkan nilai ini ke setiap permintaan.

Di ketukan Berhenti Anda dapat mengatur dua jenis nilai:

1) Ekspresi bersyarat. Terapkan ketika salah satu nilainya benar. Misalnya:

{
	"condition":"IS_DC1",
	"value":"3",
}, 
{
	"condition": "CLUSTER==2 and IS_BERU", 
	"value": "4!" 
}

Nilai "3" akan diterapkan ketika permintaan diproses di lokasi DC1. Dan nilainya adalah β€œ4” saat permintaan diproses pada cluster kedua untuk situs beru.ru.

2) Nilai tanpa syarat. Terapkan secara default jika tidak ada ketentuan yang terpenuhi. Misalnya:

nilai, nilai!

Jika suatu nilai diakhiri dengan tanda seru, maka nilai tersebut diberi prioritas lebih tinggi.

Pengurai parameter CGI mem-parsing URL. Kemudian terapkan nilai dari Stop Tap.

Nilai dengan prioritas berikut diterapkan:

  1. Dengan peningkatan prioritas dari Stop Tap (tanda seru).
  2. Nilai dari permintaan.
  3. Nilai default dari Hentikan ketuk.
  4. Nilai default dalam kode.

Ada banyak tanda yang ditunjukkan dalam nilai bersyarat - itu cukup untuk semua skenario yang kita ketahui:

  • Pusat Data.
  • Lingkungan: produksi, pengujian, bayangan.
  • Tempat: pasar, beru.
  • Nomor klaster.

Dengan alat ini, Anda dapat mengaktifkan fungsionalitas baru pada sekelompok server tertentu (misalnya, hanya di satu pusat data) dan menguji pengoperasian fungsi ini tanpa risiko tertentu terhadap keseluruhan layanan. Bahkan jika Anda membuat kesalahan serius di suatu tempat, semuanya mulai turun dan seluruh pusat data mati, penyeimbang akan mengalihkan permintaan ke pusat data lain. Pengguna akhir tidak akan menyadari apa pun.

Jika Anda melihat ada masalah, Anda dapat segera mengembalikan tanda ke nilai sebelumnya dan perubahan akan dibatalkan.

Layanan ini juga memiliki kelemahan: pengembang sangat menyukainya dan sering kali mencoba memasukkan semua perubahan ke dalam Stop Tap. Kami mencoba memerangi penyalahgunaan.

Pendekatan Stop Tap berfungsi dengan baik ketika Anda sudah memiliki kode stabil yang siap diluncurkan ke produksi. Pada saat yang sama, Anda masih ragu, dan Anda ingin memeriksa kode dalam kondisi "pertempuran".

Namun, Stop Tap tidak cocok untuk pengujian selama pengembangan. Ada cluster terpisah untuk pengembang, yang disebut β€œshadow cluster”.

Pengujian Rahasia: Cluster Bayangan

Permintaan dari salah satu cluster diduplikasi ke cluster bayangan. Namun penyeimbang sepenuhnya mengabaikan respons dari cluster ini. Diagram operasinya disajikan di bawah ini.

Cara kerja pencarian Yandex.Market dan apa yang terjadi jika salah satu server gagal

Kami mendapatkan cluster uji yang berada dalam kondisi "pertempuran" nyata. Lalu lintas pengguna normal menuju ke sana. Perangkat keras di kedua cluster sama, sehingga performa dan error dapat dibandingkan.

Dan karena penyeimbang sepenuhnya mengabaikan respons, pengguna akhir tidak akan melihat respons dari cluster bayangan. Oleh karena itu, tidak menakutkan untuk melakukan kesalahan.

Temuan

Jadi, bagaimana kami membangun pencarian Pasar?

Agar semuanya berjalan lancar, kami memisahkan fungsionalitas ke dalam layanan terpisah. Dengan cara ini kita hanya dapat menskalakan komponen-komponen yang kita perlukan dan membuat komponen-komponen tersebut menjadi lebih sederhana. Sangat mudah untuk menugaskan komponen terpisah ke tim lain dan berbagi tanggung jawab untuk mengerjakannya. Dan penghematan besi yang signifikan dengan pendekatan ini merupakan nilai tambah yang jelas.

Cluster bayangan juga membantu kami: kami dapat mengembangkan layanan, mengujinya dalam prosesnya, dan tidak mengganggu pengguna.

Tentu saja, pengujian dalam produksi. Perlu mengubah konfigurasi di ribuan server? Gampang, gunakan Stop Tap. Dengan cara ini Anda dapat segera meluncurkan solusi kompleks yang sudah jadi dan mengembalikan ke versi stabil jika muncul masalah.

Saya harap saya dapat menunjukkan bagaimana kami menjadikan Pasar cepat dan stabil dengan basis penawaran yang terus berkembang. Bagaimana kami memecahkan masalah server, menangani permintaan dalam jumlah besar, meningkatkan fleksibilitas layanan dan melakukannya tanpa mengganggu proses kerja.

Sumber: www.habr.com

Tambah komentar