2023-08-12  阅读(4)
原文作者:Ressmix 原文地址:https://www.tpvlog.com/article/71

一、数据分片

可扩展性是指当系统的任务(work)增加时,通过增加资源来应对任务增长的能力。
分布式系统出现的目的之一就是解决单个计算机无法完成的计算、存储任务。那么当任务规模增加的时候,首先要考虑的问题就是:

如何对任务进行拆分,将任务的子集分配到每一个节点,每个节点只负责原问题(即整个系统需要完成的任务)的一个子集?

比如,在分布式存储系统中,任务的拆分就是 数据分片 ,每个节点存储完整数据的一部分。
常见的数据分片算法包括:普通哈希(hash)一致性哈希(consistency hash)基于数据范围分片(range based)

无论哪一种算法,都需要考虑以下问题:

  • 如何划分原始数据集?
  • 当原问题的规模变大时,能否通过增加节点来动态适应?
  • 当某个节点故障的时候,能否将该节点上的任务/数据转移到其它节点?

每一种算法有各自的优缺点,也就有各自的适用场景。本文主要介绍一致性Hash,在这之前我们先来回顾下普通Hash。

二、普通Hash

学过数据结构的童鞋都对散列表(Hash Table,也叫哈希表)不会陌生,哈希表是通过把 键值映射成整数 作为数组的索引,并进行访问记录的一种数据结构。

关于哈希表的具体实现方式和原理,本文不再赘述,读者可以参考我的这篇文章:散列表

202308122215125401.png

基于普通hash的数据分片,也是这个思想,即按照数据的某一特征(key)来计算哈希值,并将哈希值与系统中的节点建立映射关系,从而将不同数据分布到不同的节点上。

基于普通hash的数据分片方式,优点就是简单易实现,但缺点也很明显:

  1. 容易出现数据倾斜,比如原始数据的特征值分布不均匀,导致大量的数据集中到一个物理节点上;
  2. 扩容或收缩时,会导致所有键值分布的重新计算,导致大量数据迁移,这个问题在大规模数据场景下是不可接受的。

三、一致性Hash

3.1 基本思想

传统的Hash算法将是以顺序表的形式组织Hash值空间,无法很好地解决节点平滑伸缩的问题。一致性Hash算法则将整个哈希值空间组织成一个 虚拟的圆环 ,Hash函数的值空间为 0—(2^32)-1

  1. 整个空间按顺时针方向组织, 0(2^32)-1 在零点中方向重合,如下图:

    202308122215131862.png

  2. 物理节点通过Hash函数进行哈希(比如选择服务器的IP或主机名作为关键字),这样就能确定物理节点在哈希环上的位置(如下图,NodeA、NodeB、NodeC、NodeD代表着四个物理节点):

    202308122215137413.png

  3. 接下来就是数据的定位,也就是通过数据的Key找到对应的物理节点:
    ① 首先将数据key用相同的Hash函数计算出哈希值,这样就确定了此数据在环上的位置;
    ② 从该位置沿顺时针查找,直到找到第一个物理节点,这个物理节点就是数据存储的位置。

    202308122215144424.png

3.2 容错性

假设其中某台服务器宕机了(比如上图的NodeC),那影响的仅仅是 该宕机服务器到其环空间中前一台服务器之间的数据 ,即沿着逆时针方向行走遇到的第一台服务器NodeB,其它数据不会受到影响。

这时一般需要将该宕掉的服务器中的数据重新hash计算,因为数据会落到该宕掉服务器的后一台服务器(NodeD)上。

3.3 可扩展性

假设需要扩容,新增一台服务器(比如下图的NodeX),那受影响的数据仅仅是新服务器到其环空间中后一台服务器之间的数据,即沿着顺时针方向行走遇到的第一台服务器NodeC,其它数据也不会受到影响。

这时一般需要将该前一台服务器C中的数据重新hash计算,因为部分数据可能会落到该新增服务器上。

202308122215151155.png

3.4 优缺点

优点:
一致性hash算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。当节点数越多的时候,使用一致哈希时,需要迁移的数据就越少。此外,不需要维护路由信息。

缺点:
物理节点较少时,数据分布不均,造成数据倾斜,有时也叫缓存热点问题,比如大量hash数据涌入同一个节点。

3.5 虚拟节点

针对一致性hash的数据倾斜问题,一个比较好的方案是引入 ”虚拟节点“
所谓虚拟节点,就是为原来的每个物理节点计算多个哈希,每个计算结果的位置作为一个虚节点,hash环上只放置虚拟节点,然后额外进行真实物理节点与虚拟节点的映射:

202308122215163486.png

例如:上面的情况中,为每台物理节点(NodeA、NodeB、NodeC)新增三个编号,于是形成六个虚拟节点:“NodeA#1”、“NodeA#2”、“Node A#3”、“Node B#1”、“Node B#2”、“Node B#3”。

而数据定位算法不变,通过数据的Key可以找到虚拟节点的hash环位置,然后可以维护一个 物理节点<->虚拟节点 的映射关系表,从而找到实体节点的位置。

物理节点与虚拟节点的映射,可以采用服务器ip或主机名的后面增加编号的方式

四、总结

本章,我主要对数据分片的路由算法进行了讲解,介绍了传统hash存在的一些问题,同时介绍了一致性hash的原理。一致hash是一种特殊的哈希算法,在使用一致哈希算法后,节点增减变化时只影响到部分数据的路由寻址,也就是说我们只要迁移部分数据,就能实现集群的稳定。


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文