sharding
把数据分散到多台物理机(我们称之为Shard)
实现Sharding需要解决一系列关键的技术问题,这些问题主要包括:切分策略、节点路由、全局主键生成、跨节点排序/分组/表关联、多数据源事务处理和数据库扩容等
因为表多而数据多,这时候适合使用垂直切分,把关系紧密(比如同一模块)的表切分出来放在一个server上
如果表并不多,但每张表的数据非常多,这时候适合水平切分,即把表的数据按某种规则(比如按ID散列)切分到多个数据库(server)上。
切分是按先垂直切分再水平切分的步骤进行的。
对于共享数据数据,如果是只读的字典表,每个shard里维护一份应该是一个不错的选择,这样不必打断关联关系。
跨节点Join的问题
      只要是进行切分,跨节点Join的问题是不可避免的。但是良好的设计和切分却可以减少此类情况的发生。解决这一问题的普遍做法是分两次查询实现。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。
优秀的主键生成策略:目前知道的最好的方案
不能再依赖数据库自身的主键生成机制。一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由。
思想是:建立两台以上的数据库ID生成服务器,每个服务器都有一张记录各表当前ID的Sequence表,但是Sequence中ID增长的步长是服务器的数量,起始值依次错开,这样相当于把ID的生成散列到了每个服务器节点上。
例如:如果我们设置两台数据库ID生成服务器,那么就让一台的Sequence表的ID起始值为1,每次增长步长为2,另一台的Sequence表的ID起始值为2,每次增长步长也为2,那么结果就是奇数的ID都将从第一台服务器上生成,偶数的ID都从第二台服务器上生成,这样就将生成ID的压力均匀分散到两台服务器上,同时配合应用程序的控制,当一个服务器失效后,系统能自动切换到另一个服务器上获取ID,从而保证了系统的容错。
  • 在应用服务器与数据库之间通过代理实现
在应用服务器与数据库之间加入一个代理,应用程序向数据发出的数据请求会先通过代理,代理会根据配置的路由规则,对SQL进行解析后路由到目标shard,因为这种方案对应用程序完全透明,通用性好,所以成为了很多sharding产品的选择。在这方面较为知名的产品是mysql官方的代理工具:Mysql Proxy和一款国人开发的产品:amoeba
mysql proxy本身并没有实现任何sharding逻辑,它只是作为一种面向mysql数据库的代理,给开发人员提供了一个嵌入sharding逻辑的场所,它使用lua作为编程语言,这对很多团队来说是需要考虑的一个问题。amoeba则是专门实现读写分离与sharding的代理产品,它使用非常简单,不使用任何编程语言,只需要通过xml进行配置。不过amoeba不支持事务(从应用程序发出的包含事务信息的请求到达amoeba时,事务信息会被抹去,因此,即使是单点数据访问也不会有事务存在)一直是个硬伤。当然,这要看产品的定位和设计理念,我们只能说对于那些对事务要求非常高的系统,amoeba是不适合的。
“数据库扩容”
一种允许自由规划并能避免数据迁移和修改路由代码的Sharding扩容方案:
如果系统是按增量区间进行路由(如每1千万条数据或是每一个月的数据存放在一个节点上 ),虽然可以避免数据的迁移,却有可能带来“热点”问题,也就是近期系统的读写都集中在最新创建的节点上(很多系统都有此类特点:新生数据的读写频率明显高于旧有数据),从而影响了系统性能。
理想”的扩容方案应该努力满足以下几个要求:
  1. 最好不迁移数据 (无论如何,数据迁移都是一个让团队压力山大的问题)
  2. 允许根据硬件资源自由规划扩容规模和节点存储负载
  3. 能均匀的分布数据读写,避免“热点”问题
  4. 保证对已经达到存储上限的节点不再写入数据
