docker 笔记5:redis 集群分布式存储案例

news2024/11/27 18:27:15

尚硅谷Docker实战教程(docker教程天花板)_哔哩哔哩_bilibili

目录

1.cluster(集群)模式-docker版哈希槽分区进行亿级数据存储 

1.1面试题

1.1.1  方案1 哈希取余分区

1.1.2 方案2 一致性哈希算法分区 

原理

优点

一致性哈希算法的容错性 

一致性哈希算法的扩展性 

缺点 

一致性哈希算法的数据倾斜问题

总结

1.1.3 方案3 哈希槽分区

3 多少个hash槽

哈希槽计算

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

关闭防火墙+启动docker后台服务

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

3.1大纲 :

3.2 数据读写存储

4.主从扩容案例

​编辑 4.1新建6387、6388两个节点+新建后启动+查看是否8节点

4.2  进入6387容器实例内部

4.3 将新增的6387节点(空槽号)作为master节点加入原集群

4.4检查集群情况第1次

redis-cli --cluster check 真实ip地址:6381

4.5 重新分派槽号

4.6 检查集群情况第2次

4.7 为主节点6387分配从节点6388

4.8检查集群情况第3次

5.主从缩容案例

5.1检查集群情况1获得6388的节点ID

​编辑5.2将6387的槽号清空,重新分配,本例将清出来的槽号都给6381

5.3检查集群情况第二次

 5.4将6387删除

5.5检查集群情况第三次


1.cluster(集群)模式-docker版
哈希槽分区进行亿级数据存储 

1.1面试题

1~2亿条数据需要缓存,请问如何设计这个存储案例

单机单台100%不可能,肯定是分布式存储,用redis如何落地?

上述问题阿里P6~P7工程案例和场景设计类必考题目,
一般业界有3种解决方案

1.1.1  方案1 哈希取余分区

2亿条记录就是2亿个k,v,我们单机不行必须要分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:
hash(key) % N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。

 优点:
  简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。

 缺点
   原来规划好的节点,进行扩容或者缩容就比较麻烦了额,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化:Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。
某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。

1.1.2 方案2 一致性哈希算法分区 

原理

致性Hash算法背景(是什么?)
  一致性哈希算法在1997年由麻省理工学院中提出的,设计目标是为了解决
分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不OK了。

 提出一致性Hash解决方案。(能做什么?)
目的是当服务器个数发生变动时,
尽量减少影响客户端到服务器的映射关系

 3大步骤

算法构建一致性哈希环

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

服务器IP节点映射

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

key落到服务器的落键规则

当我们需要存储一个kv键值对时,首先计算key的hash值,hash(key),将这个key使用相同的函数Hash计算出哈希值并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对存储在该节点上。
如我们有Object A、Object B、Object C、Object D四个数据对象,经过哈希计算后,在环空间上的位置如下:根据一致性Hash算法,数据A会被定为到Node A上,B被定为到Node B上,C被定为到Node C上,D被定为到Node D上。

优点

一致性哈希算法的容错性      一致性哈希算法的扩展性

一致性哈希算法的容错性 

假设Node C宕机,可以看到此时对象A、B、D不会受到影响,只有C对象被重定位到Node D。一般的,在一致性Hash算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。简单说,就是C挂了,受到影响的只是B、C之间的数据,并且这些数据会转移到D进行存储。

一致性哈希算法的扩展性 

数据量增加了,需要增加一台节点NodeX,X的位置在A和B之间,那受到影响的也就是A到X之间的数据,重新把A到X的数据录入到X上即可,
不会导致hash取余全部数据重新洗牌。

缺点 

一致性哈希算法的数据倾斜问题

 
Hash环的数据倾斜问题
一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题,
例如系统中只有两台服务器:

总结

为了在节点数目发生改变时尽可能少的迁移数据
 
将所有的存储节点排列在收尾相接的Hash环上,每个key在计算Hash后会顺时针找到临近的存储节点存放。
当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点。  
 
优点
加入和删除节点只影响哈希环中顺时针方向的相邻的节点,对其他节点无影响。
 
缺点 
数据的分布和节点的位置有关,因为这些节点不是均匀的分布在哈希环上的,所以数据在进行存储时达不到均匀分布的效果。 

1.1.3 方案3 哈希槽分区

1 为什么出现?

 一致性哈希的数据倾斜问题

哈希槽实质就是一个数组,数组[0,2^14 -1]形成hash slot空间。

解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。

解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。 

3 多少个hash槽
哈希槽计算

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


 


Redis 集群中内置了 16384 个哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。如下代码,key之A 、B在Node2, key之C落在Node3上

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

关闭防火墙+启动docker后台服务

systemctl start docker

新建6个docker容器redis实例

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
 
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
 
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
 
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
 
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
 
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386

 如果运行成功,效果如下:

命令分步解释

进入容器redis-node-1并为6台机器构建集群关系 

进入容器

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

构建主从关系

