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

Ръководство за разбиране на моделите за мащабиране на базата данни

Има много статии онлайн, описващи модели за мащабируемост на базата данни, но те са предимно разпръснати статии - просто техники, които са дефинирани хаотично без много контекст. Намирам, че те не са дефинирани стъпка по стъпка и не обсъждам кога да изберете коя опция за мащабиране, кои опции за мащабиране са осъществими на практика и защо.

Затова планирам да обсъдя подробно някои от техниките в бъдещи статии. Като начало смятам, че е по-добре да обсъждам техники стъпка по стъпка с някакъв контекст по свой собствен начин. Тази статия е статия от високо ниво - тук няма да обсъждам техниките за мащабиране в подробности, но ще предоставя общ преглед. Така че нека да започнем.

Проучване на казус

Да приемем, че сте изградили стартъп, който предлага споделяне на пътуване на евтина цена. Първоначално, когато започнете, се насочвате към град и едва ли имате десетки клиенти след първоначалната си реклама.

Вие запазвате всички клиенти, пътувания, местоположения, данни за резервации и история на пътуванията на клиенти в една и съща база данни или най-вероятно в една физическа машина. Няма фантастично кеширане или тръбопровод за големи данни за решаване на проблеми, тъй като приложението ви е много ново. Това е идеално за вашия случай на използване в този момент, тъй като има много малко клиенти и вашата система почти не резервира 1 пътуване за 5 минути, например.

Но с течение на времето все повече хора започват да се регистрират във вашата система, тъй като вие сте най-евтината услуга на пазара и благодарение на вашата промоция и реклами. Започвате да резервирате, да речем, 10 резервации в минута и бавно броят нараства до 20, 30 резервации в минута.

В този момент разбирате, че системата е започнала да се представя лошо:латентността на API се е увеличила много, а някои транзакции са в застой или гладуват и в крайна сметка се провалят. Приложението ви отнема повече време, за да отговори, което причинява недоволство на клиентите. Какво можете да направите, за да разрешите проблема?

Образец 1 – Оптимизиране на заявки и внедряване на пул за връзки:

Първото решение, което идва на ум е, че кешът често използва нединамични данни като история на резервациите, история на плащанията, потребителски профили и така нататък. Но след това кеширане на приложния слой не можете да разрешите проблема с латентността на API, излагащи динамични данни като текущото местоположение на шофьора или най-близките такси за даден клиент или текущата цена на пътуването в определен момент от времето след началото на пътуването.

Вие идентифицирате, че вашата база данни вероятно е силно нормализирана, така че въвеждате някои излишни колони (тези колони често се появяват в WHERE или JOIN ON клауза в заявки) в широко използвани таблици с цел денормализация. Това намалява заявките за присъединяване, разделя голяма заявка на множество по-малки заявки и добавя резултатите им в слоя на приложението.

Друга паралелна оптимизация, която можете да направите, е да променяте връзките към базата данни. Клиентските библиотеки на базата данни и външните библиотеки са налични в почти всички езици за програмиране. Можете да използвате библиотеки на пула за връзки за кеширане на връзки към базата данни или можете да конфигурирате размера на пула за връзки в самата система за управление на база данни.

Създаването на всяка мрежова връзка е скъпо, тъй като изисква известна комуникация напред и назад между клиент и сървър. Пулирането на връзки може да ви помогне да оптимизирате броя на връзките. Библиотеките на пула за връзки могат да ви помогнат да мултиплексирате връзки — множество нишки на приложения могат да използват една и съща връзка с база данни. Ще видя дали мога да обясня подробно обединяването на връзките в отделна статия по-късно.

Измерете латентността на вашите API и намерете вероятно 20–50% или повече намалена латентност. Това е добра оптимизация в този момент.

Вече сте разширили бизнеса си до още един град, повече клиенти се регистрират, бавно започвате да правите 80–100 резервации в минута. Вашата система не може да се справи с този мащаб. Отново виждате, че латентността на API се е увеличила, слоят на базата данни се е отказал, но този път никаква оптимизация на заявки не ви дава значително увеличение на производителността. Проверявате системния показател, установявате, че дисковото пространство е почти пълно, процесорът е зает в 80% от времето, RAM се запълва много бързо.

Модел 2 – Вертикално мащабиране или увеличаване на мащаба:

След като прегледате всички системни показатели, знаете, че няма друго лесно решение, а не надграждане на хардуера на системата. Надграждате размера на RAM паметта си 2 пъти, надграждате дисковото пространство, да речем, 3 пъти или повече. Това се нарича вертикално мащабиране или увеличаване на вашата система. Вие информирате своя инфраструктурен екип или екипа на devops или агенти на трети страни в центъра за данни за надграждане на вашата машина.

Но как да настроите машината за вертикално мащабиране?

