0

我的网站对每个客户都有一个非常精细的权限系统,使其规模相当大。

为了限制数据库查询,我一直在用户会话开始时从 mysql 数据库加载位掩码,然后将其保存为会话数据,所以它看起来像这样。这使我可以为每个用户会话进行一次(尽管它是复杂的 JOIN 查询)查询,而无需创建巨大的会话文件。

"permissions" => array(
    "type 1" => 'bitfield'
    "type 2" => 'bitfield'
     "type 3" => array(
         entity id = 'bitfield'
         entity id = 'bitfield')
     "type 4" => array(
         entity id = 'bitfield'
         entity id = 'bitfield')
)

权限完全基于组,因此给定组中的每个人都会在他们的会话数据中复制此权限。

然而,位掩码开始使用起来很痛苦,我希望转向使用 acl。然而,我一开始没有使用 acl 的原因是为了尽量减少数据库的使用。

所以.. 现在我将拥有一个完全由数据库/缓存驱动的 acl,没有任何位掩码。然而,在用户会话数据中存储大量权限似乎并不理想。(你同意?)

我认为要走的路是使用平面文件缓存来存储组权限。最简单的方法是每组一个文件吗?当有 4,000 + 个组,每个组具有 4 种权限类型(2 种权限类型是全局的,具有 40 个左右的权限,2 种类型是本地权限,每个实体有 40 个左右的权限(每种类型可能有 3 或 4 个20 个权限!)。编辑:为清楚起见,这意味着每组 160 - 200 个权限条目

这似乎是一个相当大的缓存!每次页面加载时都使用大量数据库会更好吗?这种数据大小使位掩码变得容易得多,但它们只是不够灵活了。

由于文件由 2 个不同的服务器提供服务(会话粘着,因此将位域保存到会话数据不是问题),这使得这变得更加困难,因此任何缓存都必须在服务器之间同步。数据库位于通过专用网络连接的单独服务器上,据称是 1gig 连接。

可以提出任何解决方案吗?我认为具有这么多数据的快速访问缓存(例如 memcached)只会让我的内存使用量大增?我很想只使用大量的数据库查询,但我认为这可能会给数据库服务器带来太大的压力。

相当大的问题,我希望它清楚。如果有任何需要澄清,请告诉我。任何解决方案将不胜感激!

克里斯

4

1 回答 1

0

我不认为存储在会话中的具有约 40 个条目的数据结构特别庞大。所以实际上,这可能归结为设计方面的问题是如何以最佳性能最好地将这些信息导入应用程序中。

如果您开始遇到性能问题并且您的基础架构预算允许,我认为您可能会考虑将此解决方案迁移到更多可以在任意数量的服务器之间共享的面向服务的架构。我个人非常相信这种架构,因为它可以真正帮助您处理规模问题。

您可以将“权限”公开为可以由该应用程序(或者将来可能需要开发的其他应用程序)使用的服务。它可能看起来像这样:

  • 内存缓存层(memcached 或类似),这是应用程序进行初始调用以根据组查找权限信息的地方。如果此处不存在数据,则下一层为请求提供服务
  • RESTful API。在第一次缓存未命中后,您对组的权限发出简单的 GET 请求。这将需要调用数据库层来获取信息。它还会做一些事情,比如在缓存未命中时填充缓存,在客户端 POST 一些新权限数据或 PUT 更新到现有权限集的情况下使缓存无效并重新填充缓存。
    • 仅由 RESTful 服务访问的 DB 层。如果您有更复杂的非关系数据结构,也许 MySQL 可能是一种 NoSQL 技术。

对于您的服务,您可能有一个非常小的数据库服务器(因为一旦填充了缓存,就应该不经常查询数据库本身)。一个内存缓存服务器,它有足够的内存来满足您的存储需求(或者如果需要冗余,可能是一个小型服务器集群),以及一个相对较小的服务器来处理 REST API(一旦开发了缓存,这也应该不经常访问。好消息是它们是几个 memcached 或类似的服务,你可以相对便宜地使用(如 Amazon Elasticache)。实际上,内存缓存将首当其冲来自应用程序服务器的流量,因此您不需要扩展随着流量的增长,完全启动数据库服务器的 REST 服务器。

希望这对您的思考过程有所帮助。

于 2012-08-30T22:25:46.857 回答