Documentation

InfluxDB企业版中的聚类

本文件详细描述了InfluxDB Enterprise中聚类的工作原理。 它首先对集群的不同组件进行高层次的描述, 然后概述实施细节。

架构概述

一个InfluxDB Enterprise安装由两组软件进程组成:数据节点和元节点。集群内的通信如下所示:

flowchart TB subgraph meta[Meta Nodes] Meta1 <-- TCP :8089 --> Meta2 <-- TCP :8089 --> Meta3 end meta <-- HTTP :8091 --> data subgraph data[Data Nodes] Data1 <-- TCP :8088 --> Data2 end

元节点通过TCP协议和Raft共识协议相互通信,默认使用端口 8089。该端口在元节点之间必须可达。元节点还默认将绑定到端口 8091 的HTTP API暴露出来,influxd-ctl 命令使用这个API。

数据节点通过绑定到端口 8088 的 TCP 协议相互通信。数据节点通过绑定到 8091 的 HTTP API 与元节点通信。这些端口在元节点和数据节点之间必须是可达的。

在一个集群中,所有元节点必须与其他所有元节点进行通信。所有数据节点必须与其他所有数据节点和所有元节点进行通信。

元节点保持对描述集群的元数据的一致视图。元集群使用HashiCorp的Raft实现作为基础共识协议。这与他们在Consul中使用的实现相同。

数据节点通过TCP使用Protobuf协议复制数据并相互查询。有关复制和查询的详细信息将在本文档后面介绍。

数据存储的位置

元数据节点和数据节点分别负责数据库的不同部分。

元节点

元节点保存以下所有元数据:

  • 集群中的所有节点及其角色
  • 集群中存在的所有数据库和保留策略
  • 所有分片和分片组,以及它们存在于哪些节点上
  • 群集用户及其权限
  • 所有连续查询

元节点在磁盘上的Raft数据库中保留这些数据,后端使用BoltDB。默认情况下,Raft数据库是 /var/lib/influxdb/meta/raft.db

注意: 元节点需要 /meta 目录。

数据节点

数据节点包含所有原始时间序列数据和元数据,包括:

  • 测量
  • 标签键和值
  • 字段键和值

在磁盘上,数据始终按照 // 组织。默认的父目录是 /var/lib/influxdb/data

注意: 数据节点需要 /var/lib/influxdb/ 的所有四个子目录,包括 /meta (具体来说,是 clients.json 文件),/data/wal,和 /hh

最优服务器数量

在创建集群时,您需要决定配置和连接多少个元数据节点和数据节点。您可以将InfluxDB Enterprise视为两个相互通信的独立集群:一个是元数据节点的集群,另一个是数据节点的集群。元数据节点的数量由它们需要处理的元数据节点故障的数量决定,而数据节点的数量则根据您的存储和查询需求进行扩展。

Raft 共识协议要求进行任何操作时都需要达到法定人数,因此应该始终有一个奇数的元节点。对于几乎所有应用,3 个元节点是你所需要的。这使得你拥有一个奇数的元节点,以便可以达到法定人数。如果一个元节点丢失,集群仍然可以与剩下的 2 个元节点一起操作,直到第三个被替换。增加元节点会成倍增加通信开销,除非你预期集群会频繁丢失元节点,否则不推荐这样做。

数据节点保存实际的时间序列数据。运行所需的最小数据节点数为1,之后可以进行扩展。通常,您会希望运行的数据节点数量能够被复制因子整除。例如,如果您的复制因子为2,您将希望运行2、4、6、8、10等数据节点。

Chronograf

Chronograf 是InfluxData TICK栈的用户界面组件。 这使得监控和警报的设置和维护变得简单。 它通过HTTP协议直接与数据节点和元节点通信,默认绑定到数据节点的端口 8086 和元节点的端口 8091

在集群中写入

