MariaDB
 sql >> база данни >  >> RDS >> MariaDB

Работа с големи обеми данни с MySQL и MariaDB

Повечето бази данни нарастват по размер с течение на времето. Растежът не винаги е достатъчно бърз, за ​​да повлияе на производителността на базата данни, но определено има случаи, когато това се случва. Когато се случи, често се чудим какво може да се направи, за да се намали това въздействие и как можем да осигурим гладки операции с базата данни, когато работим с данни в голям мащаб.

Първо, нека се опитаме да дефинираме какво означава „голям обем данни“? За MySQL или MariaDB това е некомпресиран InnoDB. InnoDB работи по начин, който силно се възползва от наличната памет - главно буферния пул на InnoDB. Докато данните се побират там, достъпът до диска е сведен до минимум до обработката само на записи - четенията се обслужват извън паметта. Какво се случва, когато данните надраснат паметта? Все повече и повече данни трябва да се четат от диск, когато има нужда от достъп до редове, които в момента не са кеширани. Когато количеството данни се увеличи, работното натоварване преминава от свързано с процесора към I/O. Това означава, че тесното място вече не е CPU (какъвто беше случаят, когато данните се побираха в паметта - достъпът до данни в паметта е бърз, трансформацията и агрегацията на данни е по-бавна), а по-скоро е I/O подсистемата (операциите на CPU върху данни са много по-бързо от достъпа до данни от диск.) С увеличеното приемане на флаш, свързаните с I/O работни натоварвания не са толкова ужасни, колкото бяха по времето на въртящи се дискове (произволният достъп е много по-бърз със SSD), но ударът в производителността все още е налице .

Друго нещо, което трябва да имаме предвид, че обикновено ни е грижа само за активния набор от данни. Разбира се, може да имате терабайти данни във вашата схема, но ако трябва да имате достъп само до последните 5 GB, това всъщност е доста добра ситуация. Разбира се, той все още представлява оперативни предизвикателства, но по отношение на производителността все още трябва да е наред.

Нека просто приемем за целите на този блог, а това не е научно определение, че под големия обем данни имаме предвид случай, когато размерът на активните данни значително надвишава размера на паметта. Може да бъде 100GB, когато имате 2GB памет, може да бъде 20TB, когато имате 200GB памет. Преломният момент е, че вашето работно натоварване е строго I/O обвързано. Бъдете с нас, докато обсъждаме някои от опциите, които са налични за MySQL и MariaDB.

Разделяне на дялове

Историческият (но напълно валиден) подход за обработка на големи обеми данни е да се приложи разделяне. Идеята зад него е да се раздели таблицата на дялове, нещо като подтаблици. Разделянето става според правилата, определени от потребителя. Нека да разгледаме някои от примерите (примерите за SQL са взети от документацията на MySQL 8.0)

MySQL 8.0 идва със следните типове разделяне:

  • Диапазон
  • СПИСЪК
  • КОЛОНИ
  • ХАШ
  • КЛЮЧ

Може също да създава подраздели. Тук няма да пренаписваме документацията, но все пак бихме искали да ви дадем малко представа за това как работят дяловете. За да създадете дялове, трябва да дефинирате ключа за разделяне. Тя може да бъде колона или в случай на RANGE или LIST множество колони, които ще се използват за дефиниране на това как данните трябва да бъдат разделени на дялове.

HASH разделянето изисква от потребителя да дефинира колона, която ще бъде хеширана. След това данните ще бъдат разделени на дефиниран от потребителя брой дялове въз основа на тази хеш стойност:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

В този случай хешът ще бъде създаден въз основа на резултата, генериран от функцията YEAR() в колоната „наети“.

Разделянето на KEY е подобно с изключението, че потребителят определя коя колона трябва да бъде хеширана, а останалото зависи от MySQL.

Докато дяловете HASH и KEY разпределят произволно данни в броя на дяловете, RANGE и LIST позволяват на потребителя да реши какво да прави. RANGE обикновено се използва с час или дата:

CREATE TABLE quarterly_report_status (
    report_id INT NOT NULL,
    report_status VARCHAR(20) NOT NULL,
    report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
    PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
    PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
    PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),
    PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),
    PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),
    PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
    PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
    PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
    PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
    PARTITION p9 VALUES LESS THAN (MAXVALUE)
);

Може да се използва и с друг тип колони:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

LIST дяловете работят въз основа на списък със стойности, който сортира редовете в множество дялове:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

Какъв е смисълът от използването на дялове, може да попитате? Основният момент е, че търсенията са значително по-бързи, отколкото при неразделена таблица. Да кажем, че искате да потърсите редовете, които са създадени през даден месец. Ако имате данни за няколко години, съхранявани в таблицата, това ще бъде предизвикателство – ще трябва да се използва индекс и, както знаем, индексите помагат за намирането на редове, но достъпът до тези редове ще доведе до куп произволни четения от цялата маса. Ако имате дялове, създадени на база година-месец, MySQL може просто да прочете всички редове от този конкретен дял - няма нужда от достъп до индекс, няма нужда от извършване на произволни четения:просто прочетете всички данни от дяла, последователно, и ние сме всичко е готово.

Разделите също са много полезни при справянето с ротацията на данни. Ако MySQL може лесно да идентифицира редове за изтриване и да ги съпостави в един дял, вместо да изпълнява DELETE FROM table WHERE ..., което ще използва индекс за намиране на редове, можете да съкратите дяла. Това е изключително полезно при разделянето на RANGE - като се придържаме към примера по-горе, ако искаме да запазим данни само за 2 години, можем лесно да създадем работа на cron, която ще премахне стария дял и ще създаде нов, празен за следващия месец.

