Ang compression ng data sa Apache Ignite. Ang karanasan ni Sber

Ang compression ng data sa Apache Ignite. Ang karanasan ni SberKapag nagtatrabaho sa malalaking volume ng data, ang problema ng kakulangan ng puwang sa disk ay maaaring lumitaw kung minsan. Ang isang paraan upang malutas ang problemang ito ay ang compression, salamat sa kung saan, sa parehong kagamitan, maaari mong kayang dagdagan ang mga volume ng imbakan. Sa artikulong ito, titingnan natin kung paano gumagana ang data compression sa Apache Ignite. Ilalarawan lamang ng artikulong ito ang mga pamamaraan ng pag-compress ng disk na ipinatupad sa loob ng produkto. Ang iba pang mga paraan ng pag-compress ng data (sa network, sa memorya), ipinatupad man o hindi, ay mananatili sa labas ng saklaw.

Kaya, kapag pinagana ang mode ng pagtitiyaga, bilang resulta ng mga pagbabago sa data sa mga cache, ang Ignite ay nagsimulang magsulat sa disk:

  1. Mga nilalaman ng mga cache
  2. Sumulat ng Ahead Log (pagkatapos dito ay WAL lang)

Medyo matagal nang may mekanismo para sa WAL compression, na tinatawag na WAL compaction. Ang kamakailang inilabas na Apache Ignite 2.8 ay nagpakilala ng dalawa pang mekanismo na nagbibigay-daan sa iyong i-compress ang data sa disk: disk page compression para sa pag-compress ng mga nilalaman ng mga cache at WAL page snapshot compression para sa pag-compress ng ilang WAL entries. Higit pang mga detalye tungkol sa lahat ng tatlong mekanismong ito sa ibaba.

Pag-compress ng pahina ng disk

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

Una, tingnan natin kung paano nag-iimbak ng data ang Ignite. Ang memorya ng pahina ay ginagamit para sa imbakan. Ang laki ng pahina ay nakatakda sa simula ng node at hindi mababago sa mga susunod na yugto; gayundin, ang laki ng pahina ay dapat na isang kapangyarihan ng dalawa at isang multiple ng laki ng block ng file system. Ang mga pahina ay na-load sa RAM mula sa disk kung kinakailangan; ang laki ng data sa disk ay maaaring lumampas sa halaga ng inilaan na RAM. Kung walang sapat na espasyo sa RAM upang mai-load ang isang pahina mula sa disk, ang mga luma, hindi na ginagamit na mga pahina ay aalisin mula sa RAM.

Ang data ay naka-imbak sa disk sa sumusunod na anyo: isang hiwalay na file ay nilikha para sa bawat partition ng bawat cache group; sa file na ito, ang mga pahina ay lilitaw nang sunud-sunod sa pataas na pagkakasunud-sunod ng index. Ang buong page identifier ay naglalaman ng cache group identifier, partition number, at page index sa file. Kaya, gamit ang buong page identifier, maaari naming natatanging matukoy ang file at ang offset sa file para sa bawat page. Maaari kang magbasa nang higit pa tungkol sa paging memory sa artikulo ng Apache Ignite Wiki: Ignite Persistent Store - sa ilalim ng hood.

Ang mekanismo ng pag-compress ng pahina ng disk, tulad ng maaari mong hulaan mula sa pangalan, ay gumagana sa antas ng pahina. Kapag ang mekanismong ito ay pinagana, ang data sa RAM ay pinoproseso nang walang anumang compression, ngunit kapag ang mga pahina ay nai-save mula sa RAM patungo sa disk, sila ay na-compress.