使用一致的路由算法,避免扩容时修改路由代码
目前,能够避免数据迁移的优秀方案并不多,相对可行的有两种,一种是维护一张记录数据ID和目标Shard对应关系的映射表,写入时,数据都写入新扩容的Shard,同时将ID和目标节点写入映射表,读取时,先查映射表,找到目标Shard后再执行查询。该方案简单有效,但是读写数据都需要访问两次数据库,且映射表本身也极易成为性能瓶颈。为此系统不得不引入分布式缓存来缓存映射表数据,但是这样也无法避免在写入时访问两次数据库,同时大量映射数据对缓存资源的消耗以及专门为此而引入分布式缓存的代价都是需要权衡的问题。另一种方案来自淘宝综合业务平台团队,它利用对2的倍数取余具有向前兼容的特性(如对4取余得1的数对2取余也是1)来分配数据,避免了行级别的数据迁移,但是依然需要进行表级别的迁移,同时对扩容规模和分表数量都有限制。总得来说,这些方案都不是十分的理想,多多少少都存在一些缺点,这也从一个侧面反映出了Sharding扩容的难度。
全局按增量区间分布数据,使用增量扩容,无数据迁移,局部使用散列方式分散数据读写,解决“热点”问题,同时对Sharding拓扑结构进行建模,使用一致的路由算法,扩容时只需追加节点数据,不再修改散列逻辑代码。
垂直切分只是将关系密切的表划分在一起,我们把这样分出的一组表称为一个Partition。
水平切分会将一张表的数据按增量区间或散列方式分散到多个Shard上存储。在我们的方案里,我们使用增量区间与散列相结合的方式,全局上,数据按增量区间分布,但是每个增量区间并不是按照某个Shard的存储规模划分的,而是根据一组Shard的存储总量来确定的,我们把这样的一组Shard称为一个ShardGroup,局部上,也就是一个ShardGroup内,记录会再按散列方式均匀分布到组内各Shard上。这样,一条数据的路由会先根据其ID所处的区间确定ShardGroup,然后再通过散列命中ShardGroup内的某个目标Shard。
在每次扩容时,我们会引入一组新的Shard,组成一个新的ShardGroup,为其分配增量区间并标记为“可写入”,同时将原有ShardGroup标记为“不可写入”,于是新生数据就会写入新的ShardGroup,旧有数据不需要迁移。同时,在ShardGroup内部各Shard之间使用散列方式分布数据读写,进而又避免了“热点”问题。
一个Partition在任何时候只能有一个ShardGroup是可写的
TODO:
1,ShardGroup的startId和endId如果超出怎么办?
SELECT id, startId,endId FROM `ShardGroup` where writeable = 1
如果id快要超出范围时,报警通知!
2,SELECT ShardId, ShardIp FROM `Shard` where ShardGroupId = 1 and hashValue = 1
3,SELECT tableName FROM `ShardTableName` where ShardId = 2 and startId = 1 and endId = 2000
现在查找到了某台shard(ShardIp)上的某个表
读写分离可以对这些ShardIp机器进行主备
现在的Id如何获取?
mysql> SHOW VARIABLES LIKE 'auto_inc%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
+--------------------------+-------+
参考

