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

时间:2012-08-30 21:52:58

标签: php mysql database caching

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

为了限制数据库查询,我一直在用户会话开始时从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')
)

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

然而,bitmasks开始使用起来很痛苦,我正在寻求使用acl。我之所以不首先使用acl的原因是为了尽量减少数据库的使用。

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

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

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

事实上,文件由2个不同的服务器提供服务(会话粘贴,因此将会话数据保存到会话数据不成问题),因此更加困难,因此任何缓存都必须在服务器之间同步。数据库位于由专用网络连接的单独服务器上,假设连接为1gig。

可以建议任何解决方案吗?我认为使用这么多数据的快速访问缓存(如memcached)只会将我的内存使用量从水中吹走?我很想只使用大量的数据库查询,但我认为这可能会给数据库服务器带来太大的压力。

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

克里斯

1 个答案:

答案 0 :(得分:0)

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

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

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

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

对于您的服务,您可能拥有一个非常小的数据库服务器(因为一旦填充了缓存,就应该不经常查询数据库本身)。内存缓存服务器,具有足够的内存来满足您的存储需求(或者如果需要冗余,可能是一小组服务器),以及一个相对较小的服务器来处理REST API(一旦开发缓存,这种情况应该很少被访问。好的是,它们是几个memcached或类似的服务,你可以相对便宜地使用(如Amazon Elasticache)。真正的内存缓存将承担来自应用程序服务器的流量的冲击,所以你不需要扩展随着流量的增长,完全没有数据库服务器的REST服务器。

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