19.Redis之集群

1.集群的基本介绍

  • 集群 这个词.
  • 广义的集群,只要你是多个机器,构成了分布式系统, 都可以称为是一个"集群"前面主从结构,哨兵模式,也可以称为是"广义的集群”
  • 狭义的集群,redis 提供的集群模式, 这个集群模式之下,主要是要解决,存储空间不足的问题(拓展存储空间)

哨兵模式提高了系统的可用性
哨兵模式中,本质上还是 redis 主/从节点(内存,256G,512G.上 TB 的服务器也不是没有(贵))存储数据,其中就要求一个主节点/从节点,就得存储整个数据的"全集

  • 此处关键问题,就是引入多台机器,每台机器存储一部分数据,
  • 设 有 1TB 的数据需要存储.
  • 拿两台机器来存,每个机器只需要存 512GB 即可.
  • 拿三台机器来存,每个机器只需要存 300 多 GB 即可, 
  • 拿四台机,器来存,每个机器只需要存 256GB.....
  • 随着机器数目的增加,每个机器存储的数据量就减少了
  • 【只要机器的规模足够多,就可以存储任意大小的数据了,(公司的实力)】
  • 【不是说光搞3个机器就够了每个存储数据的机器还需要搭配若于个从节点】

2.如何把数据分成多分?

  • 把数据分成多份,应该怎么分?
  • 是一个 分片(sharding).
  • 三种主流的分片方式,
  • 1.哈希求余

  • 借鉴了哈希表的基本思想.
    借助 hash 函数,把一个 key 映射到整数,再针对数组的长度
    求余,就可以得到一个数组下标.
  • 比如有三个分片,编号 012
    此时就可以针对要插入的数据的 key(redis 都是 键值对 结构的数据)计算 hash 值.(比如,使用 md5)【md5 本身就是一个计算 hash 值的算法针对一个字符串,里面的内容进行一系列的数学变换 =>整数.】再把这个 hash 值余上分片个数,就得到了一个下标,此时就可以把这个数据放到该下标对应的分片中了.
  • 【缺陷】
  • 一旦服务器集群需要扩容,就需要更高的成本了
    分片主要目的就是为了能提高存储能力.
    分片越多,能存的数据越多,成本也更高,
  • 一般都是先少搞几个分片.(3 个)
    但是随着业务逐渐增长,数据变多了~~3 个分片就已经不足以保存了
  • 就需要"扩容”
    引入新的分片,N 就改变了
    hash(key)% N >=0
  • 当 hash 函数和 key 都不变的情况下,如果 N 改变了整体的分片结果仍然会变!!
  • 如果发现某个数据,在扩容之后,不应该待在当前的分片中了,就需要重新进行分配 (搬运数据)
  • 此处列出的这些值,就可以脑补成 hash(key)假设当前计算完 hash 值之后,得到的 数值正好是 100-120
  • 共 20 个数据,只有 3 个数据不需要搬运~~ 搬运了 17 个数据如果是 20 亿 个数据呢?? 17 亿数据就要搬运...这就是一个大活了!!
  • 上述级别的扩容,开销极大的,往往是不能直接在生产环境上操作的,只能通过"替换"的方式来实现扩容。
  • 依赖的机器更多了.成本更高,操作步骤非常复杂!!!
  • 2.一致性哈希算法

  • 会导致数据不均匀的问题
  • 此时, 只需要把 0 号分⽚上的部分数据, 搬运给 3 号分⽚即可. 1 号分⽚和 2 号分⽚管理的区间都是不变的.
  • 优点: ⼤⼤降低了扩容时数据搬运的规模, 提⾼了扩容操作的效率.
  • 缺点: 数据分配不均匀 (有的多有的少, 数据倾斜).
  • 3.哈希槽分区算法

  • 【问题1】
  • Redis 集群是最多有 16384 个分片吗?
  • 每个分片上就只有一个槽位.(此时很难保证数据在各个分片上的均衡性~~)(有的槽位可能是 有多个 key,有的槽位可能是 没有 key ~)
  • key 是要先映射到槽位,再映射到分片的
  • 如果每个分片包含的槽位比较多,如果槽位个数相当, 就可以认为是包含的 key 数量相当的:
  • 如果每个分片包含的槽位非常少,槽位个数不一定能直观的反应到 key 的数目
  • 实际上 Redis 的作者建议集群分片数不应该超过(1000.
  • 如果真是1.6w 个分片,整个数据服务器的集群规模就太可怕了
  • 几万台主机构成的集群了.整个集群的可用性是非常堪忧的!!
  • 【问题2】
  • 问题二: 为什么是 16384 个槽位?
  • 心跳包中包含了该节点持有哪些 slots.
  • 需要表示出该节点持有哪些槽位
  • 虽然 8kb 比2kb 也大不了多少, 但是心跳包,周期性通信的.(非常频繁 & 网络带宽
  • 这个值个数上基本够用了.同时占用的硬件资源(网络带宽)又不是很大

 

3.搭建集群环境

3.1 生成配置文件

  • 基于 docker 在咱们云服务器上搭建出一个 redis 集群出来.
  • 当前阶段,主要是因为咱们只有一个 云服务器,搞分布式系统, 就比较麻烦
  • 实际工作中,一般是通过多个主机的方式,来搭建集群的,
第⼀步: 创建⽬录和配置
创建 redis-cluster ⽬录. 内部创建两个⽂件
一定要记得,把之前启动 redis 容器,给停止掉!!

  • 在 linux 上,以 .sh 后缀结尾的文件,称为"shell(脚本)【剧本,也可以称为脚本,】
  • 使用 linux 的时候, 都是通过一些命令来进行操作的.
  • 使用命令操作,就非常适合把命令给写到一个文件中,批量化执行,
  • 同时,还能加入, 条件,循环,函数 等机制
  • 因此,就可以基于这些来完成更复杂的工作了
  • 需要创建 11 个 redis 节点.这些 redis 的配置文件内容,大同小异.
  • 此时就可以使用脚本来批量生成.(也可以不使用脚本,手动一个一个改)
  • generate.sh 内容如下
  • for port in $(seq 1 9); \
    do \
    mkdir -p redis${port}/
    touch redis${port}/redis.conf
    cat << EOF > redis${port}/redis.conf
    port 6379
    bind 0.0.0.0
    protected-mode no
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    cluster-announce-ip 172.30.0.10${port}
    cluster-announce-port 6379
    cluster-announce-bus-port 16379
    EOF
    done
    # 注意 cluster-announce-ip 的值有变化. 
    for port in $(seq 10 11); \
    do \
    mkdir -p redis${port}/
    touch redis${port}/redis.conf
    cat << EOF > redis${port}/redis.conf
    port 6379
    bind 0.0.0.0
    protected-mode no
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    cluster-announce-ip 172.30.0.1${port}
    cluster-announce-port 6379
    cluster-announce-bus-port 16379
    EOF
    done
  •  
  • 成功!!!

3.2 创建容器 

  • 编写 docker-compose.yml

  • version: '3.3'
    networks:mynet:ipam:config:- subnet: 172.30.0.0/24
    services:redis1:image: 'redis:5.0.9'container_name: redis1restart: alwaysvolumes:- ./redis1/:/etc/redis/ports:- 6371:6379- 16371:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.101redis2:image: 'redis:5.0.9'container_name: redis2restart: alwaysvolumes:- ./redis2/:/etc/redis/ports:- 6372:6379- 16372:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.102redis3:image: 'redis:5.0.9'container_name: redis3restart: alwaysvolumes:- ./redis3/:/etc/redis/ports:- 6373:6379- 16373:16379
    command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.103redis4:image: 'redis:5.0.9'container_name: redis4restart: alwaysvolumes:- ./redis4/:/etc/redis/ports:- 6374:6379- 16374:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.104redis5:image: 'redis:5.0.9'container_name: redis5restart: alwaysvolumes:- ./redis5/:/etc/redis/ports:- 6375:6379- 16375:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.105redis6:image: 'redis:5.0.9'container_name: redis6restart: alwaysvolumes:- ./redis6/:/etc/redis/ports:- 6376:6379- 16376:16379
    command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.106redis7:image: 'redis:5.0.9'container_name: redis7restart: alwaysvolumes:- ./redis7/:/etc/redis/ports:- 6377:6379- 16377:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.107redis8:image: 'redis:5.0.9'container_name: redis8restart: alwaysvolumes:- ./redis8/:/etc/redis/ports:- 6378:6379- 16378:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.108redis9:image: 'redis:5.0.9'container_name: redis9restart: alwaysvolumes:- ./redis9/:/etc/redis/ports:- 6379:6379- 16379:16379
    command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.109redis10:image: 'redis:5.0.9'container_name: redis10restart: alwaysvolumes:- ./redis10/:/etc/redis/ports:- 6380:6379- 16380:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.110redis11:image: 'redis:5.0.9'container_name: redis11restart: alwaysvolumes:- ./redis11/:/etc/redis/ports:- 6381:6379- 16381:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.111
    

3.3 配置集群关系 

1)生成每个 redis 节点的配置文件
2)使用 docker 创建出 11 个 redis 节点, 并且启动容器
3)使用 redis-cli 执行构建集群命令

