I-load ang pag-optimize sa isang Highload na proyekto gamit ang ElasticSearch

Hoy Habr! Ang pangalan ko ay Maxim Vasiliev, nagtatrabaho ako bilang isang analyst at project manager sa FINCH. Ngayon gusto kong sabihin sa iyo kung paano, gamit ang ElasticSearch, naproseso namin ang 15 milyong kahilingan sa loob ng 6 na minuto at na-optimize ang pang-araw-araw na pag-load sa site ng isa sa aming mga kliyente. Sa kasamaang palad, kailangan naming gawin nang walang mga pangalan, dahil mayroon kaming NDA, inaasahan namin na ang nilalaman ng artikulo ay hindi magdusa mula dito. Tara na.

Paano gumagana ang proyekto

Sa aming backend, lumikha kami ng mga serbisyong nagsisiguro sa pagganap ng mga website at mobile application ng aming kliyente. Ang pangkalahatang istraktura ay makikita sa diagram:

I-load ang pag-optimize sa isang Highload na proyekto gamit ang ElasticSearch

Sa proseso ng trabaho, pinoproseso namin ang isang malaking bilang ng mga transaksyon: mga pagbili, pagbabayad, pagpapatakbo na may mga balanse ng gumagamit, kung saan nag-iimbak kami ng maraming mga log, pati na rin ang pag-import at pag-export ng data na ito sa mga panlabas na system.

Mayroon ding mga reverse na proseso kapag nakatanggap kami ng data mula sa kliyente at inilipat ito sa user. Bilang karagdagan, mayroon pa ring mga proseso para sa pagtatrabaho sa mga pagbabayad at mga programa ng bonus.

Maikling background

Sa una, ginamit namin ang PostgreSQL bilang ang tanging data store. Ang mga karaniwang bentahe nito para sa isang DBMS: ang pagkakaroon ng mga transaksyon, isang binuong wika ng sampling ng data, isang malawak na hanay ng mga tool para sa pagsasama; na sinamahan ng mahusay na pagganap ay nasiyahan ang aming mga pangangailangan sa loob ng mahabang panahon.

Talagang inimbak namin ang lahat ng data sa Postgres: mula sa mga transaksyon hanggang sa balita. Ngunit ang bilang ng mga gumagamit ay lumago, at kasama nito ang bilang ng mga kahilingan.

Para sa pag-unawa, ang taunang bilang ng mga session sa 2017 lamang sa desktop site ay 131 milyon. Sa 2018 - 125 milyon. 2019 muli 130 milyon. Magdagdag ng isa pang 100-200 milyon mula sa mobile na bersyon ng site at ang mobile application, at ikaw ay makakakuha ng malaking bilang ng mga kahilingan.

Sa paglaki ng proyekto, ang mga Postgres ay tumigil sa pagkaya sa pagkarga, wala kaming oras - isang malaking bilang ng iba't ibang mga query ang lumitaw, kung saan hindi kami makakalikha ng sapat na bilang ng mga index.

Naunawaan namin na may pangangailangan para sa iba pang mga data store na magbibigay ng aming mga pangangailangan at mag-alis ng load sa PostgreSQL. Ang Elasticsearch at MongoDB ay itinuturing na posibleng mga pagpipilian. Ang huli ay natalo sa mga sumusunod na puntos:

  1. Mabagal na bilis ng pag-index habang lumalaki ang dami ng data sa mga index. Sa Elastic, ang bilis ay hindi nakadepende sa dami ng data.
  2. Walang buong paghahanap ng teksto

Kaya pinili namin ang Elastic para sa aming sarili at naghanda para sa paglipat.

Paglipat sa Elastic

1. Sinimulan namin ang paglipat mula sa serbisyo ng paghahanap sa punto ng pagbebenta. Ang aming kliyente ay may kabuuang humigit-kumulang 70 puntos ng pagbebenta, at nangangailangan ito ng ilang uri ng paghahanap sa site at sa application:

  • Paghahanap ng teksto ayon sa pangalan ng lungsod
  • Geosearch sa loob ng ibinigay na radius mula sa ilang punto. Halimbawa, kung gusto ng user na makita kung aling mga punto ng pagbebenta ang pinakamalapit sa kanyang tahanan.
  • Maghanap sa pamamagitan ng isang ibinigay na parisukat - ang gumagamit ay gumuhit ng isang parisukat sa mapa, at lahat ng mga punto sa radius na ito ay ipinapakita sa kanya.
  • Maghanap sa pamamagitan ng mga karagdagang filter. Ang mga punto ng pagbebenta ay naiiba sa isa't isa sa assortment

