10-Docker-分布式存储算法

news2024/11/26 20:44:50

01-哈希取余算法分区

哈希取余分区(Hash Modulus Partitioning)是一种在分布式计算和数据存储中常用的分区策略,其目的是将数据或计算任务分配到多个节点或服务器上,以实现负载均衡和提高性能。这种分区策略的核心思想是使用哈希函数来将数据或任务的标识(通常是键或标签)映射到一个固定范围的分区中,然后使用取余运算来确定应该分配给哪个分区。

使用 Python 进行哈希取余算法运行代码及结果如下:

def hash_partition(data, num_partitions):
    partitions = [[] for _ in range(num_partitions)]
    
    for item in data:
        # 计算数据的哈希值,这里使用内置的哈希函数hash()
        hash_value = hash(item)
        
        # 取余以确定数据应该分配到哪个分区
        partition_index = hash_value % num_partitions
        
        # 将数据添加到相应的分区
        partitions[partition_index].append(item)
    
    return partitions

# 示例数据
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 分成3个分区
num_partitions = 3

result = hash_partition(data, num_partitions)

for i, partition in enumerate(result):
    print(f'Partition {i}: {partition}')

程序运行后,代码输入如下内容:
image.png
哈希取余分区的优点:

  • 负载均衡:通过使用哈希函数,可以确保相同标识的数据或任务始终分配到相同的分区,从而分散负载并减少不均匀分布的可能性。
  • 易于扩展:当需要增加或减少节点或服务器时,只需重新计算哈希并将数据或任务重新分配到新的分区,而不需要改变哈希函数本身。
  • 确定性:相同的标识将始终映射到相同的分区,这对于缓存和数据复制等应用非常有用。

哈希取余分区的缺点:

  • 数据倾斜(某些分区可能会处理更多的数据或任务)
  • 节点增减可能需要重新分配大量数据的问题,需要重新计算哈希分区,造成计算量上的增加。

02-一致性哈希算法分区

一致性哈希分区是一种在分布式系统中用于数据分布和负载均衡的技术。它的原理基于哈希函数和环形哈希环,主要用于确定数据在分布式系统中的存储位置。
一致性哈希算法必然有个 hash 函数并按照算法产生 hash 值,这个算法的所有可能的哈希值会构成一个全量集,这个集合可以成为一个 hash 空间 [0,2^32-1],这个是一个线性空间,但是在逻辑上我们把它视为环形空间。

一致性哈希分区是在分布式数据库、缓存系统和负载均衡器等场景中广泛使用的技术,它可以有效地分散数据存储负担,提高系统的性能和容错性。
使用 Python 进行哈希取余算法运行代码及结果如下:

import hashlib

class ConsistentHash:
    def __init__(self, num_replicas=3):
        self.num_replicas = num_replicas
        self.ring = {}  # 一致性哈希环
        self.nodes = set()  # 节点集合

    def add_node(self, node):
        for i in range(self.num_replicas):
            # 为每个节点创建多个虚拟节点
            virtual_node = f"{node}-{i}"
            hash_value = self._hash(virtual_node)
            self.ring[hash_value] = node
            self.nodes.add(node)

    def remove_node(self, node):
        for i in range(self.num_replicas):
            virtual_node = f"{node}-{i}"
            hash_value = self._hash(virtual_node)
            del self.ring[hash_value]
        self.nodes.remove(node)

    def get_node(self, key):
        if not self.ring:
            return None

        hash_value = self._hash(key)
        sorted_keys = sorted(self.ring.keys())
        for key in sorted_keys:
            if hash_value <= key:
                return self.ring[key]

        # 如果key的哈希值大于所有节点的哈希值,返回第一个节点
        return self.ring[sorted_keys[0]]

    def _hash(self, key):
        # 使用SHA-1哈希函数
        return int(hashlib.sha1(key.encode()).hexdigest(), 16)

# 示例
ch = ConsistentHash()
ch.add_node("Node1")
ch.add_node("Node2")
ch.add_node("Node3")

# 将数据分配到节点
data = ["Data1", "Data2", "Data3", "Data4", "Data5"]
for item in data:
    node = ch.get_node(item)
    print(f"Data '{item}' is assigned to Node '{node}'")

