返回顶部
首页 > 资讯 > 后端开发 > GO >Golang官方中的一致性哈希组件怎么实现
  • 595
分享到

Golang官方中的一致性哈希组件怎么实现

2023-07-05 21:07:21 595人浏览 独家记忆
摘要

这篇“golang官方中的一致性哈希组件怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Golang官方中的一致性哈希

这篇“golang官方中的一致性哈希组件怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Golang官方中的一致性哈希组件怎么实现”文章吧。

    背景

    分布式缓存中,我们需要通过一组缓存节点来提高我们的缓存容量。比如我们有3个Redis节点:

    Golang官方中的一致性哈希组件怎么实现

    最简单的路由规则是我们计算`Key`的哈希值,然后取模计算目标节点,比如我们有5个Key,计算出以下哈希值及对应的目标节点:

    Key的哈希值模3的余目标节点
    101Redis1
    41Redis1
    60Redis0
    82Redis2
    150Redis0

    如果我们这时候加入一个新的Redis节点,这时候路由变化如下:

    Key的哈希值模3的余目标节点(旧)模4的余目标节点(新)是否变化
    101Redis12Redis2
    41Redis10Redis0
    60Redis02Redis2
    82Redis20Redis0
    150Redis03Redis3

    可以看到,我们只是加入了一个节点,就导致了所有Key的目标节点被改变了,这样会导致大量缓存失效,这时请求可能就会都打到数据库里,可能会导致数据库被击垮,这也就是缓存雪崩问题。

    为了解决这个问题,一般我们会使用一致性哈希:

    一致性哈希算法

    一致性哈希算法经常被用于请求路由中,在处理节点不变的情况下,它能够把相同的请求路由到相同的处理节点上。同时还能在处理节点变动时,让相同请求尽可能的打到原先相同的处理节点上。

    原理

    一致性哈希的原理是把处理节点通过哈希映射到一个哈希环上,哈希环可以理解为一个连续编号的循环链表,一般会使用长度为32位的哈希值,也就是哈希环可以映射2^32个值。如下图所示:

    图中有三个Redis节点,通过哈希映射到环上的某个位置。Key也是通过哈希映射到环上的某个位置,然后向前寻找计算节点,第一个遇到的就是Key的目标节点。

    Golang官方中的一致性哈希组件怎么实现

    这时候如果我们加入一个新的Redis3节点,可以看到只有Key4的路由改变了,其他的Key的路由都保持不变:

    Golang官方中的一致性哈希组件怎么实现

    也就是我们新加入的处理节点,只会影响前面的处理节点的路由。

    改进

    可以看到上面的Redis节点在环上分布得并不均匀,这样会导致每个节点的负载差距过大。为了让Redis节点在环上分布得更加均匀,我们还可以再加入虚拟节点。让一个Redis节点能够映射到哈希环上的多个位置,这样节点的分布会更加均匀。

    Golang官方中的一致性哈希组件怎么实现

    可以看到因为每个Redis节点的映射位置变多了,因此更有可能会分布得更加均匀。图里每个Redis节点只有两个虚拟节点,主要是不太好画,实际上我们可能会给每个Redis节点分配几十个虚拟节点,这样基本上就很均匀了。

    实现方式

    结构和接口

    第一件需要做的事情,就是我们需要把节点进行哈希得到一个整数值,这里默认是使用crc32计算一个字节序列的哈希值,当然也可以自己指定。

    哈希环的结构里面有一个ring数组,我们使用这个数组模拟一个哈希环,当然数组并不会把最后一个元素链接到第一个元素,因此我们需要在逻辑上模拟。里面的nodes则是保存了哈希值到真实节点字符串的映射,这样我们在ring数组里面找到对应的哈希值时才能反过来找到真实节点。

    // 哈希函数type Hash func(data []byte) uint32// 哈希环// 注意,非线程安全,业务需要自行加type HashRing struct {hash Hash// 每个真实节点的虚拟节点数量replicas int// 哈希环,按照节点哈希值排序ring []int// 节点哈希值到真实节点字符串,哈希映射的逆过程nodes map[int]string}

    添加节点

    可以看到这个方法是把节点添加到哈希环里面,这里会为每个节点创建虚拟节点,这样可以分布的更加均匀。

    当然这个方法存在一个问题,就是它没有判断加入的节点是否已经存在,这样可能会导致Ring上面存在相同的节点。

    // 添加新节点到哈希环// 注意,如果加入的节点已经存在,会导致哈希环上面重复,如果不确定是否存在请使用Resetfunc (m *HashRing) Add(nodes ...string) {for _, node := range nodes {// 每个节点创建多个虚拟节点for i := 0; i < m.replicas; i++ {// 每个虚拟节点计算哈希值hash := int(m.hash([]byte(strconv.Itoa(i) + node)))// 加入哈希环m.ring = append(m.ring, hash)// 哈希值到真实节点字符串映射m.nodes[hash] = node}}// 哈希环排序sort.Ints(m.ring)}

    重置节点

    为了解决上面的问题,我们额外实现了一个重置方法,也就是先清空哈希环,再添加。当然这样就必须每次都指定完整的节点列表。

    // 先清空哈希环再设置func (r *HashRing) Reset(nodes ...string) {// 先清空r.ring = nilr.nodes = map[int]string{}// 再重置r.Add(nodes...)}

    获取Key对应的节点

    这个方法的功能是查询Key应该路由到哪个节点,也就是计算Key的哈希值,然后找到哈希值对应的处理节点(这里需要考虑ring数组逻辑上是一个环),然后再根据这个哈希值去寻找真实处理节点的字符串。

    // 获取Key对应的节点func (r *HashRing) Get(key string) string {// 如果哈希环位空,则直接返回if r.Empty() {return ""}// 计算Key哈希值hash := int(r.hash([]byte(key)))// 二分查找第一个大于等于Key哈希值的节点idx := sort.Search(len(r.ring), func(i int) bool { return r.ring[i] >= hash })// 这里是特殊情况,也就是数组没有大于等于Key哈希值的节点// 但是逻辑上这是一个环,因此第一个节点就是目标节点if idx == len(r.ring) {idx = 0}// 返回哈希值对应的真实节点字符串return r.nodes[r.ring[idx]]}

    以上就是关于“Golang官方中的一致性哈希组件怎么实现”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网GO频道。

    您可能感兴趣的文档:

    --结束END--

    本文标题: Golang官方中的一致性哈希组件怎么实现

    本文链接: https://lsjlt.com/news/355095.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Golang官方中的一致性哈希组件怎么实现
      这篇“Golang官方中的一致性哈希组件怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Golang官方中的一致性哈希...
      99+
      2023-07-05
    • 详解Golang官方中的一致性哈希组件
      目录背景一致性哈希算法原理改进实现方式结构和接口添加节点重置节点获取Key对应的节点总结背景 在分布式缓存中,我们需要通过一组缓存节点来提高我们的缓存容量。比如我们有3个Redis节...
      99+
      2023-05-14
      Golang一致性哈希算法 Golang一致性哈希组件 Golang一致性哈希 Golang 哈希
    • 一致性哈希概念与Python的简单实现
      好像从开始接触Zookeeper的时候就知道了有一致性哈希这东西。。。。不过倒是一直都没有去了解这到底是个啥东西。。。只是知道它在分布式系统设计中有十分重要的作用。。。。 好了,接下来用举例子的方式来说一下一致性哈希到底有啥用吧。。。场...
      99+
      2023-01-31
      概念 简单 一致性哈希
    • 怎么使用PHP实现分布算法之一致性哈希算法
      这篇文章主要介绍怎么使用PHP实现分布算法之一致性哈希算法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!传统算法缺陷对于服务器分布,我们要考虑的东西有如下三点:数据平均分布,查找定位准确,降低宕机影响。传统算法一般是...
      99+
      2023-06-15
    • Javascript中怎么实现一个伪哈希表
      这期内容当中小编将会给大家带来有关Javascript中怎么实现一个伪哈希表,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。javascript中实现哈希表的代码:1 fu...
      99+
      2024-04-02
    • c++中怎么实现一个哈希慢算法
      c++中怎么实现一个哈希慢算法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。首先,我定义了一个哈夫曼树结点:class hNode{ public:  friend&...
      99+
      2023-06-03
    • 怎么使用Golang哈希算法实现配置文件的监控功能
      这篇文章主要介绍“怎么使用Golang哈希算法实现配置文件的监控功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Golang哈希算法实现配置文件的监控功能”文章能帮助大家解决问题。SHA(...
      99+
      2023-07-05
    • Golang 函数在分布式系统中实现数据一致性的方法
      问题:如何在 go 中使用函数实现分布式系统数据一致性?答案:使用函数类型声明和使用函数:func(param_type_1 param_name_1, ..., param_type_...
      99+
      2024-04-19
      分布式一致性 golang
    • Vue中怎么实现一个单文件组件
      这期内容当中小编将会给大家带来有关Vue中怎么实现一个单文件组件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。背景相信大家在使用Vue开发项目时,基本都是以单文件组件的形...
      99+
      2024-04-02
    • Vuejs中怎么实现一个单文件组件
      Vuejs中怎么实现一个单文件组件,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。初识单文件组件还是利用工欲善其事必先利其器 中的源码,在 ...
      99+
      2024-04-02
    • 怎么在Golang中实现一个简单的Http中间件
      本篇内容主要讲解“怎么在Golang中实现一个简单的Http中间件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么在Golang中实现一个简单的Http中间件”吧!本文主要针对Golang的内...
      99+
      2023-06-20
    • Vue中怎么实现一个树形组件
      Vue中怎么实现一个树形组件,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。具体如下:使用SemanticUI和vue做一个me...
      99+
      2024-04-02
    • Vue2.0中怎么实现一个分页组件
      这篇文章给大家介绍Vue2.0中怎么实现一个分页组件,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。组件部分代码:Vue.component('zpagenav',&nb...
      99+
      2024-04-02
    • vue-cli3中怎么实现一个fullpage组件
      本篇文章为大家展示了vue-cli3中怎么实现一个fullpage组件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。准备$ npm i ...
      99+
      2024-04-02
    • Angular6中怎么实现一个主从组件
      Angular6中怎么实现一个主从组件,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.创建一个新的组件使用 Angular ...
      99+
      2024-04-02
    • vue中怎么实现一个翻页组件
      这篇文章将为大家详细讲解有关vue中怎么实现一个翻页组件,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。首先,翻页组件(以下称“pager组件”)一般拥有的元...
      99+
      2024-04-02
    • Vue中怎么实现一个异步组件
      今天就跟大家聊聊有关Vue中怎么实现一个异步组件,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。index.html<!DOCTYPE ...
      99+
      2024-04-02
    • VB.NET中怎么实现一个菜单组件
      VB.NET中怎么实现一个菜单组件,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Windows应用程序中往往离不开菜单,菜单的应用是十分普遍了,并且菜单的设计是十分简单的,这主...
      99+
      2023-06-17
    • VB.NET中怎么实现一个控件数组
      本篇文章为大家展示了VB.NET中怎么实现一个控件数组,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Public Class CheckBoxArrClass Chec...
      99+
      2023-06-17
    • redis怎么实现数据存储和缓存的一致性
      redis怎么实现数据存储和缓存的一致性?针对这个问题,这篇文章给出了相对应的分析和解答,希望能帮助更多想解决这个问题的朋友找到更加简单易行的办法。方式1:数据库保存数据,redis不persist red...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作