1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/blackeybaord-kingshard

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
how_to_use_kingshard.md 22 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 18:42 b4fbb46

Как использовать промежуточное ПО базы данных для расширения кластера MySQL — руководство по использованию Kingshard

В предыдущей статье я рассказывал о дизайне Kingshard. Эта статья получила много внимания от заинтересованных читателей. Один из них спросил, могу ли я написать статью о том, как использовать Kingshard для создания расширяемого кластера MySQL.

У меня было свободное время, и я написал руководство по использованию Kingshard, в котором я объясню, как правильно использовать промежуточное программное обеспечение Kingshard на основе моего понимания MySQL Proxy.

1. Сценарии использования Kingshard

Многие интернет-компании всё ещё широко используют MySQL для хранения различных типов реляционных данных. По мере увеличения объёма данных и количества запросов разработчики сталкиваются с новыми проблемами:

  • Разделение чтения и записи. Из-за увеличения количества запросов к интерфейсу одна база данных не может справиться с операциями записи и запроса. В этом случае мы должны распределить некоторые длительные запросы на несколько ведомых серверов.
  • Проблема с ёмкостью одной таблицы. Если при проектировании системы не учитывается разделение таблиц, то по мере роста объёма данных ёмкость одной таблицы становится слишком большой. Я видел таблицы с объёмом 500 миллионов записей, и даже простая операция удаления может вызвать медленные журналы в системе и потенциально привести к резкому увеличению ввода-вывода MySQL. Многие люди могут подумать об использовании индексов для полей запросов, но когда объём данных становится таким большим, даже добавление индексов не даёт заметного эффекта. В конечном счёте, проблема заключается в том, что одна таблица содержит слишком много данных, и MySQL должен сканировать множество записей, даже если он использует индексы для поиска данных.
  • Проблемы с эксплуатацией и обслуживанием базы данных. Если вы настроите хосты главного и подчинённого серверов в коде, система будет работать нормально. Однако это значительно увеличивает нагрузку на обслуживание, например, когда нагрузка на ввод-вывод MySQL увеличивается из-за увеличения трафика, администратору баз данных (DBA) необходимо добавить один подчинённый сервер, и тогда ему придётся изменить код, упаковать его и выпустить. Существует множество практических примеров, которые здесь не будут перечислены.
  • Пул соединений. Интерфейсные приложения часто подключаются к MySQL, что приводит к дополнительным накладным расходам производительности для MySQL. Если мы создадим пул соединений, каждый пул будет кэшировать определённое количество подключений MySQL, и когда интерфейсное приложение захочет подключиться к MySQL, оно сможет получить доступное соединение из пула для отправки SQL-запроса. Это значительно ускоряет скорость запроса данных и снижает нагрузку на MySQL.
  • Журналы SQL. Когда в программе возникает проблема, мы хотим получить некоторые журналы SQL, такие как какие запросы были отправлены на какие серверы баз данных в какое время. Просмотр этих журналов помогает нам быстро определить проблему.

Мы можем реализовать эти решения на стороне клиента, но это также сделает клиент более сложным и менее гибким. Как разработчик, специализирующийся на разработке баз данных, я разработал промежуточное ПО Kingshard на основе болевых точек разработки баз данных. Kingshard предлагает подходящие решения для вышеупомянутых пяти проблем. Ниже я подробно опишу основные функции Kingshard и продемонстрирую их.

2. Установка и запуск

(1). Настройка файла конфигурации

Вот пример файла конфигурации, который пользователи могут настроить в соответствии со своими потребностями:

# Адрес и порт Kingshard
addr : 0.0.0.0:9696

# Имя пользователя и пароль для подключения к Kingshard
user :  kingshard
password : kingshard
# Порт веб-API Kingshard
web_addr : 0.0.0.0:9797
# Имя пользователя и пароль для вызова API
web_user : admin
web_password : admin

