本文介绍访问云原生内存数据库Tair云数据库Redis版时的常见报错与解决方法。

报错概览

分类报错项
Redis通用异常
Proxy(代理模式)通用异常
Lua脚本与事务(Transaction)
Jedis客户端
Lettuce客户端
Redisson客户端
Spring Data Redis客户端
StackExchange.Redis客户端
Predis客户端
phpredis客户端
Go-redis客户端

Redis通用异常

ERR illegal address

可能原因:未将客户端的IP地址添加至Tair实例的白名单中。

解决方法:将客户端的IP地址添加入至Tair实例的白名单中,具体操作请参见连接诊断

ERR sentinel compatibility mode is disabled

可能原因:未开启Tair实例的Sentinel兼容。

解决方法:在控制台开启Sentinel兼容,具体操作请参见开启Sentinel兼容

ERR max number of clients reached

可能原因:客户端的连接数超过了Tair实例的最大连接数。

解决方法:
  • 检查客户端是否出现连接泄露,例如在Jedis客户端中,使用连接池后未调用close函数。
  • 通过实例会话查看当前连接实例的会话是否符合预期,您可以根据业务需求终止异常会话,或者通过升级实例配置,扩大连接数。

NOAUTH Authentication required

可能原因:Tair实例设置了密码鉴权,但客户端没有提供密码。

解决方法:请使用正确的账号密码进行访问,更多信息请参见Tair实例登录方式
说明 若实例使用Sentinel模式访问,请参见Sentinel兼容模式连接

WRONGPASS invalid username-password pair

可能原因:密码错误。

解决方法:请使用正确的账号密码进行访问,更多信息请参见Tair实例登录方式
说明 若实例使用Sentinel模式访问,请参见Sentinel兼容模式连接

ERR invalid password

可能原因:密码错误。

解决方法:请使用正确的账号密码进行访问,更多信息请参见Tair实例登录方式
说明 若实例使用Sentinel模式访问,请参见Sentinel兼容模式连接

Connection reset by peer

可能原因:客户端连接被关闭,通常是由于客户端缓冲区异常而关闭客户端连接。

解决方法:检查应用侧代码或调整客户端Buffer的大小,更多信息请参见Client buffer exception

UnknownHostException

failed to connect: xxx.redis.rds.aliyuncs.com could not be resolved

可能原因:客户端无法正常解析Tair实例的域名地址。

解决方案:请设置正确的DNS服务器地址,更多信息请参见解决因域名解析失败导致的连接问题

OOM command not allowed when used memory > 'maxmemory'

可能原因:Tair实例已使用的内存超过该实例的最大配置(maxmemory)。
说明 如果是Tair集群实例,可能是其中一个节点已使用的内存已超过该节点的最大配置。
解决方法:
  • 若实例的总内存使用率达到100%,建议升级实例配置,更多信息请参见升级实例配置
  • 若集群实例仅有单个节点的内存使用率达到100%,该实例中可能存在大Key,您可以通过离线全量Key分析实例诊断进行定位分析。

WRONGTYPE Operation against a key holding the wrong kind of value

可能原因:命令使用错误,例如对String数据类型执行HASH命令。

解决方法:修改错误代码或命令,更多信息请参Redis Commands

ERR unknown command 'xxx'

可能原因:Tair不存在您调用的命令。

解决方法:检查当前实例版本的命令支持情况,更多信息请参见Tair命令支持与限制
说明 最新小版本将提供更丰富的功能与稳定的服务,建议将实例的小版本升级到最新,具体操作请参见升级小版本

ERR command 'xxx' not support for your account

可能原因:阿里云禁止用户执行某些Tair命令,或您手动在#no_loose_disabled-commands参数中配置了禁止执行的命令。更多信息请参见Tair命令支持与限制禁用高风险命令

解决方法:若需执行您禁用的命令,您可以在#no_loose_disabled-commands参数中删除对应命令。