Ngunit ang pag-compress sa bawat pahina nang paisa-isa ay hindi solusyon sa problema; kailangan mong bawasan ang laki ng mga resultang file ng data. Kung ang laki ng pahina ay hindi na maayos, hindi na kami makakapagsulat ng mga pahina sa file nang sunud-sunod, dahil maaari itong lumikha ng ilang mga problema:

  • Gamit ang index ng pahina, hindi namin magagawang kalkulahin ang offset kung saan ito matatagpuan sa file.
  • Hindi malinaw kung ano ang gagawin sa mga pahinang wala sa dulo ng file at nagbabago ng laki. Kung bumababa ang laki ng pahina, mawawala ang espasyong binitawan nito. Kung tumaas ang laki ng pahina, kailangan mong maghanap ng bagong lugar sa file para dito.
  • Kung ang isang page ay gumagalaw nang may bilang ng mga byte na hindi isang multiple ng file system block size, ang pagbabasa o pagsusulat nito ay mangangailangan ng pagpindot ng isa pang file system block, na maaaring humantong sa pagkasira ng performance.

Upang maiwasang malutas ang mga problemang ito sa sarili nitong antas, ang disk page compression sa Apache Ignite ay gumagamit ng mekanismo ng file system na tinatawag na sparse files. Ang kalat-kalat na file ay isa kung saan maaaring markahan ang ilang zero-filled na rehiyon bilang "mga butas". Sa kasong ito, walang mga bloke ng file system ang ilalaan upang iimbak ang mga butas na ito, na nagreresulta sa pagtitipid sa espasyo sa disk.

Ito ay lohikal na upang palayain ang isang file system block, ang laki ng butas ay dapat na mas malaki kaysa o katumbas ng file system block, na nagpapataw ng karagdagang limitasyon sa laki ng pahina at Apache Ignite: para magkaroon ng anumang epekto ang compression, ang laki ng pahina ay dapat na mahigpit na mas malaki kaysa sa sukat ng file system block. Kung ang laki ng pahina ay katumbas ng laki ng bloke, hinding-hindi namin magagawang magbakante ng isang bloke, dahil para makapagbakante ng isang bloke, ang naka-compress na pahina ay dapat sumakop ng 0 byte. Kung ang laki ng pahina ay katumbas ng laki ng 2 o 4 na bloke, magagawa na naming magbakante ng kahit isang bloke kung ang aming pahina ay na-compress sa hindi bababa sa 50% o 75%, ayon sa pagkakabanggit.

Kaya, ang huling paglalarawan kung paano gumagana ang mekanismo: Kapag nagsusulat ng isang pahina sa disk, isang pagtatangka upang i-compress ang pahina. Kung ang laki ng naka-compress na pahina ay nagbibigay-daan sa isa o higit pang mga bloke ng file system na mapalaya, kung gayon ang pahina ay isusulat sa naka-compress na anyo, at isang "butas" ay ginawa sa halip ng mga napalaya na mga bloke (isang sistema ng tawag ay isinasagawa fallocate() gamit ang punch hole flag). Kung ang laki ng naka-compress na pahina ay hindi pinapayagan ang mga bloke na palayain, ang pahina ay nai-save bilang ay, hindi naka-compress. Lahat ng page offset ay kinakalkula sa parehong paraan tulad ng walang compression, sa pamamagitan ng pagpaparami ng page index sa laki ng page. Walang paglipat ng mga pahina ay kinakailangan sa iyong sarili. Ang mga offset ng page, tulad ng walang compression, ay nahuhulog sa mga hangganan ng mga bloke ng file system.

Ang compression ng data sa Apache Ignite. Ang karanasan ni Sber

Sa kasalukuyang pagpapatupad, ang Ignite ay maaari lamang gumana sa mga kalat-kalat na file sa ilalim ng Linux OS; ayon dito, ang disk page compression ay maaari lamang paganahin kapag gumagamit ng Ignite sa operating system na ito.

Mga algorithm ng compression na maaaring magamit para sa pag-compress ng pahina ng disk: ZSTD, LZ4, Snappy. Bilang karagdagan, mayroong isang operating mode (SKIP_GARBAGE), kung saan ang hindi nagamit na espasyo lamang sa pahina ay itinapon nang hindi nag-aaplay ng compression sa natitirang data, na binabawasan ang pag-load sa CPU kumpara sa mga naunang nakalistang algorithm.

Epekto sa Pagganap

