1

問題Redis的主從複製 - 對從

我有一個情況似乎在那裏,我在主創建的數據並沒有被正確地複製到我的奴隸丟失的數據。

主Redis的DB設置信息

我有10.1.1.1運行的主。配置設置爲「保存」到磁盤。下面是從配置文件中的一個片段:

save 900 1 
save 300 10 
save 60 10000 

當我運行鍼對有問題的散列掃描命令,這裏的結果(這是正確的):

127.0.0.1:6379> scan 0 match dep:* 
1) "13" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_19:00_25:00" 
    3) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

從1設置

從機1已設置爲僅在內存中運行。所以在配置文件中,所有的「保存」選項都被註釋掉了。

下面是我在從1中的數據:(缺少記錄)

127.0.0.1:6379> scan 0 match dep:* 
1) "15" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_19:00_25:00" 
127.0.0.1:6379> 

當我運行這個從「信息」命令,這是我得到的結果:(只挑選特定的項目,我認爲可能涉及到這個問題)

# Replication 
role:slave 
master_host:10.1.1.1 
master_port:6379 
master_link_status:up 
master_last_io_seconds_ago:5 
master_sync_in_progress:0 
slave_repl_offset:346292 
slave_priority:100 
slave_read_only:1 
connected_slaves:0 
master_repl_offset:0 
repl_backlog_active:0 
repl_backlog_size:1048576 
repl_backlog_first_byte_offset:0 
repl_backlog_histlen:0 

#Stats 
expired_keys:0 

#Persistence 
aof_enabled:0 

從2安裝

從2也應該是一個只在內存中的數據存儲。因此,所有的配置文件中保存的選項也被註釋掉,象這樣:

#save 900 1 
#save 300 10 
#save 60 10000 

這是我對奴隸2中的數據(請注意,它缺少數據,而是從從1不同的記錄)

127.0.0.1:6379> scan 0 match dep:* 
1) "3" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

一些來自info命令的結果:

# Replication 
role:slave 
master_host:10.1.1.1 
master_port:6379 
master_link_status:up 
master_last_io_seconds_ago:3 
master_sync_in_progress:0 
slave_repl_offset:346754 
slave_priority:100 
slave_read_only:1 
connected_slaves:0 
master_repl_offset:0 
repl_backlog_active:0 
repl_backlog_size:1048576 
repl_backlog_first_byte_offset:0 
repl_backlog_histlen:0 

#Stats 
expired_keys:0 

#Persistence 
aof_enabled:0 

這是我在使用Redis的第一條裂縫,所以我敢肯定這件事情簡單,我已經錯過了。 我還沒有嘗試在從屬設備上重新啓動REDIS,因爲我不想失去任何可能幫助我排除故障/理解我在這裏首先獲得的東西的工件。

任何建議,將不勝感激。

編輯1

在檢查上從2日誌,這是我發現:

4651:S 27 Sep 18:39:27.197 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 
4651:S 27 Sep 18:39:27.197 # Server started, Redis version 3.0.5 
4651:S 27 Sep 18:39:27.197 * The server is now ready to accept connections on port 6379 
4651:S 27 Sep 18:39:27.198 * Connecting to MASTER 10.1.1.1:6379 
4651:S 27 Sep 18:39:27.198 * MASTER <-> SLAVE sync started 
4651:S 27 Sep 18:40:28.284 # Timeout connecting to the MASTER... 
4651:S 27 Sep 18:40:28.284 * Connecting to MASTER 10.1.1.1:6379 
4651:S 27 Sep 18:40:28.284 * MASTER <-> SLAVE sync started 
4651:S 27 Sep 18:41:29.369 # Timeout connecting to the MASTER... 
4651:S 27 Sep 18:41:29.369 * Connecting to MASTER 10.1.1.1:6379 
4651:S 27 Sep 18:41:29.369 * MASTER <-> SLAVE sync started 
4651:S 27 Sep 18:42:00.452 * Non blocking connect for SYNC fired the event. 
4651:S 27 Sep 18:42:00.453 * Master replied to PING, replication can continue... 
4651:S 27 Sep 18:42:00.453 * Partial resynchronization not possible (no cached master) 
4651:S 27 Sep 18:42:00.463 * Full resync from master: b46c3622e4ef4c5586ebd2ec23eabcb04c3fcf32:1 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: receiving 173 bytes from master 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: Flushing old data 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: Loading DB in memory 
4651:S 27 Sep 18:42:00.592 * MASTER <-> SLAVE sync: Finished with success 

怎麼辦時,有一個超時連接到主redis的奴隸恢復?我也想知道這個錯誤是什麼意思「部分重新同步不可能(沒有緩存大師)」。

目前Google搜尋...但是,如果您有任何意見,請隨時

EDIT 2

這裏還有一個非常有趣的發現(至少對我來說)。 我只是增加了一個新的項目的主人,就像這樣:

127.0.0.1:6379> HMSET dep:+19999999999_15:00_18:45:00 ext 2222 dd me.net days "fri" 
OK 
127.0.0.1:6379> scan 0 match dep:* 
1) "13" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_19:00_25:00" 
    3) "dep:+19999999999_15:00_18:45:00" 
    4) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

而現在,當我再次檢查奴隸之一,它仍然只擁有2條記錄,但其下降曾經是有一個紀錄,並取代它與新的我只是說:

127.0.0.1:6379> scan 0 match dep:* 
1) "7" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> 

編輯3

從下面的答案,它看起來像由掃描命令返回的第一個數字是光標的位置......而在閱讀文檔我可以指定一個計數,指出要返回的記錄數。 但這仍然給我提出了一些問題。例如,在下面的答案線,我試圖在從以下掃描命令:

127.0.0.1:6379> scan 0 match dep:* 
1) "7" 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> scan 7 match dep:* 
1) "0" 
2) 1) "dep:+19999999999_19:00_25:00" 
    2) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

這是有道理的,我...這似乎在同一時間將返回2條記錄(仍需圖我怎樣才能改變這個默認值)

根據這篇文章 - Redis scan count: How to force SCAN to return all keys matching a pattern? - ,我可以使用「count」關鍵字來表示有多少記錄要返回。

但爲了獲得所有4條記錄,我必須在遊標值回到零之前運行幾個查詢......我不知道爲什麼。例如:

127.0.0.1:6379> scan 0 match dep:* count 3 
1) "10" 
2) 1) "dep:+19999999999_00:00_00:00" 
127.0.0.1:6379> scan 10 match dep:* count 3 
1) "3" 
2) (empty list or set) 
127.0.0.1:6379> scan 3 match dep:* count 3 
1) "7" 
2) 1) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> scan 7 match dep:* count 3 
1) "0" 
2) 1) "dep:+19999999999_19:00_25:00" 
    2) "dep:+19999999999_08:00_12:00" 
127.0.0.1:6379> 

爲什麼第一個請求沒有返回3條記錄?在我看來,最多我不得不運行這個掃描命令2次。 你能解釋一下這裏發生了什麼?

另外,也許我不應該在我的節點js REST API中使用scan命令?想象一下,一個用戶會提出一個小部件信息的請求...我需要查詢這個哈希來找到這個密鑰。它感覺像這種類型的迭代將是非常低效的。 KEYS命令也可以工作,但根據文檔,我不應該在生產中使用它,因爲它會影響性能。 任何意見/見解將不勝感激。

回答

1

您還沒有迭代Redis實例中的所有密鑰。

爲了做一個完整的迭代,你應該繼續發送SCAN命令到Redis並返回光標,直到返回的光標是0

在您的最後一個例子:

127.0.0.1:6379> scan 0 match dep:* 
1) "7" <---- returned cursor 
2) 1) "dep:+19999999999_00:00_00:00" 
    2) "dep:+19999999999_15:00_18:45:00" 
127.0.0.1:6379> 
// here, you need continue sending scan command with the returned cursor, i.e. 7 
127.0.0.1:6379> scan 7 match dep:* 
// then you can get more results from Redis 
// If the full iteration is finished, it should return something like this: 
1) "0" <----- this means the full iteration is finished 
2) 1) "dep:more result" 
    2) "dep:last result" 

編輯

count numberSCAN命令是只是一個提示。無法保證Redis應該完全返回count number結果(有關更多詳細信息,請參閱the doc)。

爲了一次性獲得所有密鑰,您可以使用KEYS命令。然而,正如你所提到的那樣,這不是一個好主意(它可能會阻塞Redis很長一段時間),這就是爲什麼Redis使用SCAN命令來獲取所有密鑰的迭代。

SCANKEYS這兩個命令都遍歷整個密鑰空間以查找匹配項。因此,如果數據集非常大,則需要很長時間來獲取/迭代所有密鑰。

從您的問題描述,我覺得你應該存儲在Redis的HASH結構中的數據,並使用HKEYSHGETALLHSCAN獲取數據:

hset dep:+19999999999 00:00_00:00:00 value 
hset dep:+19999999999 15:00_18:45:00 value 
hkeys dep:+19999999999 <----- get all fields in this hash 
hgetall dep:+19999999999 <----- get all fields and values in this hash 
hscan dep:+19999999999 0 <----- scan the hash to key fields 

這應該是比遍歷更有效整個關鍵空間。尤其是,如果散列中沒有太多字段,則HKEYSHGETALL可以一次獲得所有密鑰/數據,並且速度非常快。但是,如果散列中的字段太多,則仍然需要使用HSCAN來進行迭代。

+0

哇。謝謝!我沒有意識到這一點。那麼沒有辦法讓所有東西都在一起?或者控制每次迭代中返回的記錄數量? – Happydevdays

+0

http://stackoverflow.com/questions/33166812/redis-scan-count-how-to-force-scan-to-return-all-keys-matching-a-pattern – Happydevdays

+0

請參閱編輯3 – Happydevdays