Linux fayl sistemlərinin incə rezervasiyası. 3 terabaytlıq MySQL DB-nin 20 saniyəyə ehtiyat nüsxələrini necə yaratmaq olar

Linux fayl sistemlərinin incə rezervasiyası. 3 terabaytlıq MySQL DB-nin 20 saniyəyə ehtiyat nüsxələrini necə yaratmaq olar

Məni Yuriy adlandırırlar, mən Sitimobil-də sistem idarəetmə qrupunun rəhbəriyəm. Bu gün Linux fayl sistemlərinin “incə ayırma” (thin provisioning) texnologiyası ilə bağlı təcrübəmi paylaşacağam və bunun şirkətimizin CI/CD proseslərində necə tətbiq oluna biləcəyini izah edəcəyəm. Biz, kodu istehsala çatdırdıqda mümkün qədər tez ‘müharibə’ versiyasına yaxın, oxuma və yazma üçün əlçatan MySQL verilənlər bazası surətlərinə ehtiyacımız olan vəziyyəti müzakirə edəcəyik.

Giriş: niyə zərərli məsləhətlər vermək lazımdır?

Məntiqi sualdır, çünki test mühitlərinə verilənlər bazası sxemlərinin köçürülməsi üçün işlək mexanizmlər mövcuddur. Əslində, əsas şardlaşdırılmamış DB-nin belə həcmlərə çatdırılmasının mənası nədir? Üstəlik, test üçün bütün məlumatlar lazım deyil. İzah etməyə çalışacağam.

Təxminən bir il əvvəl taksi agregatorumuzun aktiv artım fonunda (2018-ci ildə başa çatdırılan səfərlər üzrə 15 dəfə artmışdır) məlumat həcmləri, serverlərə olan yük, yayım tezliyi artdı. Biz aşağıdakı vəziyyətlə qarşılaşdıq:

  • Əsas MySQL verilənlər bazası təxminən 1000 cədvəl ümumi həcmi 2,5 TB-a çatdı və böyüməyə davam etdi.
  • Verilənlərin bölünməsindən (şardlaşdırmadan) sürətlə keçmək imkanı yox idi və ‘istədiyim kimi və istədiyim cür verilənlər bazasına yazıram’ köhnə yanaşması buna mane olurdu, cədvəllər arasında bir çox JOIN-lar və daxili asılılıqlar var idi.
  • Test mühitlərinə verilənlər bazası sxeminin köçürülməsi mexanizmi yox idi.
  • İstiqamətə qaytarıldıqda kodun avtomatik test olunması yox idi.

Sonuncu problemi mümkün qədər tez həll etmək istəyirdik. PHP monolitinin əsasını yoxlamaq üçün artıq Postman testləri yazılmışdı, lakin aktual verilənlər bazası çatışmırdı. Eyni zamanda, gecə surət yaratmaq, onu ustad etməklə gün ərzində istifadəyə vermək imkanımız yox idi: çoxlu sayda yayım və dəyişiklik, o cümlədən verilənlər və verilənlər bazası sxemindəki dəyişikliklər gündüzün ortasında stendi işləməz hala gətirərdi. Həmçinin, yayımın yalnız iş günü ilə məhdudlaşdırılması da effektiv olmazdı.

Buna baxmayaraq, vəzifə yerinə yetirildi: ilk iş stendimizi artıq iki həftə ərzində əldə etdik. Keçən il ərzində bir çox dəyişikliklərə məruz qaldı və hələ də istifadə olunur.

Daha sonra həllimizin inkişafında bütün addımları və mərhələləri ətraflı izah edəcəyəm. Siz, bu metodun yaşayış hüququna layiq olduğunu anlamış olacaqsınız.