Разпределяте по-голяма машина. Един подход е да не мигрирате ръчно данни от старата машина, а да зададете новата машина като replica към съществуващата машина (primary )-направете временна primary replica конфигурация. Нека репликацията се случи естествено. След като репликацията приключи, повишете новата машина до основна и изведете по-старата машина офлайн. Тъй като се очаква по-голямата машина да обслужва всички заявки, цялото четене/запис ще се извършва на тази машина.

Готино. Системата ви отново работи и работи с повишена производителност.

Вашият бизнес върви много добре и решавате да мащабирате до още 3 града — вече работите в общо 5 града. Трафикът е 3 пъти в сравнение с по-рано, очаква се да направите около 300 резервации в минута. Преди дори да постигнете тази целева резервация, вие отново се сблъсквате с намаляване на производителността, размерът на индекса на базата данни се увеличава значително в паметта, има нужда от постоянна поддръжка, сканирането на таблица с индекс става по-бавно от всякога. Вие изчислявате разходите за допълнително мащабиране на машината, но не сте убедени в цената. Какво правиш сега?

Образец 3 – Разделяне на отговорността за командна заявка (CQRS):

Вие идентифицирате, че голямата машина не е в състояние да се справи с всички read/write искания. Също така в повечето случаи всяка компания се нуждае от транзакционни възможности при write но не и на read операции. Вие също сте добре с малко непоследователно или забавено read операции и вашият бизнес също няма проблем с това. Виждате възможност, при която може да е добра опция да отделите read &write операции с физическа машина. Това ще създаде обхват за отделните машини да обработват повече read/write операции.

Сега взимате още две големи машини и ги настройвате като replica към текущата машина. Репликацията на база данни ще се погрижи за разпространението на данни от primary машина към replica машини. Навигирате във всички прочетени заявки (Заявка (Q ) в CQRS ) към репликите — всяка replica може да обслужва всяка заявка за четене, вие навигирате във всички заявки за писане (команда (C ) в CQRS ) към primary . Възможно е да има малко забавяне в репликацията, но според случая на бизнес употреба това е добре.

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

Сега мащабирате до още 2 града, виждате, че вашият primary не може да обработва всички write искания. Много write заявките имат забавяне. Освен това изоставането между primary &replica понякога оказва влияние върху клиенти и шофьори бивши — когато пътуването приключи, клиентът плаща на шофьора успешно, но шофьорът не може да види плащането, тъй като активността на клиента е write заявка, която отива към primary , докато дейността на водача е read заявка, която отива към една от репликите. Цялостната ви система е толкова бавна, че шофьорът не може да види плащането поне половин минута – разочароващо както за шофьора, така и за клиента. Как го решавате?

Модел 4 – Множество първична репликация

Увеличихте наистина добре с primary-replica конфигурация, но сега имате нужда от повече производителност при запис. Може да сте готови да направите малко компромис при read изпълнение на заявката. Защо не разпространите заявката за запис до replica също?

В multi-primary конфигурация, всички машини могат да работят и като primary &replica . Можете да помислите за multi-primary като кръг от машини кажете A->B->C->D->A . B може да репликира данни от A , C може да репликира данни от B , D може да репликира данни от C , A може да репликира данни от D . Можете да пишете данни на всеки възел, докато четете данни, можете да излъчвате заявката към всички възли, който отговори, връща това. Всички възли ще имат една и съща схема на база данни, същия набор от таблици, индекс и т.н. Така че трябва да се уверите, че няма сблъсък в id между възли в една и съща таблица, в противен случай по време на излъчване множество възли ще върнат различни данни за един и същ id .

По принцип е по-добре да използвате UUID или GUID за ид. Още един недостатък на тази техника е — read заявките може да са неефективни, тъй като включва излъчване на заявка и получаване на правилния резултат – основно подход на разпръснато събиране.

Сега мащабирате до още 5 града и системата ви отново е в болка. Очаква се да обработвате около 50 заявки в секунда. Имате отчаяна нужда да се справите с голям брой едновременни заявки. Как постигате това?

Образец 5 – Разделяне:

Знаете, че вашето location базата данни е нещо, което става високо write &read трафик. Вероятно write:read съотношението е 7:3 . Това оказва голям натиск върху съществуващите бази данни. location таблиците съдържат малко първични данни като longitude , latitude , timestamp , driver id , trip id и т.н. Няма много общо с потребителските пътувания, потребителски данни, данни за плащане и т.н. Какво ще кажете за разделянето на location таблици в отделна схема на база данни? Какво ще кажете за поставянето на тази база данни в отделни машини с подходящо primary-replica или multi-primary конфигурация?

