InfluxDB 集群部署与高可用方案(一)
一、InfluxDB 简介
**
1.1 什么是 InfluxDB
InfluxDB 是一款由 InfluxData 公司开发的开源时序数据库,采用 Go 语言编写 ,这使得它具有良好的跨平台性和高效的执行效率,在 DB-Engines 时序数据库排名中常常位列前茅。它专为处理时间序列数据而设计,这类数据的特点是包含时间戳以及与之相关的一系列数值,并且数据通常按照时间顺序生成和记录。InfluxDB 针对这些特性进行了深度优化,拥有诸多亮眼特性。
- 时间索引:InfluxDB 以时间戳为核心进行数据索引,所有数据按时间戳排序存储,支持纳秒级精度,这使得基于时间范围的查询能够快速定位到所需数据 ,极大提升查询效率。例如在查询某一时间段内的服务器性能指标时,能迅速返回结果。
- 高效写入:它采用 LSM Tree(Log-Structured Merge Tree)变种和 TSM(Time Series Measurement)存储格式,这种设计让单机可支持每秒数十万数据点的写入,非常适合物联网、监控系统等需要处理大量高频数据写入的场景。
- 冷热数据分离:InfluxDB 能够自动将高频访问的热数据保留在内存中,以保证快速的读写响应;而对于冷数据,会进行压缩存储到磁盘,有效节省存储空间的同时,也不影响数据的完整性和可查询性。
InfluxDB 的数据模型包含几个关键概念:
- 存储桶(Bucket):类似于关系型数据库中的 “库”,是一个逻辑隔离的数据存储单元,用于将不同来源或用途的数据进行分类存储 。比如可以创建一个名为 “iot_data” 的存储桶专门存放物联网设备产生的数据。
- 测量(Measurement):类似于关系型数据库中的 “表”,用于存储同一类时间序列数据。例如 “cpu_usage” 测量可以用来记录服务器 CPU 使用率相关的数据。
- 标签(Tags):以键值对形式存在的元数据,如 “host=server01” ,标签主要用于索引和高效查询,可以通过标签快速筛选出特定条件的数据。比如想查询某一台服务器的相关数据,就可以通过 “host” 标签来实现。
- 字段(Fields):用于存储实际的数值或状态数据,如 “temperature=25.6”,支持浮点、整数、字符串等多种数据类型,字段是真正记录数据值的地方 。
1.2 InfluxDB 应用场景
InfluxDB 凭借其出色的性能和对时间序列数据的针对性设计,在众多领域都有着广泛的应用。
- 物联网(IoT)领域:物联网设备数量庞大且产生数据频率高,这些设备如传感器、智能家电等产生的数据多为时间序列数据。以智能家居系统为例,智能门锁可以记录用户开锁时间、次数等信息,将这些数据以 Line Protocol 格式发送到 InfluxDB 中存储 。通过 InfluxDB 的查询语言,能够实现对门锁数据的实时监控和分析,比如统计一天内不同时间段的开锁次数,判断用户的生活习惯等。同时 InfluxDB 的高效写入性能可以轻松应对大量智能设备同时上传数据的压力。
- 运维监控领域:在企业的运维监控中,需要实时收集服务器性能指标(CPU、内存、磁盘 I/O 等)、网络设备状态等监控数据 。InfluxDB 可以很好地存储和分析这些数据,当服务器 CPU 使用率持续过高时,通过 InfluxDB 结合监控工具,能够及时触发告警通知运维人员。通过对历史监控数据的分析,还可以预测服务器资源使用趋势,提前进行资源调配,保障业务稳定运行。例如某互联网公司使用 InfluxDB 来监控其大量服务器的运行状态,确保了服务的高可用性。
- 金融领域:金融行业中,时间序列数据在风险管理、交易分析、市场行情监控等方面都发挥着重要作用。比如某银行需要对客户交易数据进行实时监控和分析,以防范风险。将客户交易数据以时间序列格式存储到 InfluxDB 后,利用其查询语言,能够对交易金额、交易时间等关键信息进行实时监控 。一旦发现异常交易行为,如短时间内大额资金频繁进出,可及时采取措施进行风险控制。同时,InfluxDB 强大的聚合查询功能可以帮助金融机构对交易数据进行统计分析,为决策提供数据支持。
- 能源领域:在能源领域,InfluxDB 可以用于存储和分析电力、天然气等能源消耗数据。以电力公司为例,需要对电力消耗数据进行实时监控和分析,以优化电力调度。通过将电力消耗数据按时间序列存储在 InfluxDB 中,利用其查询语言,能够实时监控不同地区、不同用户群体的电力消耗情况 。根据这些数据,电力公司可以合理安排发电计划,避免能源浪费,提高能源利用效率 。还可以通过对历史数据的分析,预测未来的电力需求,为电网建设和升级提供依据。
二、InfluxDB 集群架构剖析
2.1 集群组件
InfluxDB 集群主要包含元数据节点(Meta Node)和数据节点(Data Node)。
元数据节点负责存储和管理整个集群的元数据信息,这些元数据涵盖了数据库的结构定义、保留策略、分片组(Shard Group)和分片(Shard)的元信息等 。比如数据库中有哪些存储桶,每个存储桶的保留策略是数据保存 30 天还是 60 天,以及每个分片组包含哪些具体分片等,都由元数据节点来维护 。元数据节点对于集群的正常运行至关重要,它就像是集群的 “大脑”,协调着各个数据节点的工作,为数据的写入和查询提供必要的元数据支持,确保整个集群的有序运行。
数据节点则是实际存储时间序列数据的地方,承担着数据的写入、读取和查询操作 。当有新的数据写入集群时,数据节点会按照既定的规则将数据存储到相应的分片和存储文件中 。例如,在物联网场景中,传感器不断产生的温度、湿度等数据,都会被写入到数据节点中进行存储 。在查询数据时,数据节点会根据查询条件,从本地存储中检索出符合条件的数据,并返回给用户或应用程序 。多个数据节点协同工作,共同承担数据存储和处理的任务,从而实现集群的高容量和高性能。
在实际运行过程中,元数据节点和数据节点密切协作 。当客户端发起数据写入请求时,首先会与元数据节点进行通信,获取目标数据节点的信息以及相关的元数据,如数据应该写入到哪个分片组和分片中 。然后,客户端根据这些信息将数据发送到对应的数据节点进行存储 。在查询时,客户端同样先与元数据节点交互,获取数据分布的元信息,再到相应的数据节点执行查询操作 。这种协作模式确保了数据的准确存储和高效查询,是 InfluxDB 集群实现高可用性和高性能的基础。
2.2 数据分片与复制
InfluxDB 采用数据分片(Sharding)机制来提高数据存储和查询的效率 。数据分片是将整个数据集按照一定的规则划分为多个较小的部分,每个部分称为一个分片 。常见的分片规则是基于时间范围,例如将数据按天、周或月进行分片 。以监控系统为例,每天产生的服务器性能监控数据可以划分为一个单独的分片 。这样做的好处是在查询特定时间段的数据时,只需要在对应的分片中进行检索,大大减少了数据扫描的范围,提高了查询速度 。比如要查询某一天的 CPU 使用率数据,直接定位到当天对应的分片进行查询即可,无需遍历整个数据集 。
为了保障数据的高可用性,InfluxDB 引入了数据复制(Replication)机制 。每个分片都会在集群中的多个数据节点上进行复制,形成多个副本 。假设一个集群中有 3 个数据节点,设置数据副本数为 2,那么每个分片都会在其中 2 个数据节点上存储 。当某个数据节点出现故障时,其他拥有该分片副本的数据节点可以继续提供服务,确保数据的完整性和可访问性 。例如,数据节点 A 上的某个分片出现故障无法访问,但由于数据节点 B 和 C 上有该分片的副本,应用程序依然可以从 B 或 C 节点上获取到相应的数据 ,从而保证了服务的连续性。
数据分片与复制机制还能实现负载均衡 。在数据写入时,写入请求会根据分片规则被分发到不同的数据节点上,避免单个节点承受过高的写入压力 。在查询时,查询请求也可以根据分片分布情况,合理地分配到各个数据节点,充分利用集群的计算资源,提高整体的查询性能 。比如在一个高并发的物联网应用中,大量传感器数据同时写入,通过分片机制可以将这些写入请求均匀地分配到多个数据节点,确保每个节点的负载相对均衡,防止出现单点性能瓶颈。
2.3 Raft 一致性协议
Raft 协议是 InfluxDB 集群中保证数据一致性和选举主节点的核心机制 。在 InfluxDB 集群中,Raft 协议主要应用于元数据节点之间以及数据节点上的分片副本之间 。
Raft 协议将集群中的节点分为三种角色:领导者(Leader)、跟随者(Follower)和候选者(Candidate) 。在正常情况下,集群中有一个领导者节点,负责处理客户端的写请求,并将数据同步到其他跟随者节点 。当领导者节点接收到写请求时,它会先将数据写入本地日志,然后向集群中的其他跟随者节点发送日志复制请求 。只有当大多数(超过半数)跟随者节点成功复制日志后,领导者节点才会将该数据标记为已提交,并返回成功响应给客户端 。这一过程确保了数据在集群中的一致性,即使部分节点出现故障,只要大多数节点正常,数据的一致性就能得到保证 。例如,在一个包含 5 个节点的集群中,领导者节点将数据写入本地后,向其他 4 个跟随者节点发送日志复制请求,当至少 3 个跟随者节点成功复制日志后,该数据就被认为是已提交的 。
当领导者节点出现故障时,Raft 协议会触发选举过程,从候选者节点中选出新的领导者 。选举的过程如下:当跟随者节点在一定时间内没有收到领导者的心跳消息时,它会认为领导者可能已经故障,于是将自己的状态转换为候选者,并发起选举 。候选者节点会向其他节点发送投票请求,要求它们给自己投票 。每个节点在一个任期(Term)内只能投一票,并且会优先投票给日志更完整的候选者 。当某个候选者节点获得超过半数节点的投票时,它就会成为新的领导者 。新的领导者产生后,会立即向其他节点发送心跳消息,以维持自己的领导地位,并开始处理客户端的请求 。例如,在上述 5 个节点的集群中,当领导者节点故障后,某个跟随者节点超时未收到心跳,成为候选者并向其他 4 个节点发送投票请求,如果它获得了 3 个及以上节点的投票,就会当选为新的领导者 。
通过 Raft 协议,InfluxDB 集群能够在面对节点故障、网络分区等异常情况时,依然保证数据的一致性和服务的可用性 ,为时间序列数据的可靠存储和高效查询提供了坚实的保障。
三、InfluxDB 集群部署实操
3.1 部署前准备
在开始部署 InfluxDB 集群之前,需要确保满足以下条件:
- 服务器环境:准备至少 3 台服务器,建议使用配置相同的服务器以保证集群性能的均衡。服务器的硬件配置应根据实际业务需求进行选择,一般来说,每个节点至少需要 2 核 CPU、4GB 内存以及 50GB 以上的磁盘空间。例如在一个中等规模的物联网监控项目中,使用了 3 台配置为 4 核 CPU、8GB 内存、100GB 磁盘的服务器来搭建 InfluxDB 集群,能够稳定地处理大量传感器数据。
- 操作系统:支持常见的 Linux 发行版,如 Ubuntu 18.04 及以上版本、CentOS 7 及以上版本 。以 CentOS 7 为例,需要确保系统已经安装了必要的依赖包,如yum install -y wget用于下载相关软件。
- 软件安装:安装 Docker 和 Docker Compose,它们能够方便地实现容器化部署,简化集群的搭建过程。可以通过官方文档提供的命令进行安装,例如在 Ubuntu 系统中,安装 Docker 的命令为:
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
安装 Docker Compose 的命令为:
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
- 时间同步:确保所有服务器的时间保持同步,因为 InfluxDB 依赖准确的时间戳进行数据处理。可以使用 NTP(Network Time Protocol)服务来同步时间,在 CentOS 系统中,安装 NTP 服务并设置开机自启的命令为:
sudo yum install ntp
sudo systemctl start ntpd
sudo systemctl enable ntpd
- 网络配置:保证集群节点之间的网络畅通,并且服务器的防火墙允许 InfluxDB 相关端口的通信,默认情况下,InfluxDB 使用 8086 端口进行 HTTP API 通信,8088 端口用于集群内部通信等。如果服务器开启了防火墙,需要开放这些端口,在 CentOS 系统中,开放端口的命令为:
sudo firewall-cmd --zone=public --add-port=8086/tcp --permanent
sudo firewall-cmd --zone=public --add-port=8088/tcp --permanent
sudo firewall-cmd --reload
还需要配置 hosts 解析,确保集群节点之间可以通过主机名解析彼此的 IP 地址 。例如,在/etc/hosts文件中添加如下内容:
192.168.1.10 influxdb-meta-01
192.168.1.11 influxdb-meta-02 influxdb-data-01
192.168.1.12 influxdb-meta-03 influxdb-data-02
3.2 配置元数据节点
元数据节点的配置主要通过修改配置文件来完成,以使用 Docker 部署为例,首先创建一个元数据节点的配置文件influxdb-meta.conf,以下是关键参数的配置说明:
- 元数据存储目录:
[meta]
dir = "/var/lib/influxdb/meta"
这里指定了元数据的存储目录为/var/lib/influxdb/meta,在实际部署中,可以根据服务器磁盘空间情况进行调整,例如将其设置到专门的数据盘挂载目录下,以提高存储性能。
- 绑定地址:
[meta]
bind-address = ":8088"
该参数指定了元数据节点用于集群内部通信的绑定地址和端口,默认为:8088,一般情况下无需修改,除非该端口被其他服务占用。
- HTTP 绑定地址:
[meta]
http-bind-address = ":8091"
用于元数据节点的 HTTP API 通信,默认端口为 8091,同样,若该端口冲突,需进行调整。
3.3 配置数据节点
数据节点的配置同样通过配置文件实现,创建数据节点的配置文件influxdb.conf,关键参数设置如下:
- 数据存储目录:
[data]
dir = "/var/lib/influxdb/data"
wal-dir = "/var/lib/influxdb/wal"
dir指定了最终数据(TSM 文件)的存储目录,wal-dir指定了预写日志(Write-Ahead Logging)的存储目录,这些目录可根据实际需求进行调整,比如设置到高速磁盘阵列上,以提升 I/O 性能。
- 元数据节点地址:
[data]
meta-nodes = ["influxdb-meta-01:8091", "influxdb-meta-02:8091", "influxdb-meta-03:8091"]
这里需要将元数据节点的地址和 HTTP 绑定端口填入meta-nodes数组中,确保数据节点能够与元数据节点进行通信,获取元数据信息。
- 其他参数:
[data]
cache-max-memory-size = 1048576000
cache-snapshot-memory-size = 26214400
cache-snapshot-write-cold-duration = "10m"
cache-max-memory-size用于限定 shard 最大值,大于该值时会拒绝写入;cache-snapshot-memory-size用于设置快照大小,大于该值时数据会刷新到 tsm 文件;cache-snapshot-write-cold-duration表示 tsm 引擎 snapshot 写盘延迟 。这些参数可以根据实际业务的读写负载和数据量进行优化调整,以提高数据节点的性能。
3.4 启动集群
完成元数据节点和数据节点的配置后,即可启动 InfluxDB 集群,同样借助 Docker Compose 来简化启动过程。
- 创建 Docker Compose 文件:创建一个docker-compose.yml文件,内容如下:
version: '3'
services:
influxdb-meta-01:
image: influxdb:latest
container_name: influxdb-meta-01
volumes:
- /data/influxdb/meta-01:/var/lib/influxdb/meta
ports:
- 8088:8088
- 8091:8091
command: -config /etc/influxdb/influxdb-meta.conf -join influxdb-meta-02:8091,influxdb-meta-03:8091
influxdb-meta-02:
image: influxdb:latest
container_name: influxdb-meta-02
volumes:
- /data/influxdb/meta-02:/var/lib/influxdb/meta
ports:
- 8088:8088
- 8091:8091
command: -config /etc/influxdb/influxdb-meta.conf -join influxdb-meta-01:8091,influxdb-meta-03:8091
influxdb-meta-03:
image: influxdb:latest
container_name: influxdb-meta-03
volumes:
- /data/influxdb/meta-03:/var/lib/influxdb/meta
ports:
- 8088:8088
- 8091:8091
command: -config /etc/influxdb/influxdb-meta.conf -join influxdb-meta-01:8091,influxdb-meta-02:8091
influxdb-data-01:
image: influxdb:latest
container_name: influxdb-data-01
volumes:
- /data/influxdb/data-01:/var/lib/influxdb/data
- /data/influxdb/wal-01:/var/lib/influxdb/wal
ports:
- 8086:8086
command: -config /etc/influxdb/influxdb.conf
influxdb-data-02:
image: influxdb:latest
container_name: influxdb-data-02
volumes:
- /data/influxdb/data-02:/var/lib/influxdb/data
- /data/influxdb/wal-02:/var/lib/influxdb/wal
ports:
- 8086:8086
command: -config /etc/influxdb/influxdb.conf
上述配置中,定义了 3 个元数据节点和 2 个数据节点的服务,通过volumes将容器内的数据目录挂载到宿主机的指定目录,以实现数据的持久化存储 。ports将容器内的端口映射到宿主机,方便外部访问 。command指定了启动容器时使用的配置文件和加入集群的相关参数。
- 启动集群:在docker-compose.yml文件所在目录下执行以下命令启动集群:
sudo docker-compose up -d
-d参数表示在后台运行容器。
- 验证集群状态:可以通过进入任意一个数据节点的容器,使用 InfluxDB 的命令行工具来验证集群是否正常运行。进入容器的命令为:
sudo docker exec -it influxdb-data-01 bash
然后在容器内执行以下命令查看集群节点状态:
influx -execute 'SHOW SERVERS'
如果集群正常运行,会显示所有元数据节点和数据节点的信息,类似如下输出:
name: data_nodes
----------------
id http_addr tcp_addr
1 192.168.1.11:8086 192.168.1.11:8088
2 192.168.1.12:8086 192.168.1.12:8088
name: meta_nodes
----------------
id http_addr tcp_addr
1 192.168.1.10:8091 192.168.1.10:8088
2 192.168.1.11:8091 192.168.1.11:8088
3 192.168.1.12:8091 192.168.1.12:8088
还可以通过向集群写入一些测试数据,然后进行查询,来进一步验证集群的数据读写功能是否正常 。例如,在命令行中执行以下命令写入测试数据:
influx -execute 'INSERT cpu,host=server1 value=50'
接着查询数据:
influx -execute 'SELECT * FROM cpu'
如果能够正确返回写入的数据,说明集群的数据读写功能正常。