Mfinyazo wa data katika Apache Ignite. Uzoefu wa Sber

Mfinyazo wa data katika Apache Ignite. Uzoefu wa SberWakati wa kufanya kazi na kiasi kikubwa cha data, tatizo la ukosefu wa nafasi ya disk wakati mwingine linaweza kutokea. Njia moja ya kutatua tatizo hili ni ukandamizaji, shukrani ambayo, kwenye vifaa sawa, unaweza kumudu kuongeza kiasi cha kuhifadhi. Katika makala hii, tutaangalia jinsi ukandamizaji wa data unavyofanya kazi katika Apache Ignite. Nakala hii itaelezea tu njia za ukandamizaji wa diski zinazotekelezwa ndani ya bidhaa. Njia zingine za ukandamizaji wa data (kwenye mtandao, kwenye kumbukumbu), iwe zinatekelezwa au la, zitabaki nje ya upeo.

Kwa hivyo, kwa hali ya kuendelea kuwezeshwa, kama matokeo ya mabadiliko ya data kwenye kache, Ignite huanza kuandika kwa diski:

  1. Yaliyomo kwenye akiba
  2. Andika Kumbukumbu Mbele (baadaye kwa urahisi WAL)

Kumekuwa na utaratibu wa mfinyazo wa WAL kwa muda mrefu sasa, unaoitwa ukandamizaji wa WAL. Apache Ignite 2.8 iliyotolewa hivi majuzi ilianzisha mifumo miwili zaidi inayokuruhusu kubana data kwenye diski: mbano wa ukurasa wa diski kwa ajili ya kubana yaliyomo kwenye kache na ukandamizaji wa muhtasari wa ukurasa wa WAL kwa kubana baadhi ya maingizo ya WAL. Maelezo zaidi kuhusu taratibu zote tatu hizi hapa chini.

Ukandamizaji wa ukurasa wa diski

Jinsi gani kazi hii

Kwanza, hebu tuangalie kwa ufupi jinsi Ignite huhifadhi data. Kumbukumbu ya ukurasa hutumiwa kuhifadhi. Saizi ya ukurasa umewekwa mwanzoni mwa nodi na haiwezi kubadilishwa katika hatua za baadaye; pia, saizi ya ukurasa lazima iwe na nguvu ya mbili na nyingi ya saizi ya kizuizi cha mfumo wa faili. Kurasa hupakiwa kwenye RAM kutoka kwa diski inavyohitajika; saizi ya data kwenye diski inaweza kuzidi kiasi cha RAM iliyotengwa. Ikiwa hakuna nafasi ya kutosha katika RAM kupakia ukurasa kutoka kwa diski, kurasa za zamani, ambazo hazitumiki tena zitaondolewa kwenye RAM.

Data imehifadhiwa kwenye diski katika fomu ifuatayo: faili tofauti huundwa kwa kila kizigeu cha kila kikundi cha kache; katika faili hii, kurasa zinaonekana moja baada ya nyingine kwa mpangilio wa faharisi unaopanda. Kitambulisho kamili cha ukurasa kina kitambulisho cha kikundi cha kache, nambari ya kizigeu, na faharasa ya ukurasa kwenye faili. Kwa hivyo, kwa kutumia kitambulisho kamili cha ukurasa, tunaweza kubaini faili kwa njia ya kipekee na kurekebisha katika faili kwa kila ukurasa. Unaweza kusoma zaidi juu ya kumbukumbu ya kurasa kwenye nakala ya Apache Ignite Wiki: Washa Hifadhi ya Kudumu - chini ya kofia.

Utaratibu wa ukandamizaji wa ukurasa wa diski, kama unavyoweza kukisia kutoka kwa jina, hufanya kazi katika kiwango cha ukurasa. Utaratibu huu unapowezeshwa, data katika RAM inachakatwa kama ilivyo, bila mgandamizo wowote, lakini kurasa zinapohifadhiwa kutoka RAM hadi diski, zinabanwa.