Това се нарича разделяне на данни по функционалност. Различни бази данни могат да хостват данни, категоризирани по различна функционалност, ако е необходимо резултатът може да бъде агрегиран в задния слой. Използвайки тази техника, можете да се съсредоточите върху добре мащабирането на онези функции, които изискват високо read/write искания. Въпреки че задният край или слоят на приложението трябва да поеме отговорността да се присъедини към резултатите, когато е необходимо, което вероятно води до повече промени в кода.

Сега си представете, че сте разширили бизнеса си до общо 20 града във вашата страна и планирате скоро да се разширите в Австралия. Вашето нарастващо търсене на приложение изисква по-бърз и по-бърз отговор. Нито един от горните методи не може да ви помогне до крайност сега. Трябва да мащабирате системата си по такъв начин, че разширяването към други държави/региони да не изисква винаги да правите чести промени в инженерството или архитектурата. Как го правиш?

Модел 6 – Хоризонтално мащабиране:

Гуглите много, четете много за това как други компании са решили проблема – и стигате до заключението, че трябва да мащабирате хоризонтално. Разпределяте да речем 50 машини - всички имат една и съща схема на база данни, която от своя страна съдържа същия набор от таблици. Всички машини просто съхраняват част от данни.

Тъй като всички бази данни съдържат един и същ набор от таблици, можете да проектирате системата по такъв начин, че локалността на данните да е там, т.е. всички свързани данни попадат в една и съща машина. Всяка машина може да има свои собствени реплики, репликите могат да се използват при възстановяване при отказ. Всяка от базите данни се нарича shard . Физическата машина може да има един или няколко shards - зависи от вашия дизайн как искате. Трябва да вземете решение за sharding key по такъв начин, че един sharding key винаги се отнася за една и съща машина. Така че можете да си представите много машини, всички държащи свързани данни в същия набор от таблици, read/write заявки за същия ред или същия набор от ресурси се намират в същата машина за база данни.

По принцип разделянето е трудно - поне инженери от различни компании казват това. Но когато обслужвате милиони или милиарди заявки, трябва да вземете толкова трудно решение.

Ще обсъдя sharding по-подробно в следващата ми публикация, така че въздържайте изкушението си да обсъждам повече в тази публикация.

Сега, тъй като разполагате с разделяне, вие сте уверени, че можете да мащабирате в много страни. Вашият бизнес е нараснал толкова много, че инвеститорите ви тласкат да разширите бизнеса си на различни континенти. Тук отново виждате някакъв проблем. Отново забавяне на API. Вашата услуга се хоства в САЩ и хората от Виетнам изпитват трудности за резервиране на пътувания. Защо? Какво правите по въпроса?

Образец 7 – Мъдър дял в центъра за данни:

Вашият бизнес се разраства в Америка, Южна Азия и в няколко страни в Европа. Правите милиони резервации дневно с милиарди заявки, които удрят вашия сървър. Поздравления - това е пиков момент за вашия бизнес.

Но тъй като заявките от приложението трябва да пътуват през континенти през стотици или хиляди сървъри в интернет, възниква латентността. Какво ще кажете за разпределението на трафика между центровете за данни? Можете да настроите център за данни в Сингапур, който обработва всички заявки от Южна Азия, център за данни в Германия може да обработва всички заявки от европейски страни, а център за данни в Калифорния може да обработва всички заявки от САЩ.

Също така активирате кръстосана репликация на центрове за данни, което помага за възстановяване след бедствие. Така че, ако центърът за данни в Калифорния направи репликация в центъра за данни в Сингапур, в случай, че центърът за данни в Калифорния се срине поради проблем с електричеството или природно бедствие, всички заявки от САЩ могат да се върнат към центъра за данни в Сингапур и така нататък.

Тази техника за мащабиране е полезна, когато имате милиони клиенти, които да обслужвате в различни държави, и не можете да посрещнете загуба на данни, винаги трябва да поддържате наличността на системата.

Това са някои общи техники стъпка по стъпка за мащабиране на база данни. Въпреки че повечето инженери нямат достатъчно шанс да внедрят тези техники, но като цяло е по-добре да получите по-широка представа за такава система, която в бъдеще може да ви помогне да направите по-добро проектиране на система и архитектура.

В следващите си статии ще се опитам да обсъдя подробно някои от концепциите. Моля, не се колебайте да дадете подходяща обратна връзка за тази публикация, ако има такава.

Статията е публикувана първоначално в медийния акаунт на автора:https://medium.com/@kousiknath/understanding-database-scaling-patterns-ac24e5223522



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql като повишаване на производителността

  2. MySQL (или PHP?) групира резултати по данни от полето

  3. Функция MySQL SIGN() – Разберете дали числото е положително или отрицателно в MySQL

  4. Отпадане на уникално ограничение от MySQL таблица

  5. TIMESTAMP() Примери – MySQL