Redis进阶 - Redis分片集群

原文首更地址,阅读效果更佳!

Redis进阶 - Redis分片集群 | CoderMast编程桅杆icon-default.png?t=N5K3https://www.codermast.com/database/redis/redis-advance-sharded-cluster.html

搭建分片集群

主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:

  • 海量数据存储问题
  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征:

  • 集群中有多个 master,每个 master 保存不同数据
  • 每个 master 都可以有多个 slave 节点
  • master 之间通过 ping 监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

#集群结构

分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:

 

这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:

IPPORT角色
192.168.150.1017001master
192.168.150.1017002master
192.168.150.1017003master
192.168.150.1018001slave
192.168.150.1018002slave
192.168.150.1018003slave

#准备实例和配置

删除之前的7001、7002、7003这几个目录,重新创建出7001、7002、7003、8001、8002、8003目录:

# 进入/tmp目录
cd /tmp
# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003

在/tmp下准备一个新的redis.conf文件,内容如下:

port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log

将这个文件拷贝到每个目录下:

# 进入/tmp目录
cd /tmp
# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:

# 进入/tmp目录
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf

#启动

因为已经配置了后台启动模式,所以可以直接启动服务:

# 进入/tmp目录
cd /tmp
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf

通过ps查看状态:

ps -ef | grep redis

发现服务都已经正常启动:

 

如果要关闭所有进程,可以执行命令:

ps -ef | grep redis | awk '{print $2}' | xargs kill

或者(推荐这种方式):

printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown

#创建集群

虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。

  1. Redis5.0之前

Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

# 安装依赖
yum -y install zlib ruby rubygems
gem install redis

然后通过命令来管理集群:

# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003
  1. Redis5.0以后

我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:

redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

命令说明:

  • redis-cli --cluster或者./redis-trib.rb:代表集群操作命令
  • create:代表是创建集群
  • --replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master

运行后的样子:

 

这里输入yes,则集群开始创建:

 

通过命令可以查看集群状态:

redis-cli -p 7001 cluster nodes

 

#测试

尝试连接7001节点,存储一个数据:

# 连接
redis-cli -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1

结果悲剧了:

 

集群操作时,需要给redis-cli加上-c参数才可以:

redis-cli -c -p 7001

这次可以了:

 

#散列插槽

Redis 会把每一个 master 节点映射到 0~16383 共 16384 个插槽(hash slot)上,查看集群信息时就能看到:

数据 key 不是与节点绑定,而是与插槽绑定。Redis 会根据 key 的有小部分计算插槽值,分两种情况:

  • key 中包含 {} ,且{}中至少包含 1 个字符,{}中的部分是有效部分
  • key 中不包含 {},整个 key 都是有效部分

::: 例如 key 是 num,那么就根据 num 计算,如果是 {itcast}num,则根据 itcast 计算。计算方式是利用 CRC16 算法得到一个 hash 值,然后对 16384 取余,得到的结果就是 slot 值。 :::

Redis如何判断某个 key 应该在哪个实例?

  • 将 16384 个插槽分配到不同的实例
  • 根据 key 的有效部分计算哈希值,对 16384 取余
  • 余数作为插槽,寻找插槽所在实例即可

如何将同一类数据固定的保存在同一个 Redis 实例?

  • 这一类数据使用相同的有效部分,例如 key 都以 { typeid } 为前缀

#集群伸缩

集群伸缩就是集群节点能够动态的增加和减少,并且在集群伸缩的同时,也伴随着槽位及槽位中数据在节点之间的移动。

redis-cli --cluster 提供了很多操作集群的命令,可以通过redis-cli --cluster help指令查看。

向集群中添加一个新 master 节点,并存储 num = 1000 :

  1. 启动一个新的 Redis 实例,端口为 7004

# 创建实例目录
mkdir 7004
# 创建 redis 服务
sed -i s/6379/7004/g 7004/redis.conf
# 运行 redis 服务
redis-server 7004/redis.conf
  1. 添加 7004 到之前的集群,并作为一个 master 节点

redis-cli --cluster add-node 192.168.150.101:7004 192.168.150.101:7001
  1. 给 7004 节点分配插槽,使得 num 这个 key 可以存储到 7004 实例

# 重新分片
redis-cli --cluster reshard 192.168.150.101:7001
# 移动 3000 个插槽
How many slots do you want to move (from 1 to 16384)? 3000
# 接收插槽的 ID
What is the receiving node ID? 「这里输入 7001 的 ID 即可」
# 使用 done 结束
# 是否确认移动
Do you want to proceed with the proposed rehard plan (yes/no)? yes

#故障转移

当集群中有一个 master 宕机会发生什么?

  1. 首先是该实例与其他实例失去连接

  2. 然后是疑似宕机

  3. 最后是确定下线,自动提升一个 slave 为新的 master

这里选取 slave 的方式是根据 offset 偏移量和 id 进行筛选

数据迁移

利用 cluster failover 命令可以手动让集群中的某个 master 宕机,切换到执行 cluster failover 命令的这个 slave 节点,实现无感知的数据迁移。具体的流程如下:

 

