数据库设计的非正统方法:Shard的来临
关于Shard和Partition的区别,大家可以看看What’s the difference between sharding DB tables and partitioning them?以及Database sharding Vs partitioning。
简单而言,就是通常意义上的Partition是在本地数据上的分片,Shard是在多台机器上的分片。Shard和Horizontal Partition,即,Shard是Partition的一种或者一个特例。
原文地址An Unorthodox Approach To Database Design : The Coming Of The Shard
曾几何时,我们通过购买更大,更快,更昂贵的机器来扩展数据库。但是这样太贵了。
Dathan Pattishall在一篇特别的两篇文章系列中解释了他创建革命性的新数据库架构的动机 - 分解 - 他在Friendster工作之前就开始思考,并在Flickr完全实现。Flickr现在每天处理超过10亿笔交易,在几秒钟之内响应,并且可以以比较低的成本进行线性扩展。
什么是分片,它是如何成为大型网站扩展问题的答案?
什么是分片?
在Auction Watch工作期间,Dathan通过创建一个数据库服务器,这台服务器仅为一组用户服务,并在多台廉价的Linux机器上运行这些服务器,从而解决了扩展问题。在这种方案中,用户A的数据存储在一台服务器上,用户B的数据存储在另一台服务器上。这是一个联邦模式(federated model)。每500K的用户组被存储在一起,这被称为Shard。
它的优点是:
- 高可用性。如果一个服务器挂了,其他服务器仍在运转。
- 更快的查询。每个用户组中的较小数据量意味着更快的查询。
- 更多的写带宽。在没有主数据库序列化写入的情况下,可以并行写入,从而提高写入吞吐量。写操作是许多网站的主要瓶颈。
- 你可以做更多的工作。平行的后端意味着你可以同时做更多的工作。您可以处理更高的用户负载,特别是在写入数据时,因为系统中存在并行路径。您可以对Web服务器进行负载平衡,这些服务器访问分散在不同网络路径上的分片,这些分离的CPU使用单独的RAM高速缓存和单独的磁盘IO路径来处理工作。很少有瓶颈限制你的工作。
Shard与传统架构有何不同?
在许多重要方面,分片与传统的数据库体系结构不同:
数据是非正则化的。
- 传统上我们希望将数据正则化。数据展开成不规则的表格,然后在需要使用时重新JOIN在一起。在Shard中,数据是非正则化的。您将一起使用的数据存储在一起。
- 这并不意味着你不要按类型分隔数据。您可以将用户的个人资料数据与他们的评论,博客,电子邮件,媒体等分开,但用户个人资料数据将作为整体进行存储和检索。这是一个非常快速的方法。你只是得到一个blob,并存储一个blob。不需要JOIN,它可以仅用一个写操作就写入。
数据跨多个物理实例并行化。
- 历史上数据库服务器已经扩大。你买更大的机器来获得更多的处理能力。
- 分片数据是并行化的。使用这种方法,您可以完成更多的工作,因为并行工作的特性。
数据保持较小。
- 数据量越大,服务器处理的难度就越高,因为存储的数据种类繁多。你需要巨大的内存空间,先今最大的RAM都不能讲你需要缓存的数据存下来。通过将数据分割成更小的Shard,则缓存就可以将正在访问的数据存在内存中。
- 更小的数据集也更容易备份,恢复和管理。
数据的可用性更强。
- 由于Shard是独立的,一个故障不会导致另一个故障。而且如果你让每个Shard仅占用50%的容量,升级Shard也就更容易了。
- 在Shard中保存多个数据副本也有助于实现冗余(redundancy),并使数据更加平行,从而可以在数据上完成更多的工作。
- 您也可以设置一个Shard,使其在Shard中具有主从关系或双主分页关系的数据库,以避免Shard内出现单点故障。如果一台服务器停机,另一台服务器可以接管。
它不使用复制。
将数据从主服务器复制到从属服务器是扩展的传统方法。数据写入主服务器,然后复制到一个或多个从服务器。此时读操作可以由从服务器处理,但所有写操作都发生在主服务器上。
主服务器显然具有写瓶颈和单点故障的特性。随着负载的增加,复制数据的成本也在增加。CPU,网络带宽和磁盘IO等等。从机的数据版本落后。YouTube中的工程师们在缩放时遇到了复制数据开销的大问题。
- Shard能够干净,优雅地解决复制的问题。
与分片有关的几个问题
分片并不完美。它确实有一些问题。
重新平衡数据。
当一个Shard超过它的服务器的存储空间,需要拆分时会发生什么?假设一些用户有一个特别大的朋友列表,这个列表会影响你的存储容量。您需要将用户移至不同的Shard。
在某些平台上,我已经做了这个是一个杀手级的问题。您必须从一开始就正确构建数据中心,因为将数据从Shard移动到Shard需要大量的暂停服务时间。
再平衡的想法必须从一开始就建立起来。 Google的Shard会自动重新平衡。为了这个工作,数据引用必须经过某种命名服务才能重新定位。这就是Flickr所做的。而且你的引用必须是无效的,所以底层的数据可以在你使用的时候移动。
连接来自多个分片的数据。
- 要创建一个复杂的朋友页面,或用户个人资料页面或线程讨论页面,通常必须将许多不同来源的不同数据汇集在一起。
- 随着分片的增多,你不能只发出一个查询就能够取回所有的数据。您必须对多个数据源进行请求,获取所有响应,然后构建页面。值得庆幸的是,由于缓存和快速的网络,这个过程通常足够快,您的网页加载时间可以很好。
你在Shard中如何Partition你的数据?你把什么数据放在哪个碎片?评论去哪里?所有的用户数据是否应该真的一起出现?用户的媒体,即时消息,朋友列表等应该去其他地方?不幸的是,这些问题都非常复杂。
利用率较低。
- 人们对传统的RDBMS工具有经验,所以在这里有很多的帮助。出现问题或者您不知道如何实施新功能时,您可能拥有书籍,专家,工具链和论坛。
- Eclipse将不会有Shard的可视化视图,并且不会为您的Shard找到任何自动备份和还原程序。Shard的一切都要我们自己处理。
实现Shard不能获得很好的支持。
- 目前,Sharding主要是由个人实现的。 LiveJournal使他们的工具链可用。 Hibernate有一个正在开发的库。MySQL增加了对分区的支持。但总的来说,它仍然是你必须实现的东西。
好,这儿为朋友的公司做一个广告。
Pincap的[TiDB](TiDB is a distributed HTAP database compatible with the MySQL protocol ),完全兼容MySQL命令的分布式数据库。
TiDB具有无限的水平可伸缩性,强大的一致性和高可用性。非常适合做Sharding。