InnoDB компресия

Ако имаме голям обем данни (не е задължително да мислим за бази данни), първото нещо, което ни идва на ум, е да ги компресираме. Има много инструменти, които предоставят възможност за компресиране на вашите файлове, като значително намаляват размера им. InnoDB също има опция за това - MySQL и MariaDB поддържат компресия на InnoDB. Основното предимство на използването на компресия е намаляването на I/O активността. Данните, когато са компресирани, са по-малки, така че са по-бързи за четене и запис. Типичната страница на InnoDB е с размер 16KB, за SSD това са 4 I/O операции за четене или запис (SSD обикновено използва 4KB страници). Ако успеем да компресираме 16KB в 4KB, ние просто намалихме I/O операциите с четири. Това всъщност не помага много по отношение на съотношението набор от данни към памет. Всъщност това може дори да го влоши - MySQL, за да работи с данните, трябва да декомпресира страницата. И все пак той чете компресирана страница от диск. Това води до буферен пул на InnoDB, съхраняващ 4KB компресирани данни и 16KB некомпресирани данни. Разбира се, има алгоритми за премахване на ненужни данни (некомпресираната страница ще бъде премахната, когато е възможно, запазвайки само компресирана в паметта), но не можете да очаквате твърде голямо подобрение в тази област.

Също така е важно да имате предвид как работи компресията по отношение на съхранението. Твърдотелните устройства са норма за сървърите на бази данни в наши дни и имат няколко специфични характеристики. Те са бързи, не им пука много дали трафикът е последователен или произволен (въпреки че все още предпочитат последователния достъп пред произволния). Те са скъпи за големи обеми. Те страдат от „износване“, тъй като могат да се справят с ограничен брой цикли на запис. Компресията значително помага тук - като намаляваме размера на данните на диска, намаляваме цената на слоя за съхранение на база данни. Чрез намаляване на размера на данните, които записваме на диск, ние увеличаваме живота на SSD.

За съжаление, дори компресията да помогне, за по-големи обеми данни може да не е достатъчно. Друга стъпка би била да потърсите нещо различно от InnoDB.

MyRocks

MyRocks е двигател за съхранение, достъпен за MySQL и MariaDB, който се основава на различна концепция от InnoDB. Моят колега, Себастиан Инсаусти, има хубав блог за използването на MyRocks с MariaDB. Същността е, че поради своя дизайн (използва Log Structured Merge, LSM), MyRocks е значително по-добър по отношение на компресията от InnoDB (който се основава на B+Tree структура). MyRocks е проектиран за работа с големи количества данни и за намаляване на броя на записванията. Той произхожда от Facebook, където обемите на данни са големи и изискванията за достъп до данните са високи. По този начин SSD съхранение - все пак в такъв голям мащаб всяка печалба от компресия е огромна. MyRocks може да осигури дори до 2 пъти по-добра компресия от InnoDB (което означава, че намалявате броя на сървърите с два). Той също така е проектиран да намали усилването при запис (брой записи, необходими за обработка на промяна на съдържанието на реда) - изисква 10 пъти по-малко записи от InnoDB. Това, очевидно, намалява I/O натоварването, но още по-важното е, че ще удължи живота на SSD десет пъти в сравнение с предаването на същото натоварване с InnoDB). От гледна точка на производителността, по-малък е обемът на данните, толкова по-бърз е достъпът, следователно механизмите за съхранение като този могат също да помогнат за по-бързото извеждане на данните от базата данни (въпреки че това не беше най-високият приоритет при проектирането на MyRocks).

Колонни хранилища за данни

Свързани ресурси Управление на производителността на ClusterControl Разбиране на ефектите от високата латентност при решенията с висока наличност MySQL и MariaDB Материал за производителност на MySQL

В един момент всичко, което можем да направим, е да признаем, че не можем да се справим с такъв обем данни, използвайки MySQL. Разбира се, можете да го разделите, можете да правите различни неща, но в крайна сметка просто вече няма смисъл. Време е да се търсят допълнителни решения. Едно от тях би било използването на колонни хранилища за данни - бази данни, които са проектирани с мисъл за анализ на големи данни. Разбира се, те няма да помогнат с OLTP типа на трафика, но анализите са почти стандартни в днешно време, тъй като компаниите се опитват да се управляват от данни и да вземат решения въз основа на точни числа, а не на случайни данни. Има много колонни хранилища за данни, но бихме искали да споменем тук две от тях. MariaDB AX и ClickHouse. Имаме няколко блога, обясняващи какво представлява MariaDB AX и как може да се използва MariaDB AX. Важното е, че MariaDB AX може да се мащабира под формата на клъстер, подобрявайки производителността. ClickHouse е друга опция за извършване на анализи - ClickHouse може лесно да бъде конфигуриран да репликира данни от MySQL, както обсъдихме в една от публикациите ни в блога. Той е бърз, безплатен е и може също да се използва за формиране на клъстер и за разделяне на данни за още по-добра производителност.

Заключение

Надяваме се, че тази публикация в блога ви даде представа за това как големи обеми данни могат да се обработват в MySQL или MariaDB. За щастие има няколко опции на наше разположение и в крайна сметка, ако не можем наистина да го накараме да работи, има добри алтернативи.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как QUOTE() работи в MariaDB

  2. Сравняване на MariaDB Enterprise Backup с ClusterControl Backup Management

  3. Как работи SLEEP() в MariaDB

  4. Инсталиране на Laravel на Ubuntu с поддръжка на Apache, MariaDB и PHP

  5. Разлика между TRIM() и TRIM_ORACLE() в MariaDB