提高基于DB的ID生成性能方案-IDSnowman

提高基于DB的ID生成性能方案-IDSnowman_第1张图片
ID Snow Man

背景:

分布式需求下的ID生成方案有很多种。但满足以下条件的不多:
1、除现有的DB外,不增加运维负担和不增加基础设施的资源要求
2、ID大体趋势递增(实际情况中一般不需要严格递增,即使是用AUTO_INCREMENT字段,也因事务提交顺序和rollback问题不会严格递增)
3、ID种子状态需要持久化

词汇:

OSP:唯品会服务化基础平台
Saturn:唯品会分布式JOB平台
VMS:唯品会MQ平台

基于AUTO_INCREMENT字段的方案

基于现有应用环境,用DB实现以上需求可能是比较简单的方案。
基于mysql的持久化和协调,可以有两个方案:
1、建立带AUTO_INCREMENT字段的表,用AUTO_INCREMENT机制生成ID。
有两个子方案:
1a:获取ID时,insert into 然后 last_insert_id
1b:加入唯一索引字段,获取ID时,replace into(唯一字段名) values ('重复的唯一字段值') 然后 last_insert_id。

方案1b的好处是保证数据库中只有和行记录,不需要定期归档数据。
基于AUTO_INCREMENT字段问题是:在高并发情况下生成ID相关的并发数、TPS数要求与数据一致。在业务已经分库,但ID生成没分库的情况下,势必成为瓶颈。
解决方法是:
1、把AUTO_INCREMENT字段的表也分库,按一定策略路由ID生成请求到不同的库。库与库进行ID号的隔离,方法可以是:
a. AUTO_INCREMENT中不同的大初始号段
b. AUTO_INCREMENT相同步长(如32),不同的初始值
以上分库方法的问题是可能使ID大体趋势不是递增。

批量号段派发方案-IDSnowman

如果应用和DB的一次交互可以拿到一批连续ID,而且拿到ID有使用有效期。这样既可以减少DB TPS、并发、连接数,也可以提高ID的生成的平均时效。

DB表结构

CREATE TABLE `sequence_table` (
    `biz_type` VARCHAR(50) NOT NULL COMMENT '业务类型',
    `cur_id` BIGINT(20) NOT NULL COMMENT '当前值',
    `step` INT(11) NOT NULL COMMENT '步长',
    `time_to_live` INT(11) NOT NULL COMMENT '生存时长(秒)',
    PRIMARY KEY (`biz_type`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

架构设计

提高基于DB的ID生成性能方案-IDSnowman_第2张图片
架构图

说明:
每个应用的业务线程池中,维护一个线程本地变量,IDBuffer,其结构大体如下:

线程本地ID Buffer : [
占用相关: {batch_max_id=800, cur_id=601, birthday="20170115 03:02:01"}
调整相关:{……}]

每个业务类型记录其当前批次的最大值,当前值,批次发放时间。

具体的实时顺序图:

提高基于DB的ID生成性能方案-IDSnowman_第3张图片
具体的实时顺序图

说明:
ID生成库使用与业务分享独立的DB连接池,DB连接的事务为autocommit=1。即不使用事务。
注意到其中的LAST_INSERT_ID(cur_id + Step) 。函数为设计DB连接的会话本地last_insert_id变量,不影响其它会话(见:http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id)。

这样,DB的TPS、并发、连接数可以因批次步长和批次有效时间的大小而数倍下降。ID也大体趋势递增。
封装方法
可以封装为OSP服务(好处是减少DB连接数)。或一个公共JAR(好处是减少运行服务依赖),由应用控制DB连接池。

单点问题 single point of failure (SPOF)

由DB决定。为DBA保障。

封装讨论

实现上,是否真有需要跨表的唯一顺序ID生成需求。这是值得考虑的。如果没有这个需求,事情可以简单很多。

[参考文章]

http://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/
http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id
https://my.oschina.net/CandyDesire/blog/619122
http://tech.meituan.com/mtddl.html

提高基于DB的ID生成性能方案-IDSnowman_第4张图片
ID Snow Man

你可能感兴趣的:(提高基于DB的ID生成性能方案-IDSnowman)