Проблемы горизонтального масштабирования с блокировкой строк в системе разрешений - PullRequest
0 голосов
/ 24 мая 2018

Требование

В настоящее время я создаю систему разрешений.Одним из требований является его горизонтальное масштабирование.

Для достижения этой цели мы сделали следующее:

Существует одна таблица "разрешения скомпилированного ресурса", которая выглядит примерно так:

| user_id | resource_id | reason |
|    1    |      1      |   1    |
|    1    |      2      |   3    |
|    2    |      1      |   2    |

Структура этой таблицы обозначает пользователь 1 имеет доступ к ресурсу 1 & 2 , а пользователь 2 имеет доступ только к ресурсу 1 .

Столбец «причина» - это побитовое число, в котором биты включены, в зависимости от того, «почему» они имеют такое разрешение.Двоичный бит «1» означает, что они являются администратором, а двоичный бит «2» означает, что они создали ресурс.

Таким образом, пользователь 1 имеет доступ к ресурсу 1, поскольку он является администратором.У него есть доступ к ресурсу 2, потому что он администратор, и он создал этот ресурс.Если бы он больше не был администратором, у него все равно был бы доступ к билету 2, но не к билету 1.

Чтобы выяснить, что нужно добавить в эту таблицу, мы используем класс «patcher», который программно обходит пользователейи ресурсы, переданные ему, и логически просматривает все таблицы БД, необходимые для определения того, какие строки необходимо добавить и какие строки необходимо удалить из таблицы.

Как мы пытаемся масштабировать и проблема

Чтобы по горизонтали масштабировать это, мы разделяем логику на куски и даем ее нескольким «работникам» в асинхронной очереди

Кажется, что это масштабируется только до того, как больше не ускоряетсяили иногда даже происходит блокировка строки, что замедляет ее.

Существует ли какой-то особый тип блокировки строки, который мы можем использовать, чтобы позволить ему масштабироваться бесконечно?

Мы подходим к этому с совершенно неправильной точки зрения?У нас есть много «Причин» и много сложной логики разрешений, которые нам нужны, чтобы иметь возможность достаточно быстро перекомпилировать

Запросы SQL, которые выполняются одновременно, для справки

Когда мы «добавляем» причины:

INSERT INTO `compiled_permissions` (`user_id`, `resource_id`, `reason`) VALUES ((1,1,1), (1,2,3), (2,1,2)) ON DUPLICATE KEY UPDATE `reason` = `reason` | VALUES(`reason`);

Когда мы «удаляем» причины:

UPDATE `compiled_permissions` SET `reason` =  `reason` & ~ (CASE
            (user_id = 1 AND resource_id = 1 THEN 2 ... CASE FOR EVERY "REASON REMOVAL")
            ELSE `reason`
            END)
        WHERE (`user_id`, `resource_id`) IN ((1,1),(1,2) .. ETC )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...