分布式系统中主键生成策略

1、为什么要全局分布式ID

  1. 在复杂的分布式系统中,需要对大量的数据和消息进行唯一标识,
  2. 对数据分库分表后需要有一个唯一ID来标识一条数据或消息,方便未来能够分库分表

2、ID生成规则部分硬性要求

2.1、全局唯一

不能出现重复的ID号

2.2、趋势递增

在Mysql的InnoDb引擎中使用的是聚集索引,有序的主键能保证写入性能。

2.3、单调递增

保证下一个ID一定大于上一个ID

2.4、信息安全:

如果ID是连续的,恶意用户的扒取工作就很容易了,直接按顺序下载指定的URL就行,如果订单号就更危险了,竞争对手可以直接知道我们一天的单量。所以在一些应用场景下,需要ID无规则,让竞争对手不好猜。

2.5、含时间戳

让我们知道这个ID在什么时候生成的。

3、ID生成系统的可用性要求

3.1、高可用

发一个获取分布式ID的请求同,服务器要保证100%的情况下给我们创建一个唯一的分布式ID

3.2、低延时

毫秒级的生成,如,一毫秒生成4096个

3.3、高QPS(Queries-per-second每秒查询率)

4、通用的解决方案

4.1、自增ID:auto_increment

使用数据库的自动增长(auto_increment),是比较简单和常见的ID生成方案,数据库内部可以确保生成id的唯一性。

优点:
  1. 数据库自动编号,速度快,而且是增量增长,聚集型主键按顺序存放,对于检索非常有利。
  2. 数字型,占用空间小,易排序,在程序中传递方便。
缺点
  1. 不支持水平分片架构,不能保证全局唯一,有主键冲突风险。
  2. 对数据库有依赖,每种数据库可能实现不一样,数据库切换时候,涉及到代码的修改,不利于

4.2、数据库自增主键:replace into

replace into 作用

replace into首先尝试插入数据列表中,如果发现表中已有的此行数据(根据主键或唯一索引判断),则先删除,再插入。否则直接插入新数据。

REPLACE INTO 的含义是插入一行记录,如查表中唯一索引的值遇到冲突,则替换老数据。

CREATE TABLE t_test(
    id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    stub CHAR(1) NOT NULL DEFAULT '',
    UNIQUE KEY stub (stub)
);

REPLACE INTO t_test(stub) values('x');


步骤1:创建一个表 u,id 自增长
CREATE TABLE u(
    id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    stub CHAR(1) NOT NULL DEFAULT '',
    UNIQUE KEY stub (stub)
);
  

步骤2:所有插入操作的主键id,都通过对u表插入操作来获取。
//如果x冲突,x对应数据删除,新增一个(x,id+1)的数据
REPLACE INTO t_test(stub) values('x');


//获取当前客户端插入的主键id,也就是刚刚的id+1
SELECT LAST_INSERT_ID();
步骤3:建立统一的主键生成表(路由表)
  1. 通过一个统一的表(所有系统共享),给所有的业务表分配主键id
  2. 当如果业务压力很大,每秒都要大量的插入,可以设置N个类似u的表,主键跨步也要设置为N,这样是防止不同的u表生产的id冲突。
缺点

单机性能不够,数据库横向扩展非常麻烦

4.4、UUID

UUID(Universally Unique Identifier)的标准形式包含32个16进制的数字,以连字号分为5段,形式为8-4-4-4-12个字符,
如:941e3b9a-a6a8-43fd-8b74-d0627f12323f

优点

性能非常高:本地生成,没有网络消耗

缺点
  1. 不易于存储
    1. UUID太长,16字节128位,通常以36长度的字符串表示,很多场景不适用。
  2. 信息不安全
    1. 基于MAC地址生成UUID的算法可能会造成MAC地址泄露
    2. 这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。
  3. UUID是无序的,InnoDb引擎中使用的是聚集索引,无序的主键能会损失写入性能。
  4. MySQL官方有明确的建议主键要尽量越短越好,36个字符长度的UUID不符合要求。
  5. 对MySQL索引不利
    1. 作为数据库主键,在InnoDB引擎下,UUID的无序性可能会引起数据位置频繁变动,严重影响性能。

4.5、基于Redis生成全局主键

因为Redis是单线程原子操作可以使用incr和incrby来实现

优点

并发能力起来了,有点NB了

缺点:
  1. 代价太大
  2. redis集群扩容会出现ID不连续的问题(步长不好设置)

4.6、基于zookeeper生成全局主键

原理,使用数据的版本号

缺点

代价太大

4.7、利用hash

  1. 不同业务的表主键使用自增长,主键的跨步为N(N为数据库集群数量)

4.8、Snowflake(雪花算法,现在非常流行)

https://blog.csdn.net/zhou920786312/article/details/122201559
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值