Lakini kubana kila ukurasa mmoja mmoja sio suluhisho la shida; unahitaji kwa njia fulani kupunguza saizi ya faili za data zinazosababishwa. Ikiwa saizi ya ukurasa haijasasishwa tena, hatuwezi tena kuandika kurasa kwa faili moja baada ya nyingine, kwani hii inaweza kuunda shida kadhaa:

  • Kwa kutumia index ya ukurasa, hatutaweza kuhesabu kukabiliana na ambayo iko kwenye faili.
  • Haijulikani wazi nini cha kufanya na kurasa ambazo haziko mwisho wa faili na kubadilisha ukubwa wao. Ikiwa saizi ya ukurasa itapungua, nafasi iliyoachiliwa hupotea. Ikiwa ukubwa wa ukurasa unaongezeka, unahitaji kutafuta mahali mpya kwenye faili kwa ajili yake.
  • Ikiwa ukurasa unasonga kwa idadi ya baiti ambazo si nyingi ya ukubwa wa kuzuia mfumo wa faili, basi kusoma au kuandika itahitaji kugusa kizuizi kimoja zaidi cha mfumo wa faili, ambayo inaweza kusababisha uharibifu wa utendaji.

Ili kuepuka kutatua matatizo haya kwa kiwango chake, ukandamizaji wa ukurasa wa diski katika Apache Ignite hutumia utaratibu wa mfumo wa faili unaoitwa faili za sparse. Faili ndogo ni ile ambayo baadhi ya maeneo yenye sifuri yanaweza kuwekewa alama kama "mashimo". Katika kesi hii, hakuna vizuizi vya mfumo wa faili vitatengwa kuhifadhi mashimo haya, na kusababisha kuokoa kwenye nafasi ya diski.

Ni busara kwamba ili kufungia kizuizi cha mfumo wa faili, saizi ya shimo lazima iwe kubwa kuliko au sawa na kizuizi cha mfumo wa faili, ambayo inaweka kizuizi cha ziada kwenye saizi ya ukurasa na Apache Ignite: kwa ukandamizaji kuwa na athari yoyote, saizi ya ukurasa lazima iwe kubwa zaidi kuliko saizi ya kizuizi cha mfumo wa faili. Ikiwa saizi ya ukurasa ni sawa na saizi ya kizuizi, basi hatutaweza kuachilia kizuizi kimoja, kwani ili kufungia kizuizi kimoja, ukurasa ulioshinikizwa lazima uchukue ka 0. Ikiwa saizi ya ukurasa ni sawa na saizi ya vizuizi 2 au 4, tayari tutaweza kufungia angalau kizuizi kimoja ikiwa ukurasa wetu umebanwa hadi angalau 50% au 75% mtawalia.

Kwa hivyo, maelezo ya mwisho ya jinsi utaratibu unavyofanya kazi: Wakati wa kuandika ukurasa kwenye diski, jaribio linafanywa ili kukandamiza ukurasa. Ikiwa saizi ya ukurasa ulioshinikizwa huruhusu kizuizi kimoja au zaidi cha mfumo wa faili kuachiliwa, basi ukurasa umeandikwa kwa fomu iliyoshinikwa, na "shimo" hufanywa badala ya vizuizi vilivyoachiliwa (simu ya mfumo inatekelezwa. fallocate() na bendera ya shimo la ngumi). Ikiwa saizi ya ukurasa ulioshinikizwa hairuhusu vizuizi kuachiliwa, ukurasa huhifadhiwa kama ulivyo, bila kulazimishwa. Vipimo vyote vya ukurasa vinahesabiwa kwa njia sawa na bila mbano, kwa kuzidisha faharasa ya ukurasa kwa saizi ya ukurasa. Hakuna uhamishaji wa kurasa unaohitajika peke yako. Vipimo vya ukurasa, kama vile bila kubana, huanguka kwenye mipaka ya vizuizi vya mfumo wa faili.

Mfinyazo wa data katika Apache Ignite. Uzoefu wa Sber

Katika utekelezaji wa sasa, Ignite inaweza tu kufanya kazi na faili chache chini ya Linux OS; ipasavyo, ukandamizaji wa ukurasa wa diski unaweza tu kuwezeshwa wakati wa kutumia Ignite kwenye mfumo huu wa uendeshaji.