NOPERM this user has no permissions to run the 'xxx'

可能原因:阿里云禁止用户执行某些Tair命令,或您手动在#no_loose_disabled-commands参数中配置了禁止执行的命令。更多信息请参见Tair命令支持与限制禁用高风险命令

解决方法:若需执行您禁用的命令,您可以在#no_loose_disabled-commands参数中删除对应命令。

ERR FLUSHDB is not allowed in migrating mode

可能原因:Tair云盘集群架构实例在执行增加或减少数据节点时,禁止使用FLUSHDBFLUSHALL命令。

解决方法:等待Tair云盘集群架构实例执行增加或减少数据节点结束,更多信息请参见调整云盘实例的分片数量

ERR READONLY you can't write against a read only instance

可能原因:Tair实例在主备切换、升降配或小版本升级时,将出现秒级的连接闪断和30秒以内的只读状态。

解决方法:属于正常现象,实例会自动恢复,您无需进行任何操作。请提前为您的应用设计重连机制和异常处理的能力,更多信息请参见升级实例配置

Proxy(代理模式)通用异常

ERR client ip is not in whitelist

可能原因:未将客户端的IP地址添加至Tair实例的白名单中。

解决方法:将客户端的IP地址添加入至Tair实例的白名单中,具体操作请参见连接诊断

NOWRITE You can't write against a non-write redis

NOREAD You can't read against a non-read redis

可能原因:实例处于欠费或到期状态,实例状态显示为已锁定

解决方法:对账号进行充值,或对到期的实例进行续费,更多信息请参见到期与欠费

ERR syntax error

可能原因:命令语法错误,例如需要传入4个参数,实际仅传入3个参数。

解决方法:检查命令格式是否正确,更多信息请参Redis Commands

ERR no such db node

可能原因:使用阿里云自研的Tair命令时,传入的db node错误。

解决方法:传入正确的db nodedb node需小于分片数量,更多信息请参见阿里云自研的Tair命令

ERR 'xxx' command keys must in same slot

可能原因:在Tair集群架构实例中,通过事务或脚本执行命令时要求所有Key必须在同一个Slot中,否则将返回上述错误。

解决方法:改造事务或脚本,您可以通过CLUSTER KEYSLOT命令获取目标Key的Hash Slot。
重要 Tair集群架构实例会根据CRC算法将Key均匀的写入不同Slot中。若您希望将多个Key写入到一个Slot中,您可以使用Hash Tags,但该方法若使用不当容易造成数据倾斜,请谨慎使用,更多信息请参见Hash tag

ERR for redis cluster, eval/evalsha number of keys can't be negative or zero

可能原因:执行EVALEVALSHA命令未传入Key或numkeys参数的值未大于0。

解决方法:执行EVALEVALSHA命令时,至少需要传入一个Key且numkeys参数的值大于0,更多信息请参见Lua脚本基本语法

ERR request refused, too many pending request, now count xxx, beyond threshold xxx

可能原因:由于客户端使用了不合理的Pipeline,Tair后端堆积了过多未处理的Request,新请求被拒绝。

解决方法:减少Pipeline的请求数量。

ERR redis temporary failure

可能原因:部分Tair子实例访问超时,可能是网络抖动、连接数到达上限导致断链、实例正在进行主备切换或执行慢查询等导致。

解决方法:属于正常现象,实例会自动恢复,您无需进行任何操作。请提前为您的应用设计重连机制和异常处理的能力。

ERR redis temporary failure (ErrorCode 7002)

可能原因:部分Tair子实例访问超时,可能是实例正在变配或正在进行主备切换导致。

解决方法:属于正常现象,实例会自动恢复,您无需进行任何操作。请提前为您的应用设计重连机制和异常处理的能力。

Lua脚本与事务(Transaction)

NOSCRIPT No matching script. Please use EVAL.

可能原因:使用EVALSHA命令时,若SHA1值对应的脚本未缓存至Tair中。

