1. 简介

本来想写一篇可伸缩性架构方面的文章,发现东西太多了,久久未能下笔,这里首先把大家最关注的数据切分(Partition/Sharding)方面的内容先写完,给大家参考。

我们知道,为了应对不断增长的数据,我们对数据进行切分,存储在不同的数据库里,本文提到的数据库在非特定指明的情况下,均指一个逻辑数据库(是一组数据库,比如Master-Slave),而非单一各个物理数据库。

其主要有两种方式:

  • 垂直切分(Vertical Partition/Sharding):就是把不同格式的数据,存储到不同的数据库。
  • 水平切分(Horizontal Partition/Sharding):就是把相同的数据格式的数据,存储到不同的数据库,本文将侧重这点进行讲述。

2. 垂直切分(Vertical Partition/Sharding)

对于垂直切分,其实应用非常广泛,主旨是把那些关系依赖非常紧密的数据保存到同一数据库,主要包含如下几种应用方式:

  • 不同的应用使用不同数据库:这个非常容易理解,即对于一个企业来讲,往往有多个应用,甚至有些应用逐渐演变成两个或者多个应用,这其实就是一种垂直切分应用。
  •  应用的不同模块使用不同的数据库:为同一应用的不同模块分别使用不同的数据库,之间提供低耦合的API进行访问。
  • 同一应用相同模块使用不同数据库:在一些应用中,对于适合关系查询的数据,保存在关系数据库,而另外一些适合以NoSQL数据库保存的数据(例如key-value数据库),保存在NoSQL数据库中,方便数据扩展。这里给出一个例子,比如一个论坛应用,可以对个人用户信息保存在关系数据库,例如,其访问次数,个人信息等等,而对于发表的帖子和回帖,则可以保存在一个NoSQL里,方便扩展。注意,这里给出的例子并非真实例子,只是为了易于说明给出一个假设性的例子。

3. 水平切分(Horizontal Partition/Sharding)

水平切分相对比较复杂,我们还是从水平切分的策略谈起。

3.1     水平切分策略主要分为以下几种:

1.     Round-Robin(轮询式)算法

顾名思义,就是把数据按照轮流的方式依次存放在的数据库节点上,比如,有2个节点,N0和N1,那么Data0放在N0节点上,Data1放在N1上,Data2放在N0上,依次类推……。

这种方式实现起来非常容易,对于数字键,我们有:n = key mod N。其中,key为数据的键,N为节点的数量,n为存放数据的节点编号;对于那些非数字键,我们可以让其转变为数字键,比如通过某些hash函数,让键值均匀分布,于是有:n = f (key) mod N。

这种方式有个缺点非常明显,不容易应对数据节点的变化,即不易进行二次切分。所谓二次分片是指,当数据的增长超过数据库容量时,需要增加数据库,或者系统故障导致某些数据库不能使用时,这时需要重新切分数据库。例如,有两个节点,N0和N1,现在需要增加一个节点N2,这时候,都需要吧N0上的数据和N1上的数据迁移到N2上,这个工作量是巨大的;并且可能导致上层应用对数据的改变,比如,之前数据Data5存储在N1上面,上层应用访问该数据时,根据key=5知道其存储在数据库N1里,那么便会在N1里查询数据,现在增加另外一个节点N2,那么这条数据被迁移到N2上了,上层应用就应该去N2上查询此数据了,这个看似简单,其实往往导致应用程序的复杂性很高。

2.     虚拟分片技术

为了保证二次分片时,避免对上层应用因为实际物理数据库发生改变而引起对数据访问逻辑的改变,中间加入了一个虚拟片段—物理片段映射表,数据对象存储在虚拟分片上,每个虚拟片段通过这个映射表找到相应的物理片段。这时间,上层应用依赖于虚拟分片,而非物理分片,只要保证虚拟片段足够多,就能避免上层应用的依赖。

3.     一致性Hash算法

为了避免数据库数量发生变化,引起大规模的数据迁移问题,而引入了一致性Hash算法。此算法由David Karger等人发表于1997年,论文题目为《Consistent hashing and random trees: distributed caching protocols for relieving hot spots on the World Wide Web》,这里有一篇文章讲述Java语言简单实现一致性Hash算法http://weblogs.java.net/blog/2007/11/27/consistent-hashing

