投递文章投递文章 投稿指南 RSS订阅RSS订阅

数据库水平分割中的ID生成器设计

来源:IT堂 堂友 发布时间:2011-12-21 收藏 投稿 字体:【

概述

ID生成器独立成一个数据库,数据库名称为:id_generator。数据库中的表设计原则是每一个表对应一个需要获取ID的外部表,不允许多个需要获取ID的外部表共用一个ID生成器里面的一个表。表名的规则是:id_[external_table_names],表的结构如:

CREATE TABLE `id_user` (
`AutoID` INT(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`AutoID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=1

 

 

实现原理

 

ID生成器的程序建立在每个应用服务器的数据访问层DAL中,也就是说每台应用服务器中的ID生成器程序都是一个独立完整体。

ID生成器中内部维护着一个“先进先出”的队列,此队列也起到缓存作用,每次调用ID生成器获取ID时,就从队列取出一个ID给调用者。

ID生成器初始化时,会先向数据库批量写入500次,然后取出最后写入的500个ID,接着写入“先进先出”的队列,供调用者使用。当队列为空了,将再次向数据库写入500次取出最后写入的500个ID写入队列,如此循环。

 

技术要点说明

 

为保证每次批量写入数据库并取出来的ID都是正确的,在批量写入数据库时需要启用数据库事务,通过数据库的事务来保证数据的正确性。

 

当某一个应用服务器重新启动了,ID生成器队列中维护的ID值也将会丢失,但这不会产生ID重复的情况,丢失的ID将是作废的,当ID生成器中队列为空了,会马上从数据库再次获取最新的一批ID回来供调用者使用。如果出现ID丢失的情况,表现出来的结果就是需要ID的目标表的主键ID值和表的总记录数值是不一致的,表的总记录数值将会比表的主键ID的数值小。

 

性能测试数据

 

场景一:1次获取获取500个ID和1000个ID的比较,1次就开启一个数据库的connection。

 

500

1000

60MS

122MS

58MS

119MS

63MS

141

 

场景二:10次获取5000个ID和10000个ID的比较,分10次依次调用,顺序的开启了10个数据库的connection。

 

5000

10000

653MS

963MS

745MS

875MS

591MS

915MS

 

场景三:5个线程分别获取500个ID和1000个ID的比较,1个线程开启1个数据库的connection。

 

500

1000

143~219MS

425~479MS

171~225MS

402~460MS

165~244MS

380~481MS

 

 

结论

从测试的数据来看,ID生成器的性能表现还是比较理想的,而且整个方案实现起来也比较简单,维护也简单。

 

顶一下
(1)
50%
踩一下
(1)
50%
本文Tags:
  • 表情:
  •    
  • 评价:
用户名: 密码: 匿名 注册
最新评论 查看所有评论
About iTtang - 联系我们  - 专题列表 - 友情链接  -  高级搜索  -  帮助中心  -  您的意见