手动的 Failover 支持三种不同模式:

  • 缺省:默认的流程
  • force:省略的对 offset 的一致性校验
  • takeover:直接执行第 5 步,忽略数据一致性、忽略 master 状态和其他 master 的意见

#RedisTemplate访问分片集群

RedisTemplate 底层同样基于 lettuce 实现了分片集群的支持,而使用的步骤与哨兵模式基本一致:

  1. 引入 redis 的 starter 依赖

  2. 配置分片集群地址

  3. 配置读写分离

与哨兵模式相比,其中只有分片集群的配置方式略有差异,如下:

spring:redis:cluster:nodes:    # 指定分片集群的每一个节点信息- 192.168.150.101:7001- 192.168.150.101:7002- 192.168.150.101:7003- 192.168.150.101:8001- 192.168.150.101:8002- 192.168.150.101:8003

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

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

相关文章

探索视频文本特征加速检索解决方案——倒排索引

前言 随着视频内容的不断增加,如何快速准确地检索到所需的视频成为了一个重要的问题。而视频文本特征加速检索解决方案——倒排索引,成为了解决这一问题的有效手段。该技术可以加速文本和视频片段特征匹配、相似度排序过程! 定义——何为“…

c++读取文件之---yaml-cpp使用

实际项目总会遇到有很多超参数的情况,用常规的结构体等无法有效的涵盖所有,为了方便用户进行配置使用,因此使用yaml的方式进行编辑配置,因此去调研使用了yaml-cpp的使用方法。 1、yaml-cpp下载和编译 下载方式很简单&#xff0c…

Web安全——DIV CSS基础

DIV CSS基础 一、DIV和CSS样式二、样式表类型2.1 嵌入样式表2.2 外部样式2.3 内联样式 三、注释四、样式选择器组合选择器 五、背景六、边框七、文字属性八、文本属性九、列表十、超链接十一、盒子模型十二、Border 边框margin padding 十三、float 脱离文档流浮动十四、块级元…

nvm安装nodejs-2023年6月29日

nvm安装nodejs-2023年6月29日 cmd命令行,执行如下代码,表示安装最新稳定版本的node,这里默认是国外的node节点服务器 nvm install lts报错的话,找到安装目录,打开settings.txt,添加如下代码 更换node的国内淘宝镜像节…

Selenium教程__使用Select类对象处理下拉框(15)

select标签的下拉框可以使用selenium的 Select模拟下拉框选择操作。 Select需要导入才能使用,导入路径如下 from selenium.webdriver.support.ui import Select 下面以hao123(https://www.hao123.com) 演示下拉框操作 演示代码如下 import time from selenium i…

knife4j 4.1.0(OpenAPI3)实现spring security或shiro权限注解内容显示

前两天写了个knife4j(swagger2)实现spring security或shiro权限注解内容显示,主要是使用knife4j 2.0.5来实现权限注解内容显示的扩展。 在Spring Boot 3 中只支持OpenAPI3规范,集成knife4j的stater:knife4j-openapi3-…

若隐若现的芯片

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>若隐若现的芯片</title><script src"https://unpkg.co/gsap3/dist/gsap.min.js">…

前端excel文件处理,vue2 、file-saver、xlsx, excel文件生成与excel文件链接数据导出

1、前端excel文件生成 安装插件 npm install file-saver --save如使用TS开发&#xff0c;可安装file-saver的TypeScript类型定义 npm install types/file-saver --save-dev下载文件流 import { saveAs } from file-saver /**** param {*} fileStream // 文件流* param {*} …

No CMAKE_Swift_COMPILER could be found问题解决

编译OpenCV的IOS平台包,出错: CMake Error at CMakeLists.txt:20 (enable_language): No CMAKE_Swift_COMPILER could be found. 出错定位,原因是启用Swift语言时没有找到CMAKE_Swift_COMPILER变量 CMAKE官方文档说明启用Swift语言方法 cmake 3.15开始支持swift 查找swift …

数据库监控与调优【十三】—— LIMIT语句优化

LIMIT语句优化 LIMIT语句使用规则 limit<offset>, <size> offset&#xff1a;返回结果第一行的偏移量&#xff08;想要跳过多少行&#xff09;size&#xff1a;指定返回多少条 举例说明 -- 查询第1页时&#xff0c;花费92ms SELECT * FROM employees LIMIT 0,…

【容灾系统搭建】网络杂谈(1)之容灾系统如何搭建?

涉及知识点 什么是容灾&#xff0c;容灾系统的建设&#xff0c;容灾系统的结构模型&#xff0c;容灾平台。深入了解容灾技术。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码》&#xff0c;更多内容可去其主页关注下哈&#xff0c;不胜感激 文章目录 涉及知识点前言1.容灾系统…

ElasticSearch的核心概念简单描述

我正在参加「掘金启航计划」 ES核心概念 ES是面向文档,下面表格是和关系型数据库的对比,一切都是JSON 关系数据库(Mysql)ES数据库(database)索引(indices) 和数据库一样表(tables)types 慢慢会被弃用 7.0已经过时 8.0会彻底废弃行(rows)documents (数据)文档字段(columns)fi…