分布式——ID生成策略之数据库自增ID

参考 https://tech.meituan.com/2017/04/21/mt-leaf.html

基本原理

begin;
REPLACE INTO Tickets64 (stub) VALUES ('a');
SELECT LAST_INSERT_ID();
commit;

注:mysql可以通过auto_increment_increment和auto_increment_offset两个全局参数来设置自增步长和起始ID 

故mysql自增 ID = (N-1) * increment + offset ,N为第N条记录

参考 https://www.cnblogs.com/olinux/p/6518766.html

优点

简单,有序,不影响做ID做主键

缺点

分布式系统中存在单点瓶颈问题(配置多个代理节点获取批量ID解决),

单点可用性问题(配置主从解决,但又会引发数据一致性问题,即重号)

优化方案

1.单点读写瓶颈

通过集群部署,每设置自增步长和机器数相等,起始ID相差1,比如有3台机器ABC,则A产生ID(1,4,7,10...),B(2,5,8,11....),C(3,6,9,12...)

那么如果有N台机器,比如有N台机器ABCD...N,参考 ID = (N-1) * increment + offset = (N-1)*N+offset ,offset=(0,1,2,34,...) 生成间隔ID。

缺点:当集群数目到达一定数量,水平扩展变得非常复杂,另外,每次都需要读写数据库获取ID,造成数据库压力大。

 

Leaf-segment数据库方案

使用多个代理服务节点,每个服务节点一次性从数据库获取批量ID,即一个号段。

另外生成的ID格式还可以进一步优化(用一张表来存储ID),可以按 业务标识(biz_tag)+号段下界(max_id) 来标识某个业务的ID区间,则一个代理服务节点可批量获得这个区间的ID。

数据库表结构

+-------------+--------------+------+-----+-------------------+-----------------------------+
| Field       | Type         | Null | Key | Default           | Extra                       |
+-------------+--------------+------+-----+-------------------+-----------------------------+
| biz_tag     | varchar(128) | NO   | PRI |                   |                             |
| max_id      | bigint(20)   | NO   |     | 1                 |                             |
| step        | int(11)      | NO   |     | NULL              |                             |
| desc        | varchar(256) | YES  |     | NULL              |                             |
| update_time | timestamp    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |

根据step参数来控制每次批量生成数目,比如step=1000,根据max_id+step来计算每种业务tag的号段区间,不同tag之间互不影响,即不同tag之间的ID可以重复。

优点:

ID为8字节64位,可以做主键

容易扩展,可按业务标志分库分表进行扩容

大大降低了数据库读写频率

批量获取ID提高了系统可用性,能容忍DB短暂宕机

缺点:

号码有较强连续性,可从中获取相关业务信息,一些商业数据(比如成交记录条数),因此不安全

还达不到高并发场景的可用性,以及性能指标

优化方案:

针对高并发场景,为提高请求线程响应速度,将主动请求改为被动推送,由数据库服务器节点主动按一定条件推送新生成的批量ID给代理节点。

针对生成ID在业务上不安全的问题,可采用snowflake算法

针对DB宕机导致数据丢失,号段不连续问题,可主从备份配置

转载于:https://my.oschina.net/u/3300976/blog/3027706

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值