Apache Ignite бағдарламасында деректерді қысу. Сбер тәжірибесі

Apache Ignite бағдарламасында деректерді қысу. Сбер тәжірибесіҮлкен көлемдегі деректермен жұмыс істегенде, кейде дискілік кеңістіктің жетіспеушілігі мәселесі туындауы мүмкін. Бұл мәселені шешудің бір жолы - қысу, соның арқасында сол жабдықта сақтау көлемін ұлғайтуға болады. Бұл мақалада біз Apache Ignite бағдарламасында деректерді қысу қалай жұмыс істейтінін қарастырамыз. Бұл мақалада өнімде енгізілген дискіні қысу әдістері ғана сипатталады. Деректерді қысудың басқа әдістері (желіде, жадта), енгізілген немесе жасалмағанына қарамастан, қолдану аясынан тыс қалады.

Осылайша, тұрақтылық режимі қосылған кезде, кэштердегі деректердің өзгеруі нәтижесінде Ignite дискіге жаза бастайды:

  1. Кэштердің мазмұны
  2. Алдын ала журналды жазу (бұдан әрі жай WAL)

Біраз уақыттан бері WAL қысу механизмі WAL тығыздау деп аталады. Жақында шығарылған Apache Ignite 2.8 дискідегі деректерді қысуға мүмкіндік беретін тағы екі механизмді ұсынды: кэштердің мазмұнын қысу үшін диск бетін қысу және кейбір WAL жазбаларын қысу үшін WAL бетінің суретін қысу. Төменде осы үш механизм туралы толығырақ.

Диск бетін қысу

Бұл қалай жұмыс істейді

Алдымен, Ignite деректерін қалай сақтайтынын қысқаша қарастырайық. Сақтау үшін бет жады пайдаланылады. Бет өлшемі түйіннің басында орнатылады және оны кейінгі кезеңдерде өзгерту мүмкін емес; сонымен қатар, бет өлшемі файлдық жүйе блогының өлшемінен екі және еселі болуы керек. Беттер қажет болған жағдайда дискіден ЖЖҚ-ға жүктеледі, дискідегі деректердің көлемі бөлінген ЖЖҚ көлемінен асып кетуі мүмкін. Дискіден бетті жүктеу үшін ЖЖҚ-да орын жеткіліксіз болса, ескі, енді пайдаланылмаған беттер ЖЖҚ-дан шығарылады.

Деректер дискіде келесі пішінде сақталады: әрбір кэш тобының әрбір бөлімі үшін жеке файл жасалады; бұл файлда беттер индекстің өсу ретімен бірінен соң бірі пайда болады. Толық бет идентификаторында кэш тобының идентификаторы, бөлім нөмірі және файлдағы бет индексі бар. Осылайша, толық бет идентификаторын пайдалана отырып, біз әр бет үшін файлды және файлдағы ығысуды бірегей түрде анықтай аламыз. Сіз Apache Ignite Wiki мақаласында пейджинг жады туралы көбірек оқи аласыз: Ignite Persistent Store - сорғыштың астында.

Диск бетін қысу механизмі, аты бойынша болжағаныңыздай, бет деңгейінде жұмыс істейді. Бұл механизм қосылған кезде ЖЖҚ-дағы деректер еш қысусыз бұрынғы күйінде өңделеді, бірақ беттер ЖЖҚ-дан дискіге сақталған кезде олар қысылады.

Бірақ әрбір бетті жеке қысу мәселені шешу емес, нәтижесінде алынған деректер файлдарының өлшемін қандай да бір түрде азайту керек. Егер бет өлшемі енді бекітілмесе, біз бұдан былай файлға беттерді бірінен соң бірі жаза алмаймыз, себебі бұл бірқатар проблемаларды тудыруы мүмкін:

  • Бет индексін пайдалана отырып, біз оның файлда орналасқан ығысуын есептей алмаймыз.
  • Файлдың соңында жоқ және олардың өлшемін өзгертетін беттерді не істеу керектігі түсініксіз. Бет өлшемі азайса, ол босатқан кеңістік жоғалады. Егер бет өлшемі ұлғайса, ол үшін файлдан жаңа орын іздеу керек.
  • Егер бет файлдық жүйе блогының өлшеміне еселік емес бірнеше байтқа жылжыса, оны оқу немесе жазу үшін тағы бір файлдық жүйе блогын түрту қажет болады, бұл өнімділіктің төмендеуіне әкелуі мүмкін.