“İncə ayırma” nədir?
Bu, mövcud olan resursdan daha çox tələb olunan resursu tahsis etməyə imkan verən bir hardware və ya proqram təminatı texnologiyasıdır (başqa adı sparse volumes). Burada tahsis edilən həcmin just-enough (vaxtında lazım olan) və just-in-time (lazım olan vaxtda) kriteriyalarına uyğun gəlməsi vacibdir. Əsasən ince ayırma müxtəlif saxlama sistemlərində (СХД) istifadə olunur ki, bu da faktiki əlçatanlardan daha çox tələb olunan disk sahəsini təqdim etməyə imkan verir. Bu texnologiya müxtəlif fayl sistemləri tərəfindən dəstəklənir, məsələn, LVM2, ZFS, BTRFS. İncə ayırma, virtualizasiya hipervizorlarında geniş istifadə olunur. Bizə incə ayırma, əsas məlumat bölməsinin snapshot-larından ehtiyac duyduğumuz qədər kopya yaratmağa imkan verdi (MySQL DBMS-in data-dizin).

Birinci stend, Thin LVM texnologiyası

Bu bölümü hələ də "Böyük məlumat həcmlərinə maksimum sürətli snapshot-lar necə ediləcəyi" adlandırmaq olar Thin LVM, fayl sisteminin və MySQL DBMS-in stabilitesini qeyri-etik göstəricilərə endirməklə.

Artıq LVM-i OS-in əsas bölmələrini qurmaq üçün istifadə etdiyimizdən, ondan başlamağa qərar verdik. İlk növbədə, snapshot-ları sorğu əsasında yarada biləcəyimiz fiziki bir replikamız olan ayrı bir fiziki maşın lazım idi. Test dövründə bu nüsxədə dəyişən əməliyyatlara icazə verdik, testi tamamladıqdan sonra uğurla silirdik. Server konfiqurasiyası belə idi:

  • 2 x Intel Silver 4114 (10×2,2 GHz HT)
  • 8 x 32 GB DDR4
  • 8 x 1920 GB Intel SSD Adaptec RAID kontrollerində RAID-10-da

RAID kontrolleri ilə proqram RAID MD arasında seçim mövzusunda ayrıca bir məqalə yazmaq olar. Sadəcə, seçimimizə iki amilin təsir etdiyini demək istəyirəm:

  • Tapşırıq qoyulanda bütün DBMS-ləri RAID kontrollerlərində quraşdırırdıq, buna görə də bunu tarixi olaraq belə başa düşmək olar.
  • Fayl sistemindəki sintetik testlərdə və MySQL-də müxtəlif əməliyyatlarla bağlı testlərdə performans fərqi minimal oldu.

Biz əldə edilən RAID-10-u böldük: bütün həcmi əhatə edən bir Unit Group (VG) yaratdıq (təxminən 6,7 GB xərclərlə) və sistem üçün 50 GB ölçüsündə lojiq bölmə (Logical Volume, LV) yaratdıq. Normal halda, qalan bütün yeri MySQL bölməsi üçün ayırırıq. Amma bizə incə ayırma lazım idi, ona görə də əvvəlcə, 3,5 TB ölçüsündə ⁄var⁄lib⁄mysql bölməsi yaratdığımız "pool" yaratdıq (gözlənilən DB həcmlərinə əsaslanaraq):

lvcreate -l 100%FREE -T vga/thin
lvcreate -V 3.5T -T vga/thin -n mysql

Partition formatını ext4 etdik, onu montajladıq, surətini yazdıq və ilkin stand yaratdıq. Sonra API forma bağladıq ki, bu da snapshotlar yaratmalı, müəyyən portda MySQL verilənlər bazası nümunəsini qaldırmalı və yaradılmış nümunəni silməlidir. Bunun üçün yalnız sistem çağırışları istifadə edildiyi üçün skriptin yazılma dili kimi adi bash seçdik, API bağlanma nöqtəsi olaraq HTTP → bash, açıq mənbə həllini işə saldıq. goexpose, Go-da yazılmışdır.

Bir gün bash skriptlərimizi açıq mənbəyə yerləşdirəcəyik, amma indiki halda əsas alqoritmi sadəcə təsvir edəcəyəm:

Əsas snapshotun yaradılması snapmain:

  1. Əsas surəti dayandırırıq.
  2. snapmain snapshotu üçün əməliyyatlara bloklama qoyuruq.
  3. Yeni snapshot creat edirik snapmain.
  4. MySQL'i işə salırıq və bloklamanı qaldırırıq.

