[转帖]关于一致性哈希算法在游戏服务器端的思考

关于,一致性,哈希,算法,游戏,服务器,端的,思考 · 浏览次数 : 0

小编点评

**a. 新增/减少节点问题** 1. 使用一致性哈希算法来确定要新增或减少的节点。 2. 当新节点连接时,对其进行一致性哈希计算,并将其映射到合适的节点上。 3. 当节点数量变化时,对已经连接的节点进行一致性哈希计算,并更新其节点映射关系。 **b. 整体负载均匀问题** 1. 使用负载均衡算法,例如 Round Robin,将所有节点分配到不同的服务器上。 2. 监控节点负载,并根据负载变化动态调整服务器分配。 3. 使用一致性哈希,在添加或删除节点时,重新分布节点,以保持负载均衡。 **扩展思路** 1. 使用有限负载一致性哈希 (FLSH) 来降低添加/删除节点的影响。 2. 使用动态负载一致性哈希 (DLSH) 来动态调整节点分配。 3. 使用多台服务器的负载均衡器来提高性能。

正文

https://www.jianshu.com/p/b8ae27cf22a9

突然想明白 其实网易的将军令 就是一个一致性哈希的玩法

 

关于一致性哈希算法在游戏服务器端的思考

  1. 需求分析

    • 后端有很多逻辑node节点(not-section binded),节点启动后注册到注册中心
      • node本身有状态,有内存cache,有过期时间
    • 客户端登陆,需要从注册中心分配一个node
      • a. 客户端需要在一段时间内连接固定节点(长连接)。因为内存有状态,最好支持客户端断线一段时间再次连接还是之前的节点
      • b. 节点最好是相对负载均匀的
      • 考虑新增/减少节点(宕机),最好保证a/b两点
  2. 引入一致性hash算法

    • 算法主要参考:dubbo ConsistentHashSelector 并做部分修改

    • 算法测试

      • a. 初始运营服5个,每个服10w注册,即50w注册。后端一个node承载1w,后端初始50个node

        算法步骤

        1. 初始化50w个rid,rid格式 serverId_id,shuffle
        2. build hash ring,replicaNumber(虚拟节点) = 160
        3. 依次遍历shuffle后的rid list,从hash ring select
        4. 看node整体分布情况(最大、最小、平均、标准差)
        5. 不断调整虚拟节点数目

        统计结果展示

        [7743, 8777, 8847, 8932, 8985, 9100, 9185, 9229, 9274, 9308, 9330, 9478, 9625, 9638, 9660, 9697, 9699, 9728, 9748, 9791, 9794, 9847, 9904, 10021, 10053, 10055, 10063, 10073, 10257, 10258, 10263, 10291, 10356, 10374, 10376, 10486, 10519, 10521, 10581, 10620, 10628, 10678, 10719, 10783, 10790, 10837, 10859, 11001, 11120, 12099]
        replica:160 |max:12099|min:7743|mean:10000.0|std:750.9|median:10054.0

        [9142, 9393, 9518, 9525, 9549, 9578, 9626, 9659, 9667, 9690, 9765, 9777, 9811, 9831, 9848, 9850, 9886, 9889, 9909, 9933, 9940, 9958, 9998, 10002, 10007, 10029, 10030, 10050, 10052, 10129, 10152, 10158, 10182, 10184, 10202, 10212, 10213, 10215, 10247, 10265, 10273, 10279, 10297, 10321, 10322, 10342, 10358, 10420, 10456, 10861]

        replica:1280 |max:10861|min:9142|mean:10000.0|std:317.2|median:10018.0

        结论

        1. 在节点不动态变化的情况,算法可以保证同一个rid每次都select到同一个node
        2. 通过调整replicaNumber,可以让node负载相对均匀
        3. 因为rid样本是可确定的,所以可以这种方式不断调整hash ring的参数,来符合实际的负载情况,即是可预测的
          • 如果一个node负载是1w,那么目前会有node overloaded。实际可以考虑将node负载调整为9k
      • b. 从a的结果上看,看似很美好,比较好的满足我们的需求,but 我们还要考虑新增/减少节点的情况

        假设

        1. 让我们问问题先简化一下 因为我们本身是长连接,所以假设之前的50w个rid全部连接到已知的50个node

        2. 需求:准备开始开第6个服,在新增10个node,用来承载10w人,并重建hash ring

        测试输出

        // 这个是已经连接的50个node的数据分布情况,和a的结果一致,也验证了本身一致性hash算法的正确性

        [9142, 9393, 9518, 9525, 9549, 9578, 9626, 9659, 9667, 9690, 9765, 9777, 9811, 9831, 9848, 9850, 9886, 9889, 9909, 9933, 9940, 9958, 9998, 10002, 10007, 10029, 10030, 10050, 10052, 10129, 10152, 10158, 10182, 10184, 10202, 10212, 10213, 10215, 10247, 10265, 10273, 10279, 10297, 10321, 10322, 10342, 10358, 10420, 10456, 10861]

        replica:1280 |max:10861|min:9142|mean:10000.0|std:317.2|median:10018.0

        // 这个是新增10个node后的数据分布情况

        [1499, 1534, 1569, 1652, 1673, 1675, 1684, 1712, 1713, 1723, 10585, 10948, 11119, 11162, 11173, 11177, 11223, 11267, 11270, 11324, 11348, 11404, 11504, 11511, 11530, 11546, 11547, 11569, 11570, 11610, 11631, 11635, 11674, 11681, 11684, 11706, 11742, 11750, 11758, 11769, 11796, 11815, 11842, 11855, 11878, 11908, 11912, 11921, 11933, 11952, 11991, 11996, 12019, 12068, 12068, 12077, 12089, 12157, 12215, 12657]

        replica:1280 |max:12657|min:1499|mean:10000.0|std:3783.8|median:11620.5

        结论

        1. 我们在假设条件成立的情况下,我们期望新增的10w客户端全部负载到新的10个node上。但是从结果上看,其实是负载了整个的60个node上(这个其实也是相对均匀的)。这个和我们预期完全不相符
        2. 从一致性hash的算法实现上看,对于新增/减少节点来说,一定是会有一部分客户端重新分配节点,这个是由算法本身决定的
  3. 继续沿着一致性hash的思路走

    • 主要问题
      • a. 如何解决新增/减少节点,部分客户端select节点变化的问题?
      • b. 如何解决新增节点,整体的负载均匀问题(甚至分配过程中的相对均匀,即不会出现分配过程中某一个node先达到上限,而是整体均衡)?
    • 一些扩展思路
      • 对于a
        • 可以在客户端select到一个节点后,将客户端和节点的映射关系保存下来。客户端断线再连接还是同一个节点。当内存数据过期后,下次再连接,可以再次重新映射
        • 可以在每次客户端断线时,强制刷新一下对应的node内存数据到外部缓存。这样当客户端再次连接时,如果切到了其他的node也没有关系,只不过额外走一次加载流程。不过如果是频繁断线重连的情况下则需要额外注意
      • 对于b
        • 可以引入有限负载一致性哈希,即node有负载的概念。首选还是按照正常的一致性hash算法选择某一个node。不过区别是会判断此node是否overloaded,如果overloaded,则继续从hash ring寻找下一个node,直到未超过负载。引入该算法后,对于2b中的测试来说,新的10w人会被主要分流到新增的10个node上
          • 我目前实现的一个版本是可以设置一个node的负载上限比如9000
          • 不过引入负载后,就需要额外维护负载这个指标。比如客户端内存数据过期后,将客户端所属的node的负载-1
    • 思考
      • 如果我们按照一致性hash的思路实现需求,是可以做的,只不过有不少额外成本。那这样的必要性大吗?
      • 一致性hash最早的例子是用在如memcache,根据key hash到对应的node。而这个应用场合是缓存,即使key没有命中的话(增/减),那么对于应用层来是可以重新从数据库加载的。所以其实应用场合并一定特别适合
      • 对于我们的需求,我们手动实现一个基于负载的类似轮询算法,是不是更简单?
  4. 再换一个思路 假如我们把连接和数据分开呢?

    • 假如我们让客户端不是直接连接后端的node,而是一个网关呢?
    • 网关负责连接,node负责数据
    • 我们有一组网关,网关的数量是固定的(当然也可以在维护时间调整),先通过客户端rid做hash运算到对应的网关(为保证均匀,可以考虑一致性hash)
    • 然后再通过网关和后端node的映射关系得出客户端该路由到那个node上。这样node节点动态变化时,只需要修改路由表中网关和动态node之前的关系即可
    • TODO
      • Consistent Hashing + Distributed Hash Table (Orleans)
  5. ref