# 移除一个节点
ch.remove_node("Node2")

# 再次分配数据
print("\nAfter removing Node2:")
for item in data:
    node = ch.get_node(item)
    print(f"Data '{item}' is assigned to Node '{node}'")

程序运行后,代码输入如下内容:image.png
比起哈希取余算法,一致性哈希算法解决了哈希取余的容错性扩展性。如果某个节点失败,数据可以被映射到下一个最近的节点,而不会造成大规模的数据迁移。
扩展性指的是增加一台 Node X,X 的位置在 A 和** B 之间,那收到影响的也只是 A 到 X 之间的数据,不会导致 Hash 取余全部重新洗牌。
但是一致性 Hash 算法存在
数据倾斜**的问题,一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜。
为了在节点数目发生改变时尽可能少的迁移数据
将所有的存储节点排列在收尾相接的Hash环上,每个key在计算Hash后会顺时针找到临近的存储节点存放而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点。

03-哈希槽算法分区

哈希槽算法分区是大厂常用的算法,只有会哈希槽算法才会和大厂的认知匹配。
一致性哈希算法存在数据倾斜的问题,哈希槽算法本质上是一个数组,数组 [0,2^14-1] 形成 hash slot 空间。
哈希槽可以解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽,用于管理节点和数据之间的关系,就相当于节点上放的是槽,槽上面放的是数据。
槽解决的是颗粒度的问题,相当于把颗粒度变大,便于数据的移动。
哈希解决的是映射的问题,使用 key 来计算所在的槽,便于数据的分配。

使用 Python 进行哈希槽算法运行代码及结果如下:

class HashSlot:
    def __init__(self, size):
        self.size = size
        self.slots = [None] * size

    def _hash_function(self, key):
        return hash(key) % self.size

    def insert(self, key, value):
        index = self._hash_function(key)
        if self.slots[index] is None:
            self.slots[index] = [(key, value)]
        else:
            for i, (existing_key, existing_value) in enumerate(self.slots[index]):
                if existing_key == key:
                    self.slots[index][i] = (key, value)
                    break
            else:
                self.slots[index].append((key, value))

    def get(self, key):
        index = self._hash_function(key)
        if self.slots[index] is not None:
            for existing_key, existing_value in self.slots[index]:
                if existing_key == key:
                    return existing_value
        raise KeyError(f"Key '{key}' not found")

    def delete(self, key):
        index = self._hash_function(key)
        if self.slots[index] is not None:
            for i, (existing_key, _) in enumerate(self.slots[index]):
                if existing_key == key:
                    del self.slots[index][i]
                    break
            else:
                raise KeyError(f"Key '{key}' not found")

    def __str__(self):
        return str(self.slots)

# 示例
hash_slot = HashSlot(8)

hash_slot.insert("apple", 5)
hash_slot.insert("banana", 10)
hash_slot.insert("cherry", 15)

print(hash_slot)

print("Value for 'apple':", hash_slot.get("apple"))
print("Value for 'banana':", hash_slot.get("banana"))
print("Value for 'cherry':", hash_slot.get("cherry"))

hash_slot.delete("banana")
print("After deleting 'banana':", hash_slot)

·· 当运行这段代码后,以下事件将发生:

  1. 创建哈希槽对象:代码首先创建了一个名为hash_slot的哈希槽对象,这个哈希槽的大小被初始化为8个槽位。
  2. 插入键值对:接下来,代码使用insert方法向哈希槽中插入三个键值对:"apple"对应5,"banana"对应10,"cherry"对应15。这些键值对将被根据它们的键进行哈希,然后存储在合适的槽位中。
  3. 打印哈希槽:代码使用print(hash_slot)语句打印哈希槽的内容,显示存储在各个槽位中的键值对。
  4. 获取键值:代码使用get方法获取键"apple"、"banana"和"cherry"对应的值,分别为5、10和15。
  5. 删除键值:代码使用delete方法删除键"banana"对应的键值对。
  6. 打印更新后的哈希槽:最后,代码再次使用print(hash_slot)语句打印哈希槽的内容,显示删除了"banana"键值对后的哈希槽状态。