İstənilən portda snapmain-dən verilənlər bazasının yaradılması:

  1. Müəyyən DB nümunəsində (port) bloklama qoyuruq.
  2. Əsas snapshotun yaradılmasının bloklanma vəziyyətini yoxlayırıq. Əgər varsa, 5 saniyə aralıqlarla gözləyib yenidən yoxlayırıq.
  3. Nümunənin köhnə LV partitionunun olub-olmadığını yoxlayırıq.
    3.1 Əgər varsa, MySQL nümunəsini kill -9 ilə dayandırırıq və LV partitionunu silirik.
  4. snapmain-dən yeni nümunə yaradırıq.
  5. Bu nümunə üçün qovluqları hazırlayır və montajlayırıq.
  6. Slave olduğuna dair əlamətləri silirik (fail) və MySQL nümunəsini işə salırıq.
  7. Onu master edirik.
  8. Bloklamanı qaldırırıq.

İstənilən portda verilənlər bazasının silinməsi:

  1. Müəyyən DB nümunəsində (port) bloklama qoyuruq.
  2. MySQL nümunəsini kill -9 ilə öldürürük.
  3. Qovluqları montajdan çıxarırıq.
  4. LV partitionunu silirik və bloklamanı qaldırırıq.

Yeni verilənlər bazası nümunələrinin parçalarını klonlamaq üçün nümunə komandalar:

lvcreate -n stage_3307 -s vga/snapmain
lvchange -ay -K vga/stage_3307
mount -o noatime,nodiratime,data=writeback /dev/mapper/vga-stage_3307 /mnt/stage_3307

İndi qarşılaşdığımız əsas problemi anlatacağam - biz incə ehtiyatlama istifadə edərkən SSD disklərinin performansına çarpdıq. Bu, Thin LVM-nin xüsusiyyətləri səbəbindən baş verdi: onun əsasında (əsasən) cihaz səviyyəsində kiçik bloklar 4 MB-lıq ölçüdə istifadə edilir. Bu belə görünürdü:

  1. Əsas partitiondan snapshot yaradırıq /var/lib/mysql.
  2. Masteri yetişdirmək üçün replika işə salırıq.
  3. Replika cədvəllərində hər hansı bir dəyişiklik snapshot bölməsində köhnə dəyişməmiş verilən bloklarını saxlamağa səbəb olur.
  4. Yüksək test nümunəsində hər hansı bir dəyişiklik bu nümunə üçün klonlanmış snapshot bölməsində köhnə dəyişməmiş blokları saxlamağa səbəb olur.
  5. Giriş-çıxış əməliyyatlarının 100% yüklənməsini alırıq, hər hansı əməliyyatı yavaşladır və replikanın tədricən geridə qalmasına səbəb olur.
  6. İş günü sonunda bir neçə saat geridə qalmış bir stand alırıq.

Bununla mübarizə aparmağımız və daha rahat nəticə əldə etməyimiz (əsas məqamlar):

RAID-kontroller:

  • Bütün növ kəsmələri standart olaraq söndürdük.
  • Writeback rejimi tətbiq olundu (məhsul yaddaşa girməzdən əvvəl, yazma prosesinin başa çatması).

Fayl sistemi:

  • Montaj nöqtəsində /var/lib/mysql düzəldildi noatime,nodiratime,data=writeback
  • ext4 jurnalını tune2fs ilə bağladıq.

MySQL:

  • Düzəldildi innodb_flush_method = O_DSYNC (yazma sürətini artırdı, beləliklə etibarlılığı azaltdı).
  • Jurnalın bağlanması, loglara ehtiyacımız olmadığına görə.
  • Düzəldildi innodb_buffer_pool_size = 4G (InnoDB hovuzunun ölçüsü nə qədər kiçikdirsə, MySQL xidmətinin dayanması o qədər sürətli olacaq və snapshot yaratma prosesi də o qədər sürətli başa çatacaq).

Bu tam siyahı deyil, xüsusilə MySQL üçün. Digər dəyişikliklər isə əhəmiyyətcə daha azdır və çox vaxt tətbiq edilmir və dəqiq deyildir. Məsələn, disk yükləməsini azaltmaq üçün biz belə də etsək: innodb_parallel_doublewrite_path şəklində /dev/shm, bəzi hallarda yanlış başa çatmış instansiyanın başladığı vaxtdan 5 saniyə qazana bilərdi.

