如何将机器添加到 SQL 数据库中已经分片的数据?
Posted
技术标签:
【中文标题】如何将机器添加到 SQL 数据库中已经分片的数据?【英文标题】:How can I add machines to data already been sharded in SQL database? 【发布时间】:2021-09-02 02:38:37 【问题描述】:我有很多用户数据。每个都有一个唯一的用户 ID,由六个字符的 base64 表示。例如(Fga6=gY)。 我使用哈希函数将用户分布在我的 mysql 机器上。
我有四台机器,所以当我想保存一个新用户时,我只需检查应该保存在哪个服务器上:
hash(userId) % 4
我的问题是如何添加更多机器以防 4 台机器上的负载过多。 如果我将开始使用 6 台机器并使用模 6 而不是 4 它将适用于新用户。但是当尝试查询老用户时,我的应用服务器会被转发到错误的机器上。
对于已经投入生产的系统,我该如何解决?
我怎样才能更好地规划一个系统,以便我可以在需要时横向扩展机器?
【问题讨论】:
要回答“我如何才能更好地规划系统以允许横向扩展”的问题,consistent hashing 是一个很好的起点! 另一种不涉及重新分配的方法是拥有一个“协调器”(可能由数据库支持)来跟踪每个帐户的存储位置。然后你会使用它而不是你的 hash + mod 函数。 【参考方案1】:很遗憾,您在实现那个简单的哈希之前没有问。
第一
我强烈建议编写一个脚本来将一个用户从一个分片移动到另一个分片。这将是以下大多数建议的重要组成部分。
哈希的替代品
“字典查找”是您在表格中列出的用户,以及他们所在的分片。这允许将单个用户从一个分片移动到另一个分片。 (这种“移动”的细节可能相当复杂。)这可以带来很多好处:将一些用户从繁忙的服务器转移到不太繁忙的服务器;添加一个新的分片;装备一个新的分片,然后将用户移动到新的服务器。等等。
“字典”和“散列”之间的折衷如下:将 user_id 散列为 512 个可能的值。然后使用只有 512 个条目的字典来查找这些用户所在的分片。这需要移动一组用户,而不仅仅是单个用户,而是将字典保持在固定大小。
在任何一种情况下,“字典”都需要传播到所有客户端以供他们使用。
小帮助
重新散列基本上涉及移动所有数据。这在停机时间是相当昂贵的。相反,思考这一点。哈希 mod 8(特别是 2*4)。然后将 一个 分片分成两台服务器。这只会让 1/4 的用户感到痛苦。实际上,使用“移动一个用户”脚本,只有 1/8 的用户会受到影响。当然,客户端中有一些代码可以理解某些分片拥有 1/4 的用户;有些有1/8。 (这会引导您从 4->8,而不是您要求的 4->6。)
替代拓扑
如果您的客户端与分片位于同一台服务器上,请考虑将应用代码移动到其他服务器上。也就是说,数据库分片上只有 MySQL;在其他服务器上有其他东西。如果需要,可以对它们进行不同的配置(RAM、IOPS 等)。您的系统实际上可能需要多于 4 台或少于 4 台客户端计算机来处理相关负载。这种拓扑允许单独缩放每个。
优化
您是否打开了慢速日志? long_query_time
的值较低?针对该日志运行 pt-query-digest
。然后,让我们讨论前几个查询。他们可能运行得比他们可能的要慢。 http://mysql.rjweb.org/doc.php/mysql_analysis#slow_queries_and_slowlog
这可能会让您推迟添加分片。
【讨论】:
以上是关于如何将机器添加到 SQL 数据库中已经分片的数据?的主要内容,如果未能解决你的问题,请参考以下文章