• LovRNA
    2019-12-21
    带有限负载的一致性hash,在查询数据时,怎么确定数据存储在哪个节点上呢?

    作者回复: 带有限负载的一致性hash在存储时实际是分两步走,第一步通过一致性哈希计算出一个命中节点,如果命中节点有足够的空间,则存储在命中节点上,否则按顺时针方向,依次遍历下一个节点,直到找到下一个节点为止。

    查询的时候如果按照存储的方式去计算命中节点,然后再去顺时针依次遍历下一个节点,这时你就会发现问题来了。

    因为,如果查询数据不存在的话,需要遍历完整个哈希环上的所有节点。这种遍历的开销就太大了,因为这是网络上的遍历,可不是单机内存内的遍历。

    一种思路是,在哈希命中节点上额外添加一个索引表,用以记录命中到该节点上的数据存储在哈希环上的位置。这样在通过一致性哈希计算出命中的节点后,只需要再查询这个节点上的索引表就可以找到实际的存储节点了。

    其实这个本质上就是一个解决哈希冲突的过程,你可以再回想一下我们在数据结构中的哈希表解决冲突的方法,通过对比学习,可以更进一步加深你的理解。

    
     5
  • Eternal
    2019-11-23
    本节课是分布式相关的知识点中最熟悉的一节,但是之前都是零碎的信息,没有把这四种数据分布方式进行细致的对比,这次老师的对比
    让我豁然开朗。下面总结一下我的思考:

    提到hash的时候,学后端的小伙伴一定会回想到数据结构课程中的hash,会想到Java的经典面试题:HashMap的原理,其实我想说的是
    分布式的数据分布其实就是从基本的hash演化来的。


    数据的最基本的存储组织方式:数组,所有的数据按照地址顺序放在一个列表
    数组通过游标查询快,修改数据快,删除数据和插入数据需要移动数据就慢了,分配内存需要连续的内存空间,内存使用的效率低

    于是链表诞生--->>>

    链表修改数据快,删除数据,插入数据快,分配的内存空间不需要连续,内存使用的效率高,但是链表的查询需要遍历很慢



    于是hash表诞生--->>>

    hash散列表存储键值对数据,key通过hash函数计算出一个hash值,这个hash值再和数据的地址做一个映射就找到数据了,hash解决
    了链表的查询慢的问题;但是hash又引入了新的问题:hash函数性能损耗,hash散列不均衡,hash冲突等


    这里再想想Java中的HashMap怎么优化这个问题--->>>

    hash函数性能损耗:通过取模(CPU的原生指令)提高效率
    hash散列冲突:数组+链表 、数组+红黑树的方式解决冲突

    从上面对比我想到,需求的本质就像想做数据映射,通过key和value做映射,value可能是内存地址,可能是hash值,
    可能一次映射不够就做两次。

    然后想想数据库的索引也就是为了做数据映射,更快更高效的对数据进行增删该查。

    在分布式的场景下,我们可以迁移这些思想,
    一个数如何据映射到具体节点上,这和一个值映射到具体哪个内存地址有共享。


    最后--->>>
    老师讲到的hash,一致性hash,有限负载的一致性hash,虚列节点的一致性hash以及它们各种特性比较。
    老师总结的非常好,自己对对于这个块知识不是很清楚的地方这次也明白了:

    均衡性:也就hash的分散性,老师讲的从两个维度理解。第一:每个节点的数据量要均衡分配,第二:用户访问的请求要均衡的落在每个节点
    ,第二个维度可以理解为系统的热点数据访问怎么处理,不能让热点数据成为系统访问的压力,要分散它。


    节点异构:我们组的系统刚好做过通过虚拟节点的一致性hash方式实现数据分布,当时一直理解的是虚拟节点再多了一次映射就是为了数据分散
    更均衡,老师讲的是因为节点以后的原因,然后通过虚拟节点来实现数据分散,这个本质的今天才get到。


    我有2个疑问:
    1.如果相同的数据被映射到了不同的节点,空间不是就浪费了?
    2.做数据分布映射的时候我们是不是需要考虑有key是单调递增的场景呢?


    最后说说老师的课后问题:寻找其它数据分布的方式

    散列:老师讲的hash三个都是属于这一类
    范围:按照id划分,按照地区,国家,民族等自定义的维度
    循环:按照一个步长循环
    组合:以上三种方式按照特定场景的组合

    个人认为:数据分布,数据分片,索引,hash,负载均衡实现的方式中有共性

    疑问:如果我们能把数据按照页的级别分布在不同的节点上,我们是不是可以通过一个可棵 B+树 来组织分布式的数据???
    展开
    
     2
  • 随心而至
    2019-11-22
    范围分区:通过确定分区键是否在一定范围内来选择分区。比如按照年龄范围分区。
    列表分区:为分区分配值列表。比如按照所属国家对用户分区。
    循环分区:对于n个分区,将插入顺序中的第i个元组分配给i%n分区
    散列函数:将数据的某些字段通过散列函数计算得到分区号。比如Redis。
    组合分区:允许上述划分方案的某些组合
    参见:
    https://en.wikipedia.org/wiki/Partition_(database)
    https://dev.mysql.com/doc/refman/8.0/en/partitioning-types.html
    展开
    
     2
  • Victor
    2020-01-06
    老师,redis用的不是带有虚拟节点的一致性hash算法么?
     1
     1
  • Jackey
    2019-11-22
    之前这些方法也都知道,但就是说不清楚,有些也不知道叫什么名。这回终于能说明白了,感觉以后面试又可以吹一波了。至于今天的思考题…能力有限,坐等课代表科普
     1
     1
  • 一毛钱
    2019-12-15
    根据划定的单位分区,根据指定的规则分区
    
    
  • Geek_e986e3
    2019-11-25
    老师 两个问题
    1.带有限状态的分布式一致hash 在读取的时候怎么做的呢,打个比方。如果要存储的节点满了。存到顺时针之后好几个节点。但是读的时候。可能节点已经不满了。怎么做到读取呢?每个都遍历一遍吗?有没有更优雅的方法?
    2.还是有限状态的。如果所有节点都存满了。一般怎么处理呢?
    
    
  • 锦
    2019-11-22
    终于明白了一致性哈希算法,关键在于一个环,如何确定环上的数据组成是需要考虑的地方,老师举例中是跟数据等值分布,节点再使用ip哈希定位到环中的某个数据,确定这些后,其实数据会被切分成多份,每个节点对应左边的数据就行。
    有限数据一致性哈希是解决稳定性问题的,而带虚拟节点一致性哈希算法是解决节点异构问题的,可以理解成带权重的节点。

    
    
  • leslie
    2019-11-22
    哈希这块一直学过可是原理不清楚,为此还去学习算法了解其本源;可是像老师这样清楚的梳理还是没有明白。知其然知其所以然:明白清楚了在数据系统中的使用就更加从容了。
    
    
  • 随心而至
    2019-11-22
    有一些疑问:
    1.是不是带有限负载的一致性哈希,所有机器的存储上线都只能是同一个上限值吗?按照老师文中它没有解决不同机器的异构性,以及带虚拟节点的一致性哈希就是用来解决该问题,猜测是这样。
    2.带有限负载的一致性哈希,是不是可能导致读写的时候查多次,因为有个上线的概念?还是说每个节点都有各个节点保存数据的范围,最多只会转发一次读写。
    
    
  • xingoo
    2019-11-22
    按照范围进行分片,典型的代表hbase。
    因为它需要根据rowkey范围锁定数据存储的位置,相邻的rowkey数据会按照顺序存储在磁盘,因此在执行rowkey的单位查询时,性能非常快。为了避免单位的热点不均衡,伴随着也有很多差分和合并的机制。
    
    
我们在线,来聊聊吧