Database 评论文章可伸缩性:每个用户排名前n,1次更新,大量阅读

Database 评论文章可伸缩性:每个用户排名前n,1次更新,大量阅读,database,scalability,message-queue,Database,Scalability,Message Queue,情况是这样的。数百万用户的网站。每个用户的页面都有一个消息部分。任何人都可以访问用户页面,在那里他们可以留言或查看最后100条消息 消息是包含一些额外元数据的短文本。每条消息都必须永久存储,唯一必须实时快速的是消息更新和阅读(人们将其用作聊天)。将经常读取大量消息以检查更改。定期归档旧消息(那些>100)是可以的,但它们必须是可访问的 目前,所有这些都集中在一个大型数据库表中,阅读消息列表和发送更多更新的人之间的争用正在成为一个问题 如果必须重新构建系统,您会使用什么存储机制/缓存?这里可以使用

情况是这样的。数百万用户的网站。每个用户的页面都有一个消息部分。任何人都可以访问用户页面,在那里他们可以留言或查看最后100条消息

消息是包含一些额外元数据的短文本。每条消息都必须永久存储,唯一必须实时快速的是消息更新和阅读(人们将其用作聊天)。将经常读取大量消息以检查更改。定期归档旧消息(那些>100)是可以的,但它们必须是可访问的

目前,所有这些都集中在一个大型数据库表中,阅读消息列表和发送更多更新的人之间的争用正在成为一个问题


如果必须重新构建系统,您会使用什么存储机制/缓存?这里可以使用什么样的计算机科学学习?(例如集合、列表访问等)

一个简单的解决方案是将数据反规范化,并将预先计算的聚合存储在单独的表中,例如,一个消息计数表,其中有一列表示用户ID,另一列表示其消息计数。更新主消息表后,重新计算聚合


它只是将瓶颈从一个地方转移到另一个地方,但它可能会将瓶颈转移到一个负担较小的地方。

一些一般的想法,而不是特定的技术:

  • 按用户ID对数据进行分区。其思想是您可以将用户空间统一划分为大小大致相同的不同分区。您可以使用适当的散列函数在分区之间划分用户。最终,每个分区都属于一台单独的机器。但是,即使在同一台机器上的不同表/数据库上,这也将消除一些争用。分区限制了争用,并为将来的“线性”扩展打开了大门。这有助于负载分布和扩展

  • 当选择一个散列函数对记录进行分区时,寻找一个能够最大限度地减少在添加/删除分区时必须移动的记录数的函数

  • 与许多其他应用程序一样,我们可以假设服务的使用遵循幂律曲线:很少的用户页面会导致大部分流量,然后是长尾。缓存方案可以利用这一点。曲线越陡,缓存就越有效。对于这些短消息,如果每个页面显示100条消息,并且每条消息平均为100字节,那么1GB的RAM缓存中可以容纳大约100000个顶级页面。这些缓存的页面可能会被惰性地写入数据库。在1000万用户中,有10万人在发挥作用

  • 对web服务器进行分区,可能使用相同的哈希方案。这使您可以在不争用的情况下保持单独的RAM缓存。潜在的好处是随着用户数量的增加而增加缓存大小

  • 如果适合您的环境,确保新消息最终写入数据库的一种方法是在将它们放入RAM缓存之后立即将它们放入持久消息队列。队列不存在争用,并有助于确保消息不会在机器出现故障时丢失


  • 谢谢你的回答。我们已经使用memcached incr/decr来存储计数。问题更多的是更新/插入之间的争论。在不了解您的环境的情况下,很难推荐体系结构解决方案。