10-Docker-分布式存储算法

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-总结与归纳

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java网络通信:Springboot整合Websocket

网络通信 什么是webSocket&#xff1f;WebSocket 原理springboot整合websocket过程 网络通信三要素&#xff1a;ip地址&#xff08;ipv4、ipv6&#xff09;、端口号&#xff08;应用程序的唯一标识&#xff09;、协议&#xff08;连接和通信的规则&#xff0c;常用&#xff1a;…

基于袋獾算法的无人机航迹规划-附代码

基于袋獾算法的无人机航迹规划 文章目录 基于袋獾算法的无人机航迹规划1.袋獾搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用袋獾算法来优化无人机航迹规划。 1.袋獾搜索算法 …

深入探讨 Presto 中的缓存

Presto是一种流行的开源分布式SQL引擎&#xff0c;使组织能够在多个数据源上大规模运行交互式分析查询。缓存是一种典型的提高 Presto 查询性能的优化技术。它为 Presto 平台提供了显着的性能和效率改进。 缓存通过将频繁访问的数据存储在内存或快速本地存储中&#xff0c;避免…

redis的数据类型及操作

一、redis 的数据库 Redis是一个字典结构的存储服务器。一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存在哪个字典中。这与关系型数据库例中可以创建多个数据库似。因此,可以将每个字典理解为一个独立的数据库。每个数据库对外都是以0开始的递增数字命名…

HTML的表单标签和无语义标签的讲解

HTML的表单标签 表单是让用户输入信息的重要途径, 分成两个部分: 表单域: 包含表单元素的区域. 重点是 form 标签. 表单控件: 输入框, 提交按钮等. 重点是 input 标签 form 标签 使用form进行前后端交互.把页面上,用户进行的操作/输入提交到服务器上 input 标签 有很多形态,能…

本地消息表分布式事务

BASE论文 论文链接&#xff1a;https://queue.acm.org/detail.cfm?id1394128 里面提到&#xff0c; The most critical factor in implementing the queue, however, is ensuring that the backing persistence is on the same resource as the database. This is necessary…

5G边缘计算网关的功能及作用

5G边缘计算网关具有多种功能。 首先&#xff0c;它支持智能云端控制&#xff0c;可以通过5G/4G/WIFI等无线网络将采集的数据直接上云&#xff0c;实现异地远程监测控制、预警通知、报告推送和设备连接等工作。 其次&#xff0c;5G边缘计算网关可以采集各种数据&#xff0c;包…

vue中 process.env 对象为空对象问题

问题&#xff1a;今天在处理vue项目环境问题的时候&#xff0c;发现直接打印 process 对象和打印 process.env 时 env 对象输出结果是不一样的&#xff0c;如下图所示&#xff1a; 在网上搜索了一番后发现还是有挺多朋友对此感到疑惑的&#xff0c;询问了同事&#xff0c;同…

数模之线性规划

线性规划 优化类问题&#xff1a;有限的资源&#xff0c;最大的收益 例子: 华强去水果摊找茬&#xff0c;水果摊上共3个瓜&#xff0c;华强总共有40点体力值,每劈一个瓜能带来40点挑衅值,每挑一个瓜问“你这瓜保熟吗”能带来30点挑衅值,劈瓜消耗20点体力值&#xff0c;问话消耗…

Vue3 简单实现虚拟Table,展示海量单词.利用WebAPI speechSynthesis,朗读英语单词

目录 本页面完整代码 视频演示 完整的页面代码 利用webapi speechSynthesis帮助我们自动郎读英语单词&#xff0c;可以利用这个API&#xff0c;做一些小说朗读或到账提示。 本页面完整代码 用Vue写了一个简单页面&#xff0c;里面还写了一个简单的虚拟Table支持海量数据展示…

ubuntu 18.04安装自己ko驱动 修改secure boot

因为本人老折腾自己的电脑&#xff0c;所以老重装系统&#xff0c;然后配置又不见了&#xff0c;这次配置赶紧记下来 insmod netlink_test.ko 报错&#xff1a;insmod: ERROR: could not insert module netlink_test.ko: Operation not permitted 添加 sudo insmod netlink_te…

XCTF刷题十一道(01)

文章目录 Training-WWW-RobotsPHP2unserialize3view-sourceget_postrobotsbackupcookiedisabled_buttonweak_authsimple_php Training-WWW-Robots robots.txt&#xff0c;防爬虫&#xff0c;访问urlrobots.txt PHP2 phps源码泄露 >phps文件就是php的源代码文件&#xff0…

swift语言用哪种库适合做爬虫?

目录 1、Alamofire 2、URLSession 3、YepHttp 4、Kickbox 5、Vapor 注意事项 总结 在Swift语言中&#xff0c;可以使用第三方库来帮助进行网络爬虫的开发。以下是几个适合Swift语言使用的爬虫库&#xff0c;以及相应的代码示例&#xff1a; 1、Alamofire Alamofire是Sw…

【k8s】pod控制器

一、pod控制器及其功用 Pod是kubernetes的最小管理单元&#xff0c;在kubernetes中&#xff0c;按照Pod的创建方式可以将其分为两类 自主式Pod&#xff1a; kubernetes直接创建出来的Pod&#xff0c;这种Pod删除后就没有了&#xff0c;也不会重建 控制器创建的Pod&#xff1a…

润和软件HopeStage与奇安信网神终端安全管理系统、可信浏览器完成产品兼容性互认证

近日&#xff0c;江苏润和软件股份有限公司&#xff08;以下简称“润和软件”&#xff09;HopeStage 操作系统与奇安信网神信息技术&#xff08;北京&#xff09;股份有限公司&#xff08;以下简称“奇安信”&#xff09;终端安全管理系统、可信浏览器完成产品兼容性测试。 测试…

多路转接(上)——select

目录 一、select接口 1.认识select系统调用 2.对各个参数的认识 二、编写select服务器 1.两个工具类 2.网络套接字封装 3.服务器类编写 4.源文件编写 5.运行 一、select接口 1.认识select系统调用 int select(int nfds, fd_set readfds, fd_set writefds, fd_set ex…

Node.js |(六)express框架 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;express使用&#x1f407;初体验&#x1f407;express路由⭐️路由的使用⭐️获取请求参数⭐️获取路由参数&#x1f525;练习&#xff1a;根据路由参数响应歌手信息…

小白学爬虫:通过关键词搜索1688商品列表数据接口|1688商品列表数据接口|1688商品列表数据采集|1688API接口

通过关键词搜索1688商品列表数据接口可以使用1688开放平台提供的API接口实现。以下是使用关键词搜索商品列表数据的基本步骤&#xff1a; 1、注册并获取AppKey。 2、构造请求参数&#xff0c;包括搜索关键词、页码、每页条数等。 3、通过API接口链接&#xff0c;将请求参数发送…

简单漂亮的登录页面

效果图 说明 开发环境&#xff1a;vue3&#xff0c;sass 代码 <template><div class"container"><div class"card-container"><div class"card-left"><span><h1>Dashboard</h1><p>Lorem ip…

后台管理系统解决方案-中大型-Vben Admin

后台管理系统解决方案-中大型-Vben Admin 官网 Vben Admin 在线演示 Vben Admin 为什么选择它 github现有20K星&#xff0c;并且它有个可视化生成表单&#xff0c;我很喜欢 快速开始 # 拉取代码 git clone https://github.com/vbenjs/vue-vben-admin-doc# 安装依赖 yarn#…