数据库分库分表sharding1的更多相关文章

  1. 分布式事务-Sharding 数据库分库分表

      Sharding (转)大型互联网站解决海量数据的常见策略 - - ITeye技术网站 阿里巴巴Cobar架构设计与实践 - 机械机电 - 道客巴巴 阿里分布式数据库服务原理与实践:沈询_文档下载 ...

  2. 数据库分库分表(sharding)系列(一) 拆分规则

    第一部分:实施策略 数据库分库分表(sharding)实施策略图解 1. 垂直切分垂直切分的依据原则是:将业务紧密,表间关联密切的表划分在一起,例如同一模块的表.结合已经准备好的数据库ER图或领域模型 ...

  3. 转数据库分库分表(sharding)系列(二) 全局主键生成策略

    本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请参考该系列的前一篇文章:数据库分库分表( ...

  4. 转数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示

    本文原文连接: http://blog.csdn.net/bluishglc/article/details/7696085 ,转载请注明出处!本文着重介绍sharding切分策略,如果你对数据库sh ...

  5. 当当开源sharding-jdbc,轻量级数据库分库分表中间件

    近期,当当开源了数据库分库分表中间件sharding-jdbc. Sharding-JDBC是当当应用框架ddframe中,从关系型数据库模块dd-rdb中分离出来的数据库水平分片框架,实现透明化数据 ...

  6. 数据库分库分表(sharding)系列【转】

    原文地址:http://www.uml.org.cn/sjjm/201211212.asp数据库分库分表(sharding)系列 目录; (一) 拆分实施策略和示例演示 (二) 全局主键生成策略 (三 ...

  7. 数据库分库分表(sharding)系列(二) 全局主键生成策略

    本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请参考该系列的前一篇文章:数据库分库分表( ...

  8. 数据库分库分表(sharding)系列(一)拆分实施策略和示例演示

    本文原文连接: http://blog.csdn.net/bluishglc/article/details/7696085 ,转载请注明出处!本文着重介绍sharding切分策略,如果你对数据库sh ...

  9. 数据库分库分表(sharding)系列

    数据库分库分表(sharding)系列     目录; (一) 拆分实施策略和示例演示 (二) 全局主键生成策略 (三) 关于使用框架还是自主开发以及sharding实现层面的考量 (四) 多数据源的 ...

随机推荐

  1. Ditto - Windows剪贴板增强小工具,方便复制粘贴多条记录

    在平时的工作中,好多地方需要重复的复制粘帖一些重复性的代码,频繁的Ctrl+C.Ctrl+V导致效率很低,而且时间长了会很烦,Windows自带的剪切板功能一次只能进行一条记录操作,单一的不行,与提高 ...

  2. EF没有同步更新(转)

    不知道这算不算一个bug,当你新建一个从数据库生成的edmx时,他能正确的生成所有的tt文件,但是当你从数据库更新表结构时,他不能正确的更新tt文件,以建立Model1.edmx为例,在解决方案中展开 ...

  3. objective-c字典

     1 //        初始化一个空字典  2 //        NSDictionary *dictionary = [[NSDictionary alloc] init];  3 //     ...

  4. 网站上点击自定义按钮发起QQ聊天的解决方案

    一.背景 最近由于开发需要,需要在网站上自定义一个立即交谈的按钮,现将解决方式分享给大家. 二.解决方案 1.首先访问:http://shang.qq.com/widget/consult.php,适 ...

  5. Linux Shell常用快捷键

    ctrl+a[A]:将光标移到命令行开头 ctrl+e[E]:将光标移到命令行结尾 ctrl+c[C]:强制终止命令执行 ctrl+u[U]:删除/剪切光标之前的所有字符 ctrl+y[Y]:粘贴ct ...

  6. 有关Java的优秀博客集锦

    1. 在java编程中,多线程并发总有些疑惑:如为什么会产生并发?并发会有什么影响?java中提供了哪些处理并发的技术(机制) 关于并发产生的原因,我查了一些资料目前发现有两种原因:一,存在共享的资源 ...

  7. fork与vfork的区别与联系

    fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1. fork ():子进程拷贝父进程的数据段,代码段 vfork ( ):子进程与父进程共享数据段 2. fo ...

  8. Codeforces Round #344 (Div. 2)(按位或运算)

    Blake is a CEO of a large company called "Blake Technologies". He loves his company very m ...

  9. 关于快捷键 Ctrl+Alt+[方向键] 的知识

    在用PS作图时使用 Ctrl+Alt+[方向键]  组合建时屏幕莫名翻转, 平时电脑懒得维护所以略卡,我不会说一般早上起床摁了开机去上完厕所回来还--咳咳 刚按下时瞬间一黑,再黑,,继续黑--真是大吃 ...

  10. 第二课 less的学习以及移动端需要注意的问题

    一.LESS的学习笔记: 1.less介绍:一种动态样式语言.less将css赋予了动态语言的特性,如变量,继承,运算,函数,less既可以在客户端上运行(支持IE6+,webkit,firefox) ...