在每次页面加载时在缓存或大型数据库查询中存储大量数据


Storing A LOT of data in cache or large db queries on every page load

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

为了限制数据库查询,我一直在用户会话开始时从 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 (只会让我的内存使用量大吃一惊吗?我很想只使用大量数据库查询,但我认为这可能会给数据库服务器带来太大的压力。

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

克里斯

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

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

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

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

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

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