Sa kasamaang-palad, hindi ako nagsagawa ng aktwal na mga sukat ng pagganap sa mga totoong stand, dahil hindi namin planong gamitin ang mekanismong ito sa produksyon, ngunit maaari naming theoretically speculate kung saan kami matatalo at kung saan kami mananalo.

Upang gawin ito, kailangan nating tandaan kung paano binabasa at isinusulat ang mga pahina kapag na-access:

  • Kapag nagsasagawa ng read operation, ito ay unang hinanap sa RAM; kung ang paghahanap ay hindi matagumpay, ang pahina ay na-load sa RAM mula sa disk ng parehong thread na nagsasagawa ng read.
  • Kapag isinagawa ang isang write operation, ang pahina sa RAM ay minarkahan bilang marumi, ngunit ang pahina ay hindi pisikal na nai-save sa disk kaagad ng thread na gumaganap ng pagsulat. Ang lahat ng maruruming pahina ay nai-save sa disk sa ibang pagkakataon sa proseso ng checkpoint sa magkahiwalay na mga thread.

Kaya ang epekto sa read operations ay:

  • Positive (disk IO), dahil sa pagbaba sa bilang ng mga read file system blocks.
  • Negative (CPU), dahil sa karagdagang pag-load na kinakailangan ng operating system upang gumana sa mga kalat-kalat na file. Posible rin na ang mga karagdagang operasyon ng IO ay tahasang lilitaw dito upang i-save ang isang mas kumplikadong kalat-kalat na istraktura ng file (sa kasamaang-palad, hindi ako pamilyar sa lahat ng mga detalye kung paano gumagana ang mga kalat-kalat na file).
  • Negative (CPU), dahil sa pangangailangang i-decompress ang mga pahina.
  • Walang epekto sa mga pagpapatakbo ng pagsulat.
  • Epekto sa proseso ng checkpoint (lahat dito ay katulad ng read operations):
  • Positibo (disk IO), dahil sa pagbaba sa bilang ng mga nakasulat na bloke ng file system.
  • Negatibo (CPU, posibleng disk IO), dahil sa pagtatrabaho sa mga kalat-kalat na file.
  • Negatibo (CPU), dahil sa pangangailangan para sa pag-compress ng pahina.

Aling bahagi ng iskala ang mag-tip sa iskala? Ang lahat ng ito ay lubos na nakasalalay sa kapaligiran, ngunit ako ay may hilig na maniwala na ang disk page compression ay malamang na humantong sa pagkasira ng pagganap sa karamihan ng mga system. Bukod dito, ang mga pagsubok sa iba pang mga DBMS na gumagamit ng katulad na diskarte sa mga kalat-kalat na file ay nagpapakita ng pagbaba sa pagganap kapag pinagana ang compression.

Paano paganahin at i-configure

