influxdb集群模式原理
参考:https://docs.influxdata.com/enterprise_influxdb/v1/concepts/clustering
架构图:
image.png
meta节点:一般3个,他们之间通过raft协议来保证数据一致性,每个meta节点都有相同的数据
保存了如下信息:
所有节点的信息
所有的 databases and retention
shards and shard groups,以及和节点的对应关系
用户信息
continuous queries
数据节点:
个数不限,保存所有表的数据
数据节点之间是不用raft协议的,不同节点上的数据也不同
分片组和分片:
在retention 的配置中,可以定义分片的时间范围,比如1天一个分片组
分片组是由时间来决定的
一个分片组下可以有多个分片,这是由表名和标签来决定的
shard := shardGroup.shards[fnv.New64a(key) % len(shardGroup.Shards)]
一个分片组里有多少个分片,是自动计算的,即数据节点数 / 复制系数
比如总共4个数据节点,复制系数是2,那么一个组有2个分片
为什么分片组下面还有分片?这是因为分片组只是按时间划分,分片则在时间的基础上进一步的划分
可以用show shards命令查看
数据写入:
数据写入请求可以发到任何一个数据节点,并且指定consistency 参数,数据节点会计算数据属于哪个shard,这个shard在哪些数据节点,然后给他们下发写入请求,并根据consistency 来决定如何返回给客户端
比如有A B C D4个数据节点,数据属于shard 1,并且这个shard在节点A和B。节点D收到请求后,给A和B发请求,根据consistency 的不同:
any: 如果收到任何一个节点返回成功,或者自己把请求写到hinted handoff queue,就可以返回成功了
one: 任何一个节点返回成功,才给客户端返回,比any要严格一点了
quorum :需要多数节点返回成功,复制系数大于等于3时才有效,否则就相当于all
all:所有节点都要返回成功。 否则给客户端失败
hinted handoff:
他是一个基于磁盘持久化的队列,写数据时会同时写到这个队列。如果是any, one or quorum时,当给客户端返回成功,但是实际有节点失败时,负责处理请求的节点就会从队列里拿出请求,尝试重新给失败的节点发,所以这个队列是用来自动重发的,重发的次数是可配的。
即使进程重启了,也会从队列里拿出来重发。这个机制和clickhouse是类似的
数据查询:
节点收到查询时,会根据时间范围找到分片组,根据表名和标签找到分片,再根据metadata找到具体的数据节点,当复制系数大于1时,会选一个节点执行查询,并且优先考虑本节点。数据涉及多个分片时,会并发的下发到分片进行查询,收到数据后再进行合并返回给客户端