redis避坑指南
[TOC]
使用 StackExchange.Redis 客户端出现 timeout 问题
场景
开发反馈,使用StackExchange.Redis遇到如下timeout问题:
Unhandled exception. StackExchange.Redis.RedisTimeoutException: Timeout awaiting response (outbound=0KiB, inbound=0KiB, 6894ms elapsed, timeout is 5000ms), command=SET, next: SET lms:api:assement:920850957-94280756, inst: 0, qu: 0, qs: 1, aw: False, rs: ReadAsync, ws: Idle, in: 5, in-pipe: 0, out-pipe: 0, serverEndpoint: r-uf6zi628isi0e76pb7.redis.rds.aliyuncs.com:6379, mc: 1/1/0, mgr: 10 of 10 available, clientName: aiservernew-api, IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=16,Free=32751,Min=1,Max=32767), v: 2.2.4.27433 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)
分析过程
- 查看redis(1G读写分离版)连接数只有1.2,应该看代理节点(而非数据节点)的连接数(300+)
- 修改同步过期时间
SyncTimeout=5000
,连接过期时间ConnectTimeout=15000
,响应过期时间ResponseTimeout=15000
,无效
var config = new ConfigurationOptions
{
AbortOnConnectFail = false,
AllowAdmin = true,
ConnectTimeout = 15000,
SyncTimeout = 5000,
ResponseTimeout = 15000,
Password = "***",
EndPoints = { "192.168.2.110:6379" }
};
var connect = ConnectionMultiplexer.Connect(config);
解决办法
- StackExchange.Redis组件有超时的bug,更换为CSRedisCore解决;
参考
开发反馈 db0 问题
场景
Redis 5.0 社区版 1G读写分离版(1节点1只读),开发反馈有报错 Multiple databases are not supported,详细日志如下:
"exception": "StackExchange.Redis.RedisConnectionException: InternalFailure on GET appserver:api:uatupcServer:token\n
---> StackExchange.Redis.RedisCommandException: Multiple databases are not supported on this server; cannot switch to database: 2\n
at StackExchange.Redis.PhysicalConnection.GetSelectDatabaseCommand(Int32 targetDatabase, Message message) in /_/src/StackExchange.Redis/PhysicalConnection.cs:line 550\n
at StackExchange.Redis.PhysicalBridge.SelectDatabaseInsideWriteLock(PhysicalConnection connection, Message message) in /_/src/StackExchange.Redis/PhysicalBridge.cs:line 1185\n
at StackExchange.Redis.PhysicalBridge.WriteMessageToServerInsideWriteLock(PhysicalConnection connection, Message message) in /_/src/StackExchange.Redis/PhysicalBridge.cs:line 1303\n
--- End of inner exception stack trace ---\n
解决办法
- 将db2换成db0则解决,这也是为什么建议只使用db0的原因
maxmemory配置不一致而导致数据丢失
原因
例如master的maxmemory配置为4G,而slave配置2G,这个时候主从复制可以成功,但如果在进行某一次全量复制的时候,slave拿到master的RDB加载数据时发现自身的2G内存不够用,这时就会触发slave的maxmemory策略,将数据进行淘汰。更可怕的是,在高可用的集群环境下,如果将这台slave升级成master的时候,就会发现数据已经丢失了。