Kung pinag-uusapan natin ang organisasyon, kung gayon sa Postgres mayroon tayong pinagmumulan ng data para sa parehong mapa at balita, at sa Elastic Snapshots ay kinuha mula sa orihinal na data. Ang katotohanan ay sa una ay hindi nakayanan ng mga Postgres ang paghahanap ayon sa lahat ng pamantayan. Hindi lamang mayroong maraming mga index, maaari rin silang mag-overlap, kaya ang Postgres scheduler ay nawala at hindi naiintindihan kung aling index ang gagamitin.

2. Sumunod sa linya ay ang seksyon ng balita. Ang mga publikasyon ay lilitaw sa site araw-araw upang ang gumagamit ay hindi mawala sa daloy ng impormasyon, ang data ay dapat na pinagsunod-sunod bago mag-isyu. Ito ang para sa paghahanap: maaari kang maghanap sa site sa pamamagitan ng tugma ng teksto, at kasabay nito ay ikonekta ang mga karagdagang filter, dahil ginawa rin ang mga ito sa pamamagitan ng Elastic.

3. Pagkatapos ay inilipat namin ang pagproseso ng transaksyon. Ang mga gumagamit ay maaaring bumili ng isang partikular na produkto sa site at lumahok sa isang premyo na draw. Pagkatapos ng mga naturang pagbili, nagpoproseso kami ng malaking halaga ng data, lalo na sa mga weekend at holiday. Para sa paghahambing, kung sa mga ordinaryong araw ang bilang ng mga pagbili ay nasa pagitan ng 1,5-2 milyon, kung gayon sa mga pista opisyal ang bilang ay maaaring umabot sa 53 milyon.

Kasabay nito, ang data ay dapat na maproseso sa pinakamaikling posibleng oras - ang mga gumagamit ay hindi gustong maghintay para sa resulta ng ilang araw. Walang paraan upang makamit ang mga naturang deadline sa pamamagitan ng Postgres - madalas kaming nakatanggap ng mga lock, at habang pinoproseso namin ang lahat ng kahilingan, hindi masuri ng mga user kung nakatanggap sila ng mga premyo o hindi. Ito ay hindi masyadong kaaya-aya para sa negosyo, kaya inilipat namin ang pagproseso sa Elasticsearch.

Paminsan-minsan

Ngayon ang mga update ay naka-configure batay sa kaganapan, ayon sa mga sumusunod na kundisyon:

  1. Mga puntos sa pagbebenta. Sa sandaling makatanggap kami ng data mula sa isang panlabas na pinagmulan, agad naming sisimulan ang pag-update.
  2. Balita. Sa sandaling ma-edit ang anumang balita sa site, awtomatiko itong ipapadala sa Elastic.

Narito muli ito ay nagkakahalaga ng pagbanggit ng mga pakinabang ng Elastic. Sa Postgres, kapag nagpapadala ng kahilingan, kailangan mong maghintay hanggang sa matapat nitong iproseso ang lahat ng mga tala. Maaari kang magpadala ng 10 record sa Elastic at magsimulang magtrabaho kaagad, nang hindi naghihintay na maipamahagi ang mga tala sa lahat ng Shards. Siyempre, maaaring hindi agad makita ng ilang Shard o Replica ang data, ngunit magiging available na ang lahat sa lalong madaling panahon.

Mga pamamaraan ng pagsasama

Mayroong 2 paraan upang maisama sa Elastic:

  1. Sa pamamagitan ng katutubong kliyente sa TCP. Ang katutubong driver ay unti-unting namamatay: hindi na ito suportado, mayroon itong napaka-inconvenient na syntax. Samakatuwid, halos hindi namin ito ginagamit at sinusubukan na ganap na iwanan ito.
  2. Sa pamamagitan ng HTTP interface na maaaring gumamit ng parehong mga kahilingan sa JSON at Lucene syntax. Ang huli ay isang text engine na gumagamit ng Elastic. Sa bersyong ito, nakakakuha kami ng kakayahang mag-Batch sa pamamagitan ng mga kahilingan ng JSON sa HTTP. Ito ang opsyon na sinusubukan naming gamitin.

