全球多活使用限制
為保障實例的穩(wěn)定和數(shù)據(jù)一致性,在使用全球多活功能時,有一些使用約束需要您注意。
使用限制
子實例需滿足以下條件:
部署模式為經(jīng)典。
存儲介質(zhì)為內(nèi)存型。
架構(gòu)為標(biāo)準(zhǔn)架構(gòu)或集群架構(gòu)。
說明請確保各子實例規(guī)格一致,如需進(jìn)行變配,建議對所有子實例均進(jìn)行相同變配。若各子實例的規(guī)格不一致,可能會出現(xiàn)性能或容量問題。
一個分布式實例中最多可包含三個子實例,且各子實例不能位于同一可用區(qū)。第一個子實例支持從已創(chuàng)建的實例進(jìn)行轉(zhuǎn)換,第二、第三個子實例需新購。
一個分布式實例中的子實例必須都在中國內(nèi)地或都在其他地域,若您需要在中國內(nèi)地地域與其他地域之間進(jìn)行數(shù)據(jù)同步,請使用DTS數(shù)據(jù)同步功能,更多信息請參見申請跨境數(shù)據(jù)同步權(quán)限。
成為分布式實例的子實例后,存在如下限制:
不支持變更實例所屬的可用區(qū)。
不支持變更實例架構(gòu),例如從集群架構(gòu)變更為標(biāo)準(zhǔn)架構(gòu)等。
集群實例變配時,單次僅支持變配分片數(shù)或分片規(guī)格,更多信息請參見分布式集群實例變配方案。
同步命令限制
FLUSHDB或FLUSHALL命令不會被同步。
如需清空數(shù)據(jù):需對所有子實例執(zhí)行FLUSHALL命令,否則會造成數(shù)據(jù)不一致。
如需重新同步:例如以A實例為源,重新對B實例進(jìn)行同步,您需要在分布式實例中移除B實例、對B實例執(zhí)行FLUSHALL命令,再重新將B實例接入分布式實例中,接入后即可自動重新同步。
Pub和Sub命令不會被同步,如需實現(xiàn)跨域通知的消息復(fù)制,建議通過Stream數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)。
同步RESTORE命令時,如果目標(biāo)子實例具備相同的Key,則不會被執(zhí)行。
同步粒度限制
目前同步的粒度為實例級,即子實例的所有數(shù)據(jù)都會被同步,暫不支持同步子實例中的部分?jǐn)?shù)據(jù)。
如需同步部分?jǐn)?shù)據(jù),需要通過業(yè)務(wù)邏輯來實現(xiàn)。
數(shù)據(jù)一致性限制
單寫場景下(例如用作災(zāi)備場景),數(shù)據(jù)的一致性級別為最終數(shù)據(jù)一致。
多寫場景下(例如用作多活場景),業(yè)務(wù)上應(yīng)避免多個子實例在同一時刻或相近的時間修改同一個Key,否則可能造成數(shù)據(jù)不一致(即無法保障Key的最終一致性)或者數(shù)據(jù)堆積(在Streaming場景下嚴(yán)格遞增產(chǎn)生的沖突),如下表所示。
說明全球多活暫不支持CRDT(Conflict-Free Replicated Data Type)約束,您需要從業(yè)務(wù)層面自行保障。
不一致情況
圖示
說明
value互換
子實例A在1.1時刻收到SET命令(key->value_A),并于1.2時刻將數(shù)據(jù)寫入數(shù)據(jù)庫。
子實例B在2.1時刻收到SET命令(key->value_B),并于2.2時刻將數(shù)據(jù)寫入數(shù)據(jù)庫。
在3.1時刻子實例A向子實例B同步數(shù)據(jù)(key->value_A),同時子實例B向子實例A同步數(shù)據(jù)(key->value_B)。
同步完成,兩個子實例中key對應(yīng)的value發(fā)生了互換。
亂序或丟失
子實例A在1.1時刻收到命令(rpush key->value_A),并于1.2時刻將數(shù)據(jù)寫入至數(shù)據(jù)庫。
子實例B在2.1時刻收到命令(rpush key->value_B),并于2.2時刻將數(shù)據(jù)寫入至數(shù)據(jù)庫。
在3.1時刻子實例A向子實例B同步數(shù)據(jù)(rpush key->value_A),同時子實例B向子實例A同步數(shù)據(jù)(rpush key->value_B)。
當(dāng)操作類型依賴value原始值時,在交換的情況下可能會出現(xiàn)亂序甚至丟失的情況。
說明可能造成類似問題的還有、
lpush
,lpop
、append
、sort
(store)、del
、hdel
、incr
、xadd
系列等操作。
類型不一致
子實例A在1.1時刻收到命令(key->T(hash)),并于1.2時刻將數(shù)據(jù)寫入至數(shù)據(jù)庫。
子實例B在2.1時刻收到命令(key->T(string)),并于2.2時刻將數(shù)據(jù)寫入至數(shù)據(jù)庫。
在3時刻子實例間執(zhí)行數(shù)據(jù)同步將形成沖突。
寫入條件不滿足
子實例A在1.1時刻收到命令(setnx key->value_A),并于1.2時刻將數(shù)據(jù)寫入至數(shù)據(jù)庫。
子實例B在2.1時刻收到命令(setnx key->value_B),并于2.2時刻將數(shù)據(jù)寫入至數(shù)據(jù)庫。
在3時刻子實例間執(zhí)行數(shù)據(jù)同步將形成沖突。
說明可能造成類似問題的還有
set(nx | xx)
、hsetnx
操作。