您的位置:首页 > 数据库

数据库分库分表规约

2014-07-16 23:35 169 查看

数据库分库分表规约

提问者:mynewdreams(ID:193405) | 悬赏 0.0 希赛币 | 回答数:0 | 关注度:14 | 提问时间:2014-06-27

数据库分库分表规则

  from:

  一般有几个目标:

  1. 数据离散性,数据分布到多个库,多个表中

  mod, round robin, dayofweek,dayofMonth

  2. 避免热点数据在一个数据库库表上

  3. 扩容时有大的数据迁移

  以下的解决方案基于 整表搬迁但不会有表中行级数据迁移

  阶段一:一个库DB0之内分4个表,id%4

  dbRule: “DB0"

  tbRule: “t” + (id % 4)

  阶段二:增加db1库,t2和t3整表搬迁到db1

  dbRule: “DB" + ((id%4)/2)

  tbRule: “t” + (id % 4)

  阶段三:增加DB2和DB3库,t1整表搬迁到DB2,t3整表搬迁的DB3:

  为了规则表达,通过内部名称映射或其他方式,我们将DB1和DB2的名称和位置互换得到下图

  dbRule: “DB" + (id%4)

  tbRule: “t” + (id % 4)

  如果更进一步数据库的设计和部署上能做到每个表一个硬盘,那么扩容的过程只要把原有机器的某一块硬盘拔下来,

插入到新的机器上,就完成整表搬迁了!可以大大缩短停机时间。

  具体在mysql上可以以库为表。开始一个物理机上启动4个数据库实例,每次倍增机器,直接将库搬迁到新的机器上。

这样从始至终规则都不需要变化,一直都是:

  dbRule: “DB” + (id % 4)

tbRule: “t” + (id % 4)

  不足是:

  即逻辑上始终保持4库4表,每个表一个库。

  从一个库到4个库的过程中,单表的数据量一直在增长。当单表的数据量超过一定范围时,可能会带来性能问题。比如索引的问题,历史数据清理的问题。

另外当开始预留的表个数用尽,到了4物理库每库1个表的阶段,再进行扩容的话,不可避免的要从表上下手。

  阶段一:一个数据库,两个表

  分库规则dbRule: “DB0″

分表规则tbRule: “t” + (id % 2)

  阶段二:当单库的数据量接近1千万,单表的数据量接近500万时,进行扩容(数据量只是举例,具体扩容量要根据数据库和实际压力状况决定):

增加一个数据库DB1,将DB0.t1整表迁移到新库DB1。

每个库各增加1个表,未来10M-20M的数据mod2分别写入这2个表:t0_1,t1_1:

  分库规则dbRule:

  “DB” + (id % 2)

  分表规则tbRule:

  if(id < 1千万){ return "t"+ (id % 2); //1千万之前的数据,仍然放在t0和t1表。t1表从DB0搬迁到DB1库 }else if(id < 2千万){ return "t"+ (id % 2) +"_1"; //1千万之后的数据,各放到两个库的两个表中: t0_1,t1_1 }else{ throw new IllegalArgumentException("id outof range[20000000]:" + id); }

  这样10M以后的新生数据会均匀分布在DB0和DB1; 插入更新和查询热点仍然能够在每个库中均匀分布。

每个库中同时有老数据和不断增长的新数据。每表的数据仍然控制在500万以下。

  阶段三:当两个库的容量接近上限继续水平扩展时,进行如下操作:

新增加两个库:DB2和DB3. 以id % 4分库。余数0、1、2、3分别对应DB的下标. t0和t1不变,

将DB0.t0_1整表迁移到DB2; 将DB1.t1_1整表迁移到DB3

20M-40M的数据mod4分为4个表:t0_2,t1_2,t2_2,t3_2,分别放到4个库中:

  分库规则dbRule:

  if(id < 2千万){ //2千万之前的数据,4个表分别放到4个库 if(id < 1千万){ return "db"+ (id % 2); //原t0表仍在db0, t1表仍在db1 }else{ return "db"+ ((id % 2) +2); //原t0_1表从db0搬迁到db2; t1_1表从db1搬迁到db3 } }else if(id < 4千万){ return "db"+ (id % 4); //超过2千万的数据,平均分到4个库 }else{ throw new IllegalArgumentException("id
out of range. id:"+id); }

  分表规则tbRule:

  if(id < 2千万){ //2千万之前的数据,表规则和原先完全一样,参见阶段二 if(id < 1千万){ return "t"+ (id % 2); //1千万之前的数据,仍然放在t0和t1表 }else{ return "t"+ (id % 2) +"_1"; //1千万之后的数据,仍然放在t0_1和t1_1表 } }else if(id < 4千万){ return "t"+ (id % 4)+"_2"; //超过2千万的数据分为4个表t0_2,t1_2,t2_2,t3_2 }else{ throw
new IllegalArgumentException("id out of range. id:"+id); }

  dbRule: “DB” + (id % 4)

tbRule: “t” + (id % 4)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: