Шардинг и репликация mysql

Thank you for reading this post, don't forget to subscribe!

Мас­шта­би­ро­ва­ние баз дан­ных — самая слож­ная зада­ча во вре­мя роста про­ек­та. 90% всех уси­лий обыч­но при­хо­дит­ся как раз на рабо­ту, свя­зан­ную с ростом объ­е­ма дан­ных и опе­ра­ций с ними. Клас­си­че­ская схе­ма рабо­ты при­ло­же­ния с базой дан­ных выгля­дит так:

Один сер­вер базы дан­ных в какой-то момент пере­ста­ет справ­лять­ся с нагруз­кой. В этот момент и сле­ду­ет при­ме­нять опи­сан­ные тут тех­ни­ки масштабирования.

Перед тем, как при­сту­пать к мас­шта­би­ро­ва­нию, необ­хо­ди­мо про­ве­сти ана­лиз мед­лен­ных запро­сов и убе­дить­ся, что сер­вер MySQL настро­ен оптимально.

Стратегии

В осно­ве мас­шта­би­ро­ва­ния дан­ных лежит тот же прин­цип, что и в осно­ве мас­шта­би­ро­ва­ния Web при­ло­же­ний. Это раз­де­ле­ние дан­ных на груп­пы и выде­ле­ние их на отдель­ные сер­ве­ра. Суще­ству­ет две основ­ные стра­те­гии — репли­ка­ция и шардинг.

Репликация

Репли­ка­ция поз­во­ля­ет создать пол­ный дуб­ли­кат базы дан­ных. Так, вме­сто одно­го сер­ве­ра у Вас их будет несколько:

Master-slave

Чаще все­го исполь­зу­ют схе­му master-slave:

  • Master — это основ­ной сер­вер БД, куда посту­па­ют все дан­ные. Все изме­не­ния в дан­ных (добав­ле­ние, обнов­ле­ние, уда­ле­ние) долж­ны про­ис­хо­дить на этом сервере.
  • Slave — это вспо­мо­га­тель­ный сер­вер БД, кото­рый копи­ру­ет все дан­ные с масте­ра. С это­го сер­ве­ра сле­ду­ет читать дан­ные. Таких сер­ве­ров может быть несколько.

Репли­ка­ция поз­во­ля­ет исполь­зо­вать два или боль­ше оди­на­ко­вых сер­ве­ров вме­сто одно­го. Опе­ра­ций чте­ния (SELECT) дан­ных часто намно­го боль­ше, чем опе­ра­ций изме­не­ния дан­ных (INSERT/UPDATE). Поэто­му, репли­ка­ция поз­во­ля­ет раз­гру­зить основ­ной сер­вер за счет пере­но­са опе­ра­ций чте­ния на слейв.

Работа из приложения

В при­ло­же­нии у Вас будет два соеди­не­ния с базой дан­ных. Одно — для масте­ра и одно для слейва:

# При выпол­не­нии запро­сов необ­хо­ди­мо исполь­зо­вать соот­вет­ству­ю­щее соединение

Репли­ка­ция обыч­но под­дер­жи­ва­ет­ся самой СУБД (напри­мер, MySQL) и настра­и­ва­ет­ся неза­ви­си­мо от при­ло­же­ния. Читай­те деталь­нее про настрой­ку, исполь­зо­ва­ние и типы репли­ка­ции дан­ных на при­ме­ре MySQL.

Сле­ду­ет отме­тить, что репли­ка­ция сама по себе не очень удоб­ный меха­низм мас­шта­би­ро­ва­ния. При­чи­ной тому — рас­син­хро­ни­за­ция дан­ных и задерж­ки в копи­ро­ва­нии с масте­ра на слейв. Зато это отлич­ное сред­ство для обес­пе­че­ния отка­зо­устой­чи­во­сти. Вы все­гда може­те пере­клю­чить­ся на слейв, если мастер лома­ет­ся и наобо­рот. Чаще все­го репли­ка­ция исполь­зу­ет­ся сов­мест­но с шар­дин­гом имен­но из сооб­ра­же­ний надежности.

Шардинг (sharding)

Шар­динг (ино­гда шар­ди­ро­ва­ние) — это дру­гая тех­ни­ка мас­шта­би­ро­ва­ния рабо­ты с дан­ны­ми. Суть его в раз­де­ле­нии (пар­ти­ци­о­ни­ро­ва­ние) базы дан­ных на отдель­ные части так, что­бы каж­дую из них мож­но было выне­сти на отдель­ный сер­вер. Этот про­цесс зави­сит от струк­ту­ры Вашей базы дан­ных и выпол­ня­ет­ся пря­мо в при­ло­же­нии в отли­чие от репликации:

Вертикальный шардинг

Вер­ти­каль­ный шар­динг — это выде­ле­ние таб­ли­цы или груп­пы таб­лиц на отдель­ный сер­вер. Напри­мер, в при­ло­же­нии есть такие таблицы:

  • users — дан­ные пользователей
  • photos — фото­гра­фии пользователей
  • albums — аль­бо­мы пользователей

Таб­ли­цу users Вы остав­ля­е­те на одном сер­ве­ре, а таб­ли­цы photos и albums пере­но­си­те на дру­гой. В таком слу­чае в при­ло­же­нии Вам необ­хо­ди­мо будет исполь­зо­вать соот­вет­ству­ю­щее соеди­не­ние для рабо­ты с каж­дой таблицей:

# Для каж­дой таб­ли­цы или груп­пы таб­лиц будет отдель­ное соединение

В отли­чие от репли­ка­ции, мы исполь­зу­ем раз­ные соеди­не­ния для любых опе­ра­ций, но с опре­де­лен­ны­ми таб­ли­ца­ми. Читай­те подроб­нее об исполь­зо­ва­нии вер­ти­каль­но­го шар­дин­га на практике.

Горизонтальный шардинг

Гори­зон­таль­ный шар­динг — это раз­де­ле­ние одной таб­ли­цы на раз­ные сер­ве­ра. Это необ­хо­ди­мо исполь­зо­вать для огром­ных таб­лиц, кото­рые не уме­ща­ют­ся на одном сер­ве­ре. Раз­де­ле­ние таб­ли­цы на кус­ки дела­ет­ся по тако­му принципу:

  • На несколь­ких сер­ве­рах созда­ет­ся одна и та же таб­ли­ца (толь­ко струк­ту­ра, без данных).
  • В при­ло­же­нии выби­ра­ет­ся усло­вие, по кото­ро­му будет опре­де­лять­ся нуж­ное соеди­не­ние (напри­мер, чет­ные на один сер­вер, а нечет­ные — на другой).
  • Перед каж­дым обра­ще­ни­ем к таб­ли­це про­ис­хо­дит выбор нуж­но­го соединения.

Допу­стим, наше при­ло­же­ние рабо­та­ет с огром­ной таб­ли­цей, кото­рая хра­нит фото­гра­фии поль­зо­ва­те­лей. Мы под­го­то­ви­ли два сер­ве­ра (обыч­но они назы­ва­ют­ся шар­да­ми) для этой таб­ли­цы. Для нечет­ных поль­зо­ва­те­лей мы будем рабо­тать с пер­вы­ми сер­ве­ром, а для чет­ных — со вто­рым. Таким обра­зом, на каж­дом из сер­ве­ров будет толь­ко часть всех дан­ных о фот­ках поль­зо­ва­те­лей. Это будет выгля­деть так:

# Перед обра­ще­ни­ем к таб­ли­це, мы выби­ра­ем нуж­ное нам соединение

Резуль­тат вот этой опе­ра­ции $user_id % 2 будет остат­ком от деле­ния на 2. Т.е. для чет­ных чисел — 0, а для нечет­ных — 1.

Любая рабо­та с таб­ли­цей photos теперь будет про­ис­хо­дить толь­ко после полу­че­ния нуж­но­го соеди­не­ния на осно­ве $user_id.

Гори­зон­таль­ный шар­динг — это очень мощ­ный инстру­мент мас­шта­би­ро­ва­ния дан­ных. Но в то же вре­мя и очень нетри­ви­аль­ный. Читай­те деталь­но об исполь­зо­ва­нии гори­зон­таль­но­го шар­дин­га на практике.

Не сле­ду­ет при­ме­нять тех­ни­ку шар­дин­га ко всем таб­ли­цам. Пра­виль­ный под­ход — это поэтап­ный про­цесс раз­де­ле­ния рас­ту­щих таб­лиц. Сле­ду­ет заду­мы­вать­ся о гори­зон­таль­ном шар­дин­ге, когда коли­че­ство запи­сей в одной таб­ли­це пере­хо­дит за пре­де­лы от несколь­ких десят­ков мил­ли­о­нов до сотен миллионов.

Совместное использование

Шар­динг и репли­ка­ция часто исполь­зу­ют­ся сов­мест­но. В нашем при­ме­ре, мы мог­ли бы исполь­зо­вать по два сер­ве­ра на каж­дый шард таблицы:

  • photos_master_1 — мастер пер­вой поло­ви­ны таблицы.
  • photos_slave_1 — слейв пер­вой поло­ви­ны таблицы.
  • photos_master_2 — мастер вто­рой поло­ви­ны таблицы.
  • photos_slave_2 — слейв вто­рой поло­ви­ны таблицы.

Тогда в при­ло­же­нии рабо­та с этой таб­лич­кой может выгля­деть так:

# Чита­ем дан­ные со слей­вов, а запи­сы­ва­ем на мастер-сервера

Такая схе­ма часто исполь­зу­ет­ся не для мас­шта­би­ро­ва­ния, а для обес­пе­че­ния отка­зо­устой­чи­во­сти. Так, при выхо­де из строя одно­го из сер­ве­ров шар­да, все­гда будет запасной.

Key-value базы данных

Сле­ду­ет отме­тить, что боль­шин­ство Key-value баз дан­ных под­дер­жи­ва­ет шар­динг на уровне плат­фор­мы. Напри­мер, Memcache. В таком слу­чае, Вы про­сто ука­зы­ва­е­те набор сер­ве­ров для соеди­не­ния, а плат­фор­ма сде­ла­ет все остальное:

# Мем­кеш сам уме­ет опре­де­лять нуж­ный сер­вер для каж­до­го ключа

Шар­динг и репли­ка­ция — это попу­ляр­ные и мощ­ные тех­ни­ки мас­шта­би­ро­ва­ния систем рабо­ты с дан­ны­ми. Несмот­ря на при­ме­ры для MySQL, эти под­хо­ды уни­вер­саль­ны и могут при­ме­нять­ся для любой технологии.