解决方法:通过EVAL命令或SCRIPT LOAD命令将目标脚本缓存至Tair中后进行重试,更多信息请参见处理NOSCRIPT错误

BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.

可能原因:处理Lua脚本超时。

解决方法:通过SCRIPT KILL命令终止Lua脚本或等待Lua脚本执行结束,更多信息请参见处理Lua脚本超时

ERR command eval not support for normal user

可能原因:无法执行EVAL的相关命令。

解决方法:请将实例的小版本升级至最新,具体操作请参见升级小版本

ERR eval/evalsha command keys must be in same slot

可能原因:Lua脚本操作的Key不在同一个Slot(槽)中,该报错通常产生于集群实例中。

解决方法:改造Lua脚本,您可以通过CLUSTER KEYSLOT命令获取目标Key的Hash Slot,更多信息请参见集群中Lua脚本的限制

ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array

可能原因:Proxy(代理)节点的Lua脚本限制。

解决方法:所有Key都应该由KEYS数组来传递,例如EVAL "return redis.call('mget', KEYS[1], KEYS[2])" 2 foo {foo}bar,不能使用Lua变量替换KEYS,更多信息请参见集群中Lua脚本的限制

EXECABORT Transaction discarded because of previous errors

可能原因:事务中的命令执行失败,可能是命令语法错误或运行错误等。

解决方法:检查代码逻辑,修复错误命令。

Jedis客户端

Could not get a resource from the pool

可能原因:无法从连接池获取到Jedis连接。

解决方法:增大连接数或检查是否有慢查询,更多信息请参见Could not get a resource from the pool

java.net.SocketTimeoutException: connect timed out

可能原因:客户端连接Tair实例超时。

解决方法:更多信息请参见Connection timeout

java.net.SocketTimeoutException: Read timed out

可能原因:Jedis API调用超时。

解决方法:适当增大超时时间或进行实例诊断,更多信息请参见Client read /write timeout

No reachable node in cluster

可能原因:JedisCluster地址无法访问。

解决方法:如果是首次访问Tair实例,请检查是否将客户端的IP地址添加至Tair白名单中或客户端的网络情况;若不是首次访问Tair实例,可以进行实例诊断,进行问题定位。

Caused by: java.lang.NumberFormatException: For input string: "6379@13028"

可能原因:Jedis 2.8.0及以下版本引入了ClusterNodeInformationParser来解析cluster slots返回值,但Redis后续更改了此命令返回值类型,所以报错NumberFormatException

解决方法:将Jedis升级至2.9.0及以上版本。

No more cluster attempts left

可能原因:JedisCluster在API超时之后会默认重试5次(MaxAttempts,默认为5),并且在均失败之后抛出此错误。

解决方法:适当增大超时时间或进行实例诊断

Unexpected end of stream

可能原因:Jedis缓冲区异常。

解决方法:检查是否有多线程共用Jedis代码或客户端Buffer用完造成服务端断连,更多信息请参见Client buffer exception

java.lang.Long cannot be cast to java.util.List

可能原因:在多线程环境中使用Jedis,Jedis本身存在线程安全问题。

解决方法:使用JedisPool,而非Jedis,更多信息请参见JedisPool资源池优化

Broken pipe (Write failed)

可能原因:在Jedis单连接模式(未使用JedisPool)下超时后,客户端关闭了Socket,此时若您继续调用读写接口写入数据,会返回该报错。

解决方法:使用JedisPool,而非Jedis,更多信息请参见JedisPool资源池优化

No way to dispatch this command to Redis Cluster because keys have different slots

可能原因:JedisCluster操作的Key不在同一个Slot(槽)中。

解决方法:通过Hash tags对Key进行改造,更多信息请参见Hash tags
说明 您也可以使用Proxy(代理)模式屏蔽集群的限制。

Lettuce客户端

