数据水平切分后的主键全局唯一方案

作者:sky | 分类: 大话技术 | 标签: , , | 日期:2009-03-16

现在通过数据的水平切分(sharding)来实现数据库 Scale Out 的解决方案受到了越来越多人的青睐,但是在切分过程中可能遇到的问题也肯定不在少数,如切分规则的设计,切分后的访问路由,切分后的主键的全局唯一等等。

这里我主要列举几个可以使用在 MySQL 数据库主键全局唯一方案及其优劣,供大家参考:

  • 通过应用程序生成一个GUID,然后和数据一起插入切分后的集群。优点是维护简单,实现也容易。缺点是应用的计算成本较大,且GUID比较常,占用数据库存储空间较大,涉及到应用的开发。
  • 通过独立的应用程序事先在数据库中生成一系列唯一的 ID,各应用程序通过接口或者自己去读取再和数据一起插入到切分后的集群中。优点是全局唯一主键简单,维护相对容易。缺点是实现复杂,需要应用开发。
  • 通过中心数据库服务器利用数据库自身的自增类型(如 MySQL的 auto_increment 字段),或者自增对象(如 Oracle 的 Sequence)等先生成一个唯一 ID 再和数据一起插入切分后的集群。优点是?好像没有特别明显的优点。缺点是实现较为复杂,且整体可用性维系在这个中心数据库服务器上,一旦这里crash 了,所有的集群都无法进行插入操作,涉及到应用开发。
  • 通过集群编号加集群内的自增(auto_increment类型)两个字段共同组成唯一主键。优点是实现简单,维护也比较简单,对应用透明。缺点是引用关联操作相对比较复杂,需要两个字段,主键占用空间较大,在使用 InnoDB 的时候这一点的副作用很明显。
  • 通过设置每个集群中自增 ID 起始点(auto_increment_offset),将各个集群的ID进行绝对的分段来实现全局唯一。当遇到某个集群数据增长过快后,通过命令调整下 一个 ID 起始位置跳过可能存在的冲突。优点是实现简单,且比较容易根据 ID 大小直接判断出数据处在哪个集群,对应用透明。缺点是维护相对较复杂,需要高度关注各个集群 ID 增长状况。
  • 通过设置每个集群中自增 ID 起始点(auto_increment_offset)以及 ID 自增步长(auto_increment_increment),让目前每个集群的起始点错开 1,步长选择大于将来基本不可能达到的切分集群数,达到将 ID 相对分段的效果来满足全局唯一的效果。优点是实现简单,后期维护简单,对应用透明。缺点是第一次设置相对较为复杂。

除了上述方案之外,各位网友如果想到什么比较巧妙的解决方案,希望能不吝分享。

原文链接:http://www.jianzhaoyang.com/database/sharding_groups_global_pk

9人发表了评论  ↓发表评论↓
  • 俺们用的是最后一种方案. step by 3.

    木匠Charlie @ March 17, 2009 |

  • 谢谢SKY,学习了

    0537 @ March 17, 2009 |

  • 谢谢~国内愿意分享的人太少了。

    Willko @ March 21, 2009 |

  • 我们在对用户表进行水平切分时遇到这样的问题:
    我们预先创建了table_count个表,分别为user_0,user_1,user_2,…
    对于一个新注册的用户,我们通过hash(”someone@domain.com”) % table_count这样的算法决定要将这个用户插入到哪张表。
    但是考虑到以后我们增加了表,user表数变成了new_table_count。这时再用上面的算法就很大可能someone@domain.com映射到另一个表去了,导致登录时找不到该用户。
    我们现在能想到的有可能的办法:
    1)增加表时将原来的数据重新MAP并移到新的表,但很明显这种方法不行
    2)到每个表去找
    后来我们改进了一下,用Consistent Hashing来映射email地址,减少了MAP的变动,但是还是有部分数据需要移动。

    不知道你们是怎么解决这个问题,或者是通过其它途径来决定新注册的用户要加入到哪张表。

    Cykit @ March 25, 2009 |

  • 想到的另一个可能的方法:用BerkeleyDB存储emial到id的一个反向索引。

    Cykit @ March 25, 2009 |

  • 我投票给最后一个.不过要是再切一次呢?
    可以最后一个方案+倒数第二个方案.

    可扩展性比较好.

    MyZ @ April 5, 2009 |

  • 对了,楼上的某人怎么有头像?

    MyZ @ April 5, 2009 |

  • 我回了一个,有时间可以看看
    http://blog.csdn.net/marising/archive/2009/04/17/4087871.aspx

    map @ April 17, 2009 |

  • 有头像是不是因为用了Gravatar?

    flmn @ March 25, 2010 |

表情:<( ̄︶ ̄)> | (⊙ˍ⊙) | >﹏< | b( ̄▽ ̄)d | (─.─||) | (^_-)

[ Ctrl+Enter提交 ]

DBA