//注意,进入docker容器后才能执行一下命令,且注意自己的真实IP地址

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

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

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

一切OK的话,3主3从搞定

链接进入6381作为切入点,查看集群状态

cluster info       cluster nodes

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

3.1大纲 :

3.2 数据读写存储

启动6机构成的集群并通过exec进入

对6381新增两个key

防止路由失效加参数-c并新增两个key

 查看集群信息

redis-cli --cluster check 192.168.111.147:6381

容错切换迁移

主6381和从机切换,先停止主机6381

6381宕机了,6385上位成为了新的master。
备注:本次脑图笔记6381为主下面挂从6385。
每次案例下面挂的从机以实际情况为准,具体是几号机器就是几号

先还原之前的3主3从


 
中间需要等待一会儿,docker集群重新响应。

先启动6381  :docker start redis-node-1

再停6385 :docker stop redis-node-5

 再启6385  :docker start redis-node-5

主从机器分配情况以实际情况为准

查看集群状态

redis-cli --cluster check 自己IP:6381

4.主从扩容案例

 4.1新建6387、6388两个节点+新建后启动+查看是否8节点

docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-

docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387



docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388

docker ps

4.2  进入6387容器实例内部

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

4.3 将新增的6387节点(空槽号)作为master节点加入原集群

将新增的6387作为master节点加入集群
redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
6387 就是将要作为master新增节点
6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群

 

4.4检查集群情况第1次

redis-cli --cluster check 真实ip地址:6381

4.5 重新分派槽号

重新分派槽号
命令:redis-cli --cluster reshard IP地址:端口号
redis-cli --cluster reshard 192.168.111.147:6381

4.6 检查集群情况第2次

槽号分派说明

 为什么6387是3个新的区间,以前的还是连续?
重新分配成本太高,所以前3家各自匀出来一部分,从6381/6382/6383三个旧节点分别匀出1364个坑位给新节点6387

4.7 为主节点6387分配从节点6388

 命令:redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
 
redis-cli --cluster add-node 192.168.111.147:6388 192.168.111.147:6387 --cluster-slave --cluster-master-id e4781f644d4a4e4d4b4d107157b9ba8144631451-------这个是6387的编号,按照自己实际情况

4.8检查集群情况第3次

redis-cli --cluster check 192.168.111.147:6382

5.主从缩容案例

5.1检查集群情况1获得6388的节点ID

redis-cli --cluster check 192.168.111.147:6382

5.2将6388删除
从集群中将4号从节点6388删除

命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID
 
redis-cli --cluster del-node 192.168.111.147:6388 5d149074b7e57b802287d1797a874ed7a1a284a8


5.2将6387的槽号清空,重新分配,本例将清出来的槽号都给6381

redis-cli --cluster reshard 192.168.111.147:6381

5.3检查集群情况第二次

redis-cli --cluster check 192.168.111.147:6381
 
4096个槽位都指给6381,它变成了8192个槽位,相当于全部都给6381了,不然要输入3次,一锅端

 5.4将6387删除

命令:redis-cli --cluster del-node ip:端口 6387节点ID
 
redis-cli --cluster del-node 192.168.111.147:6387 e4781f644d4a4e4d4b4d107157b9ba8144631451

5.5检查集群情况第三次

 
redis-cli --cluster check 192.168.111.147:6381
 

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

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

相关文章

恢复数据的利器:易我数据恢复终身技术版v16.2.0.0

EaseUS Data Recovery Wizard为全球提供数据恢复方案,用于误删数据数据,电脑误删文件恢复,格式化硬盘数据恢复,手机U盘数据恢复等,RAID磁盘阵列数据恢复,分区丢失及其它未知原因丢失的数据恢复,简单易用轻松的搞定数据恢复。 特点描述 - 易我数据恢复中文便携版,无…

一笑的大型连续剧之第一集

自我介绍 哈喽,大家好。首先在开篇之前我想先自己介绍一下,我叫一笑,大家也可以叫我小舒。是一名又菜又爱写代码的Java程序员。当然这个也是我目前的一个想法,可以后期也可能想着去写一下其他的语言。介绍完成之后也就是单纯的想…

VPG算法

VPG算法 前言 首先来看经典的策略梯度REINFORCE算法: 在REINFORCE中,每次采集一个episode的轨迹,计算每一步动作的回报 G t G_t Gt​,与动作概率对数相乘,作为误差反向传播,有以下几个特点: …

Linux命令200例:Dump用来做文件系统备份

🏆作者简介,黑夜开发者,CSDN领军人物,全栈优质新星创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师&#xff0…

C. Queries for the Array - 思维

分析: 分析出现矛盾的地方,也就是可能遇到0,并且已有字符串的长度小于等于1,另一种情况就是,遇到了1并且已有字符串不是排好序的,或者遇到了0已有字符串是排好序的,那么可以遍历字符串&#xff…

Arthas教程 - 安装篇 (一)