Niyə MySQL-i snapshotdan əvvəl dayandırırıq? Axı, işləyən replica-dan snapshot ala bilərik. Bu doğrudur, lakin bu snapshot-dan yeni DB instansiyası standart olaraq zədələnmiş hesab olunacaq və işə salınanda tam skan etmə tələb edəcək. Replica-nı dayandırmaq mütləq daha sürətlidir, baxmayaraq ki, bu, nəticədə bütün prosesin ən uzun əməliyyatı olur.

Nəticədə, daha qəbul edilən zamanlama və işlək bir mühit əldə etdik. Lakin, əsas replica-nın replikasiyasının ən ifadəli qrafikindən göründüyü kimi, vəziyyət hələ də ideal deyil:
Linux fayl sistemlərinin incə rezervasiyası. 3 terabaytlıq MySQL DB-nin 20 saniyəyə ehtiyat nüsxələrini necə yaratmaq olar

Digər çatışmazlıqlardan biri, Thin LVM hovuzunu izləməyin praktiki olaraq mümkün olmamasıdır: sistem standart funksiyaları olan iostat-dan başqa, məsələn, hovuzun hansı hissəsinin fayl sisteminə daha çox yük verdiyini anlamaq mümkün deyil.

Yuxarıda təsvir edilən optimizasiya əlaqədar bir böyük çatışmazlığa ayrıca diqqət yetirilməlidir: biz YOLO mühiti əldə etdik. Təxminən bir-iki ayda bir, ext4 belə cür həddindən artıq yükə dözmədi və geri dönülməz şəkildə sıradan çıxaraq formatlanmağı və replikaya yüklənməsini tələb etdi. Sürət qazandıq, lakin stabilik itirdik.

Thin LVM istifadəsi zamanı hansı metrikalarla izləmək lazımdır:

  • Thin pool data %
  • Thin pool metadata %

Əgər yığılmış yerin sona çatdığı bizim mühitimiz sürdüyü halda (diskləri təmizləmək kifayətdir), metadata üçün yerin bitməsi hovuzun tam çökməsinə və sıfırdan yenidən yaradılma lazım olmasına səbəb olacaq.

Hovuz içindəki fayl sistemi zamanla çox parçalana bilir. Gündə bir dəfə cronla fstrim -v /var/lib/mysql.

Aralıq nəticələr:

  • Texnologiya asanlıqla tətbiq oluna bilər, LVM də eyni şəkildə və mühəndisin xüsusi bir bacarığına ehtiyac yoxdur.
  • Bu, kiçik ölçülü və çox yüklənməmiş DB-lər üçün yaxşı bir seçimdir. DB nə qədər kiçikdirsə, fayl sistemində çökdüyü qədər o qədər az çəkinir və disklərə yük daha az olur.
  • Bizim vəzifəmiz üçün başqa həll yolları axtarmağa başladıq, hər şey gələcək hissədə olacaq.

İkinci stend, ZFS texnologiyası

Bir zamanlar ZFS fayl sistemi ilə işləmişdim, amma o zaman ZFS, öz doğma Solaris əməliyyat sistemi ailəsində yaxşı işləyirdi. FreeBSD-yə port edilmiş versiya mövcud idi, lakin onun reallaşma səviyyəsi kifayət qədər yaxşı idi. Linux-da isə az bir insanın istifadə etdiyi yarımçıq bir port var idi. B-tree məlumatların saxlanılması strukturu (bu arada, InnoDB MySQL-də də eyni strukturdur) səbəbindən ZFS, çoxlu sayda fayl olan quraşdırmalarda yaxşı nəticə vermirdi. Bütün bunlar və istifadəyə başlamadan öncə mövzunu öyrənmək lazım olması, bu fayl sistemini təcrübəmdən uzun müddət çıxartdı. ext4 və xfs ortaya çıxdı, standart halına gəldi. Lakin bizim vəzifəmiz üçün ZFS tamamilə uyğundur, həm də Linux versiyası, fikrimcə, yetərincə etibarlı bir məhsula çevrilmişdir (tam dəstək olmasa da, bu səbəbdən ZFS-də tamamilə sıfırdan sistem quraşdıra bilmək yalnız bir sıra müxtəlif mariflər iə mümkündür), onu sınaqdan keçirməyə qərara aldıq.

