注意:這篇文檔預(yù)設(shè)前提是對(duì)通道配置更新交易有非常豐富的經(jīng)驗(yàn)酗洒,因?yàn)檫@個(gè)遷移交易會(huì)涉及到多個(gè)通道配置更新交易匹表。在你熟悉Add an Organization to a Channel這篇詳細(xì)介紹如何進(jìn)行通道更新的操作文章之前,請(qǐng)不要嘗試進(jìn)行 Kafka 到 Raft 的遷移
對(duì)于那些希望將基于 Kafka 共識(shí)的通道過渡到基于 Raft 共識(shí)的通道的用戶來說望几,v1.4.2 版本允許網(wǎng)絡(luò)中的每個(gè)通道通過一系列的通道配置更新交易實(shí)現(xiàn)這個(gè)目標(biāo)枫攀。
這篇教程將會(huì)從一個(gè)比較宏觀的層次來描述這個(gè)過程,必要時(shí)會(huì)提供具體細(xì)節(jié)冯乘,但是不會(huì)展示具體的命令操作。
假設(shè)和前提
在嘗試遷移之前晒夹,請(qǐng)先考慮以下因素:
- 這個(gè)過程僅僅用于從 Kafka 到 Raft 的遷移裆馒。其他任何共識(shí)類型之間的遷移現(xiàn)階段是不支持的;
- 遷移過程是單向的丐怯。一旦共識(shí)服務(wù)遷移到 Raft 并開始提交交易之后喷好,就再也不可能回到 Kafka 共識(shí)了;
- 由于共識(shí)節(jié)點(diǎn)在這個(gè)過程中會(huì)停機(jī)和重啟读跷,因此遷移過程需要允許停機(jī)梗搅;
- 只有在合適的時(shí)間點(diǎn)(本文后面會(huì)介紹)進(jìn)行數(shù)據(jù)備份之后才有可能從對(duì)失敗的遷移進(jìn)行回滾。如果你不進(jìn)行備份效览,而遷移有失敗了无切,那么之前的狀態(tài)將無(wú)法恢復(fù);
- 所有的通道必須都在同一個(gè)維護(hù)窗口期進(jìn)行遷移丐枉。在恢復(fù)操作之前只對(duì)部分通道進(jìn)行遷移是不可行的哆键;
- 在遷移過程的最后,所有的通道都將擁有相同的 Raft 節(jié)點(diǎn)共識(shí)集合瘦锹。這也是和系統(tǒng)通道中的共識(shí)集合一樣的籍嘹。這個(gè)特征使得我們可以判斷一個(gè)遷移過程是否成功;
- 遷移是使用現(xiàn)有的已部署排序節(jié)點(diǎn)的賬本完成的弯院,增加或移除排序節(jié)點(diǎn)都需要在遷移動(dòng)作完成后再進(jìn)行辱士;
宏觀的遷移流程
遷移分5個(gè)階段進(jìn)行。
- 系統(tǒng)進(jìn)入維護(hù)模式听绳,應(yīng)用交易將被拒絕识补,只有排序服務(wù)管理員可以對(duì)通道配置進(jìn)行更新;
- 系統(tǒng)停止運(yùn)行辫红,考慮到遷移過程可能出錯(cuò)凭涂,對(duì)數(shù)據(jù)進(jìn)行備份贴妻;
- 系統(tǒng)啟動(dòng),每個(gè)通道的共識(shí)類型和基礎(chǔ)數(shù)據(jù)進(jìn)行了修改名惩;
- 系統(tǒng)重啟,并開始以 Raft 共識(shí)模式運(yùn)行;每個(gè)通道都驗(yàn)證確認(rèn)已經(jīng)完成了選舉攻谁;
- 系統(tǒng)退出維護(hù)模式并正常提供服務(wù);
遷移準(zhǔn)備
在嘗試遷移之前有幾步需要準(zhǔn)備:
- 規(guī)劃 Raft 的部署戚宦,決定將哪些排序服務(wù)節(jié)點(diǎn)保留作為 Raft 的共識(shí)節(jié)點(diǎn)个曙。你需要在集群中部署至少3個(gè)排序節(jié)點(diǎn),但是你要知道部署至少5個(gè)節(jié)點(diǎn)會(huì)使得系統(tǒng)允許一個(gè)節(jié)點(diǎn)down掉從而具備高可用性受楼,但是3節(jié)點(diǎn)的配置一旦有一個(gè)節(jié)點(diǎn)因任何原因(比如節(jié)點(diǎn)處于維護(hù)周期)down掉垦搬,系統(tǒng)將失去高可用性;
- 準(zhǔn)備生成 Raft 的
Metadata
配置的素材艳汽。注意:所有的通道都應(yīng)該接收相同的 RaftMetadata
配置猴贰。參考[Raft configuration guide](Raft configuration guide) 獲取這些配置項(xiàng)的細(xì)節(jié)。提示:你會(huì)發(fā)現(xiàn)使用 Raft 共識(shí)協(xié)議啟動(dòng)一個(gè)排序服務(wù)網(wǎng)絡(luò)是非常容易的河狐,然后拷貝和修改共識(shí)配置相關(guān)的基本配置參數(shù)米绕。任何情況下,你都需要以下元素(沒一個(gè)排序服務(wù)節(jié)點(diǎn)):hostname
port
server certificate
client certificate
- 整理出系統(tǒng)中所有的通道(系統(tǒng)通道和應(yīng)用通道)列表馋艺。確保你擁有合適的身份對(duì)通道配置更新進(jìn)行簽名栅干。比如相應(yīng)的排序服務(wù)管理員身份;
- 確保所有的共識(shí)服務(wù)節(jié)點(diǎn)都運(yùn)行在相同的 Fabric 版本下丈钙,這個(gè)版本需要是 v1.4.2 或更高非驮;
- 確保所有的 peer 節(jié)點(diǎn)至少是 v1.4.2 版本交汤,確保所有的通道配置具備允許遷移的配置:
- Orderer capability
V1_4_2
(或更高) - Channel capability
V1_4_2
(或更高)
- Orderer capability
進(jìn)入維護(hù)模式
在將排序服務(wù)設(shè)置為維護(hù)模式之前雏赦,建議將網(wǎng)絡(luò)中的 peer 服務(wù)和客戶端都關(guān)停。保持 peer 節(jié)點(diǎn)和客戶端正常運(yùn)行可是可行的芙扎,但是排序服務(wù)會(huì)拒絕所有請(qǐng)求星岗,它們的日志中會(huì)充滿無(wú)害但是容易引起誤導(dǎo)的錯(cuò)誤信息。
依照Add an Organization to a Channel 的知道來為所有的通道準(zhǔn)備配置更新戒洼,從系統(tǒng)通道開始俏橘。在這一步中,你唯一需要修改的通道配置項(xiàng)是/Channel/Orderer/ConsensusType
圈浇。用 JSON 格式表示的話就是:.channel_group.groups.Orderer.values.ConsensusType
寥掐。
ConsensusType
配置節(jié)包含三部分:Type
、Metadata
和 State
:
-
Type
要么是kafka
要么是etcdraft
(Raft)磷蜀,這個(gè)值只允許在維護(hù)模式時(shí)更改召耘; -
Metadata
會(huì)為空當(dāng)Type
為kafka的時(shí)候,但當(dāng)Type
為etcdraft
時(shí)褐隆,這個(gè)配置項(xiàng)就需要攜帶正確的 Raft 基礎(chǔ)參數(shù)污它。下文會(huì)有更多描述; -
State
可以是NORMAL
,當(dāng)通道正在正常處理交易的時(shí)候衫贬,或者為MAINTENANCE
德澈,當(dāng)處于遷移過程時(shí);
通道配置更新的第一步梆造,僅僅是將State
從 NORMAL
修改為 MAINTENANCE
澳窑。不要修改 Type
和 Metadata
這兩個(gè)域摊聋。注意栈暇,此時(shí)的 Type
應(yīng)該為kafka
源祈。
在維護(hù)模式期間香缺,正常交易、與遷移無(wú)關(guān)的配置更新交易以及來自其他 peer 節(jié)點(diǎn)的用于獲取新塊的 Deliver
請(qǐng)求都將被拒絕锋拖。這樣做是為了防止 peer 遷移期間備份和必要時(shí)的還原動(dòng)作同時(shí)出現(xiàn)兽埃,因?yàn)樗鼈冎粫?huì)在遷移成功完成后才會(huì)接收更新柄错。換句話說售貌,我們希望能夠保持排序服務(wù)的備份點(diǎn)(下一步將要處理的)在 peer 節(jié)點(diǎn)的賬本前面颂跨,以便在需要時(shí)能夠進(jìn)行回滾给僵。然而排序服務(wù)節(jié)點(diǎn)管理員可以處理 Deliver
請(qǐng)求(他們需要具備能力以保證遷移過程的繼續(xù))。
確保每個(gè)排序服務(wù)節(jié)點(diǎn)上的每一個(gè)通道都進(jìn)入了維護(hù)模式蔓同。這個(gè)可以通過拉取每個(gè)通道最新的配置塊并確認(rèn) Type
斑粱、Metadata
和 State
分別是 kafka
则北、空值(回想下五续,kafka 模式下沒有元數(shù)據(jù))和 MAINTENANCE
臀规。
如果通道配置都成功更新了误墓,排序服務(wù)就可以準(zhǔn)備開始備份了方篮。
停止服務(wù)并備份文件
停止所有的排序服務(wù)節(jié)點(diǎn),Kafka 服務(wù)和 Zookeeper 服務(wù)匕得。首先關(guān)停排序服務(wù)節(jié)點(diǎn)很重要巾表。之后攒发,等 Kafka 服務(wù)將日志刷寫到磁盤之后(通常會(huì)花費(fèi)30s惠猿,但是取決于你的系統(tǒng)情況也可能花費(fèi)更長(zhǎng)時(shí)間)负间,Kakfa 服務(wù)應(yīng)該就停掉了。在關(guān)閉排序節(jié)點(diǎn)的同時(shí)關(guān)閉 kafka 服務(wù)節(jié)點(diǎn)可能會(huì)導(dǎo)致排序節(jié)點(diǎn)寫入文件系統(tǒng)的狀態(tài)比 kafka 記錄的更新從而導(dǎo)致網(wǎng)絡(luò)無(wú)法重啟趾访。
為這些服務(wù)的文件系統(tǒng)創(chuàng)建備份扼鞋。然后重啟 kafka 服務(wù),在重啟排序服務(wù)節(jié)點(diǎn)云头。
在維護(hù)模式下切換到 Raft
遷移過程的下一個(gè)步驟是針對(duì)每個(gè)通道的又一次通道配置更新溃槐。在這次的配置更新中,將 Tyte
修改為 etcdraft
(代表 Raft)同時(shí)保持 State
為 MAINTENANCE
猴鲫,并填充 metadata
相關(guān)配置谣殊。強(qiáng)烈建議所有通道的 Metadata
配置保持一致。如果你想要使用不同的節(jié)點(diǎn)設(shè)置不同的共識(shí)集合匣缘,那么你需要在系統(tǒng)重啟為etcdraft
之后重新配置 Metadata
配置項(xiàng)肌厨。提供相同的 Metadata
元數(shù)據(jù)就是提供相同的共識(shí)集合柑爸,這意味著當(dāng)節(jié)點(diǎn)重啟后表鳍,入股系統(tǒng)通道能夠成功完成選舉并退出維護(hù)模式祥诽,那么其他通道也能一樣。為不通通道提供不通的共識(shí)集可能導(dǎo)致有的通道成功組件集群而有的失敗厘熟。
然后绳姨,通過拉取并檢查每個(gè)通道最新的配置信息來驗(yàn)證是否成功提交了針對(duì) ConsensusType
的配置更新飘庄。
注意:修改 ConsensusType
的配置交易必須是重啟節(jié)點(diǎn)(下一步)前的最后一個(gè)配置交易购撼。如果在這一步之后有其他配置交易發(fā)生,那么很可能節(jié)點(diǎn)重啟后會(huì)崩潰狞甚,或者產(chǎn)生其他未知行為哼审。
重啟并驗(yàn)證領(lǐng)導(dǎo)者
注意:退出維護(hù)模式必須在重啟之后做孕豹。
在所有通道的 ConsensusType
都成功更新只有励背,停止所有排序服務(wù)節(jié)點(diǎn)叶眉、Kafka 服務(wù)和 Zookeeper 服務(wù),然后僅重啟排序服務(wù)節(jié)點(diǎn)莲趣。它們應(yīng)該重啟成為 Raft 節(jié)點(diǎn)喧伞,每個(gè)通道組建一個(gè)集群并推選出領(lǐng)導(dǎo)者绩郎。一定要確保通過觀察節(jié)點(diǎn)日志(你會(huì)在下文中看到需要觀察什么日志)來驗(yàn)證每個(gè)通道都選出了領(lǐng)導(dǎo)者。通過這個(gè)來確認(rèn)整個(gè)過程是否成功完成溉仑。
當(dāng)領(lǐng)導(dǎo)者成功選舉之后状植,日志將會(huì)顯示如下信息:
"Raft leader changed: 0 -> node-number channel=channel-name
node=node-number "
例如:
2019-05-26 10:07:44.075 UTC [orderer.consensus.etcdraft] serveRequest ->
INFO 047 Raft leader changed: 0 -> 1 channel=testchannel1 node=2
在這個(gè)例子中逐沙,節(jié)點(diǎn) node2
報(bào)告通道 testchannel1
的集群中領(lǐng)導(dǎo)者已經(jīng)選舉出來了(領(lǐng)導(dǎo)者是 node1
)洼畅。
退出維護(hù)模式
為每個(gè)通道在執(zhí)行一次配置更新(把配置更新發(fā)到之前一直發(fā)的那個(gè)排序節(jié)點(diǎn)上)帝簇,將 State
從 MAINTENANCE
修改為 NORMAL
丧肴。跟以前一樣芋浮,從系統(tǒng)通道開始。如果在系統(tǒng)通道上成功了镇草,那么這個(gè)遷移在其他通道基本也是成功的梯啤。為了驗(yàn)證因宇,從排序節(jié)點(diǎn)拉取系統(tǒng)通道最新的配置塊并檢查它的 State
是否為 NORMAL
察滑。為了完整杭棵,在每個(gè)排序節(jié)點(diǎn)上都做一次這個(gè)驗(yàn)證魂爪。
這個(gè)過程完成之后艰管,排序服務(wù)就準(zhǔn)備好了在所有通道上接收任何交易牲芋。如果你按照建議的那樣關(guān)停了 peer 節(jié)點(diǎn)和應(yīng)用端缸浦,那么此時(shí)你可以重啟它們了裂逐。
中止和回滾
在遷移過程中,如果是在退出維護(hù)模式之前出現(xiàn)了問題卜高,那么按照如下流程執(zhí)行回滾程序即可:
- 關(guān)停排序服務(wù)節(jié)點(diǎn)和 Kafka 服務(wù)(Kafka 服務(wù)節(jié)點(diǎn)以及配套的 Zookeeper 節(jié)點(diǎn));
- 將這些服務(wù)的文件系統(tǒng)回滾到維護(hù)模式期間在修改
ConsensusType
之前的備份上疼进; - 重啟相關(guān)服務(wù),排序服務(wù)會(huì)以維護(hù)模式下的 Kafka 共識(shí)啟動(dòng)伞广;
- 發(fā)送配置更新退出維護(hù)模式使排序服務(wù)繼續(xù)使用 Kafka 作為共識(shí)算法,或者在備份點(diǎn)之后恢復(fù)操作并修復(fù)阻止 Raft 節(jié)點(diǎn)組成合法共識(shí)集群的錯(cuò)誤灾票,然后使用正確的 Raft 配置元數(shù)據(jù)
Metadata
重試遷移操作刊苍。
下面有幾種狀態(tài)可以用來判斷遷移是否失斦病:
- 有些節(jié)點(diǎn)崩潰或停止運(yùn)行;
- 日志中沒有針對(duì)每個(gè)通道正常選舉出領(lǐng)導(dǎo)者的記錄主经;
- 將系統(tǒng)通道的維護(hù)模式修改為
NORMAL
動(dòng)作失敗庭惜。