Docker高级篇之安装Redis集群(分布式存储案例)

文章目录

    • 1. 案例场景
    • 2. 3主3从redis集群扩缩容配置案例架构说明
    • 3. 3主3从redis集群扩缩容配置案例搭建
    • 4. 主从容错切换迁移案例
    • 5. 主从扩容
    • 6. 主从缩容

1. 案例场景

1~2亿条数据需要缓存,如何设计这个存储案例?这种情况下单机存储100%是不可能的,肯定是分布式存储,那么用redis如何落地?

  • 哈希取余分区

在这里插入图片描述
2亿条记录就是2亿个k-v对,我们单机不行必须要用分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:hash(key)%N台机器数,计算出hash值,用来决定映射到哪一个节点上。这样做的优点是,简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落在一台服务器上,这样每台服务器固定处理一部分请求,起到负载均衡+分而治之的作用。但这个方法缺点也是很明显的,原来规划好的节点,进行扩容或者缩容就比较麻烦,每次数据变动导致节点有变动,映射关系需要重新计算,在服务器个数不变时,哈希取余分区方法是很高效的,如果需要弹性扩容或者故障停机的情况下,原来的取模公式就会发生变化。此时,如果某个节点宕机了,那么导致整个hash取余就会重新洗牌,根据公式获取数据失效。

  • 一致性哈希算法

一致性hash算法是在1997年由麻省理工学院提出来的,设计目标是为了解决分布式缓存数据变动和映射问题,某个机器宕机了,分母数量就会改变了,自然取余失效的情况。(当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系),该方法步骤如下:

  1. 使用一致性算法构建哈希环

一致性hash算法必然有个hash函数,并按照算法产生hash值,这个算法所有可能哈希值会构成一个全量集,这个集合可以成为一个hash空间 [ 0 , 2 32 − 1 ] [0,2^{32}-1] [0,2321],这个是一个线性空间,但是在算法中,我们通过适当的逻辑控制将它首位相连,这样让它逻辑上形成一个环形空间。一致性哈希算法也是按照使用取模的方法,不不同hash不同的是,一致性hash算法取模对象不是服务器数量,而是对 2 32 2^{32} 232取模,简单来说,一致性hash算法将整个hash空间组织成了一个虚拟的环,如果设某hash函数H的值空间为 [ 0 , 2 32 − 1 ] [0,2^{32}-1] [0,2321],整个hahs环如下图:整个空间按顺时针方向组织,圆的正上方的点代表0,0右侧的第一个点代表1,以此类推,2、3、4…直到 2 32 − 1 2^{32}-1 2321,也就是说0点左侧的第一个点代表 2 32 − 1 2^{32}-1 2321,0和 2 32 − 1 2^{32}-1 2321在0点中方向重合,我们把这个由 2 32 2^{32} 232个点组成的圆称为hash环。

在这里插入图片描述
2. 服务器IP节点映射

将集群中某个IP节点映射到环上的某一个位置。将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行hash,这样每台机器就能确定其在hash环上的位置,假如4个节点Node A、B、C、D,经过IP地址的哈希函数计算(hash(ip)),使用IP地址哈希后的环空间位置如下:
在这里插入图片描述

  1. key落到服务器的落键规则

当我们需要存储一个k-v时,首先计算key的hash值,hash(key),将这个key使用相同的函数Hash计算出hash值并确定此数据在环上的位置,从次位置沿环顺时针行走,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对存储在该节点上。

在这里插入图片描述

一致性hash算法有很多优点,首先它具有容错性,假设上图的Node C节点宕机了,此时Object C的数据就会放到Node D中,也就是说在一执行hash算法中,如果一台服务器不可用,则受影响的数据仅仅是次服务器到其环空间中前一台服务器的数据,其它不会收到影响。此外,一致性hash算法还具有扩展性,假如上图中Node A和Node B中加入了一个Node X,此时受到影响的也就是A到X之间的数据,重新把A到X的数据录入到X上即可,不会导致hash取余全部数据重新洗牌。

当然一致性hash算法也有一定的局限性,一致性hash算法有数据倾斜问题,一致性hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题,例如下图系统只有两个服务器:
在这里插入图片描述

  • hash槽分区(用的比较广泛)