# Уровень журнала, [debug|info|warn|error], по умолчанию — error
log_level : debug
# Включить или отключить SQL-журнал, установить значение on; выключить SQL-журнал, установить значение off
log_sql : on
# Если установлено, выводить только SQL-журналы, выполнение которых занимает больше времени, чем slow_log_time (мс), в противном случае выводить все SQL-журналы
slow_log_time : 100
# Путь к файлу журнала, если не настроен, вывод будет направлен на терминал.
log_path : /Users/flike/log
# Файл чёрного списка SQL, все SQL в этом файле будут отклонены Kingshard
blacklist_sql_file: /Users/flike/blacklist
# Разрешить только IP-адресам в списке подключаться к Kingshard, если не настроено, подключение к IP-адресу Kingshard не ограничено.
allow_ips: 127.0.0.1
# Набор символов, используемый Kingshard, если набор символов не установлен, Kingshard использует utf8 в качестве набора символов по умолчанию
proxy_charset: utf8mb4

# Один узел узла представляет собой фрагмент данных MySQL кластера, включая один главный и несколько подчинённых (можно не настраивать подчинённые)
nodes :
-
    # Имя узла
    name : node1

    # Максимальное количество свободных соединений в пуле соединений, то есть максимальное количество соединений, которое Kingshard может установить с базой данных MySQL
    max_conns_limit : 16

    # Пользователь, подключающийся к базе данных MySQL в Kingshard, имя пользователя и пароль главного и подчиненного сервера должны совпадать
    user :  kingshard
    password : kingshard

    # Главный сервер
    master : 127.0.0.1:3306

    # Подчинённый сервер, можно не настраивать
    slave : 192.168.0.12@2,192.168.0.13@3
    # Если Kingshard не может подключиться к MySQL в течение 300 секунд, Kingshard отключит этот MySQL
    down_after_noalive : 300
-
    name : node2
    max_conns_limit : 16
    user :  kingshard
    password : kingshard

    master : 192.168.59.103:3307
    slave :
    down_after_noalive: 100

# Правила разделения таблиц
schema :
    # Узел, на который распределяются неразделённые таблицы
    default: node1
    shard:
    -
        # База данных, используемая для разделения таблиц
        db : kingshard
        # Имя таблицы
        table: test_shard_hash
        # Ключ разделения таблицы
        key: id
        # Узел распределения таблицы
        nodes: [node1,node2]
        # Тип разделения таблицы
        type: hash
        # Распределение дочерних таблиц, указывающее, что node1 имеет 4 дочерние таблицы,
        node2 имеет 4 дочерние таблицы.
        locations: [4,4]

    -
        # База данных, используемая для разделения таблиц
        db : kingshard
        # Имя таблицы
        table: test_shard_range
        # Ключ разделения таблицы
        key: id
        # Тип разделения таблицы
        type: range
        # Разделение узлов таблицы
        nodes: [node1, node2]
        # Количество дочерних таблиц на узел, указывающее, что на node1 имеется 4 дочерних таблицы, а на node2 — 4 дочерних таблицы.
        locations: [4,4]
        # Представляет максимальное количество записей в каждой дочерней таблице, то есть каждая дочерняя таблица может содержать не более 10 000 записей. То есть дочерняя таблица 1 соответствует диапазону идентификаторов [0,10000), дочерняя таблица 2 соответствует диапазону [10000,20000)....
        table_row_limit: 10000

Здесь я хотел бы подчеркнуть правила разделения таблиц:
* Kingshard поддерживает два типа правил разделения таблиц: hash и range.
* Дочерние таблицы, участвующие в разделении таблиц Kingshard, должны быть созданы вручную в соответствующих базах данных, формат: `table_name_%4d`, то есть индекс дочерней таблицы состоит из 4 цифр. Например: `table_name_0000,table_name_0102`.
* Все операции с неразделёнными таблицами SQL будут отправляться на узел по умолчанию.

