键值设计
key 设计
- 遵循基本格式:[业务名称]:[数据名]:[id]。
- 长度不超过44字节。key是string类型,底层编码包含int、embstr和raw三种。在小于44字节会使用embstr,采用连续内存空间。
- 不包含特殊字符。
value 设计
- 合理的拆分数据,拒绝BigKey。
- 选择合适数据结构。
- Hash结构的entry数量不要超过1000。
- 设置合理的超时时间。
拒绝 BigKey
- 类型:
- String 类型的 value 超过 1MB。
- 复合类型(List、Hash、Set、Sorted Set 等)的 value 包含的元素超过 5000 个。
- 危害:

- 如何发现BigKey
- 使用 Redis 自带的
--bigkeys
参数来查找。这种方式只能找出每种数据结构 top 1 bigkey。 - 使用 Redis 自带的 SCAN 命令。
- 借助开源工具分析 RDB 文件。前提是你的 Redis 采用的是 RDB 持久化。
- 借助公有云的 Redis 分析服务。
- 如何处理BigKey
- 分割 bigkey:将一个 bigkey 分割为多个小 key。例如,将一个含有上万字段数量的 Hash 按照一定策略(比如二次哈希)拆分为多个 Hash。
- 手动清理:Redis 4.0+ 可以使用 UNLINK 命令来异步删除一个或多个指定的 key。Redis 4.0 以下可以考虑使用 SCAN 命令结合 DEL 命令来分批次删除。
- 采用合适的数据结构:例如,文件二进制数据不使用 String 保存、使用 HyperLogLog 统计页面 UV、Bitmap 保存状态信息(0/1)。
- 开启 lazy-free(惰性删除/延迟释放):lazy-free 特性是 Redis 4.0 开始引入的,指的是让 Redis 采用异步方式延迟释放 key 使用的内存,将该操作交给单独的子线程处理,避免阻塞主线程。
批处理
- 使用批量操作可以减少网络传输次数,进而有效减小网络开销,大幅减少 RTT。
原生批量操作命令
- Redis 中有一些原生支持批量操作的命令,比如:
MGET
(获取一个或多个指定 key 的值)、MSET
(设置一个或多个指定 key 的值)HMGET
(获取指定哈希表中一个或者多个指定字段的值)、HMSET
(同时将一个或多个 field-value 对设置到指定哈希表中)SADD
(向指定集合添加一个或多个元素)
Pipeline
MSET
等虽然可以批处理,但是却只能操作部分数据类型,因此如果有对复杂数据类型的批处理需要,建议使用Pipeline功能。- 原生批量操作命令是原子操作,pipeline 是非原子操作。
- pipeline 可以打包不同的命令,原生批量操作命令不可以。
- 原生批量操作命令是 Redis 服务端支持实现的,而 pipeline 需要服务端和客户端的共同实现。
集群下的批处理
- MSET或Pipeline这样的批处理需要在一次请求中携带多条命令,而此时如果Redis是一个集群,那批处理命令的多个key必须落在一个插槽中,否则就会导致执行失败。

安全问题:配合 SSH key 文件实现 Redis 未授权访问
- Redis 默认绑定在0.0.0.0:6379且未启用认证(AUTH)时,攻击者可远程连接并执行高危命令。
- Redis 默认监听端口6379,若服务器配置为绑定所有网络接口(bind 0.0.0.0),且防火墙未限制该端口的访问,则 Redis 服务会直接暴露在公网或内网中。攻击者无需通过SSH或其他方式登录目标服务器,只需知道目标服务器的 IP 地址和 Redis 端口(默认6379),即可通过网络直接连接到 Redis 服务。
- 流程:
- 攻击者在本地生成 id_rsa(私钥)和 id_rsa.pub(公钥)用于后续攻击。
- 构造公钥文件 foo.txt。
- 连接 Redis,将公钥内容作为键值存入 Redis。
- 修改Redis持久化配置:
- 设置备份目录为 /root/.ssh(其实这是SSH密钥默认存储路径)。
- 设置备份文件名为 authorized_keys(其实这是SSH公钥文件名)。
- 执行 save 命令触发持久化,将内存数据写入目标文件。
- 使用私钥直接登录目标服务器:
ssh -i id_rsa root@<target-ip>
,若公钥成功写入且权限正确,攻击者可绕过密码认证获得root权限。
- 核心漏洞:
- Redis 未设置密码。
- 使用了 Root 账号权限启动Redis,使得攻击者可以覆盖/root/.ssh/authorized_keys文件。
- 应对方法:
- Redis一定要设置密码。
- 不要使用Root账户启动Redis。
- 尽量不是有默认的端口。
- 禁止线上使用 keys、flushall、flushdb、config set等命令,可以通过 rename-command 禁用。
- 网络隔离:
- 将Redis绑定到内网IP(bind 127.0.0.1),禁止公网暴露。
- 使用防火墙限制仅允许可信IP访问Redis端口。