redis-cli --cluster create 172.30.0.101:6379 172.30.0.102:6379 172.30.0.103:6379 172.30.0.104:6379 172.30.0.105:6379 172.30.0.106:6379 172.30.0.107:6379 172.30.0.108:6379 172.30.0.109:6379 --cluster-replicas 2

3.4 使用集群

  • redis-cli -h 172.30.0.101 -p 6379
  • 4.故障处理

  •  

5.集群扩容 

101-1099个主机,构成了3主,6 从结构的集群了
110 和 111 也加入到集群中
以110为 master, 111为 slave.=>把数据分片从 3->4
集群扩容操作,是一件风险较高,成本较大的操作!!!

1.新的主节点(110) 加入到集群中
redis-cli --cluster add-node 172.30.0.110:6379 172.30.0.101:6379

 2.重新分配 slots

redis-cli --cluster reshard 172.30.0.101:6379

 

3.给新的主节点添加从节点
光有主节点了, 此时扩容的⽬标已经初步达成. 但是为了保证集群可⽤性, 还需要给这个新的主节点添加从节点, 保证该主节点宕机之后, 有从节点能够顶上 
redis-cli --cluster add-node 172.30.0.111:6379 172.30.0.101:6379 --cluster-slave --cluster-master-id c999d6e82415680b57868cc3c59f9f1a779a59cd

6.集群的缩容

把一些节点拿掉,减少分片的数量,
般都是进行扩容,很少缩容!

7.小结

1)集群是什么,解决了什么问题?
2)数据分片算法[重点/考点]
a)哈希求余
b)一致性哈希算法
c)哈希槽分区算法(redis)
3)搭建 redis 集群,
4)集群容灾.故障转移
5)集群扩容.
6)代码连接集群
使用的库, 得能够支持 集群模式.

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

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

相关文章

科普健康短视频:成都鼎茂宏升文化传媒公司

科普健康短视频&#xff1a;引领健康知识新潮流 在数字化时代的浪潮中&#xff0c;短视频以其短小精悍、直观易懂的特点&#xff0c;迅速成为大众获取信息的重要渠道。其中&#xff0c;科普健康短视频更是凭借其科学、权威、实用的内容&#xff0c;吸引了大量关注健康的观众。…

Linux —— MySQL操作(1)

一、用户与权限管理 1.1 创建与赋予权限 create user peter% identified by 123465 # 创建用户 peter&#xff0c;# %&#xff1a;允许所有用户登录这个用户访问数据库 刚创建的新用户是什么权限都没有&#xff0c;需要赋予权限 grant select on mysql.* to peter%; # 赋予…

什么是数据资产管理?数据资产管理包括了哪些内容?

数据资产管理包括数据模型管理、数据标准管理、数据质量管理等 10 个活动职能&#xff0c;覆盖数据资源化、数据资产化两个阶段。本章参考 PDCA 方法&#xff0c;从计划、执行、检查、改进四个环节着手&#xff0c;阐述数据资产管理活动职能的核心理念与实践要点。 一、数据模型…

使用Python操作Git

大家好&#xff0c;当谈及版本控制系统时&#xff0c;Git是最为广泛使用的一种&#xff0c;而Python作为一门多用途的编程语言&#xff0c;在处理Git仓库时也展现了其强大的能力。通过Python&#xff0c;我们可以轻松地与Git仓库进行交互&#xff0c;执行各种操作&#xff0c;从…

2024全新交友盲盒+付费进群二合一源码 包含全套源码+视频教程

2024全新交友盲盒付费进群二合一源码 包含全套源码视频教程39同校 三九同校 最高版本&#xff0c;纸条&#xff0c;交友&#xff0c;源码&#xff0c;搭建包上线运营&#xff0c;防封红&#xff0c;独家唯一版本盲盒交友脱单系统源码&#xff0c;带教程&#xff0c;免授权这套源…

Golang | Leetcode Golang题解之第119题杨辉三角II

题目&#xff1a; 题解&#xff1a; func getRow(rowIndex int) []int {row : make([]int, rowIndex1)row[0] 1for i : 1; i < rowIndex; i {row[i] row[i-1] * (rowIndex - i 1) / i}return row }

分布式任务队列系统 celery 原理及入门

基本 Celery 是一个简单、灵活且可靠的分布式任务队列系统&#xff0c;用于在后台执行异步任务处理大量消息。支持任务调度、任务分发和结果存储&#xff0c;并且可以与消息代理&#xff08;如 RabbitMQ、Redis 等&#xff09;一起工作&#xff0c;以实现任务的队列管理和执行…