**(2). Установка и запуск Kingshard**
1. Установите среду выполнения Go (версия Go 1.3 или выше), подробные шаги см. в Google.
2. git clone https://github.com/flike/kingshard.git src/github.com/flike/kingshard
3. cd src/github.com/flike/kingshard
4. source ./dev.sh
5. make
6. Настройте файл конфигурации
7. Запустите Kingshard. ./bin/kingshard -config=etc/ks.yaml

**Примечание: Kingshard будет реагировать на сигналы SIGINT, SIGTERM и SIGQUIT, плавно завершая работу. Рекомендуется избегать отправки этих сигналов на машине, где работает Kingshard, чтобы избежать ненормального завершения работы Kingshard! Рекомендуется использовать инструмент supervisor для запуска Kingshard в фоновом режиме.**

**3. Разделение таблиц между узлами**
Поскольку у меня есть только две базы данных MySQL, я создал два узла, оба из которых имеют только одну главную роль MySQL, а конкретная топология выглядит следующим образом:
![Топология](./kingshard_access_node_arch.jpg)

### 3.1. Демонстрация операций разделения таблиц **Разделение таблиц на шарды: типы и создание подтаблиц**

Существуют два типа разделения таблиц на шарды — hash и range. В этом тексте рассматривается только разделение по типу hash. Разделение по типу range работает аналогично, поэтому не будет рассматриваться здесь.

На узлах node1 и node2 создаются по 4 подтаблицы. Приведён пример создания подтаблицы test_shard_hash_0000 на узле node1:

```CREATE TABLE `test_shard_hash_0000` (
  `id` bigint(64) unsigned NOT NULL,
  `str` varchar(256) DEFAULT NULL,
  `f` double DEFAULT NULL,
  `e` enum('test1','test2') DEFAULT NULL,
  `u` tinyint(3) unsigned DEFAULT NULL,
  `i` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8```

**Вставка и запрос данных в разделённые таблицы**

Выполняются SQL-запросы для вставки данных в таблицу test_shard_hash. Запросы выполняются на разных узлах, и данные распределяются по соответствующим подтаблицам.

Для обеспечения согласованности данных рекомендуется использовать транзакции при обновлении данных на нескольких узлах.

Соответствующие записи в журнале SQL:

```2015/09/02 18:48:24 - INFO - 127.0.0.1:55003->192.168.59.103:3307:insert into test_shard_hash_0007(id, str, f, e, u, i) values (15, 'flike', 3.14, 'test2', 2, 3)
2015/09/02 18:49:05 - INFO - 127.0.0.1:55003->192.168.59.103:3307:insert into test_shard_hash_0007(id, str, f, e, u, i) values (7, 'chen', 2.1, 'test1', 32, 3)```

Можно видеть, что первые две строки были отправлены на узел node2, а вторые две — на узел node1.

Затем выполняется запрос SELECT для просмотра данных. Запрос поддерживает запросы к нескольким узлам.

Запись в журнале SQL:
```mysql> select * from test_shard_hash where id < 18;
+----+--------+------+-------+------+------+
| id | str    | f    | e     | u    | i    |
+----+--------+------+-------+------+------+
| 17 | github |  2.5 | test1 |   32 |    3 |
|  7 | chen   |  2.1 | test1 |   32 |    3 |
| 15 | flike  | 3.14 | test2 |    2 |    3 |
+----+--------+------+-------+------+------+
3 rows in set (0.02 sec)```

Поскольку используется разделение по типу hash, для запросов диапазона необходимо запрашивать каждую подтаблицу отдельно. Соответствующие записи в журнале SQL:

```2015/09/02 18:55:01 - INFO - 127.0.0.1:55003->127.0.0.1:3306:select * from test_shard_hash_0000 where id < 18
2015/09/02 18:55:01 - INFO - 127.0.0.1:55003->127.0.0.1:3306:select * from test_shard_hash_0001 where id < 18
2015/05/02 18:55:01 - INFO - 127.0.0.1:55003->127.0.0.1:3306:select * from test_shard_hash_0002 where id < 18
2015/09/02 18:55:01 - INFO - 127.0.0.1:55003->127.0.0.1:3306:select * from test_shard_hash_0003 where id < 18```

