Шардинг в 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
]