广告位 · 页头(后台-模块管理-新建模块后替换此区域)

Riak集群如何用HAProxy实现负载均衡与高可用?

Riak 是一个基于 Dynamo 理论的分布式键值数据库,集群中每个节点都能独立接收读写请求,节点之间通过 gossip 协议同步状态。理论上客户端可以直接连接任意一个 Riak 节点,但随着节点数量增加,客户端维护全部节点地址会变得复杂,节点上下线时也需要人工调整。引入 HAProxy 作为统一入口,可以把集群地址收敛成一个虚拟 IP 或域名,由 HAProxy 自动探测节点健康状态并分发流量,这对生产环境的稳定性非常重要。

Riak集群如何用HAProxy实现负载均衡与高可用?

Riak 为什么需要独立的负载均衡层

Riak 本身已经具备数据分区和副本机制,应用层读写请求到达任意节点后,该节点会作为协调者转发到数据所在节点。这种设计让单节点故障不会影响数据可用性,但也带来一个问题:客户端连接哪个节点完全由应用自行决定。如果客户端硬编码了三个节点地址,其中一个节点宕机后,请求失败率会明显上升,直到客户端超时重试其他节点。通过 HAProxy 做反向代理后,客户端只需要连接 HAProxy 暴露的一个地址,后端节点故障由 HAProxy 的健康检查自动发现并摘除,客户端无需感知节点变化。

另一个容易被忽略的问题是连接数管理。Riak 节点对并发连接数有一定承受能力,尤其是 Protocol Buffers 接口会维持大量长连接。如果每个应用实例都直连所有节点,连接数会成倍增长。HAProxy 可以在前端合并连接,通过 maxconn 限制总连接数,避免后端节点被突发流量打满。同时,HAProxy 还能做 TLS 终止,让内部 Riak HTTP 接口走明文,外部统一提供 HTTPS 访问,简化证书管理。

此外,Riak 的运维操作经常涉及节点替换、滚动升级和容量扩容。直接暴露节点地址时,这些操作需要通知所有客户端更新配置。使用 HAProxy 后,只需在 HAProxy 配置中修改 server 行并 reload,客户端完全无感知。这种解耦对长期维护非常有价值。

HAProxy 配置 Riak HTTP 接口负载均衡

Riak 提供 HTTP API 和 Protocol Buffers API 两种访问方式。HTTP 接口默认监听 8098 端口,健康检查可以通过发送 GET /ping 请求来判断节点是否存活。下面是一份基于 HTTP 模式的 HAProxy 配置,监听 80 端口并将请求转发到三台 Riak 节点的 8098 端口。

global
    log 127.0.0.1 local0 info
    maxconn 20000
    user haproxy
    group haproxy
    daemon
defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    retries 3
frontend riak_http_front
    bind *:80
    default_backend riak_http_back
backend riak_http_back
    mode http
    balance leastconn
    option httpchk GET /ping
    http-check expect status 200
    default-server inter 3s fall 3 rise 2
    server riak1 192.168.10.11:8098 check
    server riak2 192.168.10.12:8098 check
    server riak3 192.168.10.13:8098 check

这份配置中,backend 使用 leastconn 算法,将新连接优先分配给当前活动连接数最少的节点。Riak 的读写请求处理时间不一致,leastconn 比简单的轮询更能反映节点实际负载。option httpchk GET /ping 让 HAProxy 每隔几秒向后端发送 HTTP GET 请求,Riak 节点存活时会返回 200 状态码,请求失败或超时则标记该节点 down。http-check expect status 200 进一步确认状态码,避免 301 或 404 被误判为健康。

健康检查参数 inter 3s fall 3 rise 2 表示每 3 秒检查一次,连续失败 3 次后摘除节点,连续成功 2 次后重新加入。这个参数需要根据网络抖动情况调整:检查过于频繁会增加后端压力,过慢则故障切换不及时。对于 Riak 这类数据库,建议 fall 设置为 3,rise 设置为 2,既能避免瞬时网络抖动导致频繁摘除,又能在节点真正宕机后十几秒内完成切换。

如果 Riak 集群配置了 URL 前缀,例如 riak_core 配置中设置了 http.prefix,那么健康检查路径需要同步修改为 GET /your_prefix/ping。但要确保该路径能正确返回 200。实际部署中,很多团队会关闭前缀,让 /ping 直接可用,减少配置出错概率。

