Muat pengoptimalan pada proyek Highload dengan ElasticSearch

Hai Habr! Nama saya Maxim Vasiliev, saya bekerja sebagai analis dan manajer proyek di FINCH. Hari ini saya ingin memberi tahu Anda bagaimana, dengan menggunakan ElasticSearch, kami dapat memproses 15 juta permintaan dalam 6 menit dan mengoptimalkan pemuatan harian di situs salah satu klien kami. Sayangnya, kami harus melakukannya tanpa nama, karena kami memiliki NDA, kami berharap isi artikel tidak mengalami hal ini. Ayo pergi.

Bagaimana proyek ini bekerja

Di backend kami, kami menciptakan layanan yang menjamin kinerja situs web dan aplikasi seluler klien kami. Struktur umum dapat dilihat pada diagram:

Muat pengoptimalan pada proyek Highload dengan ElasticSearch

Dalam proses kerja, kami memproses sejumlah besar transaksi: pembelian, pembayaran, operasi dengan saldo pengguna, yang mana kami menyimpan banyak log, serta mengimpor dan mengekspor data ini ke sistem eksternal.

Ada juga proses sebaliknya ketika kami menerima data dari klien dan mentransfernya ke pengguna. Selain itu, masih ada proses pengerjaan pembayaran dan program bonus.

Latar belakang singkat

Awalnya, kami menggunakan PostgreSQL sebagai satu-satunya penyimpan data. Keuntungan standarnya untuk DBMS: adanya transaksi, bahasa pengambilan sampel data yang dikembangkan, berbagai alat untuk integrasi; dikombinasikan dengan kinerja yang baik memenuhi kebutuhan kami untuk waktu yang cukup lama.

Kami benar-benar menyimpan semua data di Postgres: mulai dari transaksi hingga berita. Namun jumlah pengguna bertambah, dan seiring dengan itu jumlah permintaan.

Sebagai pemahaman, jumlah sesi tahunan pada tahun 2017 hanya di situs desktop adalah 131 juta. Pada tahun 2018 - 125 juta. 2019 lagi 130 juta. Tambahkan 100-200 juta lagi dari situs versi seluler dan aplikasi seluler, dan Anda akan mendapatkan permintaan dalam jumlah besar.

Dengan pertumbuhan proyek, Postgres berhenti mengatasi beban, kami tidak punya waktu - sejumlah besar permintaan berbeda muncul, sehingga kami tidak dapat membuat indeks dalam jumlah yang cukup.

Kami memahami bahwa ada kebutuhan akan penyimpanan data lain yang dapat memenuhi kebutuhan kami dan meringankan beban PostgreSQL. Elasticsearch dan MongoDB dianggap sebagai opsi yang memungkinkan. Yang terakhir ini kalah dalam beberapa hal berikut:

  1. Kecepatan pengindeksan lambat seiring bertambahnya jumlah data dalam indeks. Dengan Elastic, kecepatan tidak bergantung pada jumlah data.
  2. Tidak ada pencarian teks lengkap

Jadi kami memilih Elastic untuk diri kami sendiri dan bersiap untuk transisi.

Transisi ke Elastis

1. Kami memulai transisi dari layanan pencarian titik penjualan. Klien kami memiliki total sekitar 70 titik penjualan, dan ini memerlukan beberapa jenis pencarian di situs dan aplikasi:

  • Pencarian teks berdasarkan nama kota
  • Geosearch dalam radius tertentu dari beberapa titik. Misalnya saja pengguna ingin melihat tempat penjualan mana yang paling dekat dengan rumahnya.
  • Cari berdasarkan kotak tertentu - pengguna menggambar kotak di peta, dan semua titik dalam radius ini ditampilkan kepadanya.
  • Cari berdasarkan filter tambahan. Tempat penjualan berbeda satu sama lain dalam jangkauannya

Jika kita berbicara tentang organisasi, maka di Postgres kita memiliki sumber data untuk peta dan berita, dan di Elastic Snapshots diambil dari data asli. Faktanya adalah pada awalnya Postgres tidak dapat mengatasi pencarian berdasarkan semua kriteria. Tidak hanya indeksnya banyak, bisa juga tumpang tindih sehingga penjadwal Postgres tersesat dan tidak paham indeks mana yang akan digunakan.

2. Baris berikutnya adalah bagian berita. Publikasi muncul di situs setiap hari, agar pengguna tidak tersesat dalam arus informasi, data harus disortir sebelum diterbitkan. Inilah gunanya pencarian: Anda dapat mencari situs dengan pencocokan teks, dan pada saat yang sama menghubungkan filter tambahan, karena filter tersebut juga dibuat melalui Elastic.

3. Kemudian kita pindahkan proses transaksinya. Pengguna dapat membeli produk tertentu di situs dan berpartisipasi dalam pengundian hadiah. Setelah pembelian tersebut, kami memproses data dalam jumlah besar, terutama pada akhir pekan dan hari libur. Sebagai perbandingan, jika pada hari biasa jumlah pembelian berkisar antara 1,5-2 juta, maka pada hari libur angkanya bisa mencapai 53 juta.

Pada saat yang sama, data harus diproses dalam waktu sesingkat mungkin - pengguna tidak suka menunggu hasilnya selama beberapa hari. Tidak ada cara untuk mencapai tenggat waktu seperti itu melalui Postgres - kami sering menerima kunci, dan saat kami memproses semua permintaan, pengguna tidak dapat memeriksa apakah mereka menerima hadiah atau tidak. Ini sangat tidak menyenangkan bagi bisnis, jadi kami memindahkan pemrosesan ke Elasticsearch.

