我来详细解释这个代码,这是一个分布式id生成器的实现。
第一部分:代码结构分析
1. 正则表达式
non_number = re.compile(r"[^0-9]")
- 作用:匹配所有非数字字符
- 示例:
"abc123"→ 匹配到"a"、“b”、“c” - 用途:清理字符串中的非数字字符,确保纯数字处理
2. 类定义
class referencegenerator3(object):
这是一个分布式唯一id生成器,用于在分布式系统中生成不重复的参考编号。
第二部分:核心流程解析
步骤1:确保种子在redis中
# 伪代码示例
def ensure_seed_in_redis(self):
redis_key = f"ref_seed:{self.item_type}"
if redis.exists(redis_key): # 1.1 如果redis中已存在
return true
# 1.2 从数据库加载
seed_from_db = db.query("select max(ref_seq) from ref_table where type=?", self.item_type)
if seed_from_db is none:
seed_from_db = 0
# 插入redis
redis.set(redis_key, seed_from_db)
return true
步骤2:获取下一个序列
# 伪代码示例
def get_next_seq(self):
redis_key = f"ref_counter:{self.item_type}"
# 使用redis的incr命令,原子性增加
next_seq = redis.incr(redis_key)
return next_seq
步骤3:原子更新
# 伪代码示例
def atomic_update(self, next_seq):
# 3.1 插入或更新数据库
db.execute("""
insert into ref_table (ref_id, ref_seq, type)
values (?, ?, ?)
on duplicate key update ref_seq = ?
""", new_ref_id, next_seq, self.item_type, next_seq)
# 3.2 更新种子(如果当前种子 <= 新序列)
if current_seed <= next_seq:
db.execute("update seed_table set seed = ? where type = ?",
next_seq, self.item_type)
第三部分:实际使用示例
场景:电商订单编号生成
# 初始化生成器
order_generator = referencegenerator3(
item_type=1, # 订单类型
trace_uuid="req-123", # 请求追踪id
name="order_ref" # 生成器名称
)
# 生成的redis键
# 假设站点前缀是"ecm",item_type=1
# redis_key = "ecm:ref:1"
# 数据库表结构示例
"""
create table reference_sequence (
id bigint auto_increment,
item_type int not null, -- 业务类型:1=订单,2=用户,3=商品
ref_seq bigint not null, -- 当前序列号
ref_id varchar(100), -- 生成的参考id
updated_at timestamp,
primary key (id),
unique key (item_type, ref_id)
);
create table seed_table (
item_type int primary key,
seed bigint default 0,
updated_at timestamp
);
"""
第四部分:详细运行流程
示例1:第一次生成订单号
初始状态:
- redis: 无数据
- db seed_table: {item_type: 1, seed: 0}
- db reference_sequence: 空
步骤1:确保种子
- redis不存在key,从db加载seed=0
- redis设置:"ecm:ref:1" = 0
步骤2:获取下一个序列
- redis执行 incr "ecm:ref:1" → 返回1
- next_seq = 1
步骤3:原子更新
- 插入db: (ref_id="ord202300001", ref_seq=1, item_type=1)
- 更新seed_table: seed=1 (因为0 <= 1)
示例2:并发生成(两个请求同时)
请求a: 请求b: 1. redis incr → 返回2 1. redis incr → 返回3 2. 尝试插入ref_seq=2 2. 尝试插入ref_seq=3 3. 成功 3. 成功 4. 更新seed=2 4. 更新seed=3 结果: - 订单a: ord202300002 - 订单b: ord202300003 - 无重复
第五部分:关键特性分析
1. 分布式安全
- redis incr:原子操作,避免并发冲突
- 数据库事务:确保数据一致性
- 重试机制:失败后从步骤2重试
2. 可追溯性
self.msg = u"item_type={}, trace_uuid={}, name={}"
- 包含跟踪uuid,便于问题排查
- 记录操作上下文
3. 容错处理
- 名称截断:
itruncate(name, 1024)防止过长 - redis前缀:
append_redis_prefix()统一管理 - 类型检查:
force_text()确保文本格式
第六部分:实际调用示例
# 生成用户id
user_generator = referencegenerator3(
item_type=2, # 用户类型
trace_uuid="create-user-001",
name="user_id_generator"
)
user_id = user_generator.generate() # 假设返回"usr202300001"
# 生成商品sku
product_generator = referencegenerator3(
item_type=3,
trace_uuid="import-products-2023",
name="product_sku_generator"
)
sku = product_generator.generate() # 假设返回"pro202300001"
总结
这个referencegenerator3类是一个生产级的分布式id生成器,具有以下特点:
- 高并发支持:通过redis原子操作处理并发
- 数据一致性:数据库+redis双重保障
- 可扩展性:按item_type分区,不同业务独立序列
- 可维护性:完整的日志追踪和错误处理
- 容错性:失败重试机制,防止数据丢失
这种设计常用于电商、金融、物流等需要生成唯一业务编号的系统,能够保证在分布式环境下生成全局唯一的递增id。
到此这篇关于redis分布式唯一id生成器的实现的文章就介绍到这了,更多相关redis分布式唯一id生成器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论