扩展Pinterest用户表分片并确保打开新分片时的一致性

时间:2019-03-01 21:59:19

标签: mysql sharding

因此,这很大程度上是一个概念性的问题(就像我很想构建一个十亿用户的应用程序一样,我认为这不会发生)。

我已经阅读了Pinterest上有关它们如何多次扩展MySQL舰队的文章(https://medium.com/@Pinterest_Engineering/sharding-pinterest-how-we-scaled-our-mysql-fleet-3f341e96ca6f),但我仍然不了解他们如何在不影响现有用户的情况下“打开新的碎片”。

该文章指出,每个表都位于每个分片上,包括User表。 因此,我假设当用户注册并为他们分配了随机分片时,必须通过一个函数执行此操作,无论该分片数量如何,该函数将始终返回相同的结果。

例如,如果我在test@example.com上注册,他们可能会使用该电子邮件来计算分片ID,这必须考虑到当前“开放”分片的数量。我最初的假设是,他们将使用稍后在文章中提到的mod碎片之类的东西,例如

  md5($email) % number_of_shards

但是当它们打开分片的数量时,它将改变函数的结果。

然后,我认为也许他们有一个单独的数据库来保存纯用户信息以用于身份验证,并且其中还将包含带有分配的shard_id的列,但是正如我所说的,这篇文章暗示着即使用户表也位于每个碎片。

其他人对这样的工作方式有什么想法或见解吗?

1 个答案:

答案 0 :(得分:1)

您正在分派“用户”,对吗?我看到了三种划分用户的一般方法。

分片的模方法有很大的问题。添加分片时,突然大多数用户需要将大多数个用户移至其他分片。

另一个极端(取模)是“字典”方法。您可以进行某种查找,指出每个用户所在的分片。对于数以百万计的用户而言,词典的维护变得代价不菲。

我更喜欢混合动力:

  1. 对4096做模(或一些适当的大数)
  2. 使用包含4096个条目的字典。这会将4096个值映射到当前的分片数量。
  3. 您有一个软件包,可以将用户从一个分片迁移到另一个分片。 (这是系统的重要组成部分-您将使用它进行升级,严重崩溃等,负载平衡等)
  4. 添加分片涉及将4096中的几个移至新分片并更改字典。迁移的用户可能来自“最忙碌”的碎片,从而减轻了他们的压力。

是的,第4项会影响某些用户,但只影响一小部分。您可以通过选择“空闲”,“小”或“熟睡”的用户移动来减轻打击。这将涉及为4096个丛中的每一个计算一些指标。