Redis连接DB0查到DB3数据之谜
在开发或者运维的时候你可能遇到过这样的问题“我连的明明是 Redis 的 DB0为什么执行KEYS *会看到本来应该在 DB3 的数据”看起来很奇怪其实这和 Redis 的部署方式有关系。下面我们就从原理讲起用实际例子说清楚这个问题。一、Redis 多数据库是怎么回事在单机Standalone模式下Redis 默认有16 个逻辑数据库编号是db0到db15。你可以通过配置文件里的databases参数改这个数量。每个数据库都有自己的键空间也就是说在 DB0 里写SET user:1 Alice在 DB3 里写SET user:1 Bob这两个 key 不会互相影响。你可以用SELECT 编号来切换当前用的是哪个数据库127.0.0.1:6379 SELECT 3 OK 127.0.0.1:6379[3] SET test hello OK二、为什么连 DB0 却能看到 DB3 的数据具体情况比如你用客户端连上 Redis然后运行127.0.0.1:6379 KEYS * 1) session:abc 2) cache:user:123 3) temp:data你记得这些 key 是在 DB3 里存的但现在没切到 DB3怎么还能查到真正原因你用的是 Redis 集群Cluster模式在Redis Cluster 模式下只支持 DB0所有SELECT命令都会报错127.0.0.1:7000 SELECT 3 (error) ERR SELECT is not allowed in cluster mode而且集群模式根本没有 DB1、DB2……DB15 这些东西所有数据都放在同一个地方——就是 DB0。所以你“以为”把数据写进了 DB3其实全都写到了 DB0。自然在 DB0 就能查到它们。三、为什么 Redis 集群不支持多个数据库这是因为 Redis 集群用了槽位slot分片的方式来管理数据。所有 key 被分成16384 个槽每个 key 用CRC16(key) % 16384算出属于哪个槽槽被分配到不同节点上实现分布式存储如果允许多个数据库就会出问题同一个 key比如user:1在 DB0 和 DB3 里会算出一样的槽号但它们其实是不同的数据这样就乱了节点迁移、备份、恢复这些操作也会变得很难处理所以Redis 官方直接在代码里禁止了集群模式下的多数据库功能。源码里写得很清楚In cluster mode, only DB0 is allowed.四、什么时候可以用多数据库部署方式能不能用多个 DB建议单机 Redis✅ 可以可以用来分开开发、测试等环境比如 DB0开发DB1测试主从复制✅ 可以主库的所有 DB 都会同步到从库Sentinel 高可用✅ 可以因为基于主从也支持多 DBRedis Cluster❌只能用 DB0不要用 SELECT所有数据都在 DB0建议做法在集群环境下如果要分开不同用途的数据请用key 加前缀的方法比如user:123、order:456不要靠换数据库。五、怎么排查这个问题如果你发现 DB0 里有“DB3 的数据”可以这样做先看是不是集群模式CLUSTER INFO如果有返回内容说明是集群。检查你的代码是不是以为切到了 DB3但其实没成功在集群里用SELECT会报错要看看有没有忽略这个错误。查一下数据是怎么写进去的可以临时用MONITOR注意会影响性能或者看日志确认写 key 的时候到底在哪个 DB。六、总结一下单机 RedisDB0 到 DB15 是分开的SELECT有用。Redis Cluster只有 DB0所有数据都在一起。所谓“在 DB0 查到 DB3 的数据”其实是数据根本没进 DB3全在 DB0。用集群时要用key 前缀来区分不同类型的数据不要依赖数据库编号。搞懂这一点既能避免数据混乱也能在面试时清楚回答“为什么 Redis 集群只能用 DB0”