一致性Hash算法的主要思想是不改变Hash函数本身,当减少节点时,临近的节点接手该节点,因此,消失节点上的数据迁移只迁移到临近节点上面;而增加节点时,只接手其临近的一个节点的部分数据,因此,只有一部分临近节点的数据被迁移至新加节点。

我们来详细了解一下具体实现:我们的Hash函数生成的数据都有一个值区间[min,max],我们把该区间用一个环来表示,每个节点的hash值都映射到这个环上,如下图所示:

假设我们的值区间是[1,12],我们有三个节点,1,4,9,数据的键也映射到这个环上,a的键值介于1~4之间,则存储在节点4上,即按照顺时针方向存储数据,同样b存储于节点9,而c存储于节点1。

假设节点4不可用时,那么数据a就会被迁移至节点9,其他节点的数据不发生迁移,如下图所示:

假设增加节点7,那么将把节点9上的部分数据迁移至节点7,其他节点数据不发生改变,如下图所示:

4.     按照数据的特点进行切分数据

最常见的就是按照地理位置切分数据,那么我们按照用户的注册信息或者用户数据提交的ip地址等来把它们放置于离它们地理位置最近的数据库中。

3.2 实际应用

在真实的应用中,往往会结合这些策略,甚至提供更为抽象的接口让开发人员实现适合自己的切分方法。我们这里讲述Mongodb和Hibernate Shards的分片方式。

3.2.1       Mongodb Sharding

Mongo db是基于文档的NoSQL数据库,查询方式和关系数据库非常接近。

Mongodb把数据存放在称为Chuncks数据结构上面,Chunck的默认大小是64M,每个Chunck上面存储一定切分范围的数据,当数据超过64M时,会自行分裂成两个Chunks,相当于一致性Hash算法添加了一个节点,只是这个节点不是DB。而每台物理db(称为Shard)上含有多个Chunks,为了达到更好的负载均衡,这些物理db上的Chunks会自动迁移,使得db上的Chunks发布均衡。

3.2.2       Hibernate Shards

Hibernate Shards是在Hibernate Core上做的一层扩展,目的是在关系数据库上封装和降低水平切分的复杂性。

Hibernate Shards为开发者提供了抽象接口,开发人员可以实现自己想要的切分策略,为了避免物理数据库发生改变引起应用程序的改变,其采用虚拟分片技术。

Hibernate Shards参考中文文档请参见:http://redhat.iteye.com/blog/328032

3.3  应注意的问题

水平切分数据库之后,会给查询造成一定的困难,特别是Aggregation查询。Mongodb采用Map/Reduce方式,能够比较高效进行Aggregation查询。

4        总结

对于大规模,可伸缩,海量数据的应用,数据切分是其架构必须考虑的一个重点内容,我们在进行数据切分时,往往采用先垂直,再水平方式对数据分片。

转自:

可伸缩架构常用技术--数据切分