Бұл мәселелерді өз деңгейінде шешуді болдырмау үшін Apache Ignite жүйесінде диск бетін қысу сирек файлдар деп аталатын файлдық жүйе механизмін пайдаланады. Сирек файл - кейбір нөлмен толтырылған аймақтарды «саңылаулар» ретінде белгілеуге болатын файл. Бұл жағдайда бұл саңылауларды сақтауға файлдық жүйе блоктары бөлінбейді, нәтижесінде дискілік кеңістік үнемделеді.

Файлдық жүйе блогын босату үшін саңылау өлшемі файлдық жүйе блогынан үлкен немесе оған тең болуы қисынды, бұл бет өлшеміне және Apache Ignite-ге қосымша шектеулер қояды: қысу кез келген әсерге ие болуы үшін, бет өлшемі файлдық жүйе блогының өлшемінен қатаң түрде үлкен болуы керек. Егер бет өлшемі блок өлшеміне тең болса, біз ешқашан бір блокты босата алмаймыз, өйткені бір блокты босату үшін қысылған бет 0 байт алуы керек. Егер бет өлшемі 2 немесе 4 блоктың өлшеміне тең болса, бетіміз сәйкесінше кем дегенде 50% немесе 75% қысылған болса, біз кем дегенде бір блокты босата аламыз.

Осылайша, механизмнің жұмысының соңғы сипаттамасы: Дискіге бет жазу кезінде бетті қысу әрекеті жасалады. Егер қысылған беттің өлшемі бір немесе бірнеше файлдық жүйе блоктарын босатуға мүмкіндік берсе, онда бет қысылған түрде жазылады және босатылған блоктардың орнына «тесік» жасалады (жүйелік қоңырау орындалады). fallocate() тесік жалаушасымен). Егер қысылған беттің өлшемі блоктарды босатуға мүмкіндік бермесе, бет қысылмаған күйінде сақталады. Барлық беттердің ығысулары бет индексін бет өлшеміне көбейту арқылы қысусыз сияқты есептеледі. Өз бетіңізше беттердің орнын ауыстыру қажет емес. Беттің ығысулары, қысусыз сияқты, файлдық жүйе блоктарының шекараларына түседі.

Apache Ignite бағдарламасында деректерді қысу. Сбер тәжірибесі

Ағымдағы іске асыруда Ignite тек Linux ОЖ астында сирек файлдармен жұмыс істей алады; сәйкесінше, диск бетін қысуды тек осы операциялық жүйеде Ignite пайдаланған кезде қосуға болады.

Диск бетін қысу үшін қолдануға болатын қысу алгоритмдері: ZSTD, LZ4, Snappy. Бұдан басқа, жұмыс режимі (SKIP_GARBAGE) бар, онда қалған деректерге қысуды қолданбай, беттегі тек пайдаланылмаған кеңістік лақтырылады, бұл бұрын аталған алгоритмдермен салыстырғанда CPU жүктемесін азайтады.

Өнімділікке әсер ету

Өкінішке орай, мен нақты стендтерде өнімділікті өлшеуді жүргізген жоқпын, өйткені біз бұл механизмді өндірісте қолдануды жоспарламаймыз, бірақ біз қай жерде ұтылатынымызды және қай жерде ұтатынымызды теориялық түрде болжауға болады.

Ол үшін кіру кезінде беттердің қалай оқылатынын және жазылатынын есте сақтау керек:

  • Оқу әрекетін орындаған кезде ол алдымен ЖЖҚ-да ізделеді, егер іздеу сәтсіз болса, бет оқуды орындайтын сол ағынмен дискіден ЖЖҚ-ға жүктеледі.
  • Жазу операциясы орындалғанда, ЖЖҚ-дағы бет лас деп белгіленеді, бірақ жазуды орындайтын ағынмен бет дереу дискіге физикалық түрде сақталмайды. Барлық ластанған беттер кейінірек бақылау нүктесі процесінде бөлек ағындарда дискіге сақталады.

Сонымен оқу операцияларына әсері:

  • Оқыған файлдық жүйе блоктарының санының азаюына байланысты оң (диск IO).
  • Теріс (CPU), сирек файлдармен жұмыс істеу үшін операциялық жүйе қажет ететін қосымша жүктемеге байланысты. Сондай-ақ, күрделірек сирек файл құрылымын сақтау үшін қосымша IO операциялары жасырын түрде пайда болуы мүмкін (өкінішке орай, мен сирек файлдардың қалай жұмыс істейтіні туралы барлық мәліметтермен таныс емеспін).
  • Теріс (CPU), беттерді ашу қажеттілігіне байланысты.
  • Жазу операцияларына әсер етпейді.
  • Бақылау пункті процесіне әсер ету (мұнда барлығы оқу операцияларына ұқсас):
  • Жазбаша файлдық жүйе блоктарының санының азаюына байланысты оң (диск IO).
  • Теріс (CPU, мүмкін диск IO), сирек файлдармен жұмыс істеуге байланысты.
  • Теріс (CPU), бетті қысу қажеттілігіне байланысты.