本节描述了集群中的写入是如何工作的。我们将通过一个包含四个数据节点的集群来进行一些示例: A, B, C, 和 D。假设我们有一个保留策略,副本因子为 2,分片持续时间为 1 天。

分片组

集群在一个分片组内创建分片,以最大化使用的数据节点数量。如果集群中有N个数据节点,并且复制因子为X,则在每个分片组中创建N/X个分片,舍弃任何小数部分。

这意味着每一天写入的数据都会创建一个新的分片组。在每个分片组内会创建2个分片。由于复制因子的原因,每个分片在2台服务器上都会有副本。例如,我们有一个分片组用于 2016-09-19,它有两个分片 12。分片 1 被复制到服务器 AB,而分片 2 被复制到服务器 CD

当一个写入到达,带有时间戳值2016-09-19时,集群必须首先确定在分片组内哪个分片应该接收该写入。这是通过对measurement + 排序的tagset(元系列)进行哈希并将其分配到正确的分片来完成的。在Go中,这看起来像:

// key is measurement + tagset
// shardGroup is the group for the values based on timestamp
// hash with fnv and then bucket
shard := shardGroup.shards[fnv.New64a(key) % len(shardGroup.Shards)]

这个方案对确定数据在集群中所在位置有多个影响。首先,对于任何给定的元系列,在任何给定的一天,所有数据都存在于一个单独的分片中,因此仅存在于那些托管该分片副本的服务器上。其次,一旦创建了分片组,向集群添加新服务器将无法提升该分片组的写入能力。复制在创建分片组时是固定的。

然而,当扩展集群时,有一种方法可以在当前分片组(即今天)中扩展写入。可以使用 influxd-ctl truncate-shards 将当前分片组截断,以停止在当前时间。这会立即关闭当前分片组,强制创建一个新的分片组。新的分片组继承最新的保留策略和数据节点更改,然后适当地复制到新可用的数据节点上。运行 influxd-ctl truncate-shards help 获取有关该命令的更多信息。

写一致性

每个对HTTP API的请求可以通过consistency查询参数指定一致性级别。在这个例子中,我们假设一个HTTP写入被发送到服务器D,并且数据属于分片1。该写入需要复制到分片1的所有者:数据节点AB。当写入到达D时,该节点从其元存储的本地缓存中确定该写入需要复制到AB,并立即尝试同时写入这两个节点。后续行为取决于选择的一致性级别:

  • any - 一旦任何节点已成功写入响应,或接收节点已将数据写入其提示转发队列,则立即将成功返回给客户端。在我们的示例中,如果 ABD 返回成功的写入响应,或者如果 D 在其本地提示转发中缓存了写入,D 会将写入成功返回给客户端。
  • one - 一旦任何节点以写入成功的方式响应客户端,就立即返回成功给客户端,但如果写入仅在提示接管中,则不会如此。在我们的例子中,如果 ABD 返回成功的写入响应,D 会向客户端返回写入成功。如果 D 无法将数据发送到 AB,而是将数据放入提示接管中,D 将向客户端返回写入失败。请注意,这意味着写入可能会返回失败,但当提示接管完成时,数据最终可能会成功持久化。
  • quorum - 当大多数节点返回成功时返回成功。此选项仅在复制因子大于2时有用,否则它等同于all。在我们的例子中,如果AB都向D返回成功的写入响应,D会向客户端返回写入成功。如果AB中的任何一个未返回成功,则大多数节点未成功持久化写入,D会向客户端返回写入失败。如果我们暂时假设数据要发送至三个节点ABC,那么如果其中任何两个节点响应写入成功,D会向客户端返回写入成功。如果一个或更少的节点响应成功,D会向客户端返回写入失败。请注意,这意味着写入可能返回失败,而数据最终可能仍然成功持久化,当提示交接耗尽时。
  • all - 只有当所有节点都返回成功时才返回成功。在我们的示例中,如果 AB 都返回成功的写入响应给 D,则 D 向客户端返回写入成功。如果 AB 中的任何一个没有返回成功,那么 D 向客户端返回写入失败。如果我们再次假设有三个目标节点 ABC,那么如果三个节点都响应写入成功,D 将向客户端返回写入成功。否则,D 向客户端返回写入失败。请注意,这意味着写入可能返回失败,但数据可能最终在提示移交时成功持久化。