Periodisitas

Sekarang pembaruan dikonfigurasikan berdasarkan peristiwa, sesuai dengan kondisi berikut:

  1. Poin penjualan. Segera setelah kami menerima data dari sumber eksternal, kami segera memulai pembaruan.
  2. Berita. Segera setelah berita apa pun diedit di situs, berita tersebut secara otomatis dikirim ke Elastic.

Di sini sekali lagi perlu disebutkan keunggulan Elastic. Di Postgres, saat mengirim permintaan, Anda harus menunggu hingga permintaan tersebut memproses semua catatan dengan jujur. Anda dapat mengirim 10 catatan ke Elastic dan segera mulai bekerja, tanpa menunggu catatan didistribusikan ke seluruh Shard. Tentu saja, beberapa Shard atau Replika mungkin tidak langsung melihat datanya, tetapi semuanya akan segera tersedia.

Metode integrasi

Ada 2 cara untuk berintegrasi dengan Elastic:

  1. Melalui klien asli melalui TCP. Driver asli secara bertahap mati: tidak lagi didukung, ia memiliki sintaksis yang sangat merepotkan. Oleh karena itu, kami praktis tidak menggunakannya dan mencoba untuk meninggalkannya sepenuhnya.
  2. Melalui antarmuka HTTP yang dapat menggunakan permintaan JSON dan sintaksis Lucene. Yang terakhir adalah mesin teks yang menggunakan Elastic. Dalam versi ini, kami mendapatkan kemampuan untuk melakukan Batch melalui permintaan JSON melalui HTTP. Ini adalah opsi yang kami coba gunakan.

Berkat antarmuka HTTP, kita dapat menggunakan perpustakaan yang menyediakan implementasi klien HTTP yang tidak sinkron. Kita dapat memanfaatkan Batch dan API asinkron, yang menghasilkan kinerja tinggi, yang sangat membantu pada hari-hari promosi besar (selengkapnya di bawah)

Beberapa angka untuk perbandingan:

  • Menyimpan pengguna bounty Postgres dalam 20 thread tanpa pengelompokan: 460713 catatan dalam 42 detik
  • Klien elastis + reaktif untuk 10 utas + batch untuk 1000 elemen: 596749 catatan dalam 11 detik
  • Klien elastis + reaktif untuk 10 utas + batch untuk 1000 elemen: 23801684 entri dalam 4 menit

Sekarang kami telah menulis manajer permintaan HTTP yang membangun JSON sebagai Batch/bukan Batch dan mengirimkannya melalui klien HTTP apa pun, apa pun perpustakaannya. Anda juga dapat memilih untuk mengirim permintaan secara sinkron atau asinkron.

Dalam beberapa integrasi, kami masih menggunakan klien transport resmi, tetapi ini hanya masalah pemfaktoran ulang berikutnya. Dalam hal ini, klien khusus yang dibangun berdasarkan Spring WebClient digunakan untuk pemrosesan.

Muat pengoptimalan pada proyek Highload dengan ElasticSearch

promosi besar

Setahun sekali, proyek ini mengadakan promosi besar-besaran untuk pengguna - ini adalah Highload yang sama, karena saat ini kami bekerja dengan puluhan juta pengguna secara bersamaan.

Biasanya puncak muatan terjadi pada hari libur, namun promosi ini berada pada level yang sama sekali berbeda. Setahun sebelumnya, pada hari promosi, kami menjual 27 unit barang. Data diproses lebih dari setengah jam, sehingga menimbulkan ketidaknyamanan bagi pengguna. Pengguna menerima hadiah atas partisipasinya, namun menjadi jelas bahwa prosesnya perlu dipercepat.

Pada awal tahun 2019, kami memutuskan bahwa kami membutuhkan ElasticSearch. Selama setahun penuh, kami mengatur pemrosesan data yang diterima di Elastic dan penerbitannya di api aplikasi seluler dan situs web. Alhasil, tahun berikutnya saat kampanye, kami proses 15 entri dalam 131 menit.

Karena kami memiliki banyak orang yang ingin membeli barang dan berpartisipasi dalam pengundian hadiah dalam promosi, ini adalah tindakan sementara. Sekarang kami mengirimkan informasi terkini ke Elastic, tetapi di masa depan kami berencana untuk mentransfer informasi yang diarsipkan selama beberapa bulan terakhir ke Postgres sebagai penyimpanan permanen. Agar tidak menyumbat indeks elastis yang juga memiliki keterbatasan.

Kesimpulan/Kesimpulan

Saat ini, kami telah mentransfer semua layanan yang kami inginkan ke Elastic dan telah menghentikannya untuk saat ini. Sekarang kami sedang membangun indeks di Elastic di atas penyimpanan persisten utama di Postgres, yang mengambil alih beban pengguna.

Di masa depan, kami berencana untuk mentransfer layanan jika kami memahami bahwa permintaan data menjadi terlalu beragam dan dicari dalam jumlah kolom yang tidak terbatas. Ini bukan lagi tugas Postgres.

Jika kita memerlukan pencarian teks lengkap dalam hal fungsionalitas atau jika kita memiliki banyak kriteria pencarian yang berbeda, maka kita sudah tahu bahwa ini perlu diterjemahkan ke dalam Elastic.

⌘⌘⌘

Terima kasih sudah membaca. Jika perusahaan Anda juga menggunakan ElasticSearch dan memiliki kasus penerapannya sendiri, beri tahu kami. Akan menarik untuk mengetahui bagaimana keadaan orang lain πŸ™‚

Sumber: www.habr.com

Tambah komentar