`
thinkerAndThinker
  • 浏览: 276047 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案

 
阅读更多

作为一种数据存储层面上的水平伸缩解决方案,数据库Sharding技术由来已久,很多海量数据系统在其发展演进的历程中都曾经历过分库分表的Sharding改造阶段。简单地说,Sharding就是将原来单一数据库按照一定的规则进行切分,把数据分散到多台物理机(我们称之为Shard)上存储,从而突破单机限制,使系统能以Scale-Out的方式应对不断上涨的海量数据,但是这种切分对上层应用来说是透明的,多个物理上分布的数据库在逻辑上依然是一个库。实现Sharding需要解决一系列关键的技术问题,这些问题主要包括:切分策略、节点路由、全局主键生成、跨节点排序/分组/表关联、多数据源事务处理和数据库扩容等。关于这些问题可以参考笔者的博客专栏http://blog.csdn.net/column/details/sharding.html 本文将重点围绕“数据库扩容”进行深入讨论,并提出一种允许自由规划并能避免数据迁移和修改路由代码的Sharding扩容方案。

 

Sharding扩容——系统维护不能承受之重

 

任何Sharding系统,在上线运行一段时间后,数据就会积累到当前节点规模所能承载的上限,此时就需要对数据库进行扩容了,也就是增加新的物理结点来分摊数据。如果系统使用的是基于ID进行散列的路由方式,那么团队需要根据新的节点规模重新计算所有数据应处的目标Shard,并将其迁移过去,这对团队来说无疑是一个巨大的维护负担;而如果系统是按增量区间进行路由(如每1千万条数据或是每一个月的数据存放在一个节点上 ),虽然可以避免数据的迁移,却有可能带来“热点”问题,也就是近期系统的读写都集中在最新创建的节点上(很多系统都有此类特点:新生数据的读写频率明显高于旧有数据),从而影响了系统性能。面对这种两难的处境,Sharding扩容显得异常困难。

 

一般来说,“理想”的扩容方案应该努力满足以下几个要求:

  1.  最好不迁移数据 (无论如何,数据迁移都是一个让团队压力山大的问题)
  2. 允许根据硬件资源自由规划扩容规模和节点存储负载
  3. 能均匀的分布数据读写,避免“热点”问题
  4. 保证对已经达到存储上限的节点不再写入数据

 

目前,能够避免数据迁移的优秀方案并不多,相对可行的有两种,一种是维护一张记录数据ID和目标Shard对应关系的映射表,写入时,数据都写入新扩容的Shard,同时将ID和目标节点写入映射表,读取时,先查映射表,找到目标Shard后再执行查询。该方案简单有效,但是读写数据都需要访问两次数据库,且映射表本身也极易成为性能瓶颈。为此系统不得不引入分布式缓存来缓存映射表数据,但是这样也无法避免在写入时访问两次数据库,同时大量映射数据对缓存资源的消耗以及专门为此而引入分布式缓存的代价都是需要权衡的问题。另一种方案来自淘宝综合业务平台团队,它利用对2的倍数取余具有向前兼容的特性(如对4取余得1的数对2取余也是1)来分配数据,避免了行级别的数据迁移,但是依然需要进行表级别的迁移,同时对扩容规模和分表数量都有限制。总得来说,这些方案都不是十分的理想,多多少少都存在一些缺点,这也从一个侧面反映出了Sharding扩容的难度。

 

取长补短,兼容并包——一种理想的Sharding扩容方案

 

如前文所述,Sharding扩容与系统采用的路由规则密切相关:基于散列的路由能均匀地分布数据,但却需要数据迁移,同时也无法避免对达到上限的节点不再写入新数据;基于增量区间的路由天然不存在数据迁移和向某一节点无上限写入数据的问题,但却存在“热点”困扰。我们设计方案的初衷就是希望能结合两种路由规则的优势,摒弃各自的劣势,创造出一种接近“理想”状态的扩容方式,而这种方式简单概括起来就是:全局按增量区间分布数据,使用增量扩容,无数据迁移,局部使用散列方式分散数据读写,解决“热点”问题,同时对Sharding拓扑结构进行建模,使用一致的路由算法,扩容时只需追加节点数据,不再修改散列逻辑代码。

 

原理

 

首先,作为方案的基石,为了能使系统感知到Shard并基于Shard的分布进行路由计算,我们需要建立一个可以描述Sharding拓扑结构的编程模型。按照一般的切分原则,一个单一的数据库会首先进行垂直切分,垂直切分只是将关系密切的表划分在一起,我们把这样分出的一组表称为一个Partition。 接下来,如果Partition里的表数据量很大且增速迅猛,就再进行水平切分,水平切分会将一张表的数据按增量区间或散列方式分散到多个Shard上存储。在我们的方案里,我们使用增量区间与散列相结合的方式,全局上,数据按增量区间分布,但是每个增量区间并不是按照某个Shard的存储规模划分的,而是根据一组Shard的存储总量来确定的,我们把这样的一组Shard称为一个ShardGroup,局部上,也就是一个ShardGroup内,记录会再按散列方式均匀分布到组内各Shard上。这样,一条数据的路由会先根据其ID所处的区间确定ShardGroup,然后再通过散列命中ShardGroup内的某个目标Shard。在每次扩容时,我们会引入一组新的Shard,组成一个新的ShardGroup,为其分配增量区间并标记为“可写入”,同时将原有ShardGroup标记为“不可写入”,于是新生数据就会写入新的ShardGroup,旧有数据不需要迁移。同时,在ShardGroup内部各Shard之间使用散列方式分布数据读写,进而又避免了“热点”问题。最后,在Shard内部,当单表数据达到一定上限时,表的读写性能就开始大幅下滑,但是整个数据库并没有达到存储和负载的上限,为了充分发挥服务器的性能,我们通常会新建多张结构一样的表,并在新表上继续写入数据,我们把这样的表称为“分段表”(Fragment Table)。不过,引入分段表后所有的SQL在执行前都需要根据ID将其中的表名替换成真正的分段表名,这无疑增加了实现Sharding的难度,如果系统再使用了某种ORM框架,那么替换起来可能会更加困难。目前很多数据库提供一种与分段表类似的“分区”机制,但没有分段表的副作用,团队可以根据系统的实现情况在分段表和分区机制中灵活选择。总之,基于上述切分原理,我们将得到如下Sharding拓扑结构的领域模型:

 

图1. Sharding拓扑结构领域模型

 

 

在这个模型中,有几个细节需要注意:ShardGroup的writable属性用于标识该ShardGroup是否可以写入数据,一个Partition在任何时候只能有一个ShardGroup是可写的,这个ShardGroup往往是最近一次扩容引入的;startId和endId属性用于标识该ShardGroup的ID增量区间;Shard的hashValue属性用于标识该Shard节点接受哪些散列值的数据;FragmentTable的startId和endId是用于标识该分段表储存数据的ID区间。

 

确立上述模型后,我们需要通过配置文件或是在数据库中建立与之对应的表来存储节点元数据,这样,整个存储系统的拓扑结构就可以被持久化起来,系统启动时就能从配置文件或数据库中加载出当前的Sharding拓扑结构进行路由计算了(如果结点规模并不大可以使用配置文件,如果节点规模非常大,需要建立相关表结构存储这些结点元数据。从最新的Oracle发布的《面向大规模可伸缩网站基础设施的MySQL参考架构》白皮书一文的“超大型系统架构参考”章节给出的架构图中我们可以看到一种名为:Shard Catalog的专用服务器,这个其实是保存结点配置信息的数据库),扩容时只需要向对应的文件或表中加入相关的节点信息重启系统即可,不需要修改任何路由逻辑代码。

 

示例

 

让我们通过示例来了解这套方案是如何工作的。

 

阶段一:初始上线

 

假设某系统初始上线,规划为某表提供4000W条记录的存储能力,若单表存储上限为1000W条,单库存储上限为2000W条,共需2个Shard,每个Shard包含两个分段表,ShardGroup增量区间为0-4000W,按2取余分散到2个Shard上,具体规划方案如下:

图2. 初始4000W存储规模的规划方案

 

与之相适应,Sharding拓扑结构的元数据如下:

图3. 对应Sharding元数据

 

 

阶段二:系统扩容

 

经过一段时间的运行,当原表总数据逼近4000W条上限时,系统就需要扩容了。为了演示方案的灵活性,我们假设现在有三台服务器Shard2、Shard3、Shard4,其性能和存储能力表现依次为Shard2<Shard3<Shard4,我们安排Shard2储存1000W条记录,Shard3储存2000W条记录,Shard4储存3000W条记录,这样,该表的总存储能力将由扩容前的4000W条提升到10000W条,以下是详细的规划方案:

图4. 二次扩容6000W存储规模的规划方案

 

相应拓扑结构表数据下:

 

图5. 对应Sharding元数据

 

 

从这个扩容案例中我们可以看出该方案允许根据硬件情况进行灵活规划,对扩容规模和节点数量没有硬性规定,是一种非常自由的扩容方案。

 

增强

 

接下来让我们讨论一个高级话题:对“再生”存储空间的利用。对于大多数系统来说,历史数据较为稳定,被更新或是删除的概率并不高,反映到数据库上就是历史Shard的数据量基本保持恒定,但也不排除某些系统其数据有同等的删除概率,甚至是越老的数据被删除的可能性越大,这样反映到数据库上就是历史Shard随着时间的推移,数据量会持续下降,在经历了一段时间后,节点就会腾出很大一部分存储空间,我们把这样的存储空间叫“再生”存储空间,如何有效利用再生存储空间是这些系统在设计扩容方案时需要特别考虑的。回到我们的方案,实际上我们只需要在现有基础上进行一个简单的升级就可以实现对再生存储空间的利用,升级的关键就是将过去ShardGroup和FragmentTable的单一的ID区间提升为多重ID区间。为此我们把ShardGroup和FragmentTable的ID区间属性抽离出来,分别用ShardGroupInterval和FragmentTableIdInterval表示,并和它们保持一对多关系。

 

图6. 增强后的Sharding拓扑结构领域模型

 

 

让我们还是通过一个示例来了解升级后的方案是如何工作的。

 

阶段三:不扩容,重复利用再生存储空间

 

假设系统又经过一段时间的运行之后,二次扩容的6000W条存储空间即将耗尽,但是由于系统自身的特点,早期的很多数据被删除,Shard0和Shard1又各自腾出了一半的存储空间,于是ShardGroup0总计有2000W条的存储空间可以重新利用。为此,我们重新将ShardGroup0标记为writable=true,并给它追加一段ID区间:10000W-12000W,进而得到如下规划方案:

图7. 重复利用2000W再生存储空间的规划方案

 

 

相应拓扑结构的元数据如下:

图8. 对应Sharding元数据

 

小结

 

这套方案综合利用了增量区间和散列两种路由方式的优势,避免了数据迁移和“热点”问题,同时,它对Sharding拓扑结构建模,使用了一致的路由算法,从而避免了扩容时修改路由代码,是一种理想的Sharding扩容方案。

分享到:
评论

相关推荐

    毕业设计:基于SSM的mysql-羽毛球交流平台系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_羽毛球交流平台系统(源码 + 数据库 + 说明文档) 2 关键技术介绍 6 2.1 JSP技术概述 6 2.2 MYSQL简介 6 2.3 B/S结构 7 2.4 JAVA语言 8 2.5 MyEclipse简介 9 2.6 性能分析 9 2.7 SSM概述 10 3 需求分析与设计 11 3.1 系统需求分析 11 3.2 运行可行性 11 3.3 系统可行性分析 11 3.3.1 技术可行性 11 3.3.2 经济可行性 12 3.3.3 操作可行性 12 3.4 系统功能分析 12 3.5 系统功能结构图 13 3.6 系统流程分析 14 4 数据库设计 17 4.1数据库逻辑结构设计 17 4.2数据库物理结构设计 20 5 系统的详细设计与实现 25 5.1首页页面 25 5.2站内新闻页面 25 5.3场地列表页面 26 5.4场地详情页面 26 5.5在线留言页面 27 5.6修改密码页面 27 5.7注册用户管理信息页面 28 5.8场地信息管理页面 28 5.9场地预约管理页面 29 5.10评论信息管理页面 29 5.11添加友情链

    node-v10.15.1-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    VLT 变频器工程指南 danfoss

    VLT 变频器工程指南 Guía de funcionamiento Safe Torque off Convertidores de frecuencia VLT

    基于Java的C语言试题生成与考试系统的设计与实现(源代码+论文)

    基于Java的C语言试题生成与考试系统的设计与实现是一个毕业设计题目,旨在通过使用Java编程语言设计和开发一个功能完善的C语言试题生成与考试系统。 该毕业设计题目的背景和意义在于,随着计算机科学的不断发展,C语言作为一门基础编程语言,被广泛应用于软件开发、系统编程等领域。为了更好地评估学生对C语言的掌握程度,传统的纸质试卷已经无法满足需求,因此,开发一个基于Java的C语言试题生成与考试系统具有重要的实际意义。 该毕业设计题目的主要研究内容包括以下几个方面:首先,需要进行系统需求分析,明确系统的功能需求和技术要求。然后,需要进行系统设计,包括数据库设计、模块划分、算法设计等。接下来,需要使用Java编程语言进行系统开发,包括前端界面开发、后台逻辑实现、数据库操作等。最后,需要进行系统测试和优化,确保系统的稳定性和可靠性。 通过完成该毕业设计题目,学生可以深入学习和掌握Java编程语言,提高软件开发能力。同时,学生还可以学习和了解C语言的相关知识,以及试题生成和考试系统的设计与实现方法。这对于学生未来的职业发展具有积极的推动作用。

    毕业设计:基于SSM的mysql-智能图书馆导航系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_智能图书馆导航系统(源码 + 数据库 + 说明文档) 2 系统总体设计 1 2.1 需求调研 1 2.2系统功能性需求 2 2.3可行性分析 3 2.2.1经济可行性 3 2.2.2技术可行性 3 2.2.3操作可行性 4 2.4功能性需求分析 4 2.5本章小结 5 第3章 系统设计 6 3.1设计的思路 6 3.2系统结构设计 6 3系统功能结构 6 3.3数据库设计 7 3.3.1数据库设计概述 7 3.3.2概念设计 8 3.3.3表设计 9 3.4业务功能设计与实现 11 3.4.1查询功能的设计与实现 11 3.4.2借阅功能的设计与实现 12 第四章 系统实现 14 4.1 系统登录页面实现 14 4.2管理员操作界面实现 14 4.3 图书管理实现 15 4.4读者表管理实现 17 4.5 借还管理实现 17 4.6图书借阅实现 18 4.7我的借还信息实现 18 第五章 系统测试 20 5.1系统测试环境 20 5.2系统单元测试 20 5.3集成测试 20 5.4测试用例 21 5.5 性能测试 21 5.6 测试结果分析 22

    毕业设计:基于SSM的mysql-学习交流平台(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学习交流平台(源码 + 数据库 + 说明文档) 第二章 需求分析 5 2.1需求调研 5 2.2可行性分析 6 2.2.1技术的可行性 6 2.2.2经济的可行性 6 2.2.3操作可行性 6 2.2.4法律的可行性 7 2.3系统用户用例图 7 2.3.1管理员用例图 7 2.4功能模块需求分析 7 2.5设计的基本思想 9 2.6性能需求 9 2.6.1系统的安全性 9 2.6.2数据的完整性 9 2.7界面需求 10 2.7非功能性需求分析 11 2.7.1端到端响应时间 11 2.7.2易用性需求 11 2.7.3 可扩展性 11 第三章 系统分析与设计 12 3.1数据库的分析与设计 12 3.1.1数据库的概念结构设计 13 3.1.2数据库的逻辑结构设计 14 第四章 系统功能实现 17 4.1系统登陆页面实现 17 4.2总体功能模块 18 4.2.1注册用户信息管理 19 4.2.2学习资讯管理信息管理 20 4.2.3文章发表管理 21 4.2.4公告信息管理 22 4.2.5留言信息管理 22 4.2.6修改密码 23 4.2.

    基于JAVA的RSA文件加密软件的设计与实现(源代码+论文).rar

    本资料包名为“基于JAVA的RSA文件加密软件的设计与实现”,是一个针对计算机专业学习者提供的实用资源。它包含了完整的Java源代码以及一篇详细的论文,旨在帮助用户深入理解并实践RSA加密算法在文件加密领域的应用。该源码是基于Java语言开发的,利用了Java平台的安全和网络特性,实现了一个简单而强大的RSA文件加密工具。通过这个工具,用户可以对任意文本或数据文件进行加密和解密操作,确保信息传输的安全性。代码结构清晰,注释齐全,便于学习和修改。配套的论文则详细介绍了整个项目的设计理念、开发过程、关键技术点以及可能的改进方向。它从理论到实践,逐步引导读者了解RSA加密原理,并通过实例演示如何在Java环境中实现这一算法。无论是对于正在学习密码学、网络安全或是Java编程的学生,还是对于需要实现文件加密功能的开发者来说,这份资料包都是一份宝贵的学习资源。它不仅提供了现成的解决方案,更开辟了一条探索信息安全和Java编程深层次结合的道路。重新回答||

    毕业设计:基于SSM的mysql-学生网上请假系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学生网上请假系统(源码 + 数据库 + 说明文档) 第2章 主要技术和工具介绍 5 2.1 SSM 框架 5 2.1.1. Spring 框架 5 2.1.2 SpringMVC 6 2.1.3. MyBatis 的选用 6 2.2 mysql数据库 6 2.3eclipse与Tomcat简介 6 第3章 系统分析 4 3.1可行性分析 4 3.1.1经济可行性 4 3.1.2技术可行性 4 3.1.3操作可行性 4 3.2需求分析 4 3.3业务流程分析 5 3.4数据流程分析 5 第4章 系统设计 8 4.1系统结构设计 8 4.2功能模块设计 8 4.3数据库设计 9 4.3.1数据库设计概述 9 4.3.1概念设计 9 4.3.2表设计 11 第5章 系统实现 15 5.1基本论坛 15 5.2主页面的实现 15 5.3登录模块的实现 16 5.4班级信息管理模块的实现 17 5.6基础信息模块的实现 18 5.6用户权限管理模块的实现 19 5.7学生请假管理模块的实现 22 第6章 系统测试 23 6.1测试目的 23 6.2测试概述

    MFC,C++-简单学生成绩管理系统.zip

    学生成绩管理系统c

    node-v8.5.0-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar

    基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar

    M24LC04B EEPROM的Verilog行为模型

    M24LC04B EEPROM的Verilog行为模型

    node-v12.5.0-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2023商业银行数据资产体系白皮书,主要介绍了“三位一体”数据资产体系的构成与工作机制,以及商业银行数据资产体系建设实践

    2023商业银行数据资产体系白皮书 目录 第 1 章 数据资产化与数据要素市场化相辅相成,相互促进 第 2 章 数据资产化是企业数据治理向上演进的必经之路 第 3 章 数据资产体系发展概述 第 4 章 “三位一体”数据资产体系的构思 4.1“三位一体”数据资产体系的构成与工作机制 数据资产管理 数据资产运营 数据资产评价 数据资产体系工作机制 4.2“三位一体”数据资产体系的相互作用关系 4.3“三位一体”数据资产体系的构建 4.4“三位一体”数据资产体系的优势 第 5 章 商业银行数据资产体系建设实践 5.1商业银行开展数据资产体系建设的背景和目标 5.2商业银行数据资产体系建设的工作步骤 5.3上海银行数据资产体系建设实践的主要成果 第 6 章 数据要素流通市场赋能企业数据资产化 6.1全国多层次数据要素市场的建设 6.2上海数据交易所赋能企业数据资产化 6.3数据要素流通交易市场赋能企业数据资产化的展望 第 7 章 未来演进与展望

    基于matlab实现wsn路由,用matlab仿真,具有选簇的功能.rar

    基于matlab实现wsn路由,用matlab仿真,具有选簇的功能.rar

    什么是学生成绩管理系统c++以及学习学生成绩管理系统的意义

    学生成绩管理系统c++

    Dubins曲线算法讲解和在运动规划中的使用.pdf

    Dubins曲线算法讲解和在运动规划中的使用.pdf

    基于TOGAF的4A企业架构规划方法论.pptx

    基于TOGAF的4A企业架构规划方法论.pptx

Global site tag (gtag.js) - Google Analytics