很多做物联网或者监控系统的开发者,用InfluxDB存时序数据的时候,都会碰到同一个问题:单节点扛不住流量,要么写入失败,要么查询卡成狗,这时候就需要给InfluxDB集群搭个负载均衡,把请求分摊到多个节点上,今天就把我在项目里实践的方案和细节讲清楚。
一、InfluxDB集群负载均衡的核心需求与应用场景
1.1 哪些场景必须用负载均衡
首先得搞清楚,什么时候才需要给InfluxDB集群加负载均衡,不是所有情况都要。 第一种是设备上报量突增,比如我之前做的社区智能电表项目,平时三千多台电表每10秒上报一次数据,单节点刚好够,但是到了节假日,小区的电表会集中上传当日的电费统计,上报量直接翻2倍,单节点的CPU和内存瞬间拉满,写入成功率跌到60%以下,这时候必须分摊流量。 第二种是多终端高频查询,比如企业的监控平台,同时有上百个运维人员看服务器状态面板,每个面板要拉取最近1小时的10个指标,这么多查询请求堆在单节点上,查询延迟会从几百毫秒涨到10秒以上,用户体验极差。 第三种是业务扩容,项目初期用单节点就能搞定,后期用户量起来了,加了2-3个InfluxDB节点,这时候必须让新节点也参与请求处理,不能让新节点闲置,负载均衡就是干这个的。
1.2 不用负载均衡的坑
要是不用负载均衡,所有请求都打在主节点上,一旦主节点崩了,整个监控系统就瘫痪了,而且主节点的压力会越来越大,最后数据丢失或者延迟超标的情况很常见,负载均衡其实就是给集群加一道保险,同时提升性能。
二、适合InfluxDB集群的负载均衡方案选择
2.1 主流方案对比
现在给InfluxDB做负载均衡的方案有三种,选哪种得看团队的技术能力和业务规模: 第一种是用Nginx,这个是最适合中小团队的,配置简单,不用改业务代码,只要写几行配置就能跑通,还能加健康检查、调整请求策略,门槛很低; 第二种是用HAProxy,性能比Nginx好一点,但是配置比Nginx复杂,适合对性能要求极高的大规模集群; 第三种是用云服务商的负载均衡,比如阿里云、腾讯云的LB,不用自己维护,但是要花钱,而且不能完全自定义策略,适合没有运维团队的小团队。
2.2 我们的方案选择
我当时的项目是中小团队,技术人员不多,所以选了Nginx,毕竟配置简单,出问题了自己能改,不用找云厂商的客服,而且Nginx也支持健康检查,足够应付我们的业务规模。
三、Nginx配合InfluxDB集群的实践方案
3.1 核心配置示例(带详细注释)
技术栈:Nginx 1.22.0 + InfluxDB 2.6.0集群 这里给的是完整的Nginx配置,直接复制就能用,注意改里面的节点IP和域名:
# 这个文件是Nginx的配置文件,路径一般在/etc/nginx/conf.d/influx-lb.conf
# 第一步:定义InfluxDB集群的后端节点,把所有节点列在这里,配置负载策略
upstream influx_cluster {
server 192.168.1.10:8086; # 第一个InfluxDB节点,默认端口8086
server 192.168.1.11:8086; # 第二个节点
server 192.168.1.12:8086; # 第三个节点,InfluxDB集群至少要2个节点才能高可用
}
# 第二步:配置Nginx的监听端口和域名,把外部请求导进来
server {
listen 80; # 监听80端口,所有HTTP请求都会被截下来处理
server_name influx-lb.your-domain.com; # 改成你自己的域名,或者内网的IP地址
location / {
# 核心:把所有请求转发给刚才定义的influx_cluster集群
proxy_pass http://influx_cluster;
# 下面的四个头信息必须加,不然InfluxDB会报错,或者日志里看不到真实的客户端IP
proxy_set_header Host $host; # 把请求的Host头传给后端节点,让节点知道对应的域名
proxy_set_header X-Real-IP $remote_addr; # 把真实客户端的IP传给后端,方便排查问题
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录整个代理链的IP
proxy_connect_timeout 60s; # 连接后端节点的超时时间,太长的话请求会卡,太短会误判
proxy_send_timeout 60s; # 发送数据的超时时间,适合时序数据的大写入
proxy_read_timeout 60s; # 接收响应的超时时间,这个一定要设够,不然慢查询会被断开
}
}
3.2 负载策略调整
刚才的配置默认用轮询策略,就是请求逐个发给节点,适合所有节点性能一样的情况,要是节点性能不一样,比如有的节点配置高,能扛更多请求,可以加权重,示例:
upstream influx_cluster {
server 192.168.1.10:8086 weight=5; # 权重是5,比默认的1高,能接更多请求
server 192.168.1.11:8086 weight=3; # 权重3,比高配置节点少接
server 192.168.1.12:8086 weight=1; # 权重1,性能稍差的节点少接
}
还有一种策略是ip_hash,就是同一IP的请求固定发给同一个节点,适合需要会话保持的场景,不过InfluxDB是无状态的,一般不用这个,没必要。
四、实践中的注意事项
4.1 后端节点必须是真正的集群节点
这个是最容易踩的坑,要是把单独的InfluxDB节点加进来,不是集群的,那负载均衡转发的请求会被当成独立节点处理,导致数据不一致,怎么验证?用这个命令:
# 在任意一个InfluxDB节点上执行,查看集群的节点状态
influxd inspect show membership
注释:这个命令会列出所有加入集群的节点,状态是active就是正常的,要是没有集群,得先把节点加进去,用influxd join 其他节点IP:8088命令,这个是前提,不然负载均衡白搭。
4.2 必须加健康检查
要是某个InfluxDB节点挂了,默认Nginx会把请求继续发给它,导致大量失败请求,必须加健康检查,示例:
upstream influx_cluster {
server 192.168.1.10:8086 weight=5;
server 192.168.1.11:8086 weight=3;
server 192.168.1.12:8086 weight=1;
# 健康检查配置,每5秒检查一次节点的健康状态
health_check interval=5s fails=2 passes=2;
# 检查的是InfluxDB默认的健康接口/health,返回200就是正常的
health_check_http_code 200;
}
注释:这个配置的意思是,连续2次检查失败就标记节点不可用,连续2次成功就恢复,这样某个节点挂了,Nginx会自动把它踢出去,不影响整体服务。
4.3 超时时间不能设太短
时序数据的查询有时候会比较慢,比如查最近24小时的所有电表数据,可能需要几秒甚至十几秒,要是超时设成10秒,就会导致很多正常的查询被断开,我当时设的是60秒,刚好平衡了性能和稳定性。
五、方案的优缺点总结
5.1 优点
第一个是配置简单,中小团队不用花太多时间就能搭起来,改个配置就生效,不用改业务代码; 第二个是灵活,能根据节点性能调整权重,还能加健康检查、调整超时,适合不同的业务场景; 第三个是可控性强,所有配置自己说了算,不用依赖第三方服务,出问题了自己能排查。
5.2 缺点
第一个是要自己维护Nginx,比如要监控Nginx的状态,要更新Nginx的版本,要是Nginx挂了,整个负载均衡就失效了,所以还要给Nginx做高可用,比如用Keepalived做双机热备; 第二个是集群规模太大的时候,比如超过10个节点,Nginx的性能可能跟不上,这时候要换HAProxy或者云LB。
六、实际项目中的调整
我当时的项目里,一开始只有2个InfluxDB节点,用了Nginx之后,写入成功率从70%升到了99.9%,后来又加了1个节点,调整权重,把新节点的权重设成3,分担了一部分查询请求,查询延迟从1秒降到了300毫秒,用户的反馈好了很多,这个方案真的解决了我们的实际问题。
七、总结
给InfluxDB集群加负载均衡,核心是选对适合自己团队的方案,中小团队用Nginx就足够了,关键要做好健康检查、加对必要的头信息、设置合理的超时时间,这样就能避免单节点压力过大,保证时序数据的写入和查询稳定,要是大规模集群再考虑其他方案,这个方案适合大多数中小团队的场景,新手也能快速上手。
评论
围绕“InfluxDB集群环境下的负载均衡方案与实践”参与讨论