Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > Redis分布式唯一ID生成器

Redis分布式唯一ID生成器的实现

作者:Leon_Jinhai_Sun

本文主要介绍了Redis分布式唯一ID生成器的实现,利用Redis原子操作和数据库事务,实现高并发下的全局唯一编号,具有一定的参考价值,感兴趣的可以了解一下

我来详细解释这个代码,这是一个分布式ID生成器的实现。

第一部分:代码结构分析

1. 正则表达式

NON_NUMBER = re.compile(r"[^0-9]")

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. 分布式安全

2. 可追溯性

self.msg = u"item_type={}, trace_uuid={}, name={}"

3. 容错处理

第六部分:实际调用示例

# 生成用户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生成器,具有以下特点:

  1. 高并发支持:通过Redis原子操作处理并发
  2. 数据一致性:数据库+Redis双重保障
  3. 可扩展性:按item_type分区,不同业务独立序列
  4. 可维护性:完整的日志追踪和错误处理
  5. 容错性:失败重试机制,防止数据丢失

这种设计常用于电商、金融、物流等需要生成唯一业务编号的系统,能够保证在分布式环境下生成全局唯一的递增ID。

到此这篇关于Redis分布式唯一ID生成器的实现的文章就介绍到这了,更多相关Redis分布式唯一ID生成器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文