Algorithms ya ukandamizaji ambayo inaweza kutumika kwa ukandamizaji wa ukurasa wa diski: ZSTD, LZ4, Snappy. Kwa kuongeza, kuna hali ya uendeshaji (SKIP_GARBAGE), ambayo nafasi pekee isiyotumiwa kwenye ukurasa inatupwa nje bila kutumia compression kwenye data iliyobaki, ambayo inapunguza mzigo kwenye CPU ikilinganishwa na algorithms zilizoorodheshwa hapo awali.

Athari ya Utendaji

Kwa bahati mbaya, sikufanya vipimo halisi vya utendaji kwenye stendi halisi, kwa kuwa hatuna mpango wa kutumia utaratibu huu katika uzalishaji, lakini tunaweza kutafakari kinadharia wapi tutapoteza na wapi tutashinda.

Ili kufanya hivyo, tunahitaji kukumbuka jinsi kurasa zinavyosomwa na kuandikwa wakati wa kufikia:

  • Wakati wa kufanya operesheni ya kusoma, hutafutwa kwanza kwenye RAM; ikiwa utaftaji haujafaulu, ukurasa hupakiwa kwenye RAM kutoka kwa diski na uzi ule ule unaosoma.
  • Operesheni ya uandishi inapofanywa, ukurasa katika RAM huwekwa alama kuwa chafu, lakini ukurasa haujahifadhiwa kimwili kwa diski mara moja na uzi unaoandika. Kurasa zote chafu zinahifadhiwa kwenye diski baadaye katika mchakato wa ukaguzi katika nyuzi tofauti.

Kwa hivyo athari kwenye shughuli za kusoma ni:

  • Chanya (disk IO), kutokana na kupungua kwa idadi ya vizuizi vya mfumo wa faili zilizosomwa.
  • Hasi (CPU), kutokana na mzigo wa ziada unaohitajika na mfumo wa uendeshaji kufanya kazi na faili chache. Inawezekana pia kwamba shughuli za ziada za IO zitaonekana hapa ili kuhifadhi muundo ngumu zaidi wa faili chache (kwa bahati mbaya, sijui maelezo yote ya jinsi faili chache hufanya kazi).
  • Hasi (CPU), kwa sababu ya hitaji la kupunguza kurasa.
  • Hakuna athari kwa shughuli za uandishi.
  • Athari kwenye mchakato wa ukaguzi (kila kitu hapa ni sawa na shughuli za kusoma):
  • Chanya (disk IO), kutokana na kupungua kwa idadi ya vitalu vya mfumo wa faili zilizoandikwa.
  • Hasi (CPU, ikiwezekana diski IO), kwa sababu ya kufanya kazi na faili chache.
  • Hasi (CPU), kwa sababu ya hitaji la ukandamizaji wa ukurasa.

Je, ni upande gani wa mizani utaongeza kiwango? Hii yote inategemea sana mazingira, lakini nina mwelekeo wa kuamini kuwa compression ya ukurasa wa diski itasababisha uharibifu wa utendaji kwenye mifumo mingi. Zaidi ya hayo, majaribio kwenye DBMS nyingine zinazotumia mbinu sawa na faili chache huonyesha kushuka kwa utendakazi wakati mgandamizo umewashwa.

Jinsi ya kuwezesha na kusanidi

Kama ilivyoelezwa hapo juu, toleo la chini la Apache Ignite ambalo linaauni ukandamizaji wa ukurasa wa diski ni 2.8 na ni mfumo wa uendeshaji wa Linux pekee unaotumika. Washa na usanidi kama ifuatavyo:

  • Lazima kuwe na moduli ya kubana-washa katika njia ya darasa. Kwa chaguo-msingi, iko katika usambazaji wa Apache Ignite kwenye saraka ya libs/hiari na haijajumuishwa kwenye njia ya darasa. Unaweza tu kusogeza saraka hadi ngazi moja hadi libs na kisha utakapoiendesha kupitia ignite.sh itawezeshwa kiotomatiki.
  • Uvumilivu lazima uwezeshwe (Imewashwa kupitia DataRegionConfiguration.setPersistenceEnabled(true)).
  • Saizi ya ukurasa lazima iwe kubwa kuliko saizi ya kizuizi cha mfumo wa faili (unaweza kuiweka ukitumia DataStorageConfiguration.setPageSize() ).
  • Kwa kila kashe ambayo data yake inahitaji kubanwa, lazima usanidi mbinu ya ukandamizaji na (hiari) kiwango cha mgandamizo (mbinu). CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