重要的是要注意失败是如何处理的。在失败的情况下,数据库使用提示交接系统。

提示转交

提示交接是 InfluxDB Enterprise 在写入过程中处理数据节点故障的方式。提示交接本质上是一个持久的基于磁盘的队列。当以 anyonequorum 一致性进行写入时,当一个或多个副本在成功返回给客户端后返回错误时,将使用提示交接。当以 all 一致性写入时,除非所有节点都返回成功,否则写入不能返回成功。暂时停滞或失败的写入仍可能进入提示交接队列,但集群已经向写入返回了失败响应。接收节点在磁盘上为每个无法访问的数据节点(和分片)创建一个单独的队列。

我们再用一个例子,写入到 D,应该发送到 AB 的分片 1。如果我们指定了一致性级别为 one 且节点 A 返回成功,D 立即向客户端返回成功,即使写入到 B 仍在进行中。

现在假设 B 返回了一个错误。节点 D 然后将写入操作放入节点 B 上分片 1 的提示交接队列中。在后台,节点 D 继续尝试通过将数据写入节点 B 来清空提示交接队列。配置文件中有关于提示交接队列中数据的最大大小和年龄的设置。

如果数据节点被重新启动,它会检查提示转交队列中的待处理写入,并重新尝试复制这些写入。重要的是要注意,提示转交队列是持久的,并且能够在进程重启后存活。

在一个活跃的集群中重新启动节点时,例如在升级或维护期间,集群中的其他节点会将提示转交写入到离线节点,并在节点再次可用时进行复制。因此,一个健康的集群应该在每个数据节点上有足够的资源余量来处理节点故障后提示转交写入的激增。返回的节点需要处理稳定状态的流量和来自其他节点的排队提示转交写入,这意味着其写入流量在任何超出几秒钟的故障后将会有显著的激增,直到提示转交队列被清空。

如果一个节点有待处理的提示转交,当另一个数据节点接收到发往该节点的写入时,它将该写入添加到提示转交队列的末尾,而不是尝试直接写入。这确保了数据节点能够按大致的时间顺序接收数据,并防止在另一个节点离线时进行不必要的连接尝试。

集群中的查询

集群中的查询是根据所查询的时间范围和数据的复制因子进行分配的。例如,如果保留策略的复制因子为4,则接收查询的协调数据节点会随机选择存储分片副本的4个数据节点中的任何一个来接收该查询。如果我们假设系统的分片持续时间为一天,那么对于查询覆盖的每一天,协调节点会选择一个数据节点来接收该天的查询。

协调节点在可能的情况下执行并实现查询。 如果查询必须扫描多个分片组(上面示例中的多个日期),协调节点将查询转发给其他节点,以便处理它本地没有的分片。 查询以并行方式转发,以扫描其自己的本地数据。 查询被分发到尽可能多的节点,以便每个分片组查询一次。 随着来自每个数据节点的结果返回,协调数据节点将它们组合成返回给用户的最终结果。



Flux的未来

Flux 正在进入维护模式。您可以像现在一样继续使用它,而无需对您的代码进行任何更改。

阅读更多

InfluxDB 3 开源版本现已公开Alpha测试

InfluxDB 3 Open Source is now available for alpha testing, licensed under MIT or Apache 2 licensing.

我们将发布两个产品作为测试版的一部分。

InfluxDB 3 核心,是我们新的开源产品。 它是一个用于时间序列和事件数据的实时数据引擎。 InfluxDB 3 企业版是建立在核心基础之上的商业版本,增加了历史查询能力、读取副本、高可用性、可扩展性和细粒度安全性。

有关如何开始的更多信息,请查看: