摘要:Nebula Operator 是 Nebula Graph 在 Kubernetes 系統上的自動化部署運維插件。在本文,你將瞭解到 Nebula Operator 的特性及它的工做原理。git
從 Nebula Graph 的架構談起
Nebula Graph 是一個高性能的分佈式開源圖數據庫,從架構上能夠看出,一個完整的 Nebula Graph 集羣由三類服務組成,即 Meta Service, Query Service(Computation Layer)和 Storage Service(Storage Layer)。github
每類服務都是一個由多副本組件組成的集羣,在 Nebula Operator 中,咱們分別稱這三類組件爲: Metad / Graphd / Storaged。數據庫
- Metad:主要負責提供和存儲圖數據庫的元數據,並承擔集羣中調度器的角色,指揮存儲擴容和數據遷移,leader 變動等運維操做。
- Graphd:主要負責處理 Nebula 查詢語言語句(nGQL),每一個 Graphd 都運行着一個無狀態的查詢計算引擎,且彼此間無任何通訊關係。計算引擎僅從 Metad 集羣中讀取元信息,並和 Storaged 集羣進行交互。同時,它也負責不一樣客戶端的接入和交互。
- Storaged:主要負責 Graph 數據存儲。圖數據被切分紅不少的分片 Partition,相同 ID 的 Partition 組成一個 Raft Group,實現多副本一致性。Nebula Graph 默認的存儲引擎是 RocksDB 的 Key-Value 存儲。
在瞭解了 Nebula Graph 核心組件的功能後,咱們能夠得出一些結論:api
- Nebula Graph 在設計上採用了存儲計算分離的架構,組件間分層清晰,職責明確,這意味着各個組件均可以根據自身的業務需求進行獨立地彈性擴容、縮容,很是適合部署在 Kubernetes 這類容器編排系統上,充分發揮 Nebula Graph 集羣的彈性擴縮能力。
- Nebula Graph 是一個較爲複雜的分佈式系統,它的部署和運維操做須要比較深刻的領域知識,這帶來了頗高的學習成本和負擔。即便是部署運行在 Kubernetes 系統之上,有狀態應用的狀態管理、異常處理等需求,原生的Kubernetes 控制器也不能很好的知足,致使 Nebula Graph 集羣不能發揮出它最大的能力。
所以,爲了充分發揮 Nebula Graph 原生具有的彈性擴縮、故障轉移等能力,也爲了下降對 Nebula Graph 集羣的運維管理門檻,咱們開發了 Nebula Operator。架構
Nebula Operator 是 Nebula Graph 在 Kubernetes 系統上的自動化部署運維插件,依託於 Kubernetes 自身優秀的擴展機制,咱們把 Nebula Graph 運維領域的知識,以 CRD + Controller
的形式全面注入到 Kubernetes 系統中,讓 Nebula Graph 成爲真正的雲原生圖數據庫。運維
爲了可以更好的理解 Nebula Operator 的工做原理,讓咱們先回顧一下什麼是 Operator分佈式
什麼是 Nebula Operator
Operator 並非什麼很新的概念,早在 2017 年,就有 CoreOS 公司推出了 Etcd Operator。Operator 的初衷是爲了擴展 Kubernetes 功能,以更好的管理有狀態應用,這得益於 Kubernetes 的兩大核心概念:聲明式 API 和控制循環(Control Loop)。oop
咱們能夠用一段僞代碼來描述這一過程。性能
在集羣中聲明對象X的指望狀態並建立X for { 實際狀態 := 獲取集羣中對象 X 的實際狀態 指望狀態 := 獲取集羣中對象 X 的指望狀態 if 實際狀態 == 指望狀態 { 什麼都不作 } else { 執行事先規定好的編排動做,將實際狀態調協爲指望狀態 } }
在 Kubernetes 系統內,每一種內置資源對象,都運行着一個特定的控制循環,將它的實際狀態經過事先規定好的編排動做,逐步調整爲最終的指望狀態。學習
對於 Kubernetes 系統內不存在的資源類型,咱們能夠經過添加自定義 API 對象的方式註冊。常見的方法是使用 CustomResourceDefinition(CRD)和 Aggregation ApiServer(AA)。Nebula Operator 就使用 CRD 註冊了一個 "Nebula Cluster" 資源,和一個 "Advanced Statefulset" 資源。
在註冊了上述自定義資源以後,咱們就能夠經過編寫自定義控制器的方式來感知自定義資源的狀態變化,並按照咱們編寫的策略和邏輯去自動地運維 Nebula Graph,讓集羣的實際狀態朝着指望狀態趨近。這也是 Nebula Operator 下降用戶運維門檻的核心原理。
apiVersion: nebula.com/v1alpha1 kind: NebulaCluster metadata: name: nebulaclusters namespace: default spec: graphd: replicas: 1 baseImage: vesoft/nebula-graphd imageVersion: v2-preview-nightly service: type: NodePort externalTrafficPolicy: Cluster storageClaim: storageClassName: fast-disks metad: replicas: 3 baseImage: vesoft/nebula-metad imageVersion: v2-preview-nightly storageClaim: storageClassName: fast-disks storaged: replicas: 3 baseImage: vesoft/nebula-storaged imageVersion: v2-preview-nightly storageClaim: storageClassName: fast-disks schedulerName: nebula-scheduler imagePullPolicy: Always
咱們在這裏展現了一個簡單的 Nebula Cluster 實例,若是你想要擴展 Storaged 的副本數量至 10,你只須要簡單修改 .spec.storaged.replicas
參數爲 10,剩下的運維操做則由 Nebula Operator 經過控制循環來完成。
至此,想必你已經對 Nebula Graph 和 Operator 有了一個初步的認知,接下來,讓咱們來列舉目前 Nebula Operator 已經具有了哪些能力,讓你能更加深入的體會到使用 Nebula Operator 帶來的一些實際好處。
- 部署、卸載:咱們將一整個 Nebula Graph 集羣描述成一個 CRD 註冊進 ApiServer 中,用戶只需提供對應的 CR 文件,Operator 就能快速拉起或者刪除一個對應的 Nebula Graph 集羣,簡化了用戶部署、卸載集羣的過程。
- 擴容、縮容:經過在控制循環中調用 Nebula Graph 原生提供的擴縮容接口,咱們爲 Nebula Operator 封裝實現了擴縮容的邏輯,能夠經過 yaml 配置進行簡單的擴容,縮容,且保證數據的穩定性。
- 原地升級:咱們在 Kubernetes 原生提供的 StatefulSet 基礎上爲其擴展了鏡像原地替換的能力,它節省了 Pod 調度的耗時,而且在升級時,Pod 的位置、資源都不發生變化,極大提升了升級時集羣的穩定性和肯定性。
- 故障遷移:Nebula Operator 會內部調用 Nebula Graph 集羣提供的接口,動態的感知服務是否正常運行,一旦發現異常,會自動的去作故障遷移操做,並根據錯誤類型配有對應的容錯機制。
- WebHook:一個標準的 Nebula Graph 最少須要三個 Metad 副本,若是用戶錯誤地修改了此參數,可能會致使集羣不可用,咱們會經過 WebHook 的准入控制來檢查一些必要參數是否設置正確,並經過變動控制來強制修改一些錯誤的聲明,使集羣始終可以穩定運行。
參考資料
- Nebula Graph:https://github.com/vesoft-inc/nebula
做者有話說:Hi,我是劉鑫超,圖數據庫 Nebula Graph 的研發工程師,若是你對此文有疑問,歡迎來咱們的 Nebula Graph 論壇交流下心得~~