Mchanganyiko wa WAL

Jinsi gani kazi hii

WAL ni nini na kwa nini inahitajika? Kwa kifupi sana: hii ni logi ambayo ina matukio yote ambayo hatimaye hubadilisha hifadhi ya ukurasa. Inahitajika kimsingi kuwa na uwezo wa kupona katika kesi ya kuanguka. Operesheni yoyote, kabla ya kutoa udhibiti kwa mtumiaji, lazima kwanza irekodi tukio katika WAL, ili ikiwa itashindwa, iweze kuchezwa tena kwenye logi na kurejesha shughuli zote ambazo mtumiaji alipokea jibu la mafanikio, hata kama shughuli hizi. hakuwa na muda wa kuonyeshwa kwenye hifadhi ya ukurasa kwenye diski (tayari hapo juu Imeelezwa kuwa uandishi halisi kwenye duka la ukurasa unafanywa katika mchakato unaoitwa "checkpointing" na kuchelewa fulani kwa nyuzi tofauti).

Maingizo katika WAL yamegawanywa katika mantiki na kimwili. Zile za Boolean ndio funguo na zinajithamini zenyewe. Kimwili - huonyesha mabadiliko kwenye kurasa kwenye duka la ukurasa. Ingawa rekodi za kimantiki zinaweza kuwa muhimu kwa matukio mengine, rekodi za kimwili zinahitajika kwa ajili ya uokoaji tu ikiwa kuna ajali na rekodi zinahitajika tu tangu ukaguzi wa mwisho uliofaulu. Hapa hatutaingia kwa undani na kuelezea kwa nini inafanya kazi kwa njia hii, lakini wale wanaopenda wanaweza kurejelea nakala iliyotajwa tayari kwenye Wiki ya Apache Ignite: Washa Hifadhi ya Kudumu - chini ya kofia.

Mara nyingi kuna rekodi kadhaa za kimwili kwa kila rekodi ya kimantiki. Hiyo ni, kwa mfano, operesheni moja ya kuweka kwenye kashe huathiri kurasa kadhaa kwenye kumbukumbu ya ukurasa (ukurasa ulio na data yenyewe, kurasa zilizo na faharisi, kurasa zilizo na orodha za bure). Katika majaribio mengine ya syntetisk, niligundua kuwa rekodi za mwili zilichukua hadi 90% ya faili ya WAL. Hata hivyo, zinahitajika kwa muda mfupi sana (kwa default, muda kati ya vituo vya ukaguzi ni dakika 3). Itakuwa busara kuondoa data hii baada ya kupoteza umuhimu wake. Hivi ndivyo utaratibu wa ukandamizaji wa WAL hufanya: huondoa rekodi za mwili na kubana rekodi za kimantiki zilizobaki kwa kutumia zip, wakati saizi ya faili imepunguzwa sana (wakati mwingine kwa makumi ya nyakati).

Kimwili, WAL ina sehemu kadhaa (10 kwa chaguo-msingi) za saizi isiyobadilika (MB 64 kwa chaguo-msingi), ambazo zimeandikwa juu kwa njia ya mduara. Mara tu sehemu ya sasa inapojazwa, sehemu inayofuata inapewa kama ya sasa, na sehemu iliyojazwa inakiliwa kwenye kumbukumbu na uzi tofauti. Ufungaji wa WAL tayari unafanya kazi na sehemu za kumbukumbu. Pia, kama uzi tofauti, inafuatilia utekelezaji wa kituo cha ukaguzi na huanza kukandamiza katika sehemu za kumbukumbu ambazo rekodi za kimwili hazihitajiki tena.

Mfinyazo wa data katika Apache Ignite. Uzoefu wa Sber

Athari ya Utendaji

Kwa kuwa ukandamizaji wa WAL huendesha kama uzi tofauti, haipaswi kuwa na athari ya moja kwa moja kwenye shughuli zinazofanywa. Lakini bado huweka mzigo wa ziada wa usuli kwenye CPU (compression) na diski (kusoma kila sehemu ya WAL kutoka kwenye kumbukumbu na kuandika sehemu zilizoshinikwa), hivyo ikiwa mfumo unafanya kazi kwa kiwango cha juu zaidi, itasababisha pia uharibifu wa utendaji.