与[转帖]关于一致性哈希算法在游戏服务器端的思考相似的内容:

[转帖]关于一致性哈希算法在游戏服务器端的思考

https://www.jianshu.com/p/b8ae27cf22a9 突然想明白 其实网易的将军令 就是一个一致性哈希的玩法 关于一致性哈希算法在游戏服务器端的思考 需求分析 后端有很多逻辑node节点(not-section binded),节点启动后注册到注册中心 node本身有状态,有

[转帖]关于字节序(大小端)的一点想法

https://www.zhihu.com/people/bei-ji-85/posts 今天在一个技术群里有人问起来了,当时有一些讨论(不完全都是我个人的观点),整理一下: 为什么网络字节序(多数情况下)是大端? 早年设备的缓存很小,先接收高字节能快速的判断报文信息:包长度(需要准备多大缓存)、地

[转帖]关于统信UOS操作系统版本介绍

https://blog.csdn.net/qq43748322/article/details/120196200 当下信创产业发展的如火如荼,今天聊聊统信操作系统UOS 相比较于其它国内品牌操作系统,统信UOS的版本、分支比较多,下面为大家详细说说各UOS版本 目前统信UOS系统主要分为桌面版和

[转帖]关于华为产品生命周期

关于企业级产品都有EOL里程碑,因些需要考虑对已购产品、业务的生命周期进行升级、迁移、替换等统筹规划。另外如果遇到产品、业务整体出售,还需要评估对现有资产的影响等不可控因素。 今天聊聊华为产品的生命周期,点击查看原文 华为产品生命周期关键里程碑: 华为软件版本生命周期关键里程碑: 点击查询华为产品生