为了解决一致性hash算法的数据倾斜问题提出了hash槽分区的概念。哈希槽实质上就是一个数组,数组 [ 0 , 2 14 − 1 ] [0,2^{14}-1] [0,2141]形成hash slot空间。哈希槽能解决均匀分配的问题,在数据节点之间又加入了一层,把这层称为哈希槽,用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。
在这里插入图片描述
槽解决的事粒度问题,相当于把粒度变大了,这样便于数据移动。hash解决的事映射问题,使用key的hash值来计算所在的槽,用于数据分配。

一个redis集群只能有16384个槽,编号0-16383。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号分配给哪个主节点,集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求hash值,然后对16384取余,余数是几key就落入对应的槽中。以槽为单位移动数据,因为槽的数量是固定的,处理起来比较容器,这样数据移动的问题就解决了。

在这里插入图片描述

2. 3主3从redis集群扩缩容配置案例架构说明

  • redis集群(3主3从-docker配置案例说明)

在这里插入图片描述

3. 3主3从redis集群扩缩容配置案例搭建

  • 3主3从redis集群配置

新6个docker实例

docker run -d --name redis-node-1 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r1:/data redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6381 --daemonize no --protected-mode nodocker run -d --name redis-node-2 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r2:/data redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6382 --daemonize no --protected-mode nodocker run -d --name redis-node-3 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r3:/data redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6383 --daemonize no --protected-mode nodocker run -d --name redis-node-4 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r4:/data  redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6384 --daemonize no --protected-mode nodocker run -d --name redis-node-5 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r5:/data redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6385 --daemonize no --protected-mode nodocker run -d --name redis-node-6 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r6:/data redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6386 --daemonize no --protected-mode no

–net host:使用宿主机的IP和端口
–privileged=true:获取宿主机root用户权限
–cluster-enabled yes :开启redis集群
–appendonly yes:开启redis持久化

在这里插入图片描述
在这里插入图片描述

进入容器内部构建集群关系

首先进入redis-node-1

docker exec -it redis-node-1 /bin/bash

然后构建主从关系:

redis-cli -p 6381 --cluster  create 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 127.0.0.1:6386 --cluster-replicas 1

-cluster-replicas 1表示为每个master创建一个slave节点

在这里插入图片描述

可以上面图片中表示hash槽被分配到了三个redis节点中,可以发现节点之间的主从关系也分配好了

然后登陆6381号机器查看集群的状态:

redis-cli -p 6381
cluster info

在这里插入图片描述

cluster nodes

在这里插入图片描述

从上面可以知道,集群关系如下表所示:

masterslave
63816385
63826386
63836384

4. 主从容错切换迁移案例

  • 数据读写存储

我们进入6381机器,然后插入一条数据。出现(error) MOVED 12706 127.0.0.1:4381

这是因为k1转换后的hash值不属于这个6381分配到的hash槽位,所以插入不进去,所以我们redis-cli不能连接具体的节点,而是整个redis集群,要使用-c参数

在这里插入图片描述

redis-cli -p 6381 -c

在这里插入图片描述

现在就重定向插入成功了

#这个也可以看集群的信息
redis-cli --cluster check 127.0.0.1:6381

在这里插入图片描述

  • redis集群的主从切换

我们让master 6381宕机:

在这里插入图片描述
然后进入6382查看集群情况:

在这里插入图片描述
可以发现原来6381的从节点6385切换成了主节点

如果6381恢复了,分析现在的主从关系:

在这里插入图片描述

可以发现6381成为了6385的master了,实验完毕后恢复原来的架构图(6381再次成为master,手动恢复)

5. 主从扩容

现在我们再加入一个主从节点,成为四主四从架构。

  • 新增主机6387和6388
docker run -d --name redis-node-7 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r7:/data redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6387 --daemonize no --protected-mode nodocker run -d --name redis-node-8 --net host --privileged=true -v /Users/jackchai/Desktop/lottory_docker/learndocker/redis/r8:/data redis:6.0.8  --cluster-enabled yes --appendonly yes --port 6388 --daemonize no --protected-mode no

在这里插入图片描述

  • 进入6387中,将新增的6387节点(空槽号)作为master节点加入到原集群
redis-cli --cluster add-node 127.0.0.1:6387 127.0.0.1:6381

在这里插入图片描述

6387成功加入,但是没有分配任何hash槽