Jinsi ya kuwezesha na kusanidi

Unaweza kuwezesha ukandamizaji wa WAL kwa kutumia mali WalCompactionEnabled Π² DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)) Pia, kwa kutumia mbinu ya DataStorageConfiguration.setWalCompactionLevel(), unaweza kuweka kiwango cha mbano ikiwa haujaridhika na thamani chaguo-msingi (BEST_SPEED).

Mfinyazo wa muhtasari wa ukurasa wa WAL

Jinsi gani kazi hii

Tayari tumegundua kuwa katika rekodi za WAL zimegawanywa katika mantiki na kimwili. Kwa kila mabadiliko kwa kila ukurasa, rekodi halisi ya WAL inatolewa kwenye kumbukumbu ya ukurasa. Rekodi za kimwili, kwa upande wake, pia zimegawanywa katika aina ndogo 2: rekodi ya snapshot ya ukurasa na rekodi ya delta. Kila wakati tunapobadilisha kitu kwenye ukurasa na kukihamisha kutoka kwa hali safi hadi chafu, nakala kamili ya ukurasa huu huhifadhiwa katika WAL (rekodi ya picha ya ukurasa). Hata kama tulibadilisha baiti moja pekee katika WAL, rekodi itakuwa kubwa kidogo kuliko saizi ya ukurasa. Ikiwa tutabadilisha kitu kwenye ukurasa ambao tayari ni chafu, rekodi ya delta inaundwa katika WAL, ambayo inaonyesha mabadiliko tu ikilinganishwa na hali ya awali ya ukurasa, lakini si ukurasa mzima. Kwa kuwa kuweka upya hali ya kurasa kutoka kwa uchafu hadi safi hufanywa wakati wa mchakato wa ukaguzi, mara baada ya kuanza kwa ukaguzi, karibu rekodi zote za mwili zitajumuisha picha za kurasa (kwa kuwa kurasa zote mara baada ya kuanza kwa ukaguzi ni safi) , kisha tunapokaribia kituo cha ukaguzi kinachofuata, sehemu ya rekodi ya delta huanza kukua na kuweka upya tena mwanzoni mwa kituo cha ukaguzi kinachofuata. Vipimo katika baadhi ya vipimo vya syntetisk vilionyesha kuwa sehemu ya snapshots za ukurasa katika jumla ya rekodi za kimwili hufikia 90%.

Wazo la ukandamizaji wa muhtasari wa ukurasa wa WAL ni kubana vijipicha vya ukurasa kwa kutumia zana iliyotengenezwa tayari ya ukandamizaji wa ukurasa (angalia mbano wa ukurasa wa diski). Wakati huo huo, katika WAL, rekodi zinahifadhiwa kwa mlolongo katika hali ya kiambatisho tu na hakuna haja ya kufunga rekodi kwenye mipaka ya vizuizi vya mfumo wa faili, kwa hivyo hapa, tofauti na utaratibu wa ukandamizaji wa ukurasa wa diski, hatuitaji faili chache. yote; ipasavyo, utaratibu huu utafanya kazi sio tu kwenye OS Linux. Kwa kuongeza, haijalishi tena ni kiasi gani tuliweza kukandamiza ukurasa. Hata kama tuliachilia baiti 1, haya tayari ni matokeo chanya na tunaweza kuhifadhi data iliyobanwa katika WAL, tofauti na ukandamizaji wa ukurasa wa diski, ambapo tunahifadhi ukurasa uliobanwa ikiwa tu tuliachilia zaidi ya kizuizi 1 cha mfumo wa faili.

Kurasa ni data inayoweza kubanwa sana, sehemu yao katika jumla ya kiasi cha WAL ni ya juu sana, kwa hivyo bila kubadilisha umbizo la faili la WAL tunaweza kupata upunguzaji mkubwa wa saizi yake. Mfinyazo, ikiwa ni pamoja na rekodi za kimantiki, ungehitaji mabadiliko katika umbizo na kupoteza upatanifu, kwa mfano, kwa watumiaji wa nje ambao wanaweza kupendezwa na rekodi za kimantiki, lakini hazitasababisha kupunguzwa kwa ukubwa wa faili.