Gaya ng nabanggit sa itaas, ang pinakamababang bersyon ng Apache Ignite na sumusuporta sa disk page compression ay 2.8 at ang Linux operating system lang ang sinusuportahan. Paganahin at i-configure tulad ng sumusunod:

  • Dapat mayroong module ng ignite-compression sa class-path. Bilang default, ito ay matatagpuan sa Apache Ignite distribution sa libs/opsyonal na direktoryo at hindi kasama sa class-path. Maaari mo lamang ilipat ang direktoryo sa isang antas sa libs at pagkatapos ay kapag pinatakbo mo ito sa pamamagitan ng ignite.sh awtomatiko itong ie-enable.
  • Dapat paganahin ang pagtitiyaga (Pinagana sa pamamagitan ng DataRegionConfiguration.setPersistenceEnabled(true)).
  • Ang laki ng page ay dapat na mas malaki kaysa sa file system block size (maaari mo itong itakda gamit ang DataStorageConfiguration.setPageSize() ).
  • Para sa bawat cache na ang data ay kailangang i-compress, dapat mong i-configure ang paraan ng compression at (opsyonal) ang antas ng compression (mga pamamaraan CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

WAL compaction

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

Ano ang WAL at bakit ito kailangan? Napakaikli: ito ay isang log na naglalaman ng lahat ng mga kaganapan na sa huli ay nagbabago sa imbakan ng pahina. Ito ay kinakailangan lalo na upang makabawi sa kaso ng pagkahulog. Anumang operasyon, bago magbigay ng kontrol sa user, ay dapat munang magtala ng isang kaganapan sa WAL, upang sa kaso ng pagkabigo, maaari itong i-play muli sa log at ibalik ang lahat ng mga operasyon kung saan ang user ay nakatanggap ng matagumpay na tugon, kahit na ang mga operasyong ito ay hindi nagkaroon ng oras upang maipakita sa imbakan ng pahina sa disk (nasa itaas Ito ay inilarawan na ang aktwal na pagsulat sa tindahan ng pahina ay ginagawa sa isang proseso na tinatawag na "checkpointing" na may ilang pagkaantala sa pamamagitan ng magkahiwalay na mga thread).

Ang mga entry sa WAL ay nahahati sa lohikal at pisikal. Ang mga Boolean ay ang mga susi at pinahahalagahan ang kanilang mga sarili. Pisikal - nagpapakita ng mga pagbabago sa mga page sa page store. Habang ang mga lohikal na tala ay maaaring maging kapaki-pakinabang para sa ilang iba pang mga kaso, ang mga pisikal na tala ay kailangan lamang para sa pagbawi sa kaso ng isang pag-crash at ang mga tala ay kailangan lamang mula noong huling matagumpay na checkpoint. Dito ay hindi na namin idedetalye at ipaliwanag kung bakit ito gumagana sa ganitong paraan, ngunit ang mga interesado ay maaaring sumangguni sa nabanggit na artikulo sa Apache Ignite Wiki: Ignite Persistent Store - sa ilalim ng hood.

Kadalasan mayroong maraming pisikal na talaan bawat lohikal na tala. Iyon ay, halimbawa, ang isang inilagay na operasyon sa cache ay nakakaapekto sa ilang mga pahina sa memorya ng pahina (isang pahina na may data mismo, mga pahina na may mga index, mga pahina na may mga libreng listahan). Sa ilang synthetic na pagsubok, nalaman ko na ang mga pisikal na talaan ay sumasakop ng hanggang 90% ng WAL file. Gayunpaman, kailangan ang mga ito sa napakaikling panahon (bilang default, ang agwat sa pagitan ng mga checkpoint ay 3 minuto). Magiging lohikal na alisin ang data na ito pagkatapos mawala ang kaugnayan nito. Ito mismo ang ginagawa ng mekanismo ng compaction ng WAL: inaalis nito ang mga pisikal na tala at pinipiga ang natitirang mga lohikal na tala gamit ang zip, habang ang laki ng file ay nababawasan nang malaki (minsan ng sampu-sampung beses).

Sa pisikal, ang WAL ay binubuo ng ilang mga segment (10 bilang default) ng isang nakapirming laki (64MB bilang default), na na-overwrite sa isang pabilog na paraan. Sa sandaling mapunan ang kasalukuyang segment, ang susunod na segment ay itatalaga bilang kasalukuyan, at ang napunan na segment ay makokopya sa archive ng isang hiwalay na thread. Gumagana na ang WAL compaction sa mga segment ng archive. Gayundin, bilang isang hiwalay na thread, sinusubaybayan nito ang pagpapatupad ng checkpoint at sinisimulan ang compression sa mga segment ng archive kung saan hindi na kailangan ang mga pisikal na talaan.

Ang compression ng data sa Apache Ignite. Ang karanasan ni Sber

Epekto sa Pagganap

Dahil ang WAL compaction ay tumatakbo bilang isang hiwalay na thread, dapat ay walang direktang epekto sa mga operasyong ginagawa. Ngunit naglalagay pa rin ito ng karagdagang pag-load sa background sa CPU (compression) at disk (pagbabasa ng bawat segment ng WAL mula sa archive at pagsusulat ng mga naka-compress na segment), kaya kung ang system ay tumatakbo sa pinakamataas na kapasidad nito, hahantong din ito sa pagkasira ng pagganap.

Paano paganahin at i-configure

Maaari mong paganahin ang WAL compaction gamit ang property WalCompactionEnabled Π² DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). Gayundin, gamit ang paraan ng DataStorageConfiguration.setWalCompactionLevel(), maaari mong itakda ang antas ng compression kung hindi ka nasisiyahan sa default na halaga (BEST_SPEED).

