4

私は建築家とこれredis replicationを持っています:sentinel

5 台のサーバー: .1.2.3.4および.5

  • .1: nodejs アプリ、redis マスター、redis センチネル
  • .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)
  });
});

次に、.1nodejs アプリは正常に実行されますが、.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

だから、私のアプリはredis server経由sentinelではなく、直接接続していると思いlocalhostます。

どんな助けも感謝しています!

更新:オンにするとログに記録します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: もう 1 つ、環境を使用してローカル マシンでアプリを実行するproductionと、すべてが魅力的に機能します!!!

4

2 に答える 2

0

「localhost」に接続することにより、.2 と .3 はローカルの読み取り専用保存と通信します。「センチネル経由で接続」しません。Sentinel に接続し、マスター IP を取得してから、その IP とポートに接続します。何らかの理由で、センチネルによって報告されている IP ではなく、localhost に接続しようとしています。理由については、あなたの質問では情報が入手できないため、わかりません。

Sentinel は「localhost」ではなく IP アドレスを返すため、sentinel からの戻り値を使用していませんが、代わりに「localhost」を使用するようにコード化されているため、報告された動作が生成されます。それを見つけて修正する必要があります。

于 2017-03-16T01:08:56.373 に答える