[转帖]关于SRE方法论的一些笔记

写在前面 阿里系列有一本《云原生操作系统Kubernetes》中作者在前言里讲到Google开源的Kubernetes和《SRE Google运维解密》这本书是剑法和气功的关系换句话讲Kubernetes是术,SRE Google运维解密是道作为云原生基础设施的Kubernetes小伙伴么应该多少有

[转帖]关于ubuntu:如何在-Ubuntu-Server-2204-上设置静态IP地址

https://lequ7.com/guan-yu-ubuntu-ru-he-zai-ubuntuserver2204-shang-she-zhi-jing-tai-ip-di-zhi.html 在这篇文章中,咱们将介绍如何在 Ubuntu Server 22.04 上设置动态 ip 地址。 强烈建

[转帖]关于nginx 反向代理upstream中的 keepalive配置

一、关于nginx upstream 在nginx的模块中,分为3种类型,分别是handler,filter和upstream,其中upstream可以看做一种特殊的handler,它主要用来实现和后端另外的服务器进行通信,由于在nginx中全部都是使用非阻塞,并且是一个流式的处理,所以upstre

[转帖]关于勤奋的英语名言

http://www.zajuzi.com/mingyandaquan/juzi423.html 1、永远不抱怨,一切靠自己。 Never complain, everything depends on yourself. 2、纵不能万丈光芒,也要倒在追梦的路上! Even if you can't

[转帖]关于大内存页面 transparent_hugepage

https://www.cnblogs.com/kevinlucky/p/9955486.html Transparent Huge Pages (THP) are enabled by default in RHEL 6 for all applications. The kernel attem

[转帖]关于Bonree ONE 2.0,那些运维人不知道的一切

http://blog.itpub.net/31545813/viewspace-2924710/ 近年来,伴随着数字经济的不断深入,以云原生、Devops等为代表的新技术快速发展。传统的IT监控工具多样、分散、庞杂,并且数据种类杂、缺乏关联性,导致整个IT系统不具备真正的可观测性。那么,如何快速发