Таразыны қай жағы итереді? Мұның бәрі қоршаған ортаға байланысты, бірақ мен диск бетін қысу көптеген жүйелерде өнімділіктің төмендеуіне әкелетініне сенемін. Сонымен қатар, сирек файлдармен ұқсас тәсілді қолданатын басқа ДҚБЖ сынақтары қысу қосылған кезде өнімділіктің төмендеуін көрсетеді.

Қалай қосуға және конфигурациялауға болады

Жоғарыда айтылғандай, диск бетін қысуды қолдайтын Apache Ignite бағдарламасының ең аз нұсқасы 2.8 болып табылады және тек Linux операциялық жүйесіне қолдау көрсетіледі. Келесідей қосыңыз және конфигурациялаңыз:

  • Класс жолында тұтану-қысу модулі болуы керек. Әдепкі бойынша, ол libs/қосымша каталогтағы Apache Ignite дистрибутивінде орналасқан және сынып жолына қосылмаған. Каталогты бір деңгейге libs деңгейіне жылжытуға болады, содан кейін оны ignite.sh арқылы іске қосқан кезде ол автоматты түрде қосылады.
  • Тұрақтылық қосулы болуы керек (арқылы қосылған DataRegionConfiguration.setPersistenceEnabled(true)).
  • Бет өлшемі файлдық жүйе блогының өлшемінен үлкен болуы керек (оны пайдалану арқылы орнатуға болады DataStorageConfiguration.setPageSize() ).
  • Деректері қысылуы қажет әрбір кэш үшін қысу әдісін және (міндетті емес) қысу деңгейін (әдістер) теңшеу керек. CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

WAL тығыздау

Бұл қалай жұмыс істейді

WAL дегеніміз не және ол не үшін қажет? Өте қысқаша: бұл бет жадысын өзгертетін барлық оқиғаларды қамтитын журнал. Бұл ең алдымен құлаған жағдайда қалпына келу үшін қажет. Кез келген операция, пайдаланушыға басқаруды бермес бұрын, сәтсіз болған жағдайда, ол журналда ойнатылуы және пайдаланушы сәтті жауап алған барлық әрекеттерді қалпына келтіру үшін, ең алдымен оқиғаны WAL жүйесінде жазуы керек, тіпті бұл әрекеттер осы әрекеттер орындалса да. дискідегі бет жадысында көрсетуге уақыты болмады (жоғарыда бет қоймасына нақты жазу жекелеген ағындар арқылы біраз кідіріспен «тексеру нүктесі» деп аталатын процесте орындалатыны сипатталған).

WAL жазбалары логикалық және физикалық болып бөлінеді. Логикалық мәндер кілттер мен құндылықтар болып табылады. Физикалық - беттер қоймасындағы беттерге өзгерістерді көрсетеді. Логикалық жазбалар кейбір басқа жағдайларда пайдалы болуы мүмкін болғанымен, физикалық жазбалар тек апат жағдайында қалпына келтіру үшін қажет және жазбалар тек соңғы сәтті бақылау нүктесінен кейін қажет. Мұнда біз егжей-тегжейлі қарастырмаймыз және оның неге осылай жұмыс істейтінін түсіндірмейміз, бірақ қызығушылық танытқандар Apache Ignite Wiki сайтындағы жоғарыда аталған мақалаға сілтеме жасай алады: Ignite Persistent Store - сорғыштың астында.

Әр логикалық жазбада жиі бірнеше физикалық жазбалар болады. Яғни, мысалы, кэшке бір қою операциясы бет жадындағы бірнеше бетке әсер етеді (деректердің өзі бар бет, индекстері бар беттер, бос тізімдері бар беттер). Кейбір синтетикалық сынақтарда физикалық жазбалар WAL файлының 90% -на дейін алатынын анықтадым. Дегенмен, олар өте қысқа уақытқа қажет (әдепкі бойынша, бақылау пункттері арасындағы интервал 3 минутты құрайды). Өзектілігін жоғалтқаннан кейін бұл деректерден құтылу қисынды болар еді. WAL нығыздау механизмі дәл осылай істейді: ол физикалық жазбалардан құтылады және zip көмегімен қалған логикалық жазбаларды қысады, ал файл өлшемі өте айтарлықтай азаяды (кейде ондаған есе).