Connection to xxx not allowed. This Partition is not known in the cluster view.

可能原因:Lettuce客户端在默认情况下,配置为refreshOption = null , validateClusterNodeMembership = true,表示开启validateClusterNodeMembership检测。在Tair实例地址发生路由变化后,由于没有开启refreshOption,即不会更新路由表,此时validateClusterNodeMembership检测就会返回该报错。

解决方法:配置refreshOption选项,更多信息请参见Lettuce连接代码示例

io.lettuce.core.RedisConnectionException: Unable to connect xxx

可能原因:客户端连接Tair实例超时。

解决方法:如果是首次访问Tair实例,请检查是否将客户端的IP地址添加至Tair白名单中或客户端的网络情况;若不是首次访问Tair实例,可以进行实例诊断,进行问题定位。

java.nio.channels.UnresolvedAddressException

可能原因:大概率是Netty版本冲突。

解决方法:检查Netty依赖,建议选择较高的版本,更多信息请参见Spring-boot issues

ERR Unknown sentinel subcommand 'master'

可能原因:Lettuce在master-replica Sentinel模式下会向Redis实例发送Sentinel master/slave命令,而Tair实例在Sentinel兼容模式下仅支持Sentinel get-master-addr-by-name命令,故产生该报错。

解决方法:修改代码为普通模式(非Sentinel),Tair采用自研的高可用服务HA组件,无需Sentinel。

Redisson客户端

org.redisson.client.RedisConnectionException: Unable to connect to Redis server xxx

可能原因:客户端连接Tair实例超时。

解决方法:如果是首次访问Tair实例,请检查是否将客户端的IP地址添加至Tair白名单中或客户端的网络情况;若不是首次访问Tair实例,可以进行实例诊断,进行问题定位。

No enum constant org.redisson.cluster.ClusterNodeInfo.Flag.NOFAILOVER

可能原因:Redisson低版本Bug,更多信息请参见Redisson issue

解决方法:将Redisson升级至3.11.6及以上版本。

Spring Data Redis客户端

NOPERM this user has no permissions to run the 'config|get' command

可能原因:Spring Data Redis的KeyspaceEventMessageListener功能在服务端不支持CONFIG命令,通常在启动客户端时会产生该报错。

解决方法:可通过设置keyspaceNotificationsConfigParameter可以绕过此问题,更多信息请参见Spring Data Redis

StackExchange.Redis客户端

Multiple databases are not supported on this server; cannot switch to database

可能原因:集群架构不支持执行SELECT命令。

解决方法:将cluster_compat_enable参数设置为0(即关闭原生Redis Cluster语法兼容),具体操作请参见设置实例参数,然后重启客户端应用后重试。

Predis客户端

Error while reading line from the server.

可能原因:读取超时,您可能正在执行一个慢查询。

解决方法:适当增大超时时间或将客户端的read_write_timeout参数改为0-1,更多信息请参见Predis questions

phpredis客户端

Cannot assign requested address

可能原因:客户端通过短连接访问Tair实例时,产生该报错。

解决方法:使用pconnect替换connect的连接方式,或修改客户端所在ECS实例的tcp_max_tw_buckets内核参数,更多信息请参见Cannot assign requested address

redis protocol error, got ' ' as reply type byte

可能原因:phpredis低版本Bug,更多信息请参见phpredis issues

解决方法:将phpredis升级至最新版。

php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution

可能原因:客户端无法正常解析Tair实例的域名地址。

解决方案:请设置正确的DNS服务器地址,更多信息请参见解决因域名解析失败导致的连接问题

Go-redis客户端

panic: got 4 elements in cluster info address, expected 2 or 3

可能原因:使用的Go-redis客户端版本与Tair版本不匹配,更多信息请参见Go-redis issues

解决方案:使用对应版本的Go-redis客户端访问Tair实例。Tair(兼容Redis 6.0及以下版本)请选择Go-redis v8.0及以下版本。