Salamat sa interface ng HTTP, maaari kaming gumamit ng mga library na nagbibigay ng asynchronous na pagpapatupad ng HTTP client. Maaari naming samantalahin ang Batch at ang asynchronous na API, na nagreresulta sa mataas na pagganap, na nakatulong nang malaki sa mga araw ng malaking promosyon (higit pa sa ibaba)

Ilang numero para sa paghahambing:

  • Pag-save ng mga Postgres bounty user sa 20 thread nang walang pagpapangkat: 460713 record sa loob ng 42 segundo
  • Elastic + reactive client para sa 10 thread + batch para sa 1000 elemento: 596749 record sa loob ng 11 segundo
  • Elastic + reactive client para sa 10 thread + batch para sa 1000 elemento: 23801684 entry sa loob ng 4 na minuto

Ngayon ay nagsulat na kami ng HTTP request manager na bumubuo ng JSON bilang Batch/not Batch at ipinapadala ito sa pamamagitan ng anumang HTTP client, anuman ang library. Maaari mo ring piliing magpadala ng mga kahilingan nang sabay-sabay o asynchronously.

Sa ilang mga pagsasama, ginagamit pa rin namin ang opisyal na kliyente ng transportasyon, ngunit ito ay isang bagay lamang ng susunod na refactoring. Sa kasong ito, ang isang custom na kliyente na binuo batay sa Spring WebClient ay ginagamit para sa pagproseso.

I-load ang pag-optimize sa isang Highload na proyekto gamit ang ElasticSearch

malaking promosyon

Minsan sa isang taon, ang proyekto ay nagho-host ng malaking promosyon para sa mga user - ito ang parehong Highload, dahil sa ngayon ay nakikipagtulungan kami sa sampu-sampung milyong user nang sabay-sabay.

Karaniwan ang mga peak of load ay nangyayari sa panahon ng holidays, ngunit ang promosyon na ito ay nasa ibang antas. Noong nakaraang taon, sa araw ng promosyon, nakabenta kami ng 27 units ng mga produkto. Ang data ay naproseso nang higit sa kalahating oras, na nagdulot ng abala para sa mga user. Ang mga gumagamit ay nakatanggap ng mga premyo para sa pakikilahok, ngunit naging malinaw na ang proseso ay kailangang pabilisin.

Sa simula ng 2019, napagpasyahan namin na kailangan namin ang ElasticSearch. Sa loob ng isang buong taon, inayos namin ang pagproseso ng natanggap na data sa Elastic at ang pag-isyu ng mga ito sa api ng mobile application at website. Bilang resulta, sa susunod na taon sa panahon ng kampanya, naproseso namin 15 entries sa loob ng 131 na minuto.

Dahil marami tayong gustong bumili ng mga kalakal at makilahok sa pagguhit ng mga premyo sa mga promosyon, ito ay pansamantalang panukala. Ngayon ay nagpapadala kami ng up-to-date na impormasyon sa Elastic, ngunit sa hinaharap plano naming ilipat ang naka-archive na impormasyon sa mga nakaraang buwan sa Postgres bilang isang permanenteng storage. Upang hindi mabara ang Elastic index, na mayroon ding mga limitasyon.

Konklusyon/Konklusyon

Sa ngayon, inilipat namin ang lahat ng serbisyong gusto namin sa Elastic at itinigil na namin ito sa ngayon. Ngayon ay bubuo kami ng index sa Elastic sa ibabaw ng pangunahing patuloy na storage sa Postgres, na siyang humahawak sa pag-load ng user.

Sa hinaharap, plano naming maglipat ng mga serbisyo kung nauunawaan namin na ang kahilingan ng data ay nagiging masyadong magkakaibang at hinahanap ang walang limitasyong bilang ng mga column. Hindi na ito gawain para sa mga Postgres.

Kung kailangan namin ng full-text na paghahanap sa functionality o kung marami kaming iba't ibang pamantayan sa paghahanap, alam na namin na kailangan itong isalin sa Elastic.

⌘⌘⌘

Salamat sa pagbabasa. Kung gumagamit din ang iyong kumpanya ng ElasticSearch at may sariling mga kaso ng pagpapatupad, sabihin sa amin. Magiging kawili-wiling malaman kung paano ang iba πŸ™‚

Pinagmulan: www.habr.com

Magdagdag ng komento