TCP 模式与 Protocol Buffers 接口配置

Riak 的 Protocol Buffers 接口默认监听 8087 端口,使用二进制协议,连接建立后可以复用长连接执行多次操作。这类接口不适合在 HTTP 模式下做七层健康检查,需要切换成 TCP 模式。HAProxy 的 TCP 代理只负责连接转发,不解析应用层协议,健康检查可以用 tcp-check 连接端口判断存活。

frontend riak_pb_front
    bind *:8087
    default_backend riak_pb_back
backend riak_pb_back
    mode tcp
    balance leastconn
    option tcp-check
    default-server inter 3s fall 3 rise 2
    server riak1 192.168.10.11:8087 check port 8087
    server riak2 192.168.10.12:8087 check port 8087
    server riak3 192.168.10.13:8087 check port 8087
    timeout connect 5s
    timeout client 60s
    timeout server 60s

TCP 模式下的健康检查只验证端口是否可连接,无法判断 Riak 节点是否真正处于可用状态。例如节点进程还在但数据分区正在恢复,TCP 连接仍然成功,此时 HAProxy 会把请求继续转发过去。因此如果对可用性要求极高,建议在 Riak 节点上增加一个独立的 HTTP 健康检查端口,或者由外部监控系统配合 HAProxy 的 agent-check 脚本做深度检查。

需要提醒的是,Riak 的 PB 客户端在建立连接后会缓存节点信息,如果后端节点变化,客户端可能因为连接被 HAProxy 转发到不同节点而出现短暂的上下文不一致。这是因为 Riak PB 协议虽然无状态,但部分客户端会在连接层做节点身份校验。遇到这种场景时,可以将 HAProxy 的 balance source 与客户端 IP 哈希结合,保证同一客户端总是路由到同一节点,但这会牺牲一定的负载均衡效果。通常更推荐使用 HTTP 接口作为统一入口,让 HAProxy 发挥更大的价值。

负载均衡策略调优与高可用实践

Riak 集群的负载高低与请求的键分布、副本数量和节点硬件配置密切相关。HAProxy 提供了 roundrobin、leastconn、source、uri 等多种策略。对于 HTTP 接口,如果请求以简单 key-value 读写为主,leastconn 是较为稳妥的选择;如果客户端大量使用管道或批处理操作,可以尝试 source 哈希,让同一客户端的请求集中到一个节点,减少跨节点协调。但要注意 source 哈希在客户端 IP 较少时容易造成热点,需要配合权重参数手动调整。

在故障切换方面,HAProxy 默认只会摘除检查失败的 server,但不会主动重试已经在途的请求。对于 Riak 这类最终一致性数据库,如果一个写请求在节点故障瞬间丢失,客户端可以在应用层重试。因此建议在客户端 SDK 中配置重试策略,并把 HAProxy 的 retries 设置为 1 或 2,避免 HAProxy 层多次重试放大写请求。实际上,Riak 自身的 hinted handoff 和读取修复机制能弥补部分瞬时故障,负载均衡层的重试不必过于激进。

HAProxy 自身也会成为单点,因此生产环境通常配合 Keepalived 做 VRRP 虚拟 IP 漂移。两台 HAProxy 服务器一主一备,当主节点宕机时,备节点接管虚拟 IP,客户端连接不受影响。Keepalived 的配置思路是:主节点 priority 设置为 100,备节点为 90,通过 vrrp_script 监控 HAProxy 进程存活,如果 HAProxy 停止则降低优先级触发切换。这样整体架构就形成了客户端访问虚拟 IP,虚拟 IP 指向 HAProxy,HAProxy 分发到 Riak 节点的完整链路。

最后需要关注监控指标。HAProxy 自带统计页面,可以通过开启 stats 配置查看每个后端节点的健康状态、连接数和错误率。Riak 本身的节点状态可以通过 riak-admin status 或 HTTP 的 /stats 接口获取。将两者结合,可以快速判断是负载均衡层丢弃了请求,还是 Riak 节点本身处理能力不足。调优是一个持续过程,建议从默认配置开始,观察至少两周后再根据实际流量模式修改 balance 算法和超时时间。

广告位 · 文章底部(后台-模块管理替换此区域)