Запрос SELECT с условием равенства также выполняется на каждом узле отдельно.

Записи в журнале SQL:

```mysql> select * from test_shard_hash where id = 18;
+----+-----------+------+-------+------+------+
| id | str       | f    | e     | u    | i    |
+----+-----------+------+-------+------+------+
| 18 | kingshard |  7.3 | test1 |   32 |    3 |
+----+-----------+------+-------+------+------+
1 row in set (0.00 sec)```

```2015/09/02 18:59:37 - INFO - 127.0.0.1:55003->127.0.0.1:3306:select * from test_shard_hash_0002 where id = 18``` **3.5. Порядок через узлы**

Kingshard поддерживает порядок через узлы. Kingshard сначала отправляет соответствующий SQL на нужный узел, а затем сортирует результаты в памяти, тем самым реализуя операцию порядка через select. Пример:

mysql> select * from test_shard_hash where id > 1 order by id; +----+-----------+------+-------+------+------+ | id | str | f | e | u | i | +----+-----------+------+-------+------+------+ | 7 | chen | 2.1 | test1 | 123 | 3 | | 15 | flike | 3.14 | test2 | 123 | 3 | | 17 | github | 2.5 | test1 | 32 | 23 | | 18 | kingshard | 7.3 | test1 | 32 | 23 | +----+-----------+------+-------+------+------+ 4 rows in set (0.02 sec)


Соответствующий журнал SQL:

2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->127.0.0.1:3306:select * from test_shard_hash_0000 where id > 1 order by id asc 2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->127.0.0.1:3306:select * from test_shard_hash_0001 where id > 1 order by id asc 2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->127.0.0.1:3306:select * from test_shard_hash_0002 where id > 1 order by id asc 2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->127.0.0.1:3306:select * from test_shard_hash_0003 where id > 1 order by id asc 2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->192.168.59.103:3307:select * from test_shard_hash_0004 where id > 1 order by id asc 2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->192.168.59.103:3307:select * from test_shard_hash_0005 where id > 1 order by id asc 2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->192.168.59.103:3307:select * from test_shard_hash_0006 where id > 1 order by id asc 2015/09/03 14:54:11 - INFO - 127.0.0.1:55768->192.168.59.103:3307:select * from test_shard_hash_0007 where id > 1 order by id asc

**4. Транзакции одного узла**

Kingshard позволяет выполнять транзакции на одном узле, что означает, что одна транзакция не может охватывать несколько узлов. Если возникает ситуация с несколькими узлами, kingshard вернёт ошибку клиенту. Можно использовать разные дочерние таблицы на одном и том же узле. Пример:

mysql> begin; Query OK, 0 rows affected (0.00 sec)

mysql> insert into test_shard_hash(id,str,f,e,u,i) values(23,'proxy',9.2,'test1',12,3); Query OK, 1 row affected (0.00 sec)

mysql> commit; Query OK, 0 rows affected (0.01 sec)

Если в одной транзакции появляется запрос, который должен выполняться на другом узле, kingshard возвращает ошибку:

#SQL-запрос выполняется на узле 2 mysql> insert into test_shard_hash(id,str,f,e,u,i) values(31,'proxy',9.2,'test1',12,3); Query OK, 1 row affected (0.01 sec) #SQL-запрос должен быть выполнен на узле 1 mysql> insert into test_shard_hash(id,str,f,e,u,i) values(40,'proxy',9.2,'test1',12,3); ERROR 1105 (HY000): transaction in multi node

**6. Управление Kingshard**

Интерфейс управления Kingshard в настоящее время реализован в виде командной строки. В будущем планируется преобразовать его в веб-интерфейс. Конкретные команды управления можно найти в документации.

Формат команд управления можно разделить на две категории:
* `admin server(opt,k,v)`

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/blackeybaord-kingshard.git
git@api.gitlife.ru:oschina-mirror/blackeybaord-kingshard.git
oschina-mirror
blackeybaord-kingshard
blackeybaord-kingshard
master