在MySQL中水平扩展分片在以前的文章,MySQL的水平可伸缩性的心态,我讨论了周围的担忧日益增长的个人MySQL实例太大,一些基本的策略:

  • 优化/最小化大小与适当的数据类型
  • 删除未使用的/重复的索引
  • 保持你的主键很小
  • 修剪的数据

最后,如果这些方法已经筋疲力尽,我谈到了水平分片的方法保持个体实例在一个合理的大小。在讨论我的想法在我们的内部团队,有很多反馈,我们需要深入详细分片主题。这篇文章的目的是提供更多的理论和考虑切分连同一个轻量级ProxySQL示例实现。

切分是什么?

分片一词经常使用但经常被误解。经典的垂直扩展(通常称为“缩放”)是当你增加在一台服务器上的资源来处理更多的数据和/或负载。水平扩展(又名分片)是当你真正把你的数据分成更小的,独立的桶和保留根据需要添加新桶。

分片环境中有两个或多个组的MySQL服务器的孤立和独立于彼此。虽然具体的实现细节依赖于您的环境,这里有一些一般准则:

  • 可以单独的服务器或复制碎片的层次结构
  • 每个碎片都有相同的模式,您可以运行相同的查询模式对任何碎片和期望得到一个结果集的WHERE子句(当然不同的标识符)
  • 特定标识符确切地仅属于一个碎片——你不应该客户ID生成碎片(除非只是暂时在迁移过程中碎片例如-这是一个极端例子,需要特殊处理)

这对分片的理解,让我们来看看一些实际实现的关键问题和挑战。

切分问题和挑战

尽管分片经常成为管理爆炸数据的唯一方法,大多数专家和架构师建议尽可能长时间推迟了。如果是这样一个伟大的方式来处理数据,那么这是为什么呢?主要原因是复杂性。而垂直扩展是微不足道的(只是增加更多的硬件和没有其他变化),分片需要大量的思考和规划。的主要挑战分为几个主要桶:

  • 我该如何把我的数据?
  • 如果我的数据跨越碎片?
  • 我如何找到我需要的数据吗?

每个桶都有自己的挑战,但也可以全面拦截器在实现分片。

我如何把我的数据?

挑选碎片关键是实现分片中最重要的部分。主要概念是选择跨记录共享一个标识符,比如CustomerID, ClientID或标识。一般来说,你想要挑选最小单元可能在UserID级别(一般),但这也取决于需要什么程度的聚合(后面详细讨论)。这里的风险是关键不够选择性和你最终不均匀分割数据。然而,如果你太挑剔,你分手的风险单位,逻辑上应该保持在一起(认为分片ForumPostID vs UserID)。

如果我的数据跨越碎片?

这通常是一个决定性因素,防止组织分片。把数据和检索单个记录,而不是微不足道的,相对简单。在许多工作负载,这就足够了。找到我的小子集的数据和获取它。总查询用例规定,然而,这个工作流分解。把这个通用查询找到最新的用户在平台:

当所有的用户存储在一个单独的服务器,这个查询的方法是微不足道的。然而,当跨越多个数据碎片,我们现在需要一种方法来聚合数据。实现这是超出了本文的范围,但是一般方法是这样的:

  1. 问题查询每一个碎片
  2. 收集每个切分的结果在一个中央聚合服务
  3. /过滤个人结果合并成一个单独的结果集

如果你的用例严重依赖聚合查询,实现这种聚合层至关重要,往往很复杂。这也阻碍了很多从分片的用例,即使它是必要的。

在一个理想的场景中,主动的OLTP工作负载可以包含在单独的碎片。报告和数据仓库需要分布式查询的实现,可以通过不同的管理系统,或通过自定义聚合使用多源MySQL异步复制。

我如何找到我的数据?

现在,假设你选择了一个分片键,您需要能够检索记录。这是下一个需要克服的主要障碍。这个问题有两种截然不同的组件的挑战:

  • 确定哪些碎片保存数据
  • 如何连接,碎片从我的应用程序

找到ShardID

确定哪些碎片认为,数据可以是简单或复杂。然而,每种方法有权衡。简单的方法使用一个简单的散列/模数确定碎片看起来像这样:

最基本的例子将分片userID跨2个碎片。用户id,甚至将切分0和奇怪的用户id将切分1。虽然非常简单,我做什么当两个碎片不是足够了吗?这种体系结构的目的就是增加更多的碎片当个别碎片太大了。现在,当我添加新的碎片,碎片的数量增加的shardID可能改变的许多记录。

更灵活的方法是使用一个目录服务。在这种方法中,有一个非常简单的数据存储,将一个标识符映射到一个碎片。要确定哪些碎片保存数据,只需查询与标识符,它会返回shardID数据存储。这给了难以置信的灵活性之间移动数据碎片,还增加了系统的复杂性。自然,这服务本身需要高度可用,但没有MySQL。除了复杂性,你有可能会引入额外的延迟和额外的查询系统。

连接到碎片

一旦我们有了适当的shardID,我们需要连接到数据库集群的问题。再一次,我们可以选择和实现是依赖于应用程序。我们可以看看两种主要方法:

  • 为每个碎片使用不同的连接字符串
  • 利用智能代理层,路线

使用不同的连接字符串通常是不言而喻的:我有一个shardIDs及其相应的连接字符串的集合。当我知道shardID,然后我获取连接字符串,连接到集群,我们走。

但我们知道开发人员不想和不应该惹连接字符串和凭证。所以代理层,可以根据查询路线查询本身或一些元数据查询中是理想的。被一层7服务,ProxySQL能够检查查询自己和做出决定基于定义的规则。虽然肯定不是唯一的方法,让我们看一个示例ProxySQL实现使用查询注释路由到正确的切分。

样本ProxySQL实现

在我们的例子中,这是基本的架构:

  • 分片用户标识
  • 目录服务,简单的路由基于模量
  • ProxySQL已经用于哈
  • 数据是跨越3碎片

一个典型的用户查询可能看起来像这样:

UserID是分片键和简单的模量分片策略,我们可以轻松地识别shardID查询:

定义shardID后,我们现在可以注入评论的原始查询可以使用ProxySQL正确路线查询到正确的切分:

ProxySQL内部使用hostgroups定义路由的概念。在很多公顷情况下,这只是一个读者和作家hostgroup。分片的架构,然而,我们可以扩大hostgroups定义为真正的碎片:

hostgroups到位,我们只需要添加一个ProxySQL规则选择hostgroup基于注入的评论:

现在,在我们发出一些查询,你可以看到在ProxySQL统计,我们相应地匹配shardID和路由:

显然,这是一个巨大的简化,你想要更通用的、更复杂的hostgroups的规则。例如,您的部署需要考虑查询没有提供碎片提示或无效的情况shardID供应。然而,它显示的潜力编写自定义路由层内ProxySQL非常轻量级的工具。这种方法,虽然它需要一些额外的思考和逻辑,可能是一个可行的水平分割数据的第一步。

再一次,这只是一个概念验证样本实现。每个用例都是不同的。这篇文章的主要结论是,人工切分是可能的,但需要大量的规划和实施工作。

雷竞技下载官网MySQL Percona分布是最完整的,稳定的,可伸缩的,和安全,开源MySQL解决方案,提供企业级的数据库环境最关键业务应用程序…和它的免费使用!

raybetapp2下载

订阅
通知的
客人

3评论
最古老的
最新的 大多数投票
内联反馈
查看所有评论
Neo

恕我直言,维塔斯是分片MySQL的解决方案,它支持增加与减少的碎片没有停机时间和还支持改变分片键。还支持分散收集SQL模式。

在我看来ProxySQL维塔斯是一个劣质分片解决方案。

迈克尔·科伯恩

嗨@Neo感谢你的回复!你强调一个非常有用的切分工具MySQL在维塔斯,这是一个产品,Percona爱,经常为客户推荐和部署解决方案。雷竞技下载官网我们不否认在维塔斯有巨大的价值。在博客上我们要做的是突出许多选项,并在我们看来ProxySQL更容易部署数据库是微创堆栈(至少相比于维塔斯,这是一个真正的,操作)。

再次感谢你的反馈,这使得迈克尔和我考虑做(另一个)的帖子,我们探索更复杂的解决方案,比如维塔斯!

伊万·鲍多

将会是很有趣的一篇文章TiDB。