WAL page snapshot compression

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

Nalaman na natin na sa WAL records ay nahahati sa logical at physical. Para sa bawat pagbabago sa bawat pahina, isang pisikal na tala ng WAL ay nabuo sa memorya ng pahina. Ang mga pisikal na tala, sa turn, ay nahahati din sa 2 subtype: talaan ng snapshot ng pahina at talaan ng delta. Sa tuwing babaguhin namin ang isang bagay sa isang pahina at ilipat ito mula sa isang malinis na estado patungo sa isang maruming estado, isang kumpletong kopya ng pahinang ito ay naka-imbak sa WAL (page snapshot record). Kahit na binago namin ang isang byte lamang sa WAL, ang tala ay bahagyang mas malaki kaysa sa laki ng pahina. Kung babaguhin natin ang isang bagay sa isang maruming page, isang delta record ang mabubuo sa WAL, na nagpapakita lamang ng mga pagbabago kumpara sa nakaraang estado ng page, ngunit hindi sa buong page. Dahil ang pag-reset ng estado ng mga pahina mula sa marumi hanggang sa malinis ay ginagawa sa panahon ng proseso ng checkpoint, kaagad pagkatapos ng pagsisimula ng checkpoint, halos lahat ng pisikal na tala ay bubuo lamang ng mga snapshot ng mga pahina (dahil lahat ng mga pahina kaagad pagkatapos ng simula ng checkpoint ay malinis) , pagkatapos ay habang papalapit kami sa susunod na checkpoint, ang delta record fraction ay magsisimulang lumaki at muling mag-reset sa simula ng susunod na checkpoint. Ang mga sukat sa ilang synthetic na pagsubok ay nagpakita na ang bahagi ng mga snapshot ng pahina sa kabuuang dami ng mga pisikal na talaan ay umabot sa 90%.

Ang ideya ng WAL page snapshot compression ay upang i-compress ang mga snapshot ng pahina gamit ang isang handa na tool sa compression ng pahina (tingnan ang disk page compression). Kasabay nito, sa WAL, ang mga talaan ay nai-save nang sunud-sunod sa append-only mode at hindi na kailangang magbigkis ng mga tala sa mga hangganan ng mga bloke ng file system, kaya dito, hindi tulad ng mekanismo ng compression ng pahina ng disk, hindi namin kailangan ng mga kalat-kalat na file sa lahat; ayon dito, gagana ang mekanismong ito hindi lamang sa OS Linux. Bilang karagdagan, hindi na mahalaga sa amin kung gaano namin nagawang i-compress ang page. Kahit na nag-freeze kami ng 1 byte, isa na itong positibong resulta at makakapag-save kami ng naka-compress na data sa WAL, hindi tulad ng disk page compression, kung saan nai-save lang namin ang naka-compress na page kung na-freeze namin ang higit sa 1 file system block.

Ang mga page ay lubos na na-compress na data, ang kanilang bahagi sa kabuuang dami ng WAL ay napakataas, kaya nang hindi binabago ang format ng WAL file ay makakakuha tayo ng makabuluhang pagbawas sa laki nito. Ang compression, kabilang ang mga lohikal na tala, ay mangangailangan ng pagbabago sa format at pagkawala ng pagiging tugma, halimbawa, para sa mga panlabas na consumer na maaaring interesado sa mga lohikal na tala, ngunit hindi hahantong sa isang makabuluhang pagbawas sa laki ng file.