Kama ilivyo kwa ukandamizaji wa ukurasa wa diski, ukandamizaji wa muhtasari wa ukurasa wa WAL unaweza kutumia kanuni za ukandamizaji za ZSTD, LZ4, Snappy, pamoja na modi ya SKIP_GARBAGE.

Athari ya Utendaji

Si vigumu kutambua kwamba kuwezesha moja kwa moja ukandamizaji wa vijipicha vya ukurasa wa WAL huathiri tu nyuzi zinazoandika data kwenye kumbukumbu ya ukurasa, yaani, nyuzi zile zinazobadilisha data katika kache. Kusoma kumbukumbu za kimwili kutoka kwa WAL hutokea mara moja tu, kwa sasa node inafufuliwa baada ya kuanguka (na tu ikiwa inaanguka wakati wa ukaguzi).

Hii inathiri nyuzi zinazobadilisha data kwa njia ifuatayo: tunapata athari mbaya (CPU) kwa sababu ya hitaji la kushinikiza ukurasa kila wakati kabla ya kuandika kwa diski, na athari chanya (diski IO) kwa sababu ya kupunguzwa kwa kiasi cha diski. data iliyoandikwa. Ipasavyo, kila kitu ni rahisi hapa: ikiwa utendaji wa mfumo umepunguzwa na CPU, tunapata uharibifu mdogo, ikiwa ni mdogo na disk I / O, tunapata ongezeko.

Kwa njia isiyo ya moja kwa moja, kupunguza ukubwa wa WAL pia huathiri mitiririko (vyema) ambayo hutupa sehemu za WAL kwenye kumbukumbu na mitiririko ya kubana ya WAL.

Majaribio ya utendakazi halisi katika mazingira yetu kwa kutumia data ya sintetiki yalionyesha ongezeko kidogo (mapitio yaliongezeka kwa 10% -15%, muda wa kusubiri ulipungua kwa 10% -15%).

Jinsi ya kuwezesha na kusanidi

Toleo la Chini la Apache Ignite: 2.8. Washa na usanidi kama ifuatavyo:

  • Lazima kuwe na moduli ya kubana-washa katika njia ya darasa. Kwa chaguo-msingi, iko katika usambazaji wa Apache Ignite kwenye saraka ya libs/hiari na haijajumuishwa kwenye njia ya darasa. Unaweza tu kusogeza saraka hadi ngazi moja hadi libs na kisha utakapoiendesha kupitia ignite.sh itawezeshwa kiotomatiki.
  • Uvumilivu lazima uwezeshwe (Imewashwa kupitia DataRegionConfiguration.setPersistenceEnabled(true)).
  • Hali ya ukandamizaji lazima iwekwe kwa kutumia njia DataStorageConfiguration.setWalPageCompression(), ukandamizaji umezimwa kwa chaguo-msingi (Njia ILIYOZIMA).
  • Kwa hiari, unaweza kuweka kiwango cha ukandamizaji kwa kutumia njia DataStorageConfiguration.setWalPageCompression(), angalia javadoc kwa njia ya maadili halali kwa kila modi.

Hitimisho

Mbinu za ukandamizaji wa data zinazozingatiwa katika Apache Ignite zinaweza kutumika kwa kujitegemea, lakini mchanganyiko wowote kati yao pia unakubalika. Kuelewa jinsi zinavyofanya kazi kutakuruhusu kuamua jinsi zinavyofaa kwa kazi zako katika mazingira yako na ni nini utalazimika kutoa wakati unazitumia. Ukandamizaji wa ukurasa wa diski umeundwa kukandamiza hifadhi kuu na inaweza kutoa uwiano wa ukandamizaji wa kati. Mfinyazo wa muhtasari wa ukurasa wa WAL utatoa kiwango cha wastani cha mbano kwa faili za WAL, na kuna uwezekano mkubwa hata kuboresha utendakazi. Ufungaji wa WAL hautakuwa na athari chanya kwenye utendaji, lakini utapunguza ukubwa wa faili za WAL iwezekanavyo kwa kuondoa rekodi za kimwili.

Chanzo: mapenzi.com

Kuongeza maoni