程序运行后,代码输入如下内容:image.png

04-总结与归纳

在本次学习中,我们一共学习了三种分布式存储常用的算法,它们分别是哈希取余算法一致性哈希算法哈希槽算法。这三个算法的优点和缺点后很明显,简单归类如下:
哈希取余算法:优点是负载均衡,易于扩展;缺点是删除增加大量计算量
一致性哈希算法:优点是容错性和扩展性好;缺点是容易出现数据倾斜。
哈希槽算法:优点是快速数据查找,高效的插入和删除操作,数据分布均匀;缺点是哈希冲突,不适合范围查询。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1190639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python---列表的循环遍历,嵌套

循环遍历就是使用while或for循环对列表中的每个数据进行打印输出 while循环&#xff1a; list1 [貂蝉, 大乔, 小乔]# 定义计数器 i 0 # 编写循环条件 while i < len(list1):print(list1[i])# 更新计数器i 1 for循环&#xff08;推荐&#xff09;&#xff1a; list1 [貂…

小白学安全-KunLun-M静态白盒扫描工具

一、KunLun-M简介 KunLun-M是一个完全开源的静态白盒扫描工具&#xff0c;支持PHP、JavaScript的语义扫描&#xff0c;基础安全、组件安全扫描&#xff0c;Chrome Ext\Solidity的基础扫描。开源地址&#xff1a;https://github.com/LoRexxar/Kunlun-M Cobra是一款源代码安全审计…

springboot中定时任务cron不生效,fixedRate指定间隔失效,只执行一次的问题

在调试计算任务的时候&#xff0c;手动重置任务为初始状态&#xff0c;但是并没有重新开始计算&#xff0c;检查定时任务代码&#xff1a; 从Scheduled(fixedRate 120000)可以看到&#xff0c;应该是间隔120秒执行一次该定时任务&#xff0c;查看后台日志&#xff0c;并没有重…

追寻Moonbeam身影,泰国区块链周正在火热进行中!

继Moonbeam参与HK Web3月之后&#xff0c;下一站便是由Cryptomind Group举办的泰国2023年区块链周。本次位于泰国的区块链周以“熊市中建设&#xff0c;牛市中崛起”为理念&#xff0c;旨在为对区块链技术感兴趣的个人和投资者提供机会接触行业中的团队和专家&#xff0c;并邀请…

跨境虾皮Shopee和Lazada商品详情接口采集方案

跨境虾皮和Lazada商品详情接口采集方案可以采用以下步骤&#xff1a; 了解接口文档&#xff1a;首先需要了解跨境虾皮和Lazada的商品详情接口文档&#xff0c;包括接口地址、请求参数、返回结果等信息。获取API密钥&#xff1a;为了使用API接口&#xff0c;需要获取跨境虾皮和…

五个做原型的好处和意义

绘制原型不仅是产品开发的重要基础&#xff0c;也是UI设计师在设计过程中应该采用的主要路径标识。绘制原型的重要性不亚于建筑师手中的设计图纸&#xff01;虽然原型设计可能会给产品开发带来一些误解&#xff0c;但毫不夸张地说&#xff0c;任何开发人员都可以将优秀的开发产…

将Modbus转Profinet网关用于自动给料机的案例

自动给料机通过使用Modbus转Profinet网关&#xff08;XD-MDPN100&#xff09;连接1200PLC与G120变频器Modbus通信。这种通信方式可以实现设备之间的数据交换和控制命令传输&#xff0c;大大提高了自动给料机的运行效率和精度。使用这个网关&#xff0c;1200PLC可以准确地将控制…

13 # 手写 concat 方法

concat 的使用 concat() 方法用于合并两个或多个数组。此方法不会更改现有数组&#xff0c;而是返回一个新数组。如果省略了所有参数&#xff0c;则 concat 会返回调用此方法的现存数组的一个浅拷贝。 <script>var arr1 ["k", "a", "i"…

ES|QL(Elasticsearch 查询语言)入门