Aydındır ki, stendi oxşar konfiqurasiyada (RAID nəzarətçisindən başqa) seçdik. 1920 GB-lıq səkkiz SSD disk quraşdırdıq. Təmiz ZFS-ə server yükləmək üçün öz şəbəkə görüntümüzü yazmaq istəmədik, buna görə bütün disklərdən 50 GB götürdük və sistem üçün MD RAID-10 yaratdıq. Hər diskdə qalan 1950 GB-ı ZFS RAID-10-a birləşdirdik:

zpool create zpool mirror /dev/sda2 /dev/sdb2 mirror /dev/sdc2 /dev/sdd2 mirror /dev/sde2 /dev/sdf2 mirror /dev/sdg2 /dev/sdh2

MySQL üçün bölmələr hazırladıq:

zfs create zpool/mysql
zfs set compression=gzip zpool/mysql
zfs set recordsize=128k zpool/mysql
zfs set atime=off zpool/mysql
zfs create zpool/mysql/data
zfs set recordsize=16k zpool/mysql/data
zfs set primarycache=metadata zpool/mysql/data
zfs set mountpoint=/var/lib/mysql zpool/mysql/data

Diqqət yetirin ki, standart gzip məlumat sıxılmasını aktiv etdik. Serverimizdə çox sayda proses gücü var və onlar tamamilə istifadə edilmir. Nəticədə 3 TB-dan 1.6 TB-a çevrildi, və zəif hal, əvvəlki vəziyyətdə olduğu kimi, disklərin maksimum performansı olduğundan, məlumatlar nə qədər az olsa — bir o qədər yaxşıdır. ZFS-dən əvvəlcədən mükəmməl bir bonus alırıq! Pik vaxtında, gzip-i saxlamaq üçün tam yük altında 4 nüvəyə qədər gedir, amma bunun üçün məyus olmuruq.

Sonra tətbiq prosesi daha sürətli getdi. LVM stendindən MySQL replikasının parametrlərini kopya etdik. ZFS komandalarına skritləri yenidən yazmağa bir az vaxt sərf etmək lazım oldu, amma ümumilikdə, alqoritmlər əvvəlki kimi qaldı. Snapsyot yaratma nümunəsi:

zfs set snapdir=visible zpool/mysql/data
zfs create zpool/stage_3307
zfs clone zpool/mysql/data@snapmain zpool/stage_3307/data
zfs set mountpoint=/mnt/stage_3307 zpool/stage_3307/data

Əlavə tənzimləmələrdən: ZFS bölmələrinin metadata və l2arc və zil logları yaddaşa çıxarıldı. Sonralar gördüyümüz kimi, bu bizim üçün artıq idi, lakin indiyə qədər bu optimizasiyanı saxladıq, lazım gəldikdə dəyişdirmək çətin deyil. Mənfi effektlərdən biri isə server yenidən başladıldıqda müvafiq yaddaş sahələrinin yenidən yaradılması lazım gəlməsidir. Bu zaman məlumat itirilmir. zpool status çıxarışı:

logs
      /dev/shm/zil_slog.img   ONLINE       0     0     0
cache
      /dev/shm/l2arc.img       ONLINE       0     0     0

Belə konfiqurasiya altında biz test mühitini sınamağa başladıq və mükəmməl nəticələr əldə etdik: eyni anda işləyən iki DB nüsxəsi (və aktiv əsas replikası) ilə snapshotlarda disk yükləməsi 50-60 % oldu.

Biz əsas problemimizdən qurtulmuşuq ki, bu replikasiyaların gecikmə qrafikində görünür (əvvəlki qrafiklə müqayisə edin, İnce LVM bölməsində):
Linux fayl sistemlərinin incə rezervasiyası. 3 terabaytlıq MySQL DB-nin 20 saniyəyə ehtiyat nüsxələrini necə yaratmaq olar

