唯一ID可以标识数据的唯一性,在分布式系统中生成唯一ID的方案有很多,常见的方式大概有以下三种:

依赖数据库,使用如MySQL自增列或Oracle序列等。
根据UUID生成
snowflake雪花算法

为什么使用snowflake生成ID

使用uuid生成订单号这类东西也能凑合用,但是它有着罄竹难书的“罪行”:肉眼可见,它是无序的;长度是64位数字字母随机组合的字符串,占用空间巨大;完全不具备业务属性,也就是说使用uuid你完全无法推算出它到底是干嘛的;因为无序,所以趋势递增就更不用指望了;所以用uuid生成订单号就是自杀行为,适合它的是类似生成token令牌的场景。

雪花算法(snowflake)是Twitter开源的分布式ID生成算法,结果是一个long型的ID。为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序,让twitter可以通过一定的索引来进行检索,而在Twitter庞大的分布式系统中不同机器产生的id必须又必须不同。它的好处显而易见,不仅全局唯一,并且有序按时间递增,同时占用空间少,生成的id仅仅是19位的整形数字,正好契合mysql的bigint数据类型,简直完美。

核心思想

其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号,最后还有一个符号位,永远是0。
组成:
snowflake组成

优势

整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。 可以根据自身业务特性分配bit位,非常灵活。

缺陷

强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。

安装库

1
pip install pysnowflake

开启服务

1
snowflake_start_server --work=1

下载和启动服务

1
2
指定端口开启服务
snowflake_start_server --work=1 --port=端口号

指定端口

服务信息

1
2
3
4
5
6
import snowflake.client

print(snowflake.client.get_stats())

#worker是服务信息,time是时间戳
#{'dc': 0, 'worker': 1, 'timestamp': 1592131606294, 'last_timestamp': 550281600000, 'sequence': 0, 'sequence_overload': 0, 'errors': 0}

获取ID

1
2
3
4
5
import snowflake.client

print(snowflake.client.get_guid())

#4369836784469676033

根据ID反解析服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import snowflake.client

sid = snowflake.client.get_guid()
print(sid)
#ID:4369838396760133633
bid = bin(sid)
print(bid)
#第一位是标识符,此后是41位的时间戳,紧接着10位的节点标识码,最后12位的递增序列,
# 从后面数12位是:000000000001,再数5位是:00001 这5位就是某个节点的存储标识,我们就二进制的00001转换为十进制
#0b11110010100100110010001101111010010100110000000001000000000001
cid = bin(sid)[47:52]
print('存储节点',cid)
#存储节点 00001
print('反解析服务',int(cid,2))
#反解析服务 1

使用bigint存储

在使用好处显而易见,不仅全局唯一,并且有序按时间递增,同时占用空间少,生成的id仅仅是19位的整形数字,正好契合mysql的bigint数据类型,简直完美。
但是使用bigint有个bug,就是19位数字传到前端会发生关于js数字精度丢失问题。
关于精度丢失问题

评论





载入天数...载入时分秒...

Blog content follows the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License

Use WZH as theme, total visits times