如何向 SQL 数据库中已分片的数据添加机器?
How can I add machines to data already been sharded in SQL database?
我有很多用户数据。每个人都有一个唯一的用户 ID,由六个字符的 base64 表示。例如 (Fga6=gY)。
我使用哈希函数将用户分散到我的 MySQL 台机器上。
我有四台机器,所以当我想保存一个新用户时,我只检查我应该保存它的服务器:
hash(userId) % 4
我的问题是,如果我的 4 台机器负载过大,我该如何添加更多机器。
如果我将开始使用 6 台机器并使用模 6 而不是 4,它将适用于新用户。但是当尝试查询旧用户时,我的应用程序服务器将被转发到错误的机器。
我如何解决已经在生产中的系统?
如何更好地规划系统,以便在需要时扩展机器?
太遗憾了,您在实施该简单哈希之前没有询问。
第一
我强烈建议编写脚本将一个用户从一个分片移动到另一个分片。它将成为以下大部分建议的重要组成部分。
哈希的替代方法
“字典查找”是您在 table 中列出的用户以及他们所在的分片。这允许将单个用户从一个分片移动到另一个分片。 (这种“移动”的细节可能相当复杂。)这可以带来很多好处:将一些用户从繁忙的服务器转移到不那么繁忙的服务器;添加一个新的分片;装备一个新的分片,然后将用户移动到新的服务器。等等
“字典”和“散列”之间的折衷如下:将 user_id 散列为 512 个可能的值。然后使用只有 512 个条目的字典来查找这些用户所在的分片。这需要移动一组用户,而不仅仅是单个用户,但要使字典保持固定大小。
无论哪种情况,都需要将“字典”传播给所有客户端以供他们使用。
小帮手
重新散列基本上涉及移动所有数据。这在停机时间中是相当昂贵的。相反,请考虑一下。哈希 mod 8(具体为 2*4)。然后将一个分片拆分成两个服务器。这只会给 1/4 的用户带来痛苦。实际上,使用“移动一个用户”脚本,只有 1/8 的用户会受到影响。当然,客户端中有一些代码可以理解某些分片拥有 1/4 的用户;有些有1/8。 (这会引导您从 4->8,而不是您要求的 4->6。)
替代拓扑
如果您的客户端与分片位于同一台服务器上,请考虑将应用程序代码移到其他服务器上。也就是说,数据库分片上只有 MySQL;在其他服务器上有其他东西。并根据需要以不同方式配置它们(RAM、IOP 等)。您的系统实际上可能需要多于 4 台或少于 4 台客户端计算机来处理相关负载。此拓扑允许分别缩放。
优化
你有没有打开slowlog? long_query_time
的值较低? 运行 pt-query-digest
针对该日志。然后,让我们讨论前几个查询。他们 可能 运行 比他们应该的要慢。 http://mysql.rjweb.org/doc.php/mysql_analysis#slow_queries_and_slowlog
这可能会让您推迟添加分片。
我有很多用户数据。每个人都有一个唯一的用户 ID,由六个字符的 base64 表示。例如 (Fga6=gY)。 我使用哈希函数将用户分散到我的 MySQL 台机器上。
我有四台机器,所以当我想保存一个新用户时,我只检查我应该保存它的服务器:
hash(userId) % 4
我的问题是,如果我的 4 台机器负载过大,我该如何添加更多机器。 如果我将开始使用 6 台机器并使用模 6 而不是 4,它将适用于新用户。但是当尝试查询旧用户时,我的应用程序服务器将被转发到错误的机器。
我如何解决已经在生产中的系统?
如何更好地规划系统,以便在需要时扩展机器?
太遗憾了,您在实施该简单哈希之前没有询问。
第一
我强烈建议编写脚本将一个用户从一个分片移动到另一个分片。它将成为以下大部分建议的重要组成部分。
哈希的替代方法
“字典查找”是您在 table 中列出的用户以及他们所在的分片。这允许将单个用户从一个分片移动到另一个分片。 (这种“移动”的细节可能相当复杂。)这可以带来很多好处:将一些用户从繁忙的服务器转移到不那么繁忙的服务器;添加一个新的分片;装备一个新的分片,然后将用户移动到新的服务器。等等
“字典”和“散列”之间的折衷如下:将 user_id 散列为 512 个可能的值。然后使用只有 512 个条目的字典来查找这些用户所在的分片。这需要移动一组用户,而不仅仅是单个用户,但要使字典保持固定大小。
无论哪种情况,都需要将“字典”传播给所有客户端以供他们使用。
小帮手
重新散列基本上涉及移动所有数据。这在停机时间中是相当昂贵的。相反,请考虑一下。哈希 mod 8(具体为 2*4)。然后将一个分片拆分成两个服务器。这只会给 1/4 的用户带来痛苦。实际上,使用“移动一个用户”脚本,只有 1/8 的用户会受到影响。当然,客户端中有一些代码可以理解某些分片拥有 1/4 的用户;有些有1/8。 (这会引导您从 4->8,而不是您要求的 4->6。)
替代拓扑
如果您的客户端与分片位于同一台服务器上,请考虑将应用程序代码移到其他服务器上。也就是说,数据库分片上只有 MySQL;在其他服务器上有其他东西。并根据需要以不同方式配置它们(RAM、IOP 等)。您的系统实际上可能需要多于 4 台或少于 4 台客户端计算机来处理相关负载。此拓扑允许分别缩放。
优化
你有没有打开slowlog? long_query_time
的值较低? 运行 pt-query-digest
针对该日志。然后,让我们讨论前几个查询。他们 可能 运行 比他们应该的要慢。 http://mysql.rjweb.org/doc.php/mysql_analysis#slow_queries_and_slowlog
这可能会让您推迟添加分片。