可伸缩性架构常用技术——之数据切分 Data Sharding/Partition的更多相关文章

  1. MySql(十四):MySql架构设计——可扩展性设计之数据切分

    一.前言 通过 MySQL Replication 功能所实现的扩展总是会受到数据库大小的限制,一旦数据库过于庞大,尤其是当写入过于频繁,很难由一台主机支撑的时候,我们还是会面临到扩展瓶颈.这时候,我 ...

  2. MySQL性能调优与架构设计——第 14 章 可扩展性设计之数据切分

    第 14 章 可扩展性设计之数据切分 前言 通过 MySQL Replication 功能所实现的扩展总是会受到数据库大小的限制,一旦数据库过于庞大,尤其是当写入过于频繁,很难由一台主机支撑的时候,我 ...

  3. [翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data Access Techniques)

    Performance Comparison: Data Access Techniques Priya DhawanMicrosoft Developer Network January 2002 ...

  4. 全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等

    本文来自腾讯QQ技术团队工程师许灵锋.周海发的技术分享. 一.引言 自 2015 年春节以来,QQ 春节红包经历了企业红包(2015 年).刷一刷红包(2016 年)和 AR 红包(2017 年)几个 ...

  5. 从产业链、架构和技术三个层面,看元宇宙与RPA的发展关系

    你可能还不知道,元宇宙也将带动RPA高速发展 一文读懂RPA如何赋能元宇宙,虚拟空间更需要RPA无处不在 三个层面,解读元宇宙如何利好RPA行业发展 从产业链.架构和技术三个层面,看元宇宙与RPA的发 ...

  6. Mycat 数据切分 看这一篇就够了

    数据切分 ​ 数据切分指的是通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库上面,以达到分散单台设备负载的效果. ​ 数据的切分根据其切分规则的类型,可以分为两种切分模式.一种 ...

  7. Android无线开发的几种常用技术(阿里巴巴资深工程师原创分享)

    完整的开发一个android移动App需要经过从分解需求.架构设计到开发调试.测试.上线发布等多个阶段,在发布后还会有产品功能上的迭代演进,此外还会面对性能.安全.无线网络质量等多方面的问题. 移动A ...

  8. React.js 常用技术要点

    最近在公司的一个移动端WEB产品中使用了React这个框架(并不是React-Native),记录一下在开发过程中遇到的各种问题以及对应的解决方法,希望能对读者有所帮助. React原则 React不 ...

  9. [原创].NET 分布式架构开发实战之三 数据访问深入一点的思考

    原文:[原创].NET 分布式架构开发实战之三 数据访问深入一点的思考 .NET 分布式架构开发实战之三 数据访问深入一点的思考 前言:首先,感谢园子里的朋友对文章的支持,感谢大家,希望本系列的文章能 ...

随机推荐

  1. layui 框架 table插件 实现键盘快捷键 切换单元格编辑

    最近使用layui的框架时,发现table插件不支持键盘快捷键切换单元格,花了点时间实现此功能. 分享给有需要的朋友们~~~ 效果图 代码: 1.支持 enter,上,下,右键 切换单元格,支持隐藏列 ...

  2. Windows安装MySQL5.7教程

    导读: 我们日常学习可能会需要在本地安装MySQL服务,也遇到过小伙伴探讨关于Windows系统安装MySQL的问题.在这里建议大家安装MySQL5.7版本,当然想尝试8.0版本的同学也可以参考安装. ...

  3. Spring— 用更优雅的方式发HTTP请求(RestTemplate详解)

    RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率. 我之前的HTTP开发是用ap ...

  4. thymeleaf模板、thymeleaf语法相关中文文档教程

    thymeleaf模板在SpringBoot中是默认的模范引擎技术,SpringBoot不推荐使用比较老旧的jsp.但如果您想使用jsp的话,当然也可以.我这里为您讲述thymeleaf模板的基本th ...

  5. Pthon魔术方法(Magic Methods)-可视化

    Pthon魔术方法(Magic Methods)-可视化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.关于可视化的魔术方法简介 __str__: str()函数,format ...

  6. docker动态修改端口映射(考虑生产环境)

    今天需要修改一个容器A的外部映射的端口,在宿主机上跑着许多容器,所以在解决这个问题的时候需要考虑两个硬性条件: 1.宿主机上docker的service服务本身不能重启,影响其他线上容器. 2.该容器 ...

  7. Maven之setting.xml 配置详解

    文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${use ...

  8. 微信小程序~事件绑定和冒泡

    [1]事件绑定和冒泡 事件绑定的写法同组件的属性,以 key.value 的形式. key 以bind或catch开头,然后跟上事件的类型,如bindtap.catchtouchstart.自基础库版 ...

  9. 微信小程序~TabBar底部导航切换栏

    底部导航栏这个功能是非常常见的一个功能,基本上一个完成的app,都会存在一个导航栏,那么微信小程序的导航栏该怎么实现呢?经过无数的踩坑,终于实现了,好了,先看看效果图. 对于底部导航栏,小程序上给出的 ...

  10. python开发总结

    1.思维缜密的编程逻辑 2.满足明确的目的需求 3.运用现成的轮子加以改造 4.学会装饰自己的程序 5.化繁为简 6.多用配置文件作为入口 7.注意扩展兼容