分片 Mysql 数据库的最佳方式

Best way to shard Mysql database

我有大量的用户,所以我需要将数据库分成 n 个分片。因此,要继续进行此操作,我有以下选项-

  1. 将我的数据分成n个分片,根据userId取模n运算。即如果我有 10 个分片 userId 1999 将被发送到 1999%10=9th shard
    问题- 这种方法的问题是,如果未来对以前的引用的分片数量增加,将无法维持。

  2. 我可以用 UserId 和 ShardId
    维护一个 table 问题- 如果我的用户将来增加到数十亿,我将需要共享此映射 table,这似乎不是一个好的解决方案。

  3. 我可以在代码中维护静态映射,例如分片 1 中的 0-10000 等等。
    问题-

    • 随着分片的增加,用户代码需要更频繁地更改。
    • 如果分片中的任何特定用户拥有大量数据,则很难分离出分片。

所以,这是我本可以找到的三种方法,但都存在一些问题。什么是对 MySQL table 进行分片的替代或更好的方法,它可以补偿未来增加的分片和用户数量。

我更喜欢 1 和 2 的混合:

  1. 将 UserId 散列为 4096 个值。
  2. 在 'dictionary' 中查找该编号,其中包含分片编号。

如果一个分片太满,将所有具有某个哈希值的用户迁移到另一个分片。

如果您添加一个分片,请将一些哈希值迁移到它 - 最好从繁忙的分片迁移。

这迫使您编写用于移动用户的脚本,并使其健壮。一旦你有了它,很多其他的管理任务就变成了 'simple':

  • 淘汰一台机器
  • 升级OS(跨分片一个接一个)
  • 升级机器上的任何软件
  • 将一个庞大但不繁忙的散列号迁移到一个旧的、慢的、有大磁盘的分片。同样,将小而繁忙的数据迁移到具有更多内核和更快磁盘的分片。

为了可靠性和 read-scaling,每个分片都可以是服务器的 HA 集群(Galera、Group 复制等)。 (分片给你 write-scaling.

需要一种方法将词典分发给所有客户端 "promptly"。

如果您有 3 个不同分片中的每个哈希以实现高可用性,则所有这些都可以很好地工作。这 3 个中的每一个都位于地理位置以确保稳健性。字典将有 4 列来说明副本的位置。第 4 个将在迁移期间使用。