[Linux系统编程]文件IO

一.系统调用 什么是系统调用? 只有系统调用(系统函数)才能进入内核空间&#xff0c;库函数也是调用系统函数&#xff0c;才得以访问底层。 系统调用由操作系统实现并提供给外部应用程序的编程接口。是应用程序同系统之间数据交互的桥梁。 换句话说&#xff0c;系统调用就是操…

【计算Nei遗传距离】

报错 Warning message: In adegenet::df2genind(t(x), sep sep, ...) : Markers with no scored alleles have been removed 原因&#xff1a; 直接用plink转换为VCF&#xff0c;丢失了等位基因分型&#xff08;REF ALT&#xff09; &#xff08;plink编码的规则&…

优选算法一:双指针算法与练习(移动0)

目录 双指针算法讲解 移动零 双指针算法讲解 常见的双指针有两种形式&#xff0c;一种是对撞指针&#xff0c;一种是快慢指针。 对撞指针&#xff1a;一般用于顺序结构中&#xff0c;也称左右指针。 对撞指针从两端向中间移动。一个指针从最左端开始&#xff0c;另一个从最…

【Linux】进程(2):进程状态

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解Linux进程&#xff08;1&#xff09;&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 &#xff08;A&#xff09;R/S/D/T/t状态1. R&#xff1a;程序运…

Day-04python模块

一、模块 1-1 Python 自带模块 Json模块 处理json数据 {"key":"value"} json不是字典 本质是一个有引号的字符串数据 json注意点 {} 中的数据是字符串引号必须是双引号 使用json模块可以实现将json转为字典&#xff0c;使用字典的方法操作数据 。 或者将…

社交媒体数据恢复:最右

第一步&#xff1a;确认数据丢失原因 请确定您是因为误删、设备损坏还是其他原因导致“最右”中的数据丢失。这将有助于您更好地了解需要采取的恢复措施。 第二步&#xff1a;尝试从备份中恢复数据 如果您有定期备份的习惯&#xff0c;请尝试从备份中恢复丢失的数据。备份文…

Springboot JVM监控 通过Promethus

Springboot内置了对Prometheus得支持&#xff0c;可以监测得点有&#xff1a; JVM各指标参数&#xff08;GC&#xff0c;堆&#xff0c;非堆等&#xff09;接口调用次数&#xff0c;延时系统内存&#xff0c;IO&#xff0c;CPU使用率 部署Prometheus和Grafana 准备一台2核4G…

STM32自己从零开始实操03:输出部分原理图

一、继电器电路 1.1指路 延续使用 JZC-33F-012-ZS3 继电器&#xff0c;设计出以小电流撬动大电流的继电器电路。 &#xff08;提示&#xff09;电路需要包含&#xff1a;三极管开关电路、续流二极管、滤波电容、指示灯、输出部分。 1.2数据手册重要信息提炼 联系排列&…

手写HTML字符串解析成对应的 AST语法树

先看效果 展示如下&#xff1a; HTML模版 转成ast语法树后 在学习之前&#xff0c;我们需要了解这么一个问题&#xff0c;为什么要将HTML字符串解析成对应的 AST语法树。 为什么&#xff1f; 语法分析&#xff1a;HTML字符串是一种标记语言&#xff0c;其中包含了大量的标签…

使用PNP管控制MCU是否需要复位

这两台用到一款芯片带电池&#xff0c;希望电池还有电芯片在工作的时候插入电源不要给芯片复位&#xff0c;当电池没电&#xff0c;芯片不在工作的时候&#xff0c;插入电源给芯片复位所以使用一个PNP三极管&#xff0c;通过芯片IO控制是否打开复位&#xff0c;当芯片正常工作的…

python移动文件

测试1(直接把B文件夹移动到了A里&#xff0c;成为了A的子文件夹) import os import shutil# 移动文件夹,B文件夹在当前目录没有了&#xff0c;跑到了A的子文件里 ## shutil.move(./example1/B/, ./example1/A/)测试2(B文件不动&#xff0c;将B文件里的所有的子文件夹移动到A内…

响应式UI组件DevExtreme中文教程 - 工具栏的自适应模式

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…

Android高通 12/13 录屏流程代码位置

需求如下图 实现系统录屏功能 frameworks/base/packages/SystemUI/src/com/android/systemui/screenrecord 涉及代码 ScreenRecordDialog # startBtn RecordingService # startRecording# stopRecording ScreenMediaRecorder # start # end #save 1、点击开始录屏framewo…