目录 一、在线安装 1.1 Windows安装 1.2 小结 1.3 linux安装 二、离线安装 一、在线安装 1.1 Windows安装 本地指定目录下(例如我是:F:\测试\arthas),使用Windows的cmd窗口,执行如下命令则会将jar包下载下来。大…

STM32f103入门(10)ADC模数转换器

ADC模数转换器 ADC简介AD单通道初始化代码编写第一步开启时钟第二步 RCCCLK分频 6分频 72M/612M第三步 配置GPIO 配置为AIN状态第四步,选择规则组的输入通道第五步 用结构体 初始化ADC第六步 对ADC进行校准编写获取电压函数初始化代码如下 Main函数编写 ADC简介 ADC…

[杂谈]-快速了解Modbus协议

快速了解Modbus协议 文章目录 快速了解Modbus协议1、为何 Modbus 如此受欢迎2、范围和数据速率3、逻辑电平4、层数5、网络与通讯6、数据帧格式7、数据类型8、服务器如何存储数据9、总结 ​ Modbus 是一种流行的低速串行通信协议,广泛应用于自动化行业。 该协议由 Mo…

postgresql并行查询(高级特性)

######################## 并行查询 postgresql和Oracle一样支持并行查询的,比如select、update、delete大事无开启并行功能后,能够利用多核cpu,从而充分发挥硬件性能,提升大事物的处理效率。 pg在9.6的版本之前是不支持的并行查询的,从9.6开始支持并行查询,但是功能非常…

ISO/IEC标准之Mpeg-1到Mpeg21对应哪些ISO/IEC标准(三十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

数电再回顾

最近,花了点时间回顾数字电路,放几张我觉得比较好的截图,记录学习过程。 附录: 计算机是如何保存1和0的 - 知乎 (zhihu.com) 只读存储器ROM || ROM实现逻辑函数 || 数电 - 知乎 (zhihu.com) ROM的组成原理 -解决方案-华强电子网…

Java 复习笔记 - 字符串篇

文章目录 一,API和API帮助文档(一)API(二)API帮助文档 二,String概述三,String构造方法代码实现和内存分析四,字符串的比较五,综合练习(一)用户登…

python实现某音自动登录+获取视频数据

前言 Dy这个东西想必大家都用过,而且还经常刷,今天就来用代码,获取它的视频数据 环境使用 Python 3.8 Pycharm 模块使用 requests selenium json re 一. 数据来源分析 1. 明确需求 明确采集网站以及数据内容 网址: https://www.dy.com/…

Midjourney学习(四)光源类型prompt

序号类别光线名称英文名称描述用途示例1光线质地硬光Hard Light直接照射在主题上,产生明显的阴影和高对比度。强调轮廓,增加照片的戏剧性2光线质地软光/柔光Soft Light光线经过散射或扩散,产生柔和的阴影和低对比度。平滑细节,适合…

sublime编辑latex 出现参考文献无法编译报错:citation “...” undefined

问题描述 使用sublime编译latex文件时,参考文献按照常规的方式放好,ctrl B 编译的时候,显示找不到参考文献,编译出的pdf文件也没有references: 但是把文件放到overleaf上就可以直接编译出来,说明是本地编…

基于阻塞队列的生产消费模型

目录 一、线程同步 1.生产消费模型(或生产者消费者模型) 2.认识同步 (1)生产消费模型中的同步 (2)生产者消费者模型的特点 二、条件变量 1.认识条件变量 2.条件变量的使用 3.代码改造 三、基于阻…

B092-人力资源项目-security

目录 springsecurity权限控制使用的必要性分析及它的概念介绍基于session的认证和授权流程介绍认证流程认证检查授权流程 代码认证流程小结认证授权流程Security中核心过滤器链security执行认证的详细流程图Security授权流程剩余见代码工程 springsecurity权限控制使用的必要性…

2、Nginx 安装

文章目录 2、Nginx 安装2.1 官网下载2.2 安装 nginx2.2.1 第一步2.2.2 第二步2.2.3 第三步,安装 nginx2.2.4 第四步,修改防火漆规则 【尚硅谷】尚硅谷Nginx教程由浅入深 志不强者智不达;言不信者行不果。 2、Nginx 安装 2.1 官网下载 nginx…

vim练级攻略(精简版)

vim推荐配置: curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh 0. 规定 Ctrl-λ 等价于 <C-λ> :command 等价于 :command <回车> n 等价于 数字 blank字符 等价于 空格&#xff0c;tab&am…

HuggingFace 简介

HuggingFace 简介 0. HuggingFace 简介1. HuggingFace 官网地址2. HuggingFace 标准研发流程3. HuggingFace 工具集4. 编码工具4.1 编码工具介绍4.2 使用编码工具 5. 数据集工具5.1 数据集工具介绍5.2 使用数据集工具 6. 评价指标工具6.1 评价指标工具介绍6.2 使用评价指标工具…