【问题标题】:Redis sentinel not connect to master: Error: READONLY You can't write against a read only slave?Redis sentinel not connect to master: Error: READONLY You can't write against a read only slave?
【发布时间】:2017-08-06 05:06:34
【问题描述】:

我有这个redis replicationsentinel 建筑师:

5 个服务器:.1.2.3.4.5

  • .1: nodejs app, redis master, redis sentinel
  • .2: nodejs 应用程序,redis 从站
  • .3: nodejs 应用程序,redis 从站
  • .4: redis 哨兵
  • .5: redis 哨兵

Sentinel 按预期处理故障转移。 redis-cli -h x.y.z.5 -p 26379 sentinel get-master-addr-by-name mymaster 总是返回 .1 服务器。

我的代码连接到这个复制(我使用ioredis):

let sentinels = [
  { host: process.env.REDIS_SENTINEL_1, port: process.env.REDIS_PORT },
  { host: process.env.REDIS_SENTINEL_2, port: process.env.REDIS_PORT },
  { host: process.env.REDIS_SENTINEL_3, port: process.env.REDIS_PORT }
]
store = new Redis({
  name: 'mymaster',
  sentinels: sentinels
})
store.on('ready', () => {
  store.set('foo', new Date())
  store.get('foo', function (err, result) {
    console.log('redis: get foo: ', result)
  });
});

然后,.1 nodejs 应用运行正常,但是在.2.3 中,出现此日志的错误:

 events.js:161
       throw er; // Unhandled 'error' event
       ^

 Error: READONLY You can't write against a read only slave.

P/s:我的 redis 服务器绑定了服务器 IP 和 127.0.0.1。因为,没有127.0.0.1,我会遇到这个错误:

Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379

所以,我想,我的应用不是通过sentinel 连接到redis server,而是直接连接到localhost

任何帮助都是appriciate!

更新:当我打开DEBUG=ioredis:*时记录:

2|MyApp     | Wed, 15 Mar 2017 12:58:42 GMT ioredis:redis status[x.y.z.5:26379]: connecting -> connect
2|MyApp     | Wed, 15 Mar 2017 12:58:42 GMT ioredis:redis status[x.y.z.5:26379]: connect -> ready
2|MyApp     | Wed, 15 Mar 2017 12:58:42 GMT ioredis:connection send 1 commands in offline queue
2|MyApp     | Wed, 15 Mar 2017 12:58:42 GMT ioredis:redis write command[0] -> sentinel(get-master-addr-by-name,mymaster)
2|MyApp     | events.js:161
2|MyApp     |       throw er; // Unhandled 'error' event
2|MyApp     |       ^
2|MyApp     | Error: READONLY You can't write against a read only slave.
2|MyApp     |     at JavascriptReplyParser._parseResult (/home/demo/demo_api/source/node_modules/redis/lib/parsers/javascript.js:43:16)
2|MyApp     |     at JavascriptReplyParser.try_parsing (/home/demo/demo_api/source/node_modules/redis/lib/parsers/javascript.js:114:21)
2|MyApp     |     at JavascriptReplyParser.run (/home/demo/demo_api/source/node_modules/redis/lib/parsers/javascript.js:126:22)
2|MyApp     |     at JavascriptReplyParser.execute (/home/demo/demo_api/source/node_modules/redis/lib/parsers/javascript.js:107:10)
2|MyApp     |     at Socket.<anonymous> (/home/demo/demo_api/source/node_modules/redis/index.js:131:27)
2|MyApp     |     at emitOne (events.js:96:13)
2|MyApp     |     at Socket.emit (events.js:189:7)
2|MyApp     |     at readableAddChunk (_stream_readable.js:176:18)
2|MyApp     |     at Socket.Readable.push (_stream_readable.js:134:10)
2|MyApp     |     at TCP.onread (net.js:551:20)
2|MyApp     | [nodemon] app crashed - waiting for file changes before starting...
2|MyApp     | sentinel production
2|MyApp     | Wed, 15 Mar 2017 12:58:43 GMT ioredis:redis status[localhost:6379]: [empty] -> connecting
2|MyApp     | Wed, 15 Mar 2017 12:58:43 GMT ioredis:redis status[x.y.z.5:26379]: [empty] -> connecting
2|MyApp     | Wed, 15 Mar 2017 12:58:43 GMT ioredis:redis queue command[0] -> sentinel(get-master-addr-by-name,mymaster)
2|MyApp     | sentinel production
2|MyApp     | Wed, 15 Mar 2017 12:58:43 GMT ioredis:redis status[localhost:6379]: [empty] -> connecting
2|MyApp     | Wed, 15 Mar 2017 12:58:43 GMT ioredis:redis status[x.y.z.5:26379]: [empty] -> connecting
2|MyApp     | Wed, 15 Mar 2017 12:58:43 GMT ioredis:redis queue command[0] -> sentinel(get-master-addr-by-name,mymaster)

更新 2:还有一件事,我在本地机器上使用 production 环境运行应用程序,一切都像魅力一样运行!!!

【问题讨论】:

    标签: node.js redis-sentinel ioredis


    【解决方案1】:

    是的,终于找到了。

    当一个旧代码使用redis模块并尝试直接连接到localhost时,这是我的错误。

    将它替换为 ioredis 实例,它就像魅力一样工作:)

    【讨论】:

      【解决方案2】:

      通过连接到“localhost”,.2 和 .3 正在与它们的本地只读保存对话。 您不会“通过哨兵连接”。您连接到哨兵,获取主 IP,然后连接到该 IP 和端口。出于某种原因,您尝试连接到本地主机,而不是哨兵报告的 IP。至于为什么,我不能说,因为您的问题中没有信息。

      Sentinel 返回一个 IP 地址,而不是“localhost”,因此您没有使用来自 sentinel 的返回,而是在某处编码为使用“localhost”,这将产生您报告的行为。您需要找到并修复它。

      【讨论】:

      • 感谢您的评论,我也这么认为,但是,在我的代码中,我尝试通过sentinel 进行连接,如上所示。而且我不知道为什么它会尝试连接到本地主机???
      • 更新 2:还有一件事,我在本地机器上使用 production 环境运行应用程序,一切都像魅力一样工作!!!
      • 在我的情况下,问题是由于replicaof localhost 6380。当用replicaof 127.0.0.1 6380 替换它时,问题就解决了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多