Bunun sayəsində bütün əməliyyatlarda ciddi sürətlənmə əldə etdik: replikayı dayandırıb başlatmaqla tam bir snapshotun yaradılması 40 saniyəyə qədər davam edir, yeni MySQL nüsxəsinin snapshotdan yerləşdirilməsi 20 saniyə qədər vaxt aparır. Bu, həm bizim, həm də proqram kodu testlərimiz üçün kifayət qədərdir.

Aralıq nəticələr:

  • Nəticələrimiz kodun test edilməsi üçün döyüş DB-nin nüsxəsini əldə etmək tələblərimizi tam təmin etdi.
  • Texnologiya ilə bağlı anlayış tələb olunur: ZFS-in nə olduğu və onunla necə işləmək lazım olduğunu başa düşmək lazımdır.
  • Biz ZFS-in bir milyondan çox kiçik fayllarla işləməsi üçün cari vəziyyəti yoxlamadıq. Lakin problemin davam etdiyini düşünürük, buna görə də bu fayl sistemini hər hansı fayl saxlama yerləri üçün tövsiyə etməzdim.

Sonra ne olacak?

Test mühitində daha heç nə etməyə ehtiyacımız yoxdur, nəticə bizi qane edir. Gələcəkdə test mühitinin replikasiyasında test etmək üçün lazım olmayan cədvəlləri istisna etmək üçün konfiqurasiya əlavə etməyi düşünürük, bu Baza həcmini daha da azaldacaq. BTRFS sistemini və onun incə bərpa texnologiyasının tətbiqini sınaqdan keçirmədik. Ancaq artıq əsas məqsədimizə çatıldığına görə belə bir vəzifəyə ehtiyac yoxdur. Ümumilikdə, əlbəttə ki, yuxarıda təsvir edilən yanaşmadan uzaqlaşmağı arzulayırıq — test mühitinə işçi DB miqrasiya etmək, ayrı bir test DB döngəsi yaratmaq, əsas verilənlər bazasını parçalamaq. Bunun çoxunu artıq həyata keçiririk, bu barədə gələcək məqalələrimizdə mütləq məlumat verəcəyik.

Yekunlar

İlkin vəzifə qeyri-adi bir şəkildə həll edilib. Ara nəticələrdə tətbiq olunmuş hər bir texnologiyanın üstünlükləri və mənfi cəhətləri təsvir olunub, buna görə də hansının və nə vaxt istifadə ediləcəyini qərarlaşdıraq:

  • Ince LVM — kiçik DB-lər üçün və ZFS-i öyrənməyə vaxt ayırmaq istəmədikdə.
  • ZFS — onunla çalışmağı bilənlər üçün və ya hər hansı bir vəziyyətdə öyrənməyə vaxt ayırmaq imkanı varsa.

Daha üst səviyyədə, bu məqalə iki fayl sisteminin texnologiyasını müqayisə etməkdən çoxdur. Mənim ifadə etmək və möhkəmləndirmək istədiyim əsas fikir budur ki, biznes üçün kritik vəziyyətlərdə qeyri-adi düşünməkdən çəkinməməli və yalnız hazır reseptlərə istinad etməməliyik. Bir zamanlar, texniki departamentimiz bir yerdə başını tərpətmək və üç terabaytlıq verilənlər bazası kopyalarını bir dəqiqədən az müddətdə yaratma vəzifəsinin icra edilməz olduğunu demək olardı, riskli texnologiyalara ehtiyacımız yoxdur, gəlin düzgün edək. Bu mümkün idi, lakin biz təxminən altı aydan bir ilə qədər vaxt itirəcəkdik və müştəri səyahətlərini (səyahətlər bizim əsas biznes göstəricimizdir) testlər olmadan və tətbiq zamanı itirəcəkdik. Qeyri-adi yanaşmayla, tətbiq üçün çox vaxt itirmədik, yeni və unudulmuş köhnə texnologiyalardan təcrübə qazandıq, və məhz ehtiyac duyduğumuz anda test etməyi təmin etdik. Şübhəsiz ki, bu, bütün göstəricilərimizə müsbət təsir etdi. Seçim həmişə sizdədir, biz isə öz imkanlarımızla maraqlı cari və gələcək nailiyyətlərimizi blogumuzda paylaşmağa davam edəcəyik.

Mənbə: habr.com

DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər 🔥 DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər | ProHoster