06-Redis开发规范与最佳实践

#redis #规范 #最佳实践 #Redisson

这篇笔记讲什么
  • 强制规范:禁用 KEYS、FLUSHALL、FLUSHDB
  • Key 设计:业务前缀 + 缩写,控制长度
  • Value 设计:高效序列化,控制大小
  • Redisson 最佳实践:Watchdog 自动续期,finally 释放锁

1. 强制规范

这几条是红线,必须遵守。搞不好就是生产事故,跟缓存问题一样严重。

规范 原因
禁用 KEYS * 全量遍历,会阻塞主线程
禁用 FLUSHALL 清空所有数据,生产事故
禁用 FLUSHDB 清空当前库,生产事故

可以在配置文件里用 rename-command 把这些命令改名或禁用:

rename-command KEYS ""
rename-command FLUSHALL ""

2. Key 设计规范

2.1 用业务前缀

格式:业务名:模块名:具体标识

# 好的
user:profile:1001
order:detail:20240323001

# 不好的
u1001
order1

用缩写控制长度,Key 越短越省内存。

2.2 控制 Key 长度

Key 太长会占用内存,建议不超过 128 字节。

3. Value 设计规范

3.1 String 类型不超过 10KB

Value 太大会影响网络传输和内存占用。

3.2 集合类型不超过 1 万个元素

Hash、List、Set、SortedSet 的元素太多,操作会变慢。

3.3 用高效的序列化方式

方式 特点
JSON 可读性好,但体积大
Protobuf 体积小,但不可读
MessagePack 体积小,速度快

4. 实例容量规范

规范 原因
不同业务分不同实例 避免互相影响,方便扩容
实例容量 2~6GB 太大 fork 慢,主从同步耗时长
只存热数据 冷数据放数据库,省内存

5. 命令使用规范

命令 建议
MONITOR 慎用,会输出所有命令,性能损耗大
全量操作(HGETALLSMEMBERS 慎用,数据量大时阻塞
过期时间 写入时必须设置,避免内存泄漏
整数共享池 0~9999 的整数会复用对象,省内存

6. Redisson 最佳实践

6.1 标准用法

String lockKey = "business_action:" + relevantId;
RLock lock = redissonClient.getLock(lockKey);
try {
    // waitTime: 等待时间,建议 3-5 秒
    // leaseTime 不传或传 -1,启用 Watchdog 自动续期
    boolean getLock = lock.tryLock(3, TimeUnit.SECONDS);
    if (!getLock) {
        log.warn("获取锁失败,key: {}", lockKey);
        throw new BizException("系统繁忙,请稍后重试");
    }
    // 执行业务逻辑
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    log.error("获取锁被中断", e);
    throw new BizException("操作中断");
} catch (Exception e) {
    log.error("业务执行异常", e);
    throw e;
} finally {
    // 必须判断是否是当前线程持有,否则会解掉别人的锁
    if (lock.isHeldByCurrentThread()) {
        lock.unlock();
    }
}

6.2 关键点

要点 说明
key 要有业务含义 针对具体资源加锁,别搞全局锁
leaseTime 传 -1 启用 Watchdog 自动续期(默认 30 秒)
finally 释放锁前判断 必须 isHeldByCurrentThread(),否则可能解掉别人的锁
waitTime 3-5 秒 等待时间别太长,避免请求堆积

6.3 Watchdog 机制

Redisson 的 Watchdog 会自动给锁续期:

如果指定了 leaseTime(不是 -1),Watchdog 不会启动,锁到期自动释放。

7. 避免 Bigkey

Bigkey 会导致:

类型 建议大小
String < 10KB
Hash < 5000 字段
List < 5000 元素
Set < 5000 元素
ZSet < 5000 元素

unlink 替代 del 删除大 key,异步删除不阻塞主线程。