本文首发 Nebula Graph 官网:nebula-graph.com.cn/posts/clust…git
在用户使用 Nebula Graph 的过程当中,常常会遇到各类问题,一般咱们都会建议先经过 show hosts
查看集群状态。能够说,整个 Nebula Graph 的集群状态都是靠心跳机制来构建的。本文将从心跳提及,帮助你了解 Nebula Graph 集群各个节点之间通讯的机制。github
Nebula Graph 集群通常包含三种节点,graphd 做为查询节点,storaged 做为存储节点,metad 做为元信息节点。本文说的心跳,主要是指 graphd 和 storaged 按期向 metad 上报信息的这个心跳,借助心跳,整个集群完成了如下功能。(相关参数是 heartbeat_interval_secs
)数据库
在 Nebula Graph 中常常说起的 raft 心跳则是用于拥有同一个 partition 的多个 storaged 之间的心跳,和本文提的心跳并不相同。缓存
当咱们启动一个 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
在 metad 收到心跳时,会将心跳中的 ip、port、节点类型、心跳时间等等信息保存,以供后续使用(见下文)。运维
除此之外 storaged 在自身 leader 数量变化的时候也会上报 leader 信息,在 show hosts
中看到的 Leader count 和 Leader distribution 就是经过心跳汇报的。分布式
当客户经过 console 或者各类客户端,对集群的元信息进行更改以后(例如 create/drop space
、create/alter/drop tag/edge
、update 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 hosts
、show parts
这类命令都是经过 metad 中保存的各个节点心跳信息,组合显示出来的。balance data
、balance 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 通讯,大体原理以下:
meta_server_addrs
这个参数,生成一个 hash 值并保存在本地 kv 中。以上就是心跳机制大体的介绍,感兴趣的你能够参考下源码实现,GitHub 传送门:github.com/vesoft-inc/…。