0

0

C++如何实现带权重的负载均衡器?(轮询/随机/一致性哈希)

尼克

尼克

发布时间:2026-02-21 15:53:36

|

857人浏览过

|

来源于php中文网

原创

平滑加权轮询通过维护current_weight与total_weight实现负载均衡:每次遍历所有节点,current_weight += weight,选最大者后减去total_weight;带权随机应避免rand()%n偏差,推荐前缀和+二分查找;一致性哈希加权宜用加权跳跃哈希而非简单虚拟节点扩容;三种策略中一致性哈希最易因环同步失败导致线上事故。

c++如何实现带权重的负载均衡器?(轮询/随机/一致性哈希)

轮询策略里怎么加权重?别直接累加计数器

权重轮询不是简单地“每个节点重复调用 weight 次”,那样会破坏请求流的平滑性,尤其在节点权重差异大、总请求数少时,容易出现某节点连续被选中几十次,而另一个几乎不被选中。

真正可用的做法是维护一个当前权重(current_weight)和最大权重(max_weight),每次选择后更新:当前权重 += 节点权重,选中值最大的节点,然后该节点的当前权重 -= 总权重和。这叫“平滑加权轮询”(Smooth Weighted Round Robin)。

  • current_weight 初始设为各节点权重,不是 0
  • 每轮遍历所有节点,找 current_weight 最大的那个
  • 选中后执行 current_weight -= total_weighttotal_weight 是所有原始权重之和)
  • 其他节点的 current_weight 不变,只增不减(靠 += weight 实现)

示例片段(伪代码逻辑):

for (auto& node : nodes) {
    node.current_weight += node.weight;
}
auto selected = max_element(nodes.begin(), nodes.end(),
    [](const auto& a, const auto& b) { return a.current_weight < b.current_weight; });
selected->current_weight -= total_weight;

随机选择带权重时,为什么不能用 rand() % N 直接映射?

因为余数法(rand() % N)在 RAND_MAX 不能被 N 整除时会产生偏差——低编号节点概率略高。而带权随机要求的是按比例采样,偏差会被权重放大。

立即学习C++免费学习笔记(深入)”;

更稳妥的方式是:生成 [0,1) 区间浮点随机数,再做前缀和 + 二分查找。虽然比数组索引慢一点,但无偏差、可扩展、兼容任意浮点权重。

Dang.ai
Dang.ai

Dang.ai是一个AI工具目录集,已收集超过5000+ AI工具

下载
  • 预先计算权重前缀和数组 prefix_sum,长度为 N
  • 调用 std::uniform_real_distribution<double>(0.0, prefix_sum.back())</double> 生成目标值
  • std::lower_boundprefix_sum 中查找第一个 ≥ 目标值的位置
  • 该位置即选中节点下标

注意:如果权重是整数且范围不大(比如都在 1–100),也可用“别名法(Alias Method)”做到 O(1) 查询,但实现复杂、初始化开销大,一般服务场景没必要。

一致性哈希加权重后,虚拟节点还够用吗?

加了权重的一致性哈希,常见做法是按权重分配不同数量的虚拟节点(比如权重 3 就放 300 个虚拟节点,权重 1 就放 100 个)。但这只是近似——真实分布仍取决于哈希函数和节点数量,权重小的节点可能因哈希碰撞少反而负载更高。

更靠谱的做法是:放弃固定虚拟节点数,改用“加权跳跃哈希”(Weighted Jump Hash)或“增强型 Karger-Stein 哈希”,它们在构造环时就内建权重因子,不需要预生成大量虚拟节点。

  • 标准 ketamalibchash 不支持动态权重,硬塞虚拟节点数会放大扩容/缩容抖动
  • 若必须用传统一致性哈希,建议最小虚拟节点数不低于 100 × max_weight,否则权重区分度丢失严重
  • std::hash<:string></:string> 等默认哈希对短 key 分布不均,务必用 xxhashmurmur3 替代

三种策略实际部署时,哪个最容易出线上事故?

一致性哈希最容易在节点变更时出问题——不是算法本身错,而是工程细节没兜住。比如节点 IP 变更但没触发 rehash,或哈希环未全局同步,导致部分实例认为 A 节点已下线、另一些还认为在线,请求直接 502。

  • 轮询和随机策略状态全在内存里,重启即重置,影响面可控
  • 一致性哈希依赖外部协调(如 etcd/ZooKeeper 存环结构),一旦 watch 失败或版本冲突,就会静默降级成纯哈希(无权重)甚至固定路由
  • 权重配置若从文件加载,要注意热更新时机:轮询可立即生效;一致性哈希需重建整个环,期间必须拒绝新连接或冻结路由表

真正的难点不在选哪种算法,而在怎么让权重变更、节点上下线、配置热更这三件事,在多进程/多线程/多机环境下原子生效——这部分没标准解法,得靠你自己的协调机制兜底。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

810

2023.08.02

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

695

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

369

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

26

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

25

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

99

2026.02.06

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

459

2023.08.14

dubbo和zookeeper有什么区别
dubbo和zookeeper有什么区别

dubbo和zookeeper的区别:1、功能定位;2、使用场景;3、数据存储与协调;4、集成与关系;5、性能与可靠性;6、扩展性与灵活性;7、社区与生态系统。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

231

2024.02.23

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

796

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.9万人学习

C 教程
C 教程

共75课时 | 4.9万人学习

C++教程
C++教程

共115课时 | 18.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号