本文作者Peter Zaitsev是知名数据库专家,2006年联合创立了Percona。负责维护网站“MySQL性能”。同时,他也是《高性能MySQL》一书的联合作者。以下是他对MySQL分片的建议:
在与客户讨论分片决策的时候,我经常会先给他们讲下面这个真实的故事。
几年前,有客户来找我,希望获得关于如何对系统分片的一些指导建议。他告诉我说,自从他知道很多应用MySQL的巨头(比如Facebook和Twitter)都在使用分片技术以后他就也想这么做。他们(这些巨头)都是聪明人,所以很自然他也相信自己需要这么做。
我停了一会然后问他的数据库有多大规模。
他说:“有10GB”。
我点头表示理解,并继续问他是否要处理许多查询或者有很多非常复杂的查询。
他回答说:“没有。每秒钟只有几百个查询,这些查询给系统带来的性能消耗只占很少的百分比。
我有问他是否预期在不远的未来数据量有指数级增长,比如每周数据量就会翻倍之类的情况。
“不会的。我们的负载和数据规模去年增长了大约7%,我们预计今年乃至可预见的未来增长率也差不多。”
我给他的建议是不要在分片上浪费时间和精力了,因为他公司的情况需要的不是这个。
是否真的需要分片
在你决定如何分片之前,你最好从一开始弄明白你是否真的需要分片。诚然,在超大规模数据库需求的情况下,分片是唯一的途径。不只是对于MySQL,对大部分同类技术都是一样。
然而,由于出现了很多新兴技术,越来越多的应用都支持无需分片运行数据库。现在,我们可以很轻松地在每个MySQL实例上运行TB级数据,并在许多OLTP环境下支持数以万计的查询。可见我们可以构建非常庞大的应用而无需分片。
我们应该铭记:分片对所有环境都是不得已而为的做法。即便你使用的数据库支持开箱即用的分片功能,那也会由于引入更多组件和复杂度而带来麻烦。构建良好的分布式查询执行计划是非常复杂的任务,需要考虑网络拓扑结构和负载情况,另外还要考虑数据分布和每个独立节点的负载。
在判断是否需要分片之前,你应该首先考虑是否有替代方法可以扩展你的应用。在MySQL的世界里,通常有以下一些方案可以考虑。
分片的替代方案
功能分区:在许多环境中,单独的MySQL实例变成了各种数据库的倾销之所。你可能最终让你的主应用与Drupal共享一个数据库实例,用 WordPress增强你的站点,用vBulletin增强你的博客,甚至论坛。把所有这些应用碎片分入不同的数据库实例是你首先应该考虑的,而不是直接考虑分片。客户定制系统经常有不同数据集的应用,所以这个分法很容易实现。
复制:许多应用都是“读操作”的压力大,而扩展读操作性能要比扩展写性能更容易一些。如果是这种情况,那么复制就是非常好的选择。MySQL有自带的复制功能非常健壮,虽然其异步特性增加了应用的复杂性。这种情况下,开发人员必须判断从哪台复制服务器上读取信息,不可以从哪里获取。因为你必须绝对保证你读取到的是最新的实际数据。这也正是针对MySQL出现的可替代的异步复制技术广受欢迎的原因(例如PerconaXtraDB)。这些工具把大部分集群环境下的功能提供给向单个数据库操作的能力。
缓存和队列:缓存是降低数据库读取量的出色技术。有许多应用使用这种技术可以降低数据库读负载高达80-95%。与之相对的是队列,它是用来优化写操作的。通过合并多次写操作,提高了对数据库操作的效率。大部分大型应用都应该重点考虑这两种技术。Memcached和Redis是MySQL领域非常流行的两种缓存技术。对于队列,最流行的技术是ActiveMQ和RabbitMQ。
外部支持技术:MySQL在很多方面都很出色,但也不是所有方面都强。如果你需要高性能全文检索,应该考虑ElasticSearch、Sphinx或者 Lucene。如果你想做大规模数据分析,可以考虑基于Hadoop的基础架构或者Vertica也是不错的选择。你应该让MySQL处理它擅长的事,把其它事留给外部支持工具来做。
分片之前应该做的优化
扩展不只是针对架构而言。你还需要确保你的系统经过了合理的优化。许多人决定采用分片其实不是真正必要的,虽然对于他们来说这是获得性能提升更容易而且更有效的方式。我想说的是,如果分片最终也必须选择的话,之前做的所有这一切优化也仍然是有价值的。
硬件。考虑一下你使用的硬件合适吗?我见过好多人在寻求分片方案,但事实上只要购买其十分之一的硬件就能解决他们的问题,并保证在未来多年有效。如果你使用的数据库比较大,请确保你有大量内存和高性能闪存。在许多情况下,它几乎像变魔术一样可以极大地提升你的系统。
MySQL版本和配置。建议使用最新的MySQL版本。我指的是最新的GA版本(本文发布时最新版本是MySQL 5.6)。Percona Server是免费的,它通常可以为需要的负载提供额外的性能提升。同样也推荐采用最新版本的操作系统,尤其是如果你使用的是最新的硬件时更需如此。最后,确保MySQL配置合适。MySQL配置好坏会导致其性能的天壤之别,性能差距可能会达到十倍甚至更多。
模式与查询。相同的应用逻辑可以由多重模式和查询来表达。我见过有许多类似的应用采用不同的方法来实现,采用优化方法和性能糟糕的方法(确实应用于生产环境了)其性能差异可能达到一百倍甚至更多。许多修改可能会调整现有结构模式,比如对索引结构的微小调整。然而,如果你的结构不能很好适合你的应用需求,那么你需要的可能是重新设计。因此,尽早开始考虑问题是很有必要的。
何时考虑分片
那么我们什么时候可以开始考虑分片呢?一般来讲,如果以上列举的方法都不能令你获得满意的性能,那么就是时候考虑分片了。分片确实有使用低成本硬件或者更廉价的云实例获得潜在性能的优势。
当今的大部分开发者们都在使用敏捷开发方法,有一种通用的说法叫“架构跑道”,它说明了应用基于当前架构可以发展多远。如果你已经使用复制获得了成功,那么再使用分片可能是一种糟糕的选择,因为它会强迫开发人员处理分片和异步复制的复杂性。然而,尽管你已经使用了分片,复制通常仍然会用于获得更高的可用性,但是这种情况下就不只是未来扩展读能力了。
如果你已经确信到了必须做分片的地步,那么下面这些问题你可以自查一下,都是关于如何实施分片策略的。
分片层次:我们应该在哪个层次上做分片呢?分片并不是必须在数据库层面上做的。许多应用(尤其是SaaS)经常在更高层次上做分片,可以部署完整应用堆的多份副本实现完全独立的可用性、性能、安全等等。在许多大型扩展应用中你会看到许多完整的副本,每份副本都有其各自的分片MySQL环境。
分片关键:我们如何进行分片?在许多情况下,选择的方案取决于你是否对用户账号或者你的组织做了认证,但是也有一些情况下并不是那么明显。在选择分片方案的时候,你需要考虑两件事:1)要让尽可能多的数据访问点安排在一起,因为跨分片访问代价很昂贵(而且前提是支持的情况下);2)确保要做的分片方案不会产生新的分片,也就是说新的分片不能太大以至于不能处理相关数据规模或者访问量。例如,按国家分片就不是一个好主意,因为处理比利时的访问量和处理美国或者中国的访问量绝对不是等同的,后者要更多的资源。
模式或者实例共享:你做分片的粒度是什么呢?一般的选择是MySQL实例或者数据库(模式)。我喜欢对数据库分片的方式,因为它不会限制每个物理节点只能有一个MySQL实例。这种方式不必运行太多MySQL实例,但是如果应用在这种情况下运行更好,你可以运行更多实例。
分片单元:如果你按每个独立的MySQL服务器做分片,你很快会遇到高可用性的问题。如果你有一百台MySQL服务器,相比于只有一台的情况,发生故障的概率大概达到一百倍。因此确保实现高可用性的解决方案就成为了关键。处理针对MySQL服务器节点做分片,我们通常可以按复制集群节点做分片(比如一台作为MySQL主节点,另一台或多台作为复制服务器或者PXC,即Percona XtraDB集群)。
分片技术:你计划采用什么技术帮助实现分片呢?在MySQL的世界中,没有通用的分片技术适合于所有人使用。大部分大型web站点都根据他们自己的分片需求实现一定的定制,其中一些已经把它们的解决方案发布为开源项目。Vitess就是一个例子,它是由谷歌公司贡献的。另一个例子是JetPants,是由 Tumblr公司贡献的。推出我们自己的分片框架在一些开发人员看来貌似容易,但一般都会遇到一些难以处理的实际问题,比如平衡分片、更大规模下的再分片等。有许多专门用途的技术可以帮助实现分片,它们可能与你的团队现在管理分片的方式不同。
分片技术
这里列出了一些技术你可以参考。
MySQL Fabric:这是Oracle公司的MySQL团队开发的分片技术。MySQL Fabric是GA版本,但是目前它的功能还相当有限,尤其是在支持多分片查询方面。不过,如果再多经过一段时间,它有潜力成为MySQL的标准分片技术。
Tesora:Tesora为MySQL分片技术提供了基于代理的解决方案,前段时间它已开放源代码。如果你考虑部署OpenStack,我特别推荐Tesora,因为他们在集成方面投入了很多。
ScaleArc:ScaleArc是商业数据库代理解决方案,可以实现缓存、过滤、路由和分配。它是相当成熟的解决方案了,可以处理多种数据库而不只是MySQL。
ScaleBase:ScaleBase是专门为MySQL和云计算设计的一种分配解决方案,与MySQL类似,运营在代理层面。
在MySQL领域还有许多技术可以在无需分配的情况下扩展你的应用。不过,如果你打算成为下一个“Facebook”,那你是得考虑分片了。也有许多技术可以帮助你尽可能无痛地实现分片。以大规模数据库为基础的大型应用总会带来复杂度,针对这种应用做开发和管理是更复杂的是。付出才会成功。