Выберите наиболее эффективные ключи, чтобы уменьшить нагрузку на основные запросы
Для таблиц t_order и t_order_item, которые хранят информацию о заказах, важно, чтобы после разделения они находились в одной базе данных. Это позволит использовать локальные транзакции. Обычно используется user_id, но можно выбрать order_id. В данном демонстрационном примере используется user_id
Примечание: если выбран user_id как ключ шардинга, то все запросы, использующие order_id, будут выполняться через все базы данных.
a. Если объём данных небольшой, это может быть не проблемой
b. В данном демонстрационном примере отношение между user_id и order_id сохранено в таблице t_order_mapping, при использовании order_id для запроса сначала вычисляется user_id, затем производится поиск по user_id
c. Обработка gene id, аналогично реализации разделения баз данных и таблиц в Meituan, где order_id содержит последние цифры user_id, что позволяет маршрутизировать запросы по user_id. Эта модификация требует значительных усилий
d. Разделение нескольких столбцов, когда данные разделяются одновременно по user_id и order_id, что приводит к хранению двух экземпляров данных
```### 2. Алгоритмы шардинга
* Диапазон
> По времени или диапазону ID, например, [1-10000] в первой базе данных, [10001-20000] во второй
Преимущества: размер таблицы контролируется, естественное горизонтальное масштабирование.
Недостатки: не решает проблему концентрированного написания данных.
* Хеш
> Хэширование по модулю 2^n
Разбиение на tworaz (базы данных) * fourraz (таблицы), то есть на две базы данных, каждая из которых содержит четыре таблицы
Тогда правило маршрутизации будет следующим: номер базы данных = user_id % 2, номер таблицы = (user_id / 2) % 4
Преимущества: легкое масштабирование, решение проблемы концентрированного написания данных.
Недостатки: сложность увеличения количества баз данных, необходимость повторного хэширования (необходимо избегать перемещения данных из одной таблицы в другую), требуется миграция данных
(в данном демо используется этот метод)
<br/>### 3. Определение вместимости и планирование масштабирования
* В производстве делаем один раз, хватает на несколько лет, не нужно беспокоиться о масштабировании.
> Разделяем на 32 (базы данных) * 32 (таблицы), получается 32 базы данных, каждая из которых содержит 32 таблицы, всего 1024 таблицы (или 16 * 64).
Правила маршрутизации: номер базы = user_id % 32, номер таблицы = (user_id / 32) % 32.
* Начальная логическая распределенная схема позволяет запустить 4 машины, каждая из которых обслуживает 8 баз данных, каждая из которых содержит 32 таблицы.
> Когда данные в таблицах превышают ограничение одного сервера, можно запустить 8 машин, каждая из которых обслуживает 4 базы данных, каждая из которых содержит 32 таблицы.
Максимальное количество машин — 1024, каждая из которых обслуживает одну таблицу.
> При масштабировании достаточно изменить конфигурацию и переместить данные, при этом данные, находившиеся ранее в одной таблице, после масштабирования остаются в одной таблице.
Подробнее читайте в [реализации Meituan](https://tech.meituan.com/2016/11/18/dianping-order-db-sharding.html).### 4. Уникальный ID
* UUID (строка)
> Занимает много места, не обеспечивает последовательность.
* Алгоритм Snowflake
> Обеспечивает последовательность, хорошая производительность.
Управление `workId` затруднено,
Возможна проблема отката часов.
Большинство реализаций основано на алгоритме Snowflake.
* Реализация уникального ID от Meituan [Leaf](https://tech.meituan.com/2019/03/07/open-source-project-leaf.html)
> Более сложная реализация, пока не рассматривается.
* Реализация уникального ID от Baidu [uid-generator](https://github.com/baidu/uid-generator)
> Проще, решает проблемы управления `workId` и отката часов, но не предоставляет возможности повторного использования `workId`.
В данном демонстрационном проекте используется данная реализация, [включена возможность повторного использования `workId`](./uid-generator/src/main/java/com/baidu/fsg/uid/worker/MarkWorkerIdAssignerWrapper.java).
> [ecp-uid](https://gitee.com/zmds/ecp-uid) объединяет реализации Meituan Leaf, Baidu UidGenerator и native Snowflake, что может быть полезно.
Поскольку использование `uid-generator` достаточно просто и эффективно, `ecp-uid` пока не используется.
### 5. Миграция одной базы данных на распределенные таблицы
> Для реализации двойной записи в одну базу данных можно обратиться к примеру из системы Meituan
* ① В исходной системе удалите связанные запросы с использованием соединения (join)
> Замените join на обработку через код приложения, чтобы подготовить данные для последующего разделения на несколько баз данных и таблиц* ② Преобразуйте реализацию ID заказа в системе, используя uid-generator для генерации уникального ID
* ③ Двойная запись в базу данных (сначала запись в одну базу, затем в несколько; основной транзакцией является одна база, а чтение данных происходит также из одной базы), синхронизация истории заказов в несколько баз данных, после чего проверка и корректировка данных в нескольких базах
> a. Сначала запись в одну базу, затем в несколько; основной транзакцией является одна база, а чтение данных происходит также из одной базы
> b. Одновременно используйте DataX для синхронизации исторических данных заказов в несколько баз данных
> c. Проверьте данные в одной и нескольких базах, корректируйте данные в нескольких базах (вставка или сравнение времени обновления)* ④ После того как данные были выровнены в шаге ③, продолжайте выполнять двойную запись (сначала запись в несколько баз, затем в одну; основной транзакцией является запись в несколько баз, а чтение данных происходит из нескольких баз). Одновременно проверяйте и корректируйте данные в одной базе.
> a. Сначала запись в несколько баз, затем в одну; основной транзакцией является запись в несколько баз, а чтение данных происходит из нескольких баз.
(если количество сервисов большое, можно тестировать небольшую часть сервисов в режиме серого запуска; если возникнут проблемы, можно вернуться к шагу ③)
> b. Проверьте данные в одной и нескольких базах, корректируйте данные в одной базе (вставка или сравнение времени обновления).* ⑤ После того, как система будет работать нормально в течение нескольких дней, отключите таблицу заказов в одной базе данных
<br/>
### 6. Промежуточное программное обеспечение для распределённых таблиц
* mycat
> Реализовано на основе прокси-сервера базы данных, имеет проблему одного узла
* [shardingsphere](https://shardingsphere.apache.org/document/current/cn/overview/)
> В настоящее время стало проектом уровня Apache, поэтому использование этой технологии является лучшим выбором
>
* sharding-jdbc
> Подпроект Shardingsphere, прокси JDBC
>
a. Нет проблемы одного узла
b. Может существовать несколько конфигураций
c. Обновление затруднено, требуется общее обновление
d. Можно использовать только для языка Java
* sharding-proxy
> Подпроект Shardingsphere, прокси базы данных
a. Есть проблема одного узла
b. Проблемы совместимости
c. Преимущество — нет ограничений по языку
В демонстрационной версии используется преимущественно sharding-jdbc, а шардинг-проверка используется в качестве вторичного средства обслуживания
<br/>
## 3. Процесс использования данного демо
#### 1. Создание единой базы данных
```sql
create database db_lab;
db_lab_table.sql используется для создания таблиц
db_lab_data.sql используется для создания тестовых данных, включающих 30 000 заказов (t_order) и 90 000 позиций заказов (t_order_item)#### 3. Создание двух распределённых баз данных
create database db_lab_orders_0;
create database db_lab_orders_1;
Создание uid базы данных
create database uid;
Создание uid таблицы
DROP TABLE IF EXISTS WORKER_NODE;
CREATE TABLE WORKER_NODE
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'автоинкрементный идентификатор',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'имя хоста',
PORT VARCHAR(64) NOT NULL COMMENT 'порт',
TYPE INT NOT NULL COMMENT 'тип узла: ACTUAL или CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'дата запуска',
MODIFIED TIMESTAMP NOT NULL COMMENT 'время изменения',
CREATED TIMESTAMP NOT NULL COMMENT 'время создания',
PRIMARY KEY(ID)
)
COMMENT='DB WorkerID Assigner for UID Generator', ENGINE = INNODB;
Изменение имени пользователя и пароля для конфигурации uid базы данных
CREATE TABLE `t_order` (
`order_id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`address_id` bigint(20) NOT NULL,
`status` varchar(50) DEFAULT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
CREATE TABLE `t_order_item` (
`order_item_id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` bigint(20) DEFAULT NULL,
`user_id` int(11) NOT NULL,
`status` varchar(50) DEFAULT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`order_item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
```#### 7. Запустите проект `single-datasource-lab` для моделирования работы сингл-базового веб-приложения
Обратите внимание на следующие конфигурации, используемые для переключения между одиночной базой данных и распределёнными таблицами:
transform.step=2
Проект можно собрать и запустить вне среды IDE, высокопроизводительные машины могут игнорировать некоторые указания.
#### 8. Запустите [макет клиента](./single-datasource-lab/src/test/java/com/ttx/single/lab/MockOrderService.java) в `single-datasource-lab`
> Моделирование доступа пользователя к сервису заказов#### 9. Скачайте DataX для синхронизации истории заказов
> В этом проекте используется DataX + Sharding-JDBC для синхронизации истории заказов. Узнать больше о [способах использования](./transform-history/transform-datax-config/sharding-jdbc)
* Копируйте [конфигурацию](./transform-history/transform-datax-config/sharding-jdbc/datax/job) в локальную директорию datax/job и измените учетные записи и пароли соответственно
* Используйте команды для запуска 'job-order.json' и 'job-order_item.json' для синхронизации исторических данных в разделённые базы данных. 'job-order_mapping.json' используется для синхронизации данных о связи order_id и user_id
#### 10. При двойной записи в базу данных (шаг = 2), запустите validate-step2 для проверки компенсирующих заказов
> Когда конфигурация проекта single-datasource-lab установлена как 'transfrom.step=2',
запустите проект validate-step2 для проверки данных компенсирующих заказов в разделённых базах данных
#### 11. После проверки данных в разделённых базах данных, переключитесь на двойную запись в базу данных, при этом основной транзакцией будет транзакция в разделённой базе данных, а чтение данных будет осуществляться преимущественно из разделённой базы данных
> Измените конфигурацию single-datasource-lab на 'transfrom.step=3' и перезапустите
Обратите внимание на наличие проблем, если есть проблемы, вернитесь к шагу 2
#### 12. Перезапустите проект validate-step2 для последней проверки данных в разделённой базе данных > При запуске шага 2, он читает текущий максимальный ID заказа для проверки. Перезапуск необходим для предотвращения пропущенных данных.
#### 13. Запустите проект validate-step3 для проверки данных в одной базе данных.
> Это сделано для возможности отката назад.
#### 14. Продолжайте наблюдать за single-datasource-lab, подтвердите отсутствие проблем, затем выключите таблицу заказов в одной базе данных.
> В реальных проектах требуется продолжительное наблюдение несколько дней. Если нет проблем, измените конфигурацию на 'transform.step=4' и перезапустите выключение таблицы заказов в одной базе данных.
Если есть проблемы, вернитесь к шагу 2. Обратите внимание, что после отката проект validate-step2 также требует повторной проверки.<br/>
## Часто задаваемые вопросы
1. Нет информации маршрутизации таблицы
> Полученное имя таблицы согласно правилам маршрутизации отсутствует в базе данных. Проверьте [конфигурацию](./sharding-config/src/main/resources/application-sharding.yml)
Можно включить логи Sharding для диагностики
свойства:
sql:
показывать: true # выводить SQL
<br/>
## Дополнительные материалы
[Практика распределения таблиц в системе заказов Dianping](https://tech.meituan.com/2016/11/18/dianping-order-db-sharding.html)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )