lua实现雪花算法
- 雪花算法介绍
- 组成部分
- 优点
- 缺点
- 代码示例
雪花算法介绍
雪花算法(Snowflake Algorithm)是一种用于生成唯一ID的分布式生成算法,最初由Twitter开发。它的主要目的是在分布式系统中生成唯一的、时间有序的ID,这些ID通常用于数据库的主键或在分布式系统中的各种唯一标识符,雪花算法被广泛应用于各种需要生成唯一ID的场景,如分布式数据库、消息队列、分布式缓存系统等
雪花算法生成的ID是一个64位的整数,通常表示为:
41 bits: 时间戳(毫秒级)
10 bits: 机器ID
12 bits: 序列号
组成部分
- 时间戳(41 bits):
- 记录了从某个特定时间(通常是系统启动或某个固定时间点)以来的毫秒数
- 41位的时间戳可以支持大约69年的时间范围
- 机器ID(10 bits):
- 用于标识生成ID的机器
- 10位可以标识1024台不同的机器
- 序列号(12 bits):
- 在同一毫秒内生成的多个ID时,用于区分这些ID
- 12位可以支持每毫秒最多生成4096个唯一的ID
优点
- 唯一性:通过组合时间戳、机器ID和序列号,确保生成的ID在分布式系统中是唯一的
- 时间有序:ID是按时间顺序生成的,方便排序和查询
- 高效:生成ID的过程只需要进行简单的位运算,非常高效
缺点
- 时钟同步问题:如果系统时钟回拨,可能会导致ID冲突。通常需要处理时钟回拨的问题
- 机器ID分配:需要确保每台机器的ID是唯一的
代码示例
-- 定义常量
-- local TIMESTAMP_BITS = 41
local MACHINE_ID_BITS = 10
local SEQUENCE_BITS = 12-- 时间戳起始时间(毫秒),例如从2020-01-01 00:00:00开始
local EPOCH = 1577836800000-- 计算掩码
-- local MAX_MACHINE_ID = (1 << MACHINE_ID_BITS) - 1
local MAX_SEQUENCE = (1 << SEQUENCE_BITS) - 1-- 机器ID(0到1023之间)
local machine_id = 123-- 序列号
local sequence = 0
local last_timestamp = -1-- 获取当前时间戳(毫秒)
local function get_current_time()return os.time() * 1000
end-- 等待下一毫秒
local function wait_for_next_millisecond(last_timestamp)local timestamp = get_current_time()while timestamp <= last_timestamp dotimestamp = get_current_time()endreturn timestamp
end-- 生成雪花ID
local function next_id()local timestamp = get_current_time()-- 处理时钟回拨问题if timestamp < last_timestamp thenerror("Clock moved backwards. Refusing to generate id for " .. (last_timestamp - timestamp) .. " milliseconds")endif timestamp == last_timestamp thensequence = (sequence + 1) & MAX_SEQUENCEif sequence == 0 thentimestamp = wait_for_next_millisecond(last_timestamp)endelsesequence = 0endlast_timestamp = timestamp-- 计算时间戳部分local timestamp_left_shift = MACHINE_ID_BITS + SEQUENCE_BITSlocal timestamp_part = ((timestamp - EPOCH) << timestamp_left_shift)-- 计算机器ID部分local machine_id_shift = SEQUENCE_BITSlocal machine_id_part = (machine_id << machine_id_shift)-- 组合生成IDlocal id = timestamp_part | machine_id_part | sequencereturn id
end