MySQL分片的方法?

分割MySQL表的最佳方法是什么? 我能想到的方法是:

  1. 应用程序级别分片?
  2. 在MySQL代理层分片?
  3. 中央查找服务器分片?

你知道这个领域有什么有趣的项目或工具吗?

分割MySQL表的最好方法是不做,除非完全不可避免。

在编写应用程序时,通常要以最大限度地提高速度和开发速度的方式进行。 只有在必要时,您才能优化延迟(直到答案准备就绪的时间)或吞吐量(每个时间单位的答案数量)。

只有当所有这些分区的总和不再适合于单个数据库服务器实例时,才进行分区,然后将分区分配给不同的主机(=分片) – 原因是写入或读取。

写入的情况是:a)写入频率永久性地超载该服务器磁盘,或者b)太多的写入正在进行,因此复制永久滞后于此复制层次结构。

读取分片的情况是数据的大小如此之大,以至于其工作集不再适合内存,数据读取开始敲击磁盘而不是大部分时间从内存中提供。

只有当你必须碎片你做。


你碎片的那一刻,你是用多种方式付出的:

大部分的SQL不再是声明式的。

通常,在SQL中,您要告诉数据库您想要的数据,并将其留给优化器来将该规范转换为数据访问程序。 这是一件好事,因为它是灵活的,因为写这些数据访问程序是无聊的工作,损害速度。

在分散的环境中,您可能会将节点A上的表与节点B上的数据进行对比,或者在节点A和B上有一个大于节点的表,并正在将节点上的数据与节点B和C上的数据进行连接。您正在开始手动编写基于散列的应用程序连接解决方​​案,以便解决这个问题(或者您正在重新创buildMySQL集群),这意味着最终会产生大量不再是声明式的SQL,而是以过程方式表示SQLfunction(例如,你在循环中使用SELECT语句)。

你正在招致很多networking延迟。

通常,SQL查询可以在本地解决,优化器知道与本地磁盘访问相关的成本,并以最小化成本的方式解决查询。

在分片环境中,通过在整个networking上对多个节点运行键值访问(希望使用批次键访问而不是每次往返的单个键查找),或者通过将WHERE子句的一部分向前推到节点可以被应用(即被称为“条件下推”)或两者。

但即使在最好的情况下,这涉及到更多的networking往返当地的情况,这是更复杂的。 特别是因为MySQL优化器对networking延迟一无所知(好吧,MySQL集群正在慢慢变好,但是对于群集之外的vanilla MySQL仍是如此)。

你正在失去很多expression力的SQL。

好吧,这可能不那么重要,但外键约束和其他SQL机制的数据完整性是无法跨越多个碎片。

MySQL没有允许asynchronous查询的API。

当相同types的数据驻留在多个节点(例如,节点A,B和C上的用户数据)时,水平查询通常需要针对所有这些节点进行parsing(“查找90天内没有login的所有用户账户或者更多”)。 数据访问时间随着节点数的增加而线性增长,除非多个节点可以并行访问,并且汇总后的结果(“Map-Reduce”)。

前提条件是一个asynchronous通信API,对于MySQL来说,这个API是不存在的。 另一种select是在孩子的过程中有很多的分支和联系,这是一个季度通行证的访问世界。


一旦开始分片,数据结构和networking拓扑将变得可见,因为性能指向您的应用程序。 为了执行得相当好,你的应用程序需要知道这些事情,这意味着实际上只有应用程序级分片才有意义。

如果你想自动分片(例如,通过散列主键来确定哪一行进入哪个节点),或者如果你想以手动的方式在function上分割(“与xyz用户故事相关的表转到这个主,而abc和def相关的表去那个主“)。

function分片的优点是,如果做得对,大多数时候对于大多数开发人员来说是不可见的,因为与他们的用户故事相关的所有表都将在本地可用。 这使得他们仍然能够尽可能长时间地从声明式SQL中受益,并且由于跨网传输的数量保持最小,所以也会导致较less的networking延迟。

function分片的缺点是不允许任何单个表比一个实例大,而且这需要devise者的手动注意。

function分片的优点是,对于现有的代码库,可以相对容易地进行一些不太大的变化。 http://Booking.com在过去的几年里已经做了好几次,对他们来说效果不错。;


说了这么多,看看你的问题,我确信你在问错误的问题,或者我完全误解了你的问题陈述。

  1. 应用程序级别分片:dbShards是我所知道的“应用程序感知分片”的唯一产品。 网站上有几篇很好的文章。 就定义而言,应用程序感知分片将会更有效率。 如果一个应用程序确切地知道去哪里进行一个事务,而不必查找它或者被一个代理redirect,那么它本身就会更快。 速度往往是主要关注的问题之一,如果不是唯一的担忧,那么当有人正在研究分片时。

  2. 有些人用代理“碎片”,但在我眼中,这打破了分片的目的。 您只是使用另一台服务器来告诉您的事务在哪里查找数据或在哪里存储数据。 通过应用程序感知分片,您的应用程序可以知道自己的位置。 效率更高

  3. 这真的和#2一样。

你知道这个领域有什么有趣的项目或工具吗?

这个领域的几个新项目:

  • citusdata.com
  • spockproxy.sourceforge.net
  • github.com/twitter/gizzard/

Shard-Query是针对MySQL的基于OLAP的分片解决scheme。 它允许您定义分片表和未分片表的组合。 未分割的表(如查找表)可以自由地连接到分片表,并且分片表可以彼此连接,只要表通过分片键(没有跨分片或自连接跨越分片边界)连接即可。 作为一个OLAP解决scheme,即使对于简单的查询,Shard-Query通常也具有100ms或更短的最小响应时间,因此它不适用于OLTP。 Shard-Query用于并行分析大数据集。

MySQL也有OLTP分片解决scheme。 封闭源解决scheme包括ScaleDB , DBShards 。 开源的OLTP解决scheme包括JetPants , Cubrid或Flock / Gizzard (Twitter基础设施)。

课程的应用水平。

我在本书中发现的最红的方法

高性能MySQL http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064

简短描述:你可以在很多地方拆分你的数据,并在每个服务器上存储〜50个部分。 它将帮助您避免第二大分片 – 重新平衡的问题。 只要将其中的一些移动到新的服务器,一切都会好的:)

我强烈build议你购买它,并阅读“MySQL缩放”部分。