redis cluster 不保證強(qiáng)一致性,在一些特殊場景,客戶端即使收到了寫入確認(rèn),還是可能丟數(shù)據(jù)的。
場景1:異步復(fù)制
- client 寫入 master B
- master B 回復(fù) OK
- master B 同步至 slave B1 B2 B3
B 沒有等待 B1 B2 B3 的確認(rèn)就回復(fù)了 client,如果在 slave 同步完成之前,master 宕機(jī)了,其中一個 slave 會被選為 master,這時之前 client 寫入的數(shù)據(jù)就丟了。
wait 命令可以增強(qiáng)這種場景的數(shù)據(jù)安全性。
wait 會阻塞當(dāng)前 client 直到之前的寫操作被指定數(shù)量的 slave 同步成功。
wait 可以提高數(shù)據(jù)的安全性,但并不保證強(qiáng)一致性。
因?yàn)榧词故褂昧诉@種同步復(fù)制方式,也存在特殊情況:一個沒有完成同步的 slave 被選舉為了 master。
場景2:網(wǎng)絡(luò)分區(qū)
6個節(jié)點(diǎn) A, B, C, A1, B1, C1,3個master,3個slave,還有一個client,Z1。
發(fā)生網(wǎng)絡(luò)分區(qū)之后,形成了2個區(qū),A, C, A1, B1, C1 和 B Z1。
這時 Z1 還是可以向 B 寫入的,如果短時間內(nèi)分區(qū)就恢復(fù)了,那就沒問題,整個集群繼續(xù)正常工作,但如果時間一長,B1 就會成為所在分區(qū)的 master,Z1 寫入 B 的數(shù)據(jù)就丟了。
maximum window(最大時間窗口) 可以減少數(shù)據(jù)損失,可以控制 Z1 向 B 寫入的總數(shù):
過去一定時間后,分區(qū)的多數(shù)邊就會進(jìn)行選舉,slave 成為 master,這時分區(qū)少數(shù)邊的 master 就會拒絕接收寫請求。
這個時間量是非常重要的,稱為節(jié)點(diǎn)過期時間。
一個 master 在達(dá)到過期時間后,就被認(rèn)為是故障的,進(jìn)入 error 狀態(tài),停止接收寫請求,可以被 slave 取代。
小結(jié)
Redis Cluster 不保證強(qiáng)一致性,存在丟失數(shù)據(jù)的場景:
- 異步復(fù)制
在 master 寫成功,但 slave 同步完成之前,master 宕機(jī)了,slave 變?yōu)?master,數(shù)據(jù)丟失。
wait 命令可以給為同步復(fù)制,但也無法完全保證數(shù)據(jù)不丟,而且影響性能。
- 網(wǎng)絡(luò)分區(qū)
分區(qū)后一個 master 繼續(xù)接收寫請求,分區(qū)恢復(fù)后這個 master 可能會變?yōu)?slave,那么之前寫入的數(shù)據(jù)就丟了。
可以設(shè)置節(jié)點(diǎn)過期時間,減少 master 在分區(qū)期間接收的寫入數(shù)量,降低數(shù)據(jù)丟失的損失。
推薦學(xué)習(xí):《redis教程》