通过哈希将用户(或其他任何东西)分发到数据库服务器

时间:2009-09-13 06:25:35

标签: database hash scaling

我正在为应用程序开发早期设计,这些应用程序需要从小规模开始,但具有高度可扩展性。我特别担心用户数据库,在这种情况下,它将具有较高的INSERT和UPDATE负载,并且不太可能在单个主服务器上存活很长时间。

(虽然我的问题与任何特定的RDBMS无关,但是对于记录,我们将使用MySQL,并且MySQL Cluster并不真正满足我们的需求,所以我们需要使用它来推广我们自己的解决方案股票MySQL + InnoDB。)

我正在考虑一种策略,即根据用户名的哈希值在MySQL主人之间分配用户(加上未知用户盐,以及对任何有趣游戏的附加保险)。我以前见过这样成功的解决方案,但我自己从未设计/实现过它。

我想要输入的内容是:

1)合适的散列算法。我希望SHA-1甚至MD5都可以正常工作,因为加密安全性确实不是目标,但我不确定是否可能有其他算法可能具有这类问题的理想属性。更快的东西也可能很好。

2)任何人都能想到的重大警告。 (我已经非常意识到潜在的连接池问题,以及向池中添加新主服务并迁移受影响用户的乐趣。)

谢谢!

2 个答案:

答案 0 :(得分:2)

基于散列的解决方案的问题是移动用户。请考虑以下情形 - 您有3个用户和3个服务器。用户A有一个散列,导致他们的连接被软件分配给服务器A,用户B连接到服务器B,用户C连接到服务器C.如果服务器B出现故障,或者您希望将用户B迁移到服务器B,会发生什么情况新服务器D,因为服务器B超载 - 你不能,因为你的软件被编码为获取用户名的哈希值,并连接到基于它的服务器。

此外,您还会遇到分发问题 - 用户A,B和C的哈希值很可能会解析为服务器A,因此服务器B和C处于空闲状态。

我个人会在所有服务器中复制用户数据库表,然后在启动时随机连接到服务器,找到他们的实际数据库服务器,然后继续。这样您就可以轻松地移动用户,如果您在至少两台服务器之间复制数据,那么在服务器崩溃时您就会有冗余。

答案 1 :(得分:2)

首先,我觉得有责任告诉你,如果你对设计的考虑足够困难,你可能不需要对它进行分片。 Sharding是最后的选择。这是Percona的Baron Swartz谈论的内容(不要错过幻灯片的直接链接):http://www.percona.tv/performance/baron-schwartz-high-performance-mysql-from-a-boring-architecture-ppc-2009

关于实际建议。

要考虑的一件事是如何重新平衡您的应用程序。你从3个节点开始;在某些时候你添加第四个。你如何迁移四分之一的数据?通过重复每个用户?可能是一个坏主意。要考虑的一件事是分区为多个编号的模式,并将模式编号散列到数据库机器。这样,您可以通过仅移动需要触摸的模式进行迁移,而不是重新散列所有数据。由于模式的数量(大小)大于计算机数量,因此您也不能依靠散列来查找数据库计算机,而是使用可以为迁移更新的静态映射。这样,如果您的某些用户比其他用户更活跃并且产生偏差,您也可以使用每台计算机的非均匀分布模式 - 您可以手动重新分配负载以使其更好地工作。

您仍需要将用户映射到架构。我一直在阅读的一个有趣的方法是不是散列到存储桶,而是使用 2 散列函数散列到2个存储桶,并选择负载最少(用户数#,记录数,或两个其他指标)作为你的目标。这导致更均匀的分布,但是当您需要将用户的数据退出时,会导致检查它们的开销。这可以通过缓存来缓解,但仍然可以。但是要考虑一些事情。

您可能想要考虑复制分片 - 可能是异步的,作为后台进程,用于热备份。

最后,你考虑过替代技术吗?各种BigTable克隆虽然不提供关系模型,但对于读取和写入都具有非常好的缩放特性。查看CassandraHBase