Шардинг в DVelum 2x
(документация в разработке)
Платформа поддерживает горизонтальное масштабирование ORM из коробки.
Масштабирование осуществляется за счет разнесения данных по нескольким серверам баз данных.
Система включает в себя 3 готовых варианта шардирования ORM объектов, не сложно добавить свои.
Количество шардов не ограничено, есть возможность указать вес и группу шарда. Поддерживаются правила роутинга.
Настройки
Шардинг подключается в интерфейсе управления ORM объектами в окне редактирования основных настроек объекта.
Дополнительная вкладка Distributed Indexes позволяет добавлять колонки в индексную таблицу.
application/configs/common/dist/sharding.php - базовые настройки шардига
application/configs/common/dist/sharding_routes.php - настройки дополнительного роутинга данных (для типа global_id)
application/configs/common/dist/sharding_shards.php - список доступных шардов с настройками подключения
Виды шардинга
global_id - Уникальный сквозной распределенный идентификатор. Все записи объекта имеют сквозную нумерацию, где лежит конкретный объект знает индекс, виндекс можно добавить дополнительные колонки для быстрого доступа. Поддерживает правила роутинга. По умолчанию индексный объект это таблица базы данных, которая может лежать на отдельном сервере. В некоторых случаях этого достаточно, иначе стоит переключиться на хранение индекса в более быстром хранилище.
Как выглядит индекс:
id | shard | доп колонка |
1 | shard1 | vasia |
2 | shard2 | petia |
3 | shard1 | kolya |
Как выглядит шард:
id | shard | login | password | first_name | last_name | ... и еще колонки |
1 | shard1 | vasia | ****** | Vasili | Vasiliev | ... |
3 | shard1 | kolya | **** | Nikolai | Nikolaev | ... |
sharding_key - это то же самое что global_id только с автоматическим роутингом. Данные распределяются на шарды по пользовательскому ключу (все данные с одим ключом на одном шарде). Поддерживает дополнительные правила роутинга. Требует указания пользовательского ключа.
Как выглядит индекс:
id | shard | city |
1 | shard1 | Moscow |
2 | shard2 | London |
3 | shard1 | Moscow |
Как выглядит шард:
id | shard | city | street | building | itemcode | status |
1 | shard1 | Moscow | Leningradsky prospekt | 6 | 12097986 | ok |
3 | shard1 | Moscow | Leningradsky prospekt | 8 | 432423443 | ok |
sharding_key_no_index - похож на sharding_key, но не использует сквозные уникальные идентификаторы, используется пользовательский ключ, все данные с этим ключом находятся на шарде. Индексная таблица фиксирует привязку пользовательского ключа к шарду. Этот вид шардинга исключает большую нагрузку на индексную таблицу. Данынне индекса можно кэшировать в быстром хранилище.
Как выглядит индекс:
id | shard | key |
1 | shard1 | TOYOTA |
2 | shard2 | NISSAN |
Как выглядит шард:
id | shard | key | SKU | price | quantity |
1 | shard1 | TOYOTA | NGT1200998 | 603.12 | 10 |
2 | shard1 | TOYOTA | SVD01735 | 705.18 | 12 |
virtual_bucket - отображение данных на шард через "виртуальный бакет". Заранее известный ключ при помощи фукции отображается на "бакет", ",бакет" отображается на шард. Простым языком "виртуальный бакет" это диапазон значений от 1 до 1999, от 2000 до 3999. Размер бакета 2000. Строки преобразуется в число при помощи хэш функции crc32, можно указать любую свою функцию от ключа.
пример данных: {id:100, with:200, height:100}, {id:3000, with:150, height:150}
Как выглядит индекс:
id | shard | bucket | (key range) |
1 | shard1 | 1 | (1-2000) |
2 | shard2 | 2 | (2001-4000) |
Как выглядит шард 2:
id | shard | bucket | width | height |
3000 | shard2 | 2 | 150 | 150 |
Адаптеры роутинга
Адаптеры позволяющие описать правило распределения ORM объекта на основе его данных.
Описываются в sharding_routes.php.
Самый простой пример адаптера - складывать объекты на шард родителя
\Dvelum\Orm\Distributed\Router\WithParent
[
'id' => '', // - идентификатор правила
'title' => '', // - название правила для интерфейса управления
'objects' => [], // - список объектов к которым применяется правило, например user,order,order_item
'shard_groups' => [], // - в данном примере не используется
'shard_id' => false, // - в данном примере не используется
'adapter' => '\\Dvelum\\Orm\\Distributed\\Router\\WithParent', // класс адаптера
'config' => [
'order_item' => [ // объект "элемент заказа"
'parent' => 'order', // положить на шард родительского объекта "заказ"
'parent_field' => 'order_id' // родитель указан в поле order_id
],
'user_settings' => [
'parent' => 'user',
'parent_field' => 'user_id'
]
],
'enabled' => false
]