集羣通訊:從心跳提及

本文首發 Nebula Graph 官網:nebula-graph.com.cn/posts/clust…git

在用戶使用 Nebula Graph 的過程當中,常常會遇到各類問題,一般咱們都會建議先經過 show hosts 查看集羣狀態。能夠說,整個 Nebula Graph 的集羣狀態都是靠心跳機制來構建的。本文將從心跳提及,幫助你瞭解 Nebula Graph 集羣各個節點之間通訊的機制。github

什麼是心跳?有什麼做用?

metad storaged graphd 通訊

Nebula Graph 集羣通常包含三種節點,graphd 做爲查詢節點,storaged 做爲存儲節點,metad 做爲元信息節點。本文說的心跳,主要是指 graphd 和 storaged 按期向 metad 上報信息的這個心跳,藉助心跳,整個集羣完成了如下功能。(相關參數是 heartbeat_interval_secs數據庫

在 Nebula Graph 中常常說起的 raft 心跳則是用於擁有同一個 partition 的多個 storaged 之間的心跳,和本文提的心跳並不相同。緩存

1. 服務發現

當咱們啓動一個 Nebula Graph 集羣時,須要在對應的配置文件中填寫 meta_server_addrs。graphd 和 storaged 在啓動以後,就會經過這個 meta_server_addrs 地址,向對應的 metad 發送心跳。一般來講,graphd 和 storaged 在鏈接上 metad 前是沒法對外進行服務的。當 metad 收到心跳後,會保存相關信息(見下文第 2 點),此時就可以經過 show hosts 看到對應的 storaged 節點,在 2.x 版本中,也可以經過 show hosts graph 看到 graphd 節點。markdown

2. 上報節點信息

在 metad 收到心跳時,會將心跳中的 ip、port、節點類型、心跳時間等等信息保存,以供後續使用(見下文)。運維

除此之外 storaged 在自身 leader 數量變化的時候也會上報 leader 信息,在 show hosts 中看到的 Leader count 和 Leader distribution 就是經過心跳彙報的。分佈式

3. 更新元信息

當客戶經過 console 或者各類客戶端,對集羣的元信息進行更改以後(例如 create/drop spacecreate/alter/drop tag/edgeupdate configs 等等),一般在幾秒以內,整個集羣就都會更新元數據。oop

每次 graphd 和 storaged 在心跳的響應中會包含一個 last_update_time,這個時間是由 metad 返回給各個節點的,用於告知 metad 自身最後一次更新元信息的時間。當 graphd 或者 storaged 發現 metad 的元信息有更新,就會向 metad 獲取相應信息(例如 space 信息、schema 信息、配置更改等等)。post

咱們以建立一個 tag 爲例,若是在 graphd/storaged 獲取到新建立的這個 tag 信息以前,咱們沒法插入這個 tag 數據(會報相似 No schema found 這樣的錯誤)。而當經過心跳獲取到對應信息並保存至本地緩存後,就可以正常寫入數據了。spa

心跳上報的信息有什麼用?

  • how hostsshow parts 這類命令都是經過 metad 中保存的各個節點心跳信息,組合顯示出來的。
  • balance databalance leader 等運維命令,須要經過獲取當前集羣內哪些 storaged 節點是在線狀態,實際也是經過 metad 判斷最近一次心跳時間是否在閾值以內。
  • create space,當用戶建立一個 space 時,metad 也須要獲取 storaged 的狀態,將這個 space 的各個 partition 分配到在線的 storaged 中。

以用戶容易遇到的問題爲例:假如咱們啓動一個 storaged 後,關掉並修改端口號,而後再啓動 storaged。若是這個過程足夠快,那麼經過 show hosts 能看到兩個在線的 storaged。此時,若是新建一個 space,例如 CREATE space test(partition_num=10, replica_factor=1),這個 test space 就會分佈在先後啓動的兩個 storage 上。但若是等到在 show hosts 中看到其中一個離線後,再執行 CREATE space test(partition_num=10, replica_factor=1),即使離線的 storaged 再啓動,也只有一個 storaged 擁有這個 space(建立 test space 時 online 的那個 storaged)。

上線

掉線

心跳的演變歷史

在 18-19 年的時候,當時的心跳機制沒有這麼完善。一方面,不管元信息是否更改,都會從 metad 獲取最新的元信息。而一般來講,元信息改動不會很頻繁,按期獲取元信息有必定的資源浪費。另外一方面,想要將一個 storaged 節點加入和移除都是經過相似 add/delete hosts 這樣的命令,採起的是相似白名單的機制。對於其餘沒有認證過的節點,都沒法對外服務,這樣作當然也有一些優點,帶來的最大問題就是不夠友好。

所以,在 19 年末開始,咱們對心跳作了一系列的改動,特別鳴謝社區用戶 @zhanggguoqing。通過一段時間的驗證踩坑後,基本就造成了如今的形式。

額外的補充

有關心跳還有一個涉及到的問題就是 cluster.id 這個文件。它實際是爲了防止 storaged 與錯誤的 metad 通訊,大體原理以下:

  • 首先,metad 在啓動的時候會根據 meta_server_addrs 這個參數,生成一個 hash 值並保存在本地 kv 中。
  • storaged 在啓動的時候會嘗試從 cluster.id 這個文件中獲取對應 metad 的 hash 值,並附送在心跳中發送(若是文件不存在,則第一次使用 0 代替。收到心跳響應時,將 metad 的 hash 值保存在 cluster.id 這個文件中,後續一直使用該值)。
  • 在心跳處理中,metad 會比較本地 hash 值和來自 storaged 心跳請求中的 hash 值,若是不匹配則拒絕。此時,storaged 是沒法對外服務的,也就是 Reject wrong cluster host 這個日誌的由來。

以上就是心跳機制大體的介紹,感興趣的你能夠參考下源碼實現,GitHub 傳送門:github.com/vesoft-inc/…

推薦閱讀

相關文章
相關標籤/搜索