2. Redis错误码体系概述:常见Redis错误码分类
在搜索服务的集成测试中,Redis作为缓存层和会话存储层,其错误码的准确断言是验证系统健壮性的关键环节。Redis错误码体系遵循“前缀+数字”的规范结构,通过错误前缀即可快速定位故障域。本章系统梳理集成测试中最常遇到的四类Redis错误码,为后续断言策略奠定基础。
测试要点:集成测试中,不要仅断言“是否返回错误”,而应通过错误码前缀区分故障类型,从而验证搜索服务在不同Redis异常下的降级与重试逻辑是否正确。
2.1 错误码分类总览
Redis错误码按故障来源可分为连接错误、超时错误、数据错误和命令错误四大类。下表列出了各类的核心特征与典型错误码:
| 分类 | 错误前缀 | 典型错误码 | 触发场景 |
|---|---|---|---|
| 连接错误 | NOAUTH / READONLY / MASTERDOWN | NOAUTH Authentication required | 认证失败、只读副本写入、主节点宕机 |
| 超时错误 | TIMEOUT | READ TIMEOUT / CONNECT TIMEOUT | 网络延迟、连接池耗尽、慢查询阻塞 |
| 数据错误 | WRONGTYPE / OOM / LOADING | WRONGTYPE Operation against a key holding the wrong kind of value | 类型不匹配、内存超限、持久化加载中 |
| 命令错误 | ERR / NOSCRIPT / BUSYGROUP | ERR unknown command / NOSCRIPT No matching script | 命令不存在、脚本未加载、消费组冲突 |
搜索服务关联:在搜索服务的集成测试中,连接错误和超时错误是最常见的断言目标,它们直接影响搜索请求的缓存命中率与响应时间SLA。
2.2 连接错误
连接错误发生在客户端与Redis服务器建立或维持TCP连接的过程中。在搜索服务中,当Redis连接池配置不当或网络分区发生时,此类错误会频繁出现。
- NOAUTH:未提供密码或密码错误。测试中应验证搜索服务启动时是否携带正确的
requirepass。 - READONLY:向只读副本执行写操作。搜索服务的缓存写入逻辑必须路由到主节点。
- MASTERDOWN:主节点宕机且无自动故障转移。集成测试应模拟主节点不可用,验证服务是否触发降级。
- CLUSTERDOWN:集群模式中部分哈希槽不可用。测试需覆盖集群分片故障场景。
// 集成测试中连接错误断言示例(Java + Jedis)
try {
jedis.set("search:query:test", "result");
} catch (JedisNoAuthException e) {
assertTrue(e.getMessage().contains("NOAUTH"));
// 验证服务已记录认证失败日志并触发重连
} catch (JedisConnectionException e) {
assertTrue(e.getMessage().contains("Connection refused"));
// 验证服务已切换至本地缓存降级
}
2.3 超时错误
超时错误是搜索服务集成测试中最需要关注的性能类错误。Redis客户端通过connectTimeout、readTimeout和poolMaxWait三个参数控制超时行为。
| 超时类型 | 默认值(常见客户端) | 搜索服务影响 | 测试断言策略 |
|---|---|---|---|
| 连接超时 | 2s | 搜索请求排队,响应时间飙升 | 断言抛出JedisConnectionException,验证重试次数 |
| 读取超时 | 2s | 缓存查询失败,回源数据库 | 断言抛出JedisDataException,验证降级日志 |
| 连接池等待超时 | 3s | 请求被拒绝,返回服务不可用 | 断言抛出JedisPoolException,验证熔断状态 |
常见陷阱:集成测试中,超时错误往往被笼统地断言为“连接失败”。正确的做法是区分连接超时与读取超时,因为搜索服务对两者的降级策略不同——连接超时触发重试,读取超时触发缓存穿透保护。
2.4 数据错误
数据错误源于对Redis数据结构的误操作或资源限制。搜索服务中,缓存键的类型管理和内存水位监控是预防此类错误的关键。
- WRONGTYPE:对已存在的键执行了不兼容的操作。例如,将一个Hash类型的缓存键当作List来
LPUSH。测试中应使用TYPE命令前置校验。 - OOM:内存使用超过
maxmemory限制,且淘汰策略无法释放空间。集成测试应构造大键场景,验证服务是否触发OOM并优雅降级。 - LOADING:Redis正在加载持久化文件(RDB/AOF),暂时无法服务。测试需模拟重启加载阶段,验证搜索请求是否被缓存穿透保护拦截。
// 数据错误断言:WRONGTYPE
try {
// 假设缓存键 "search:hot:list" 已被设置为 String 类型
jedis.lpush("search:hot:list", "item1");
} catch (JedisDataException e) {
assertTrue(e.getMessage().startsWith("WRONGTYPE"));
// 验证服务已清除错误缓存键并重建
}
2.5 命令错误
命令错误通常由客户端发送了Redis不支持的指令或参数格式错误引起。在搜索服务的集成测试中,这类错误多出现在Lua脚本和Stream消费组的使用场景。
| 错误码 | 含义 | 搜索服务典型场景 |
|---|---|---|
| ERR unknown command | 命令不存在 | 使用了Redis 6.0+ 的新命令但连接的是旧版本 |
| ERR wrong number of arguments | 参数数量错误 | 缓存更新脚本参数传递不完整 |
| NOSCRIPT | 脚本未加载 | 使用EVALSHA但脚本未通过SCRIPT LOAD注册 |
| BUSYGROUP | 消费组已存在 | 重复创建Stream消费组导致冲突 |
测试技巧:对于命令错误,集成测试应优先使用
ERR前缀进行模糊匹配,因为错误消息的后半部分可能因Redis版本不同而略有差异。例如:assertTrue(e.getMessage().startsWith("ERR"))。
2.6 错误码分类关系图
下图展示了四类Redis错误码在搜索服务集成测试中的层次关系与典型断言路径:
2.7 错误码断言优先级矩阵
在搜索服务的集成测试中,不同错误码的断言优先级不同。下表给出了基于影响范围和发生频率的优先级排序:
| 优先级 | 错误码 | 影响范围 | 发生频率 | 测试覆盖要求 |
|---|---|---|---|---|
| P0 | READ TIMEOUT / CONNECT TIMEOUT | 全局搜索请求 | 高 | 必须覆盖,断言超时后降级 |
| P0 | NOAUTH / MASTERDOWN | 全局连接中断 | 中 | 必须覆盖,断言重连机制 |
| P1 | WRONGTYPE / OOM | 单缓存键 | 中 | 建议覆盖,断言缓存重建 |
| P1 | ERR / NOSCRIPT | 单命令/脚本 | 低 | 建议覆盖,断言参数校验 |
| P2 | READONLY / BUSYGROUP | 特定拓扑场景 | 低 | 按需覆盖,断言配置正确性 |
测试设计原则:P0级别的错误码必须在每个搜索服务版本的集成测试套件中覆盖,且断言逻辑应包含错误码前缀匹配和服务行为验证(如降级日志、熔断状态、重试次数)两个维度。