0

要求

我目前正在构建权限系统。要求之一是它是水平可扩展的。

为此,我们做了以下工作

有一个“已编译资源权限”表,如下所示:

| 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。

为了弄清楚需要进入这个表的内容,我们使用了一个“修补程序”类,它以编程方式循环传递给它的用户和资源,并在逻辑上查看所有必要的数据库表,以确定需要添加哪些行以及需要从中删除哪些行桌子。

我们如何尝试扩展和问题

为了横向扩展,我们将逻辑拆分为块并将其提供给异步队列上的许多“工作人员”

这似乎只是在它不再加速之前扩展,有时甚至发生行锁定,这会减慢它的速度。

我们可以使用特定类型的行锁来允许它无限扩展吗?

我们是从完全错误的角度来处理这个问题吗?我们有很多“原因”和很多复杂的权限逻辑,我们需要能够相当快地重新编译

并发运行的 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 )
4

0 回答 0