redis-cli --cluster check 127.0.0.1:6381

在这里插入图片描述

现在确实是4主4从

然后我们需要现在需要重新分配槽位(重点关注是如何分配槽位的

redis-cli --cluster reshard 127.0.0.1:6381

在这里插入图片描述
槽位分配完后,看看集群现在情况:
在这里插入图片描述

最后将6388加入为6387的从节点

redis-cli --cluster add-node 127.0.0.1:6388 127.0.0.1:6387 --cluster-slave --cluster-master-id d8c2c1b1173153a52bbb5d3b1621e264bc58e399

在这里插入图片描述
在这里插入图片描述

6. 主从缩容

现在我们删除上面增加的6387和6388恢复3主3从架构。

  • 先清除掉从节点6388
redis-cli --cluster del-node 127.0.0.1:6388 5b783d293e3499437eea2e0a368f31f488e04740

在这里插入图片描述

可以发现现在只有3个从节点了

  • 将6387的槽号清空,本例将清出来的槽号都给6381
redis-cli --cluster reshard 127.0.0.1:6381

在这里插入图片描述
在这里插入图片描述
最后删除6387节点:

redis-cli --cluster del-node 127.0.0.1:6387 d8c2c1b1173153a52bbb5d3b1621e264bc58e399

在这里插入图片描述

又恢复到3主3从架构了

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

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

相关文章

社区待就业人员信息管理系统的设计

管理员账户功能包括:系统首页,个人中心,工作岗位管理,基础数据管理,预约面试管理,就业信息管理,公告信息管理 社区工作账户功能包括:系统首页,个人中心,用户…

做自媒体素材哪里找?做自媒体必备的几个高质量素材网站分享

在自媒体的世界里,内容是王道。无论是视频还是文章,优秀的自媒体作品都需要有力的内容和高质量的素材作支撑。今天,我为大家整理了一些优质的素材网站,帮助每一位自媒体创作者,无论新手还是老手,都能找到适…

文件夹如何加密码?这4个文件夹加密方法值得一试!

文件夹如何加密码?在与朋友、家人和同事共享同一电脑计算机时,您可能有一些不希望他们查看的重要或机密文件。那么如何避免这种情况呢?使用密码保护锁定文件和文件夹可以提高你的数字隐私和安全性,因为这意味着你需要输入密码才能…

每天CTF小练一点--ctfshow年CTF

初一 题目: 2023是兔年,密码也是。聪明的小伙伴们,你能破解出下面的密码吗? 感谢大菜鸡师傅出题 flag格式是ctfshow{xxxxxx}.或许密码也有密码。 密文是: U2FsdGVkX1M7duRffUvQgJlESPfOTV2i4TJpc9YybgZ9ONmPk/RJje …

修复Windows上“发生意外错误”问题的5种方法,总有一种适合你

在尝试启动网络适配器的设置菜单时,是否收到“发生意外错误”消息?不用担心,因为在大多数情况下解决这个问题很容易。我们将向你展示在Windows 11或Windows 10计算机上解决此问题的多种方法。 为什么我收到“发生意外错误”的消息 当网络适配器出现问题时,Windows会显示一…

老师评职称三证不一致怎么办

对于老师们来说,职称评定无疑是一个重要环节,不仅关系到教师的个人荣誉,更关系到职业发展和薪酬待遇。然而,当遇到教师资格证、任职资格证上的学科与实际所教学科不一致时,职称评定之路似乎变得崎岖不平。面对这样的困…

顺序执行sql查询数据不一致的原因

原因可能包括但不限于: 脏读:一个事务在另一个事务完成之前读取了未提交的数据。 非重复读:在同一事务中,多次读取同一数据返回不同的结果,因为在此期间其他事务对数据做了修改。 幻读:一个事务在同一个事…

作业-day-240605

思维导图 C编程 设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重 再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1 设计这两个类的构造函数、析构函数。 #include <iostream>using namespace std;class Per{ private:str…

Science项目文章 | 中国农科院作科所研究团队解析“复粒稻”多粒簇生的机制

2024年3月8日&#xff0c;由中国农业科学院作物科学研究所童红宁研究员领衔的研究团队在Science发表题为“Enhancing rice panicle branching and grain yield through tissue-specific brassinosteroid inhibition”的研究论文。该研究报道了复粒稻多粒簇形成的机制&#xff0…

记一次minio集群搭建及联邦扩容

文章目录 背景一. 服务器准备1. minio集群12. minio集群23. etcd服务 二、etcd 部署三、minio集群部署1、集群12、集群2部署 四、测试 背景 根据公司业务调研引入minio做数据存储&#xff0c;考虑到后期的扩容与维护选择使用docker、etcd实现联邦扩容 一. 服务器准备 1. min…

用单链表实现集合

一、实验题目 &#xff08;1&#xff09;实验题目 用单链表实现集合 &#xff08;2&#xff09;问题描述 用有序单链表实现集合的判等、交、并和差等基本运算。 二、实验内容 &#xff08;1&#xff09;采用有序单链表存储集合&#xff1b; &#xff08;2&#xff09;实现交…

实时监控与报警:人员跌倒检测算法的实践

在全球范围内&#xff0c;跌倒事件对老年人和儿童的健康与安全构成了重大威胁。据统计&#xff0c;跌倒是老年人意外伤害和死亡的主要原因之一。开发人员跌倒检测算法的目的是通过技术手段及时发现和响应跌倒事件&#xff0c;减少因延迟救助而造成的严重后果。这不仅对老年人群…

【FPGA约束】如何对fpga进行io约束

对 FPGA 进行 I/O 输入输出约束是确保设计满足电气和物理要求的重要步骤。以下是在 Vivado 环境中设置 I/O 约束的一般步骤&#xff1a; 1. 确定 I/O 引脚需求 根据电路设计和 FPGA 芯片手册&#xff0c;确定每个 I/O 引脚的物理位置、电气特性&#xff08;如电压标准&#x…

Linux学习—Linux服务和守护进程

在Linux系统中&#xff0c;服务和守护进程是保持系统运行的关键组件。服务是运行在后台的程序&#xff0c;通常在系统启动时自动启动&#xff0c;而守护进程是持续运行的程序&#xff0c;用于监听特定的事件或执行定期任务。本文将介绍如何在Linux环境下管理服务和守护进程&…

鸿蒙开发接口安全:【@ohos.security.huks (通用密钥库系统)】

通用密钥库系统 说明 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 向应用提供密钥库能力&#xff0c;包括密钥管理及密钥的密码学操作等功能。 HUKS所管理的密钥可以由应用导入或者由应用调用HUKS接口生成。 导…

Java实现本地缓存

Java实现本地缓存主要还是适用于单体应用&#xff0c;且服务一旦重启&#xff0c;数据都将丢失。 先创建一个缓存类&#xff0c;主要是存放数据和缓存时间&#xff0c;该类的内容或属性可以根据业务自行添加。 Data public class MyCache {/*** 缓存内容*/public String valu…

2024速通python之python面向对象

文章目录 一、类与对象二、构造方法三、toString方法四、__eq__方法&#xff0c;相当于equals五、封装、继承与多态1.封装2.继承3.重写4.类型注解5.多态6.抽象类与抽象方法 「章节总览」       【2024速通python之python基础 https://blog.csdn.net/weixin_45404884/ar…

SpringBoot: 读取项目的Git版本号

在开发项目的时候&#xff0c;我们经常会想要拿到线上运行的程序版本&#xff0c;以确定程序是否正确发布。Spring Boot提供了这样的能力支持。这个能力的核心组件是3个: Maven插件git-commit-id-maven-plugin&#xff0c;用于生成.properties文件&#xff0c;里边包含git的各…

项目部署服务器--浏览器拒绝访问问题

一、检查自己的环境 是本地环境、还是虚拟环境 当您使用 Gunicorn 启动 Flask 应用并监听 0.0.0.0:5000 时&#xff0c;您的 Flask 应用已经可以在服务器上运行并通过该端口提供服务了。但是&#xff0c;0.0.0.0 是一个特殊的 IP 地址&#xff0c;它表示“所有可用的网络接口”…

字节序 大端 小端

字节序&#xff08;Byte Order&#xff09;&#xff0c;指的是在计算机系统中&#xff0c;多字节数据&#xff08;如整数、浮点数&#xff09;在内存中存储时的字节排列顺序。主要有两种类型的字节序&#xff1a;大端字节序&#xff08;Big Endian&#xff09;和小端字节序&…