Физикалық түрде WAL дөңгелек түрде қайта жазылатын бекітілген өлшемді (әдепкі бойынша 10 МБ) бірнеше сегменттерден (әдепкі бойынша 64) тұрады. Ағымдағы сегмент толтырылғаннан кейін келесі сегмент ағымдағы болып тағайындалады, ал толтырылған сегмент мұрағатқа жеке ағынмен көшіріледі. WAL нығыздау мұрағат сегменттерімен жұмыс істейді. Сондай-ақ, жеке ағын ретінде ол бақылау нүктесінің орындалуын бақылайды және физикалық жазбалар қажет болмайтын мұрағат сегменттерінде қысуды бастайды.

Apache Ignite бағдарламасында деректерді қысу. Сбер тәжірибесі

Өнімділікке әсер ету

WAL нығыздауы жеке ағын ретінде орындалатындықтан, орындалатын операцияларға тікелей әсер етпеуі керек. Бірақ ол бәрібір орталық процессорға (қысу) және дискіге (әрбір WAL сегментін мұрағаттан оқу және сығылған сегменттерді жазу) қосымша фондық жүктемені қояды, сондықтан жүйе максималды қуатында жұмыс істеп тұрса, бұл өнімділіктің төмендеуіне әкеледі.

Қалай қосуға және конфигурациялауға болады

Сипат арқылы WAL нығыздауды қосуға болады WalCompactionEnabled в DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). Сондай-ақ, DataStorageConfiguration.setWalCompactionLevel() әдісін пайдаланып, әдепкі мәнге (BEST_SPEED) қанағаттанбасаңыз, қысу деңгейін орнатуға болады.

WAL бетінің суретін қысу

Бұл қалай жұмыс істейді

Біз WAL жазбаларында логикалық және физикалық болып бөлінетінін білдік. Әрбір бетті өзгерту үшін бет жадында физикалық WAL жазбасы жасалады. Физикалық жазбалар да өз кезегінде 2 ішкі түрге бөлінеді: бетті түсіру жазбасы және дельта жазбасы. Біз беттегі бір нәрсені өзгерткен сайын және оны таза күйден лас күйге ауыстырған сайын, бұл беттің толық көшірмесі WAL (беттің сурет жазбасы) ішінде сақталады. WAL-де тек бір байтты өзгертсек те, жазба бет өлшемінен сәл үлкенірек болады. Егер біз әлдеқашан ластанған бетте бір нәрсені өзгертсек, WAL-де дельта жазбасы қалыптасады, ол беттің алдыңғы күйімен салыстырғандағы өзгерістерді ғана көрсетеді, бірақ бүкіл бетті емес. Беттердің күйін кірден тазартуға қалпына келтіру бақылау нүктесі процесінде орындалатындықтан, бақылау нүктесі басталғаннан кейін бірден барлық физикалық жазбалар тек беттердің суретінен тұрады (себебі бақылау нүктесі басталғаннан кейін бірден барлық беттер таза) , содан кейін біз келесі бақылау нүктесіне жақындаған кезде дельта жазба бөлігі өсе бастайды және келесі бақылау нүктесінің басында қайтадан қалпына келтіріледі. Кейбір синтетикалық сынақтардағы өлшемдер физикалық жазбалардың жалпы көлеміндегі бет суреттерінің үлесі 90%-ға жететінін көрсетті.

WAL бетінің суретін сығу идеясы дайын бетті қысу құралы арқылы бет суреттерін қысу болып табылады (диск бетін қысу бөлімін қараңыз). Сонымен қатар, WAL-де жазбалар тек қосымша режимінде дәйекті түрде сақталады және жазбаларды файлдық жүйе блоктарының шекараларына байланыстырудың қажеті жоқ, сондықтан мұнда диск бетін қысу механизмінен айырмашылығы, бізге сирек файлдар қажет емес: барлығы; тиісінше, бұл механизм тек Linux операциялық жүйесінде ғана жұмыс істемейді. Сонымен қатар, біз үшін парақты қаншалықты қыса алғанымыз маңызды емес. Біз 1 байтты босатқанның өзінде, бұл оң нәтиже болып табылады және диск бетін сығудан айырмашылығы, қысылған деректерді WAL жүйесінде сақтай аламыз, мұнда біз 1-ден көп файлдық жүйе блогын босатқанда ғана қысылған бетті сақтаймыз.

