共计 2639 个字符,预计需要花费 7 分钟才能阅读完成。
本文首发 Nebula Graph 官网:https://nebula-graph.com.cn/posts/cluster-communication-heartbeat/
在用户应用 Nebula Graph 的过程中,常常会遇到各种问题,通常咱们都会倡议先通过 show hosts
查看集群状态。能够说,整个 Nebula Graph 的集群状态都是靠心跳机制来构建的。本文将从心跳说起,帮忙你理解 Nebula Graph 集群各个节点之间通信的机制。
什么是心跳?有什么作用?
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 节点。
2. 上报节点信息
在 metad 收到心跳时,会将心跳中的 ip、port、节点类型、心跳工夫等等信息保留,以供后续应用(见下文)。
除此以外 storaged 在本身 leader 数量变动的时候也会上报 leader 信息,在 show hosts
中看到的 Leader count 和 Leader distribution 就是通过心跳汇报的。
3. 更新元信息
当客户通过 console 或者各种客户端,对集群的元信息进行更改之后(例如 create/drop space
、create/alter/drop tag/edge
、update configs
等等),通常在几秒之内,整个集群就都会更新元数据。
每次 graphd 和 storaged 在心跳的响应中会蕴含一个 last_update_time
,这个工夫是由 metad 返回给各个节点的,用于告知 metad 本身最初一次更新元信息的工夫。当 graphd 或者 storaged 发现 metad 的元信息有更新,就会向 metad 获取相应信息(例如 space 信息、schema 信息、配置更改等等)。
咱们以创立一个 tag 为例,如果在 graphd/storaged 获取到新创建的这个 tag 信息之前,咱们无奈插入这个 tag 数据(会报相似 No schema found 这样的谬误)。而当通过心跳获取到对应信息并保留至本地缓存后,就可能失常写入数据了。
心跳上报的信息有什么用?
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 通信,大抵原理如下:
- 首先,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 传送门:https://github.com/vesoft-inc/nebula-graph。
举荐浏览
- 分布式图数据库 Nebula Graph 的 Index 实际
- 分布式图数据库 Nebula Graph 中的集群快照实际