node_redis :2.7.1
Redis的:3.2
平台:Amazon Linux
描述:
当redis的快照发生时,它将断开redis客户端的连接。 客户端重新连接并重新订阅,但是,它们不再接收数据。 这可以通过在redis-cli上发出SAVE
命令来重现。
JS
const redis = require('redis');
const redisClient = redis.createClient({
host: config.redisEndpoint,
port: config.redisPort,
});
redisClient.on('connect', () => {
console.log('Connected to Redis');
console.log('subscription_set:', redisClient.subscription_set);
});
redisClient.on('reconnecting', (stats) => {
console.log('Reconnecting to Redis', stats);
});
redisClient.on('error', (error) => {
console.log('Failed to connect to Redis: ', error);
});
redisClient.on('subscribe', (channel, count) => { // eslint-disable-line no-unused-vars
console.log('Subscribed to: ', channel, count);
});
redisClient.on('message', (channel, message) => { // eslint-disable-line no-unused-vars
console.log('Received from: ', channel, message);
});
redisClient.subscribe('test');
日志
初始连接
info: Connected to Redis
info: subscription_set:
info: Subscribed to: test 1
在redis-cli中发出SAVE命令
info: Error: Redis connection to 34.213.3.19:6379 failed - read ECONNRESET
info: Reconnecting to Redis delay=983, attempt=4, code=ECONNRESET, errno=ECONNRESET, syscall=connect, address=127.0.0.1, port=6379, total_retry_time=1118, times_connected=1
info: Connected to Redis
info: subscription_set: subscribe_test=test
info: Subscribed to: test 1
此时,客户端将不再接收发布到通道测试的任何数据。 如果您有任何疑问或需要更多信息来复制,请告诉我。
@BridgeAR @iamjem可能与#1249相关
感谢您的详细说明,但是我还无法复制它。 当我通过redis-cli发出SAVE
,连接不会重置。
当我手动停止redis服务器并重新启动它时,似乎可以正常接收消息。
我已经在Mac上进行了测试,也会尝试在Linux上重现它
嗯...这很有趣。 它是通过从源构建完全的redis安装而发生的。 我更改的唯一选项是允许远程连接。 我会尽快查看一下,看看是否能解决问题。 @jdegger
@jdegger我无法在本地进行复制,仅在超级特定条件下才能在AWS中进行复制。 我可以创建此AMI的第二个副本,并提供允许您重现的代码,但这似乎是在AWS中运行的特定功能。 让我知道您是否有兴趣...否则我会说继续并解决问题
好了,终于可以可靠地复制了。 有一些要求:
tcp-keepalive 0
您会看到,每2小时(至少对我来说)是ECONNRESET错误。 此时,套接字似乎仍在Redis中处于打开状态,但也许节点进程已丢失对它的引用并打开了一个新的套接字? 一夜之间,从redis-cli发出CLIENT LIST
,我希望每2小时连接1个客户端,加上当前正在运行的进程。
请务必注意,所有客户端都已成功重新连接,但未接收到数据。 我有一种预感,即数据已被推出,但是对于旧的连接却不是新的连接……但这完全是一种预感。
现在,我不是100%确定这是一个node_redis错误还是实际上是一个节点错误,因此,如果这是错误的提交位置,请告诉我。 我很乐于尝试调试/逐步调试,但是时间有限。
修复方法是设置tcp-keepalive 300
,以保持连接处于活动状态...但这有点奇怪,因为客户端应该能够成功地重新连接。
@shmendo
我们的结果还表明,ECONNRESET错误每2小时发生一次。 但是我检查了tcp-keepalive,它是300
CONFIG GET tcp-keepalive
1) "tcp-keepalive"
2) "300"
最有用的评论
好了,终于可以可靠地复制了。 有一些要求:
tcp-keepalive 0
您会看到,每2小时(至少对我来说)是ECONNRESET错误。 此时,套接字似乎仍在Redis中处于打开状态,但也许节点进程已丢失对它的引用并打开了一个新的套接字? 一夜之间,从redis-cli发出
CLIENT LIST
,我希望每2小时连接1个客户端,加上当前正在运行的进程。请务必注意,所有客户端都已成功重新连接,但未接收到数据。 我有一种预感,即数据已被推出,但是对于旧的连接却不是新的连接……但这完全是一种预感。
现在,我不是100%确定这是一个node_redis错误还是实际上是一个节点错误,因此,如果这是错误的提交位置,请告诉我。 我很乐于尝试调试/逐步调试,但是时间有限。
修复方法是设置
tcp-keepalive 300
,以保持连接处于活动状态...但这有点奇怪,因为客户端应该能够成功地重新连接。