Беттер өте қысылатын деректер болып табылады, олардың WAL жалпы көлеміндегі үлесі өте жоғары, сондықтан WAL файл пішімін өзгертпестен оның өлшемін айтарлықтай азайтуға болады. Логикалық жазбаларды қоса алғанда, қысу пішімді өзгертуді және үйлесімділікті жоғалтуды талап етеді, мысалы, логикалық жазбаларға қызығушылық танытатын сыртқы тұтынушылар үшін, бірақ файл өлшемін айтарлықтай азайтуға әкелмейді.

Диск бетін қысу сияқты, WAL бетінің суретін қысу ZSTD, LZ4, Snappy қысу алгоритмдерін, сондай-ақ SKIP_GARBAGE режимін пайдалана алады.

Өнімділікке әсер ету

WAL бетінің суретін қысуды тікелей қосу деректерді бет жадына жазатын ағындарға, яғни кэштердегі деректерді өзгертетін ағындарға ғана әсер ететінін байқау қиын емес. WAL-дан физикалық жазбаларды оқу тек бір рет орындалады, қазіргі уақытта түйін құлағаннан кейін көтеріледі (және ол бақылау нүктесі кезінде құлаған жағдайда ғана).

Бұл деректерді өзгертетін ағындарға келесі жолмен әсер етеді: біз дискіге жазбас бұрын бетті әр уақытта қысу қажеттілігіне байланысты жағымсыз әсер (CPU) және көлемінің төмендеуіне байланысты оң әсер (диск IO) аламыз. деректер жазылған. Тиісінше, мұнда бәрі қарапайым: егер жүйенің өнімділігі орталық процессормен шектелсе, біз шамалы деградацияға ие боламыз, егер ол дискінің енгізу/шығаруымен шектелсе, біз өсуді аламыз.

Жанама түрде WAL өлшемін азайту WAL сегменттерін мұрағатқа және WAL тығыздау ағындарына түсіретін ағындарға да (оң) әсер етеді.

Синтетикалық деректерді пайдаланатын ортамыздағы нақты өнімділік сынақтары шамалы өсуді көрсетті (өткізу қабілеті 10%-15%-ға артты, кідіріс 10%-15%-ға төмендеді).

Қалай қосуға және конфигурациялауға болады

Ең аз Apache Ignite нұсқасы: 2.8. Келесідей қосыңыз және конфигурациялаңыз:

  • Класс жолында тұтану-қысу модулі болуы керек. Әдепкі бойынша, ол libs/қосымша каталогтағы Apache Ignite дистрибутивінде орналасқан және сынып жолына қосылмаған. Каталогты бір деңгейге libs деңгейіне жылжытуға болады, содан кейін оны ignite.sh арқылы іске қосқан кезде ол автоматты түрде қосылады.
  • Тұрақтылық қосулы болуы керек (арқылы қосылған DataRegionConfiguration.setPersistenceEnabled(true)).
  • Сығымдау режимі әдіс арқылы орнатылуы керек DataStorageConfiguration.setWalPageCompression(), қысу әдепкі бойынша өшірілген (DISABLED режимі).
  • Қосымша түрде әдіс арқылы қысу деңгейін орнатуға болады DataStorageConfiguration.setWalPageCompression(), әрбір режим үшін жарамды мәндер үшін әдісті javadoc қараңыз.

қорытынды

Apache Ignite-те қарастырылған деректерді қысу механизмдері бір-бірінен тәуелсіз пайдаланылуы мүмкін, бірақ олардың кез келген комбинациясы да қолайлы. Олардың қалай жұмыс істейтінін түсіну олардың сіздің ортаңыздағы тапсырмаларыңызға қаншалықты сәйкес келетінін және оларды пайдалану кезінде нені құрбан етуге тура келетінін анықтауға мүмкіндік береді. Диск бетін қысу негізгі жадты қысуға арналған және орташа қысу коэффициентін бере алады. WAL бетінің суретін қысу WAL файлдары үшін орташа қысу дәрежесін береді және тіпті өнімділікті жақсартады. WAL нығыздауы өнімділікке оң әсер етпейді, бірақ физикалық жазбаларды жою арқылы WAL файлдарының өлшемін барынша азайтады.

Ақпарат көзі: www.habr.com

пікір қалдыру