作者&#xff1a;Ninoslav Miskovic 通过使用 ES|QL 直接从 Discover 创建聚合、可视化和警报&#xff0c;缩短获得见解的时间。 什么是 ES|QL&#xff08;Elasticsearch 查询语言&#xff09;&#xff1f; ES|QL&#xff08;Elasticsearch 查询语言&#xff09;是 Elastic 全…

文件包含 [ZJCTF 2019]NiZhuanSiWei1

打开题目 代码审计 if(isset($text)&&(file_get_contents($text,r)"welcome to the zjctf")){ 首先isset函数检查text参数是否存在且不为空 用file_get_contents函数读取text制定的文件内容并与welcome to the zjctf进行强比较 echo "<br><h…

ByteBuf和ByteBuffer

一、背景简介 ByteBuf&#xff0c;顾名思义&#xff0c;就是字节缓冲区&#xff0c;是Netty中非常重要的一个组件。熟悉jdk NIO的同学应该知道ByteBuffer&#xff0c;正是因为jdk原生ByteBuffer使用比较复杂&#xff0c;某些场景下性能不是太好&#xff0c;netty开发团队重新设…

QT QSplitter

分裂器QSplitter类提供了一个分裂器部件。和QBoxLayout类似&#xff0c;可以完成布局管理器的功能,但是包含在它里面的部件,默认是可以随着分裂器的大小变化而变化的。 比如一个按钮放在布局管理器中,它的垂直方向默认是不会被拉伸的,但是放到分裂器中就可以被拉伸。还有一点不…

多篇论文介绍-摘要

论文地址https://arxiv.org/pdf/2301.10051.pdf 目录 01CIEFRNet&#xff1a;面向高速公路的抛洒物检测算法 02改进 YOLOv5 的 PDC 钻头复合片缺损识别 03 基于SimAM注意力机制的DCN-YOLOv5水下目标检测 04 基于改进YOLOv7-tiny 算法的输电线路螺栓缺销检测 ​编辑05 基于改进Y…

jquery的项目,html页面使用vue3 +element Plus

vue3&#xff0c;element引入 <script src"../vue3.3.8/vue.global.js"></script> <link rel"stylesheet" href"js/elementPlus/index.css"> <script src"js/elementPlus/index.full.js"></script>…

Linux友人帐之网络编程基础NFS服务器

一、概述 1.1NFS基础概念 NFS服务器&#xff08;Network File System&#xff09;是一种网络文件系统协议&#xff0c;它允许不同计算机之间共享文件系统中的文件。它是一种专门用于在网络上共享文件和目录的服务器。NFS服务器可以把本地的文件系统目录通过网络共享给其它计算…

【C++】——类与对象(一)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

Python tkinter实现复刻Windows记事本UI和菜单的文本编辑器(一)

下一篇&#xff1a;Python tkinter实现复刻Windows记事本UI和菜单的文本编辑器&#xff08;二&#xff09;-CSDN博客 介绍&#xff1a; Windows操作系统中自带了一款记事本应用程序&#xff0c;通常用于记录文字信息&#xff0c;具有简单文本编辑功能。Windows的记事本可以新…

LoadRunner脚本编写之二

下面来回顾一下嵌套循环例子。 Action() {int i,j; //生命两个变量for (i1;i<5;i) //第一重循环&#xff0c;循环5次{if (i3) break; //当i等于3时&#xff0c;跳出本重循环elselr_output_message("i%d",i); //否则&#xff0c;输入i的值for (j1;j<…

效率提升75%!要做矩阵号,更要做好矩阵号管理

在如今的信息数字化时代&#xff0c;面对竞争日趋激烈的市场&#xff0c;数字化转型成为了企业提高效率和竞争力、实现可持续发展的重要手段。 这一两年来&#xff0c;我们也发现&#xff0c;越来越多的品牌企业开始探索数字化转型的实践&#xff0c;通过使用自建或者采买的数据…

Spring Task定时任务框架

二十四、Spring Task 24.1 介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 定位&#xff1a;定时任务框架 作用&#xff1a;定时自动执行某段Java代码 为什么要在Java程序中使用Spring Task&#xff1f; 应用场景…