Tulad ng sa disk page compression, ang WAL page snapshot compression ay maaaring gumamit ng ZSTD, LZ4, Snappy compression algorithm, pati na rin ang SKIP_GARBAGE mode.

Epekto sa Pagganap

Hindi mahirap mapansin na ang direktang pagpapagana ng WAL page snapshot compression ay nakakaapekto lamang sa mga thread na nagsusulat ng data sa memorya ng pahina, iyon ay, ang mga thread na iyon na nagbabago ng data sa mga cache. Ang pagbabasa ng mga pisikal na tala mula sa WAL ay nangyayari nang isang beses lamang, sa sandaling ito ay nakataas ang node pagkatapos ng pagkahulog (at kung ito ay bumagsak lamang sa panahon ng isang checkpoint).

Nakakaapekto ito sa mga thread na nagbabago ng data sa sumusunod na paraan: nakakakuha tayo ng negatibong epekto (CPU) dahil sa pangangailangang i-compress ang page sa bawat oras bago sumulat sa disk, at isang positibong epekto (disk IO) dahil sa pagbawas sa dami ng nakasulat na datos. Alinsunod dito, ang lahat ay simple dito: kung ang pagganap ng system ay limitado ng CPU, nakakakuha tayo ng bahagyang pagkasira, kung ito ay limitado ng disk I/O, nakakakuha tayo ng pagtaas.

Sa hindi direktang paraan, ang pagbawas sa laki ng WAL ay nakakaapekto rin sa (positibong) mga stream na nagtatapon ng mga segment ng WAL sa archive at mga stream ng compaction ng WAL.

Ang mga totoong pagsubok sa performance sa aming kapaligiran gamit ang synthetic na data ay nagpakita ng bahagyang pagtaas (throughput ay tumaas ng 10%-15%, ang latency ay bumaba ng 10%-15%).

Paano paganahin at i-configure

Pinakamababang bersyon ng Apache Ignite: 2.8. Paganahin at i-configure tulad ng sumusunod:

  • Dapat mayroong module ng ignite-compression sa class-path. Bilang default, ito ay matatagpuan sa Apache Ignite distribution sa libs/opsyonal na direktoryo at hindi kasama sa class-path. Maaari mo lamang ilipat ang direktoryo sa isang antas sa libs at pagkatapos ay kapag pinatakbo mo ito sa pamamagitan ng ignite.sh awtomatiko itong ie-enable.
  • Dapat paganahin ang pagtitiyaga (Pinagana sa pamamagitan ng DataRegionConfiguration.setPersistenceEnabled(true)).
  • Ang compression mode ay dapat itakda gamit ang paraan DataStorageConfiguration.setWalPageCompression(), ang compression ay hindi pinagana bilang default (DISABLED mode).
  • Opsyonal, maaari mong itakda ang antas ng compression gamit ang pamamaraan DataStorageConfiguration.setWalPageCompression(), tingnan ang javadoc para sa pamamaraan para sa mga wastong halaga para sa bawat mode.

Konklusyon

Ang itinuturing na mga mekanismo ng compression ng data sa Apache Ignite ay maaaring gamitin nang hiwalay sa isa't isa, ngunit ang anumang kumbinasyon ng mga ito ay katanggap-tanggap din. Ang pag-unawa sa kung paano gumagana ang mga ito ay magbibigay-daan sa iyo upang matukoy kung gaano kaakma ang mga ito para sa iyong mga gawain sa iyong kapaligiran at kung ano ang kailangan mong isakripisyo kapag ginagamit ang mga ito. Ang disk page compression ay idinisenyo upang i-compress ang pangunahing storage at maaaring magbigay ng medium compression ratio. Ang WAL page snapshot compression ay magbibigay ng average na antas ng compression para sa mga WAL file, at malamang na mapapabuti pa ang pagganap. Ang WAL compaction ay hindi magkakaroon ng positibong epekto sa pagganap, ngunit babawasan ang laki ng mga WAL file hangga't maaari sa pamamagitan ng pag-alis ng mga pisikal na talaan.

Pinagmulan: www.habr.com

Magdagdag ng komento