上传文件至 /

This commit is contained in:
wxin 2024-08-14 21:21:34 +08:00
commit f28a2cf49b
3 changed files with 1567 additions and 0 deletions

178
Redis扩展部分.md Normal file
View File

@ -0,0 +1,178 @@
<h1><center>Redis扩展部分</center></h1>
------
## 一:分布式锁简介
#### 1.简介
分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁
分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路
![image-20231007214715309](https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/1.png?Expires=1723640177&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=RGr6kkgB91djekjb4fo%2F87cZC%2Bo%3D)
#### 2.分布式锁满足的条件
可见性:多个线程都能看到相同的结果,注意:这个地方说的可见性并不是并发编程中指的内存可见性,只是说多个进程之间都能感知到的变化
互斥:互斥是分布式锁的最基本的条件,使得程序串行执行
高可用:程序不易崩溃,时时刻刻都保证较高的可用性
高性能:由于加锁本身就让性能降低,所有对于分布式锁本身需要他就较高的加锁性能和释放锁性能
安全性:安全也是程序中必不可少的一环
![image-20231007215001368](https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/2.png?Expires=1723640261&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=2rF7nCnjr4rZfgUiK6CgIekpLng%3D)
#### 3.常见的分布式锁
Mysql本身就带有锁机制但是由于mysql性能本身一般所以采用分布式锁的情况下其实使用mysql作为分布式锁比较少见
Redis作为分布式锁是非常常见的一种使用方式现在企业级开发中基本都使用redis或者zookeeper作为分布式锁利用setnx这个方法如果插入key成功则表示获得到了锁如果有人插入成功其他人插入失败则表示无法获得到锁利用这套逻辑来实现分布式锁
Zookeeper也是企业级开发中较好的一个实现分布式锁的方案
![image-20231007215146879](https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/3.png?Expires=1723640278&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=28Xrz%2B08cCuUZhrAzG0dogX5J0c%3D)
#### 3.设置分布式锁
```shell
[root@ xingdian ~]# redis-cli
127.0.0.1 > SET name xingdian NX EX 10
# 添加锁 NX是互斥的 EX设置超时时间
127.0.0.1 > SETNX class cloud
# 使用SETNX创建互斥锁
```
删除
```shell
[root@ xingdian ~]# redis-cli
127.0.0.1 > DEL key
```
注意:
在获取锁时加入过期时间;可以避免服务宕机,然后死锁
添加释放锁需要判断是否是当前线程,避免锁误删操作
#### 5.核心思路
我们利用redis 的setNx方法当有多个线程进入时我们就利用该方法第一个线程进入时redis 中就有这个key 了返回了1如果结果是1则表示他抢到了锁那么他去执行业务然后再删除锁退出锁逻辑没有抢到锁的等待一定时间后重试即可
<img src="https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/4.png?Expires=1723640311&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=3WWhbZv%2BNWLggrOWyyqsN78zZsw%3D" alt="image-20231007220404622" style="zoom:50%;" />
#### 6.锁的基本接口
<img src="https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/5.png?Expires=1723640334&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=P8l0%2FqG6OMtX%2BWtEn3Qu287RUQQ%3D" alt="image-20231007220504083" style="zoom:50%;" />
## 二Redis故障的排查思路
1.了解清楚业务数据流是怎么样的
2.结合 Redis 监控查看 QPS、缓存命中率、内存使用率等信息
3.确认机器层面的资源是否有异常
4.故障时及时上机,使用 redis-cli monitor 打印出操作日志,然后分析
5.和研发沟通,确认是否有大 Key 在堵塞(大 Key 也可以在日常的巡检中获得)
6.和组内同事沟通,确实是否有误操作
7.和运维同事、研发一起排查流量是否正常,是否存在被刷的情况
## 三:常见的运维故障
1.超过内存使用后,部分数据被删除——这个有删除策略的,选择适合自己的即可
2.没开持久化,却重启了实例,数据全掉——记得非缓存的信息需要打开持久化
3.RDB的持久化需要vm.overcommit_memory=1否则会有持久化失败
4.没有持久化情况下,主从,主重启太快,从还没认为主挂的情况下,从会清空自己的数据——人为重启主节点前,先关闭从节点的同步
## 四:常见面试题
1.Redis是什么它有哪些主要特性
答案Redis是一种基于内存的键值存储系统具有高性能、可持久化、支持多种数据类型和丰富的命令集等特性
2.Redis的数据类型有哪些它们的优缺点是什么
答案Redis支持多种数据类型包括String、Hash、List、Set和Sorted Set等
String支持多种操作如字符串的存储、查找和删除等。但是不能用于复杂的数据结构
Hash支持键值对的存储可以用于存储复杂的数据结构。但是查找和删除操作比String慢
List支持在头部和尾部添加和删除元素可以用于实现队列和栈等数据结构。但是插入和删除元素比String慢
Set支持存储不重复的元素可以用于去重和集合运算等。但是插入和删除元素比String慢
Sorted Set支持存储有序的元素可以用于实现排行榜等场景。但是插入和删除元素比String慢
3.Redis如何实现数据持久化有哪些持久化策略
答案Redis提供了多种数据持久化策略包括RDBRedis Database和AOFAppend Only File等。RDB是通过将Redis内存中的数据定期写入到磁盘上来实现数据持久化的。AOF是通过将Redis的写命令追加到一个日志文件中来实现数据持久化的。RDB的优点是写入速度较快但是数据恢复时间较长AOF的优点是数据恢复速度快但是写入速度较慢
4.Redis的复制机制是如何工作的如何配置复制
答案Redis的复制机制是通过主从复制来实现的。主从复制是将主节点的数据同步到从节点上以实现数据的备份和冗余。在配置复制时需要设置主节点和从节点之间的网络连接参数如主机名、端口号和密码等
5.Redis的集群是如何工作的如何配置集群
答案Redis的集群是通过将多个Redis节点组织成一个分布式系统来实现的。在配置集群时需要设置节点之间的网络连接参数如主机名、端口号和密码等。此外还需要设置集群的配置参数如节点ID、分片数量和哈希槽分布等
6.Redis的安全性如何如何保护Redis免受攻击
答案Redis的安全性主要依赖于密码保护和数据加密等机制。在配置Redis时可以通过设置密码来限制对Redis的访问。此外还可以通过使用TLS/SSL等加密协议来保护Redis的数据传输安全
7.Redis的性能如何如何优化Redis的性能
答案Redis的性能主要依赖于内存管理和网络通信等机制
提高Redis内存使用效率如减少不必要的内存消耗、优化数据结构和算法等
优化网络通信性能,如使用更高效的协议、提高网络带宽和降低网络延迟等
提高Redis的并发性能如增加Redis实例的数量、使用更高效的数据库引擎和缓存策略等
8.Redis的使用场景有哪些如何选择合适的Redis部署方式
答案Redis适用于各种高性能的数据存储场景如缓存、实时分析、消息队列和分布式锁等
数据量:如果数据量较小,可以选择单机部署;如果数据量较大,可以选择分布式部署
读写性能:如果读性能较高,可以选择使用缓存来提高性能;如果写性能较高,可以选择使用队列来提高性能
可用性:如果需要高可用性,可以选择使用主从复制和集群等部署方式
9.Redis在实际应用中常见的问题有哪些如何解决这些问题
数据丢失由于网络故障、硬件故障或操作错误等原因可能导致Redis的数据丢失
磁盘空间不足由于数据量过大或缓存策略不当等原因可能导致Redis的磁盘空间不足
性能瓶颈由于网络延迟、内存使用率过高或数据库引擎不适用等原因可能导致Redis的性能瓶颈
安全问题由于密码设置不当、网络攻击或恶意软件等原因可能导致Redis的安全问题
在解决这些问题时,可以采取以下几种措施:
使用数据备份和恢复策略如RDB和AOF等防止数据丢失
优化Redis的缓存策略和数据结构如使用LRU和TTL等减少磁盘空间的使用
优化Redis的网络通信和数据库引擎如使用更高效的协议和数据库引擎等提高Redis的性能
使用安全策略和工具如设置强密码、使用TLS/SSL和安装安全软件等保护Redis的安全
10.关于redis的雪崩、击穿、穿透见文档

View File

@ -0,0 +1,688 @@
<h1><center>Redis数据库缓存技术</center></h1>
------
## 一:缓存服务器简介
#### 1.简介
许多Web应用都将数据保存到 RDBMS关系数据库管理系统应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中就会出现RDBMS的负担加重、数据库响应恶化、 网站显示延迟等重大影响。Memcached/redis是高性能的分布式内存缓存服务器,通过缓存数据库查询结果减少数据库访问次数以提高动态Web等应用的速度、 提高可扩展性。
#### 2.NoSql产品
产品: redis,mongodb,memcached
名词解释:非关系型数据库
以键值对的方式存储数据---Key-Value的形式
#### 3.NoSql的优点
高可扩展性
分布式计算
低成本
架构的灵活性,半结构化数据
没有复杂的关系
#### 4.NoSql的缺点
没有标准化
有限的查询功能
不直观的程序
#### 5.作用
加快访问速度 ,缓解数据库压力
注意:
非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等
## 二Redis基础
#### 1.简介
redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库
redis的官网redis.io 注:域名后缀io属于国家域名是british Indian Ocean territory即英属印度洋领地
#### 2.帮助
官方网站https://redis.io
官方各版本下载地址http://download.redis.io/releases/
Redis 中文命令参考http://redisdoc.com
中文网站1http://redis.cn
中文网站2http://www.redis.net.cn
#### 3.特点
丰富的数据结构 list,set,hash等数据结构的存储
支持持久化
支持事务 “一个完整的动作,要么全部执行,要么什么也没有做”
支持主从支持高可用,支持分布式分片集群
## 三Redis部署
#### 1.yum安装
安装仓库
```shell
[root@xingdian ~]# yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm -y
```
安装redis
```shell
[root@xingdian ~]# yum --enablerepo=remi install redis -y
```
启动和开机启动
```shell
[root@xingdian ~]# systemctl start redis
[root@xingdian ~]# systemctl enable redis
```
设置redis.conf,允许远程登录
```shell
[root@xingdian ~]# vim /etc/redis.conf
bind 127.0.0.1 改为 bind 0.0.0.0 (可选)
```
登录
```shell
[root@xingdian ~]# systemctl restart redis
[root@xingdian ~]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name xingdian
OK
127.0.0.1:6379> get name
"xingdian"
127.0.0.1:6379>
```
#### 2.编译安装
下载源码包
```shell
[root@xingdian ~]# wget https://download.redis.io/redis-stable.tar.gz
[root@xingdian ~]# tar xf redis-stable.tar.gz -C /usr/local/
```
安装编译所需软件
```shell
[root@xingdian ~]# yum install -y gcc-c++ autoconf automake make
```
编译
```shell
[root@xingdian redis-stable]# make
```
安装
```shell
[root@xingdian redis-stable]# make install
```
启动
```shell
[root@xingdian redis-stable]# cd src/
[root@xingdian src]# ./redis-server &
```
## 四Redis使用
#### 1.redis相关工具
```shell
./redis-benchmark #用于进行redis性能测试的工具
./redis-check-rdb #用于修复出问题的dump.rdb文件
./redis-cli #redis的客户端
./redis-server #redis的服务端
./redis-check-aof #用于修复出问题的AOF文件
./redis-sentinel #用于集群管理
```
#### 2.redis配置文件部分
```shell
1、是否后台运行
daemonize no/yes
2、默认端口
port 6379
3、AOF 日志开关是否打开
appendonly no/yes
4、日志文件位置
logfile /var/log/redis.log
5、RDB 持久化数据文件
dbfilename dump.rdb
6、指定IP进行监听
bind 10.0.0.51 ip2 ip3 ip4
7、禁止protected-mode
protected-mode yes/no (保护模式,是否只允许本地访问)
8、增加requirepass {password}
requirepass root9、在redis-cli中使用
```
#### 3.数据持久化
开启持久化功能后重启redis后数据会自动通过持久化文件恢复
redis提供了两种持久化的方式分别是RDBRedis DataBase和AOFAppend Only File仅追加文件
方式一RDB
RDBRedis DataBase是在不同的时间点将redis存储的数据生成快照并存储到磁盘等介质上
特点:
1.周期性
2.不影响数据写入 RDB会启动子进程备份所有数据。当前进程继续提供数据的读写。当备份完成才替换老的备份文件
3.高效;一次性还原所有数据
4.完整性较差 #故障点到上一次备份,之间的数据无法恢复
方式二AOF
AOFAppend Only File则是换了一个角度来实现持久化那就是将redis执行过的所有写指令记录下来在下次redis重新启动时只要把这些写指令从前到后再重复执行一遍就可以实现数据恢复了
特点:
1.实时性
2.完整性较好
3.体积大;记录数据的指令,删除数据的指令都会被记录下来
注意:
RDB和AOF两种方式可以同时使用如果redis重启的优先采用AOF方式进行数据恢复这是因为AOF方式的数据恢复完整度更高
如果你没有数据持久化的需求也完全可以关闭RDB和AOF方式这样的话redis将变成一个纯内存数据库就像memcache一样
如何选择:
缓存:不用开启任何持久方式
双开:因RDB数据不实时但同时使用两者时服务器只会找AOF文件,所以RDB留作万一的手段
对于我们应该选择RDB还是AOF官方的建议是两个同时使用。这样可以提供更可靠的持久化方案
写入速度快 ------------AOF
写入速度慢 ------------RDB
#### 4.持久化配置
1.RDB默认开启
```shell
[root@redis-master src]# cd ..
[root@redis-master redis]# vim redis.conf
#dbfilename:持久化数据存储在本地的文件
dbfilename dump.rdb
#dir:持久化数据存储在本地的路径
dir /data/application/redis/data
##snapshot触发的时机save <seconds> <changes>
##如下为900秒后至少有一个变更操作才会snapshot
##对于此值的设置,需要谨慎,评估系统的变更操作密集程度
##可以通过“save “””来关闭snapshot功能
#save时间以下分别表示更改了1个key时间隔900s进行持久化存储更改了10个key300s进行存储更改10000个key60s进行存储。
save 900 1
save 300 10
save 60 10000
##当snapshot时出现错误无法继续时是否阻塞客户端“变更操作”“错误”可能因为磁盘已满/磁盘故障/OS级别异常等
stop-writes-on-bgsave-error yes
##是否启用rdb文件压缩默认为“yes”压缩往往意味着“额外的cpu消耗”同时也意味这较小的文件尺寸以及较短的网络传输时间
rdbcompression yes
```
2.客户端使用命令进行持久化save存储
```shell
方式一
[root@redis-master src]# ./redis-cli -h 192.168.246.202 -p 6379 save #前台进行存储
OK
方式二
./redis-cli -h ip -p port bgsave #后台进行存储
```
3.AOF 持久化配置
```shell
appendonly yes/no 是否打开aof日志功能
appendfsync always 每1个命令,都立即同步到aof
appendfsync everysec 每秒写1次
appendfsync no 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof.
高级参数:
no-appendfsync-on-rewrite yes/no 正在导出rdb快照的过程中,要不要停止同步 aof
auto-aof-rewrite-percentage 100 aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次。
auto-aof-rewrite-min-size 64mb aof文件,至少超过64M时,重写
```
4.RDB 到 AOF 切换
1、为最新的 dump.rdb 文件创建一个备份。
2、将备份放到一个安全的地方。
3、执行以下两条命令:
```shell
redis-cli config set appendonly yes
redis-cli config set save “”
```
4、确保写命令会被正确地追加到 AOF 文件的末尾
注意:
执行的第一条命令开启了 AOF 功能: Redis 会阻塞直到初始 AOF 文件创建完成为止, 之后 Redis 会继续处理命令请求, 并开始将写入命令追加到 AOF 文件末尾
执行的第二条命令用于关闭 RDB 功能。 这一步是可选的, 如果你愿意的话, 也可以同时使用 RDB 和 AOF 这两种持久化功能
别忘了在 redis.conf 中打开 AOF 功能! 否则的话, 服务器重启之后, 之前通过 CONFIG SET 设置的配置不会生效, 程序会按原来的配置来启动服务器
#### 5.数据恢复
将数据拷贝到另外一台新的服务器
先将新机器的redis停止,将数据拷贝到新机器定义的目录下,并覆盖原有的数据
```
[root@xingdian-server-12 ~]# systemctl start redis
[root@xingdian-server-12 ~]# redis-cli
127.0.0.1:6379> get diandian
"xingdian"
```
## 五Redis数据类型
#### 1.基本数据类型
| **类型** | **说明** |
| -------------------- | ------------------------------------------------------------ |
| String 字符串 | Redis 字符串数据类型的相关命令用于管理 redis 字符串值 |
| Hash 哈希 | Redis hash 是一个string类型的field和value的映射表hash特别适合用于存储对象。Redis 中每个 hash 可以存储 2的32次方2^32 - 1 键值对40多亿。 |
| List 列表 | Redis列表是简单的字符串列表按照插入顺序排序。你可以添加一个元素到列表的头部左边或者尾部右边 一个列表最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。 |
| Set 集合 | Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 |
| Sorted set 有序集合 | Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。 |
#### 2.Redis 命令介绍
```shell
127.0.0.1:6379> help
redis-cli 6.0.7
To get help about Redis commands type:
"help @<group>" to get a list of commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit
To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
```
根据输出可以看到 help 命令有三种用法
```shell
“help @<group>” to get a list of commands in <group>,
”help <command>” for help on <command>,
”help <tab>” to get a list of possible help topics
```
**help @ 查看命令组的帮助**
help [@generic](https://my.oschina.net/generic) 查看通用组的命令包括deldump…等等通用命令
help [@string](https://my.oschina.net/u/146445) 查看字符串组命令。还可以查看其他组的命令如help [@list](https://my.oschina.net/u/587374) help [@set](https://my.oschina.net/rosetta), help @sorted_set,help @hash 等等
查看所有的分组可以通过help <tab>提示
```
127.0.0.1:6379> help @generic
DEL key [key ...]
summary: Delete a key
since: 1.0.0
DUMP key
summary: Return a serialized version of the value stored at the specified key.
since: 2.6.0
EXISTS key [key ...]
summary: Determine if a key exists
since: 1.0.0
EXPIRE key seconds
summary: Set a key's time to live in seconds
since: 1.0.0
EXPIREAT key timestamp
summary: Set the expiration for a key as a UNIX timestamp
since: 1.2.0
KEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
MIGRATE host port key| destination-db timeout [COPY] [REPLACE] [AUTH password] [KEYS key]
summary: Atomically transfer a key from a Redis instance to another one.
since: 2.6.0
MOVE key db
summary: Move a key to another database
since: 1.0.0
OBJECT subcommand [arguments [arguments ...]]
summary: Inspect the internals of Redis objects
since: 2.2.3
PERSIST key
summary: Remove the expiration from a key
since: 2.2.0
PEXPIRE key milliseconds
summary: Set a key's time to live in milliseconds
since: 2.6.0
PEXPIREAT key milliseconds-timestamp
summary: Set the expiration for a key as a UNIX timestamp specified in milliseconds
since: 2.6.0
PTTL key
summary: Get the time to live for a key in milliseconds
since: 2.6.0
RANDOMKEY -
summary: Return a random key from the keyspace
since: 1.0.0
RENAME key newkey
summary: Rename a key
since: 1.0.0
RENAMENX key newkey
summary: Rename a key, only if the new key does not exist
since: 1.0.0
RESTORE key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency]
summary: Create a key using the provided serialized value, previously obtained using DUMP.
since: 2.6.0
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
summary: Incrementally iterate the keys space
since: 2.8.0
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
summary: Sort the elements in a list, set or sorted set
since: 1.0.0
TOUCH key [key ...]
summary: Alters the last access time of a key(s). Returns the number of existing keys specified.
since: 3.2.1
TTL key
summary: Get the time to live for a key
since: 1.0.0
TYPE key
summary: Determine the type stored at key
since: 1.0.0
UNLINK key [key ...]
summary: Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking.
since: 4.0.0
WAIT numreplicas timeout
summary: Wait for the synchronous replication of all the write commands sent in the context of the current connection
since: 3.0.0
GEORADIUSBYMEMBER_RO key arg arg arg ...options...
summary: Help not available
since: not known
SUBSTR key arg arg
summary: Help not available
since: not known
PFDEBUG arg arg ...options...
summary: Help not available
since: not known
BITFIELD_RO key ...options...
summary: Help not available
since: not known
HOST: ...options...
summary: Help not available
since: not known
XSETID key arg
summary: Help not available
since: not known
ASKING
summary: Help not available
since: not known
GEORADIUS_RO key arg arg arg arg ...options...
summary: Help not available
since: not known
REPLCONF ...options...
summary: Help not available
since: not known
PFSELFTEST
summary: Help not available
since: not known
RESTORE-ASKING key arg arg ...options...
summary: Help not available
since: not known
POST ...options...
summary: Help not available
since: not known
```
**help 查看具体命令的用法**
help 具体命令可以查看命令的用法描述,命令从那个版本开始,命令属于哪个组等信息。如 help get
```shell
127.0.0.1:6379> help get
GET key
summary: Get the value of a key
since: 1.0.0
group: string
```
**help help后面参数提示补全**
help 之后按tab按键可提示参数。在命令行下 tab按键相信是用的最多的一个按键
help 空格之后一直按tab,可按顺序查看到所有可能的组和命令。也可输入需要查询的@组或命令的前缀再按tab补全
#### 3.Redis 全局 Key 操作
| **命令** | **含义** |
| --------------- | --------------------------- |
| KEYS * | 查看KEY支持通配符 |
| DEL | 删除给定的一个或多个key |
| EXISTS | 检查是否存在 |
| RENAME | 变更KEY名 |
| SORT | 键值排序,有非数字时报错 |
| TYPE | 返回键所存储值的类型 |
| DUMP RESTORE | 序例化与反序列化 |
| EXPIRE\ PEXPIRE | 以秒\毫秒设定生存时间 |
| TTL\ PTTL | 以秒\毫秒为单位返回生存时间 |
| PERSIST | 取消生时间设置 |
| RANDOMKEY | 返回数据库中的任意键 |
1、del 命令
del 命令用来 删除指定的一个或多个 key
删除一个 key
```shell
127.0.0.1:6379> set test 1234
127.0.0.1:6379> del test
```
删除多个 key
```shell
127.0.0.1:6379> mset test1 1111 test2 2222
127.0.0.1:6379> del test1 test2
```
2、exists 命令
exists 命令用来查询 key 是否存在
```shell
127.0.0.1:6379> mset test1 1111 test2 2222
192.168.152.133:6379> EXISTS test1
(integer) 1
```
3、expire 命令
expire 命令用来 设置 key 的过期秒数
```shell
127.0.0.1:6379> get test1
```
与 expire 命令相关的命令有三个,分别是:
expireat 命令用来 设置一个 UNIX 时间戳的过期时间, 从1970年1月1日0时0分0秒到你设置过期的秒数
```shell
127.0.0.1:6379> EXPIREAT test2 1592965943
(integer) 1
```
pexpire 命令用来 设置 key 的有效时间以毫秒为单位
```shell
127.0.0.1:6379> EXPIRE test3 100
(integer) 1
127.0.0.1:6379> ttl test3
(integer) 94
127.0.0.1:6379> pttl test3
(integer) 89235
```
pexpireat 命令用来 设置 key 的到期 UNIX 时间戳以毫秒为单位
```shell
127.0.0.1:6379> PEXPIREAT test3 1592965943000
(integer) 1
192.168.152.133:6379> ttl test3
(integer) 365
```
4、keys 命令
keys 命令用来 查找所有匹配给定的模式的键
```shell
127.0.0.1:6379> keys *
1) "a"
2) "test"
3) "test1"
4) "name"
```
在 Redis 中是支持模糊查询的,它有 3 个通配符,分别是:*、 ? 和 []
*:通配任意多个字符
?:通配单个字符
[]:通配括号内的某 1 个字符
[] 的用法如下:
```shell
127.0.0.1:6379> keys *[s]*
1) "test"
2) "test1"
127.0.0.1:6379> keys *[a]*
1) "a"
2) "name"
```
? 的用法如下:
```shell
127.0.0.1:6379> set a bbb
OK
127.0.0.1:6379> keys ?
1) "a"
```
5.ttl 命令
ttl 命令用来 获取 key 的有效时间(单位:秒)
```shell
127.0.0.1:6379> get test1
```
上面的命令是,我们用 expire 对一个 key 设置一个过期时间,然后使用 ttl 观察它的剩余时间
ttl 一个 key如果返回 -1则说明该 key 不会过期
ttl 一个 key如果返回 -2则说明没有指定的 key
与 ttl 相关的命令是 pttl 命令,它用来 获取 key 的有效毫秒数
#### 4.数据类型
string是redis最基本的类型一个key对应一个value。一个键最大能存储 512MB
Redis中的Hashes类型看成具有String Key和String Value的map容器所以该类型非常适合于存储值对象的信息。如Username、Password和Age等。如果Hash中包含很少的字段那么该类型的数据也将仅占用很少的磁盘空间。每一个Hash可以存储995701749 个键值对
List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样我们可以在其头部(left)和尾部(right)添加新的元素
Set类型看作为没有排序的字符集合。Set可包含的最大元素数量是4294967295
Sorted-Sets中的每一个成员都会有一个分数(score)与之关联Redis正是通过分数来为集合中的成员进行从小到大的排序。成员是唯一的但是分数(score)却是可以重复的
扩展链接地址https://docs.qq.com/doc/DQ0ZIQ0l4eWRkdm1J

701
redis集群技术.md Normal file
View File

@ -0,0 +1,701 @@
<h1><center>Redis集群技术</center></h1>
------
## 一Python连接Redis
#### 1.安装包
```shell
pip3 install redis
```
#### 2.连接
```shell
In [1]: import redis
In [2]: r = redis.Redis(host='10.18.42.174', port=6379)
In [3]: r.set("QF", "www.qfedu.com")
Out[3]: True
In [4]: r.get("QF")
Out[4]: b'www.qfedu.com'
In [5]: ret = r.get("QF")
In [6]: ret.decode()
Out[6]: 'www.qfedu.com'
```
注意:
关闭redis的保护模式protected-mode no
#### 3.连接池
redis-py使用connection pool来管理对一个redis server的所有连接避免每次建立、释放连接的开销
默认每个Redis实例都会维护一个自己的连接池
可以直接建立一个连接池然后作为参数传给Redis这样就可以实现多个 Redis 实例共享一个连接池
```shell
In [12]: pool = redis.ConnectionPool(host='172.16.153.134', port=6379)
In [13]: rs = redis.Redis(connection_pool=pool)
In [14]: rs.set("foo", "bar")
Out[14]: True
In [15]: rs.get("foo")
Out[15]: b'bar'
```
## 二Redis主从复制集群
#### 1.Redis复制特性
使用异步复制
一个主服务器可以有多个从服务器
从服务器也可以有自己的从服务器
复制功能不会阻塞主服务器
可以通过复制功能来让主服务器免于执行持久化操作,由从服务器去执行持久化操作即可
关闭主服务器持久化时,复制功能的数据是安全的
当配置Redis复制功能时强烈建议打开主服务器的持久化功能。否则的话由于延迟等问题应该要避免部署的服务自动拉起
#### 2.Redis主从复制原理
redis 主从同步有两种方式(或者所两个阶段):全同步和部分同步
从刚刚连接的时候进行全同步全同步结束后进行部分同步。当然如果有需要slave 在任何时候都可以发起全同步
主从同步的机制:
<img src="https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/6.png?Expires=1723640610&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=V3P0b1AU%2B8bSpqaS8gRDTELs5mI%3D" alt="image-20230526094614286" style="zoom:50%;" />
从服务器向主服务器发送 SYNC 命令
接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下来执行的所有写命令
当主服务器执行完 BGSAVE 命令时,它会向从服务器发送 RDB 文件,而从服务器则会接收并载入这个文件
主服务器将缓冲区储存的所有写命令发送给从服务器执行
#### 3.Redis命令传播
在主从服务器完成同步之后,主服务器每执行一个写命令,会将被执行的写命令发送给从服务器执行,这个操作被称为“命令传播”
命令传播是一个持续的过程:只要复制仍在继续,命令传播就会一直进行,使得主从服务器的状态可以一直保持一致
![image-20230228220953326](https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/7.png?Expires=1723640462&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=sVi%2BDrswiyckwFpBeY5kSlzczzk%3D)
#### 4.Redis复制一致性问题
![image-20230228221045012](https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/8.png?Expires=1723640475&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=Rr8mKRyqUuD4YgLNkNquRsg2W%2BY%3D)
在读写分离环境下,客户端向主服务器发送写命令 SET n 10086主服务器在执行这个写命令之后向客户端返回回复并将这个写命令传播给从服务器
接到回复的客户端继续向从服务器发送读命令 GET n ,并且因为网络状态的原因,客户端的 GET命令比主服务器传播的SET 命令更快到达了从服务器
因为从服务器键 n 的值还未被更新,所以客户端在从服务器读取到的将是一个错误(过期)的 n值
5.Redis复制安全性提升
主服务器只在有至少 N 个从服务器的情况下,才执行写操作从 Redis 2.8 开始, 为了保证数据的安全性, 可以通过配置, 让主服务器只在有至少 N 个当前已连接从服务器的情况下, 才执行写命令
不过, 因为 Redis 使用异步复制, 所以主服务器发送的写数据并不一定会被从服务器接收到, 因此, 数据丢失的可能性仍然是存在的
通过以下两个参数保证数据的安全:
```shell
min-slaves-to-write <number of slaves>
min-slaves-max-lag <number of seconds>
```
要求至少有1个slave数据复制和同步的延迟不能超过10秒如果说一旦所有的slave数据复制和同步的延迟都超过了10秒钟那么这个时候master就不会再接收任何请求了
减少异步复制的数据丢失:
有了min-slaves-max-lag这个配置就可以确保说一旦slave复制数据和ack延时太长就认为可能master宕机后损失的数据太多了那么就拒绝写请求这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内
减少脑裂的数据丢失:
如果一个master出现了脑裂跟其他slave丢了连接那么上面两个配置可以确保说如果不能继续给指定数量的slave发送数据而且slave超过10秒没有给自己ack消息那么就直接拒绝客户端的写请求这样脑裂后的旧master就不会接受client的新数据也就避免了数据丢失
总结:
上面的配置就确保了如果跟任何一个slave丢了连接在10秒后发现没有slave给自己ack那么就拒绝新的写请求。因此在脑裂场景下最多就丢失10秒的数据
#### 5.主从复制实战
实验环境
三台服务器,一台master,两台slave
部署
```shell
[root@xingdian /]# yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
[root@xingdian /]# yum -y --enablerepo=remi install redis
```
修改配置文件
```shell
主配置:
[root@xingdian-server-20 /]# grep -Ev "^$|#" /etc/redis.conf
bind 172.17.0.5 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass redis
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
slave-1配置文件:
[root@xingdian-server-21 /]# grep -Ev "^$|#" /etc/redis.conf
bind 172.17.0.6
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis
replicaof 172.17.0.5 6379
masterauth redis
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass redis
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
slave-2配置文件:
[root@xingdian-server-22 /]# grep -Ev "^$|#" /etc/redis.conf
bind 172.17.0.7
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis
replicaof 172.17.0.5 6379
masterauth redis
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass redis
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
```
注意:
配置文件参数地址https://xingdian-file.oss-cn-hangzhou.aliyuncs.com/redis-config.txt
启动服务
```shell
[root@xingdian /]# systemctl start redis
```
验证服务
```shell
[root@xingdian-server-20 /]# redis-cli -a redis -h 10.0.0.3
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.17.0.6,port=6379,state=online,offset=70,lag=0
slave1:ip=172.17.0.7,port=6379,state=online,offset=70,lag=0
master_replid:12e24fe583640c88aff07733c7bcd1acb32c4dd2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70
127.0.0.1:6379> set t1 aa
OK
127.0.0.1:6379> quit
slave端:
[root@xingdian-server-21 /]# redis-cli -h 172.17.0.6 -a redis
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
172.17.0.6:6379> get t1
"aa"
```
## 三Redis HA Sentinel 集群
Redis-Sentinel 是 Redis 官方推荐的高可用性(HA)解决方案当用Redis做Master-slave的高可用方案时假如master宕机了Redis本身(包括它的很多客户端)都没有实现自动进行主备切换而Redis-sentinel本身也是一个独立运行的进程它能监控多个master-slave集群发现master宕机后能进行自动切换
Sentinel 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作
<img src="https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/9.png?Expires=1723640495&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=24R2ysKzJP9xs05vBHHzgYbhsyo%3D" alt="image-20230526150237928" style="zoom:50%;" />
#### 1.Redis Sentinel 功能
Sentinel的主要功能包括主节点存活检测、主从运行情况检测、自动故障转移failover、主从切换。Redis的Sentinel最小配置是一主一从Redis的Sentinel系统可以用来管理多个Redis服务器
监控
Sentinel会不断的检查主服务器和从服务器是否正常运行
通知
当被监控的某个Redis服务器出现问题Sentinel通过API脚本向管理员或者其他的应用程序发送通知
自动故障转移
当主节点不能正常工作时Sentinel会开始一次自动的故障转移操作它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点 并且将其他的从节点指向新的主节点
配置提供者
在Redis Sentinel模式下客户端应用在初始化时连接的是Sentinel节点集合从中获取主节点的信息
#### 2.Redis Sentinel的工作流程
由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器以及所有从服务器并在被监视的主服务器进入下线状态时自动将下线主服务器属下的某个从服务器升级为新的主服务器然后由新的主服务器代替已下线的主服务器继续处理命令请求
<img src="https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/10.png?Expires=1723640510&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=9AMtkpI4DXmROdYPv67LOliVP%2BE%3D" alt="image-20230228223209112" style="zoom:50%;" />
Sentinel负责监控集群中的所有主、从Redis当发现主故障时Sentinel会在所有的从中选一个成为新的主。并且会把其余的从变为新主的从。同时那台有问题的旧主也会变为新主的从也就是说当旧的主即使恢复时并不会恢复原来的主身份而是作为新主的一个从
在Redis高可用架构中Sentinel往往不是只有一个而是有3个或者以上。目的是为了让其更加可靠毕竟主和从切换角色这个过程还是蛮复杂的
#### 3.Redis Sentinel 服务器连接
**发现并连接主服务器**
Sentinel 通过用户给定的配置文件来发现主服务器
<img src="https://oss-wxin-resource.oss-cn-beijing.aliyuncs.com/%E5%9B%BE%E7%89%87/Redis/11.png?Expires=1723640521&OSSAccessKeyId=TMP.3KfeJz2GfydC5m533sXWc3x8M2AoBTEmroU3YwdYX4zeccmetAxNCv2ZYhrhNTFVWP6fUHFL3tEbZ2xPoj72x22vyq3ANJ&Signature=%2B0j77v9FHU7o4v%2F37Ri8EkUvkZI%3D" alt="image-20230228223309007" style="zoom:33%;" />
Sentinel 会与被监视的主服务器创建两个网络连接
命令连接用于向主服务器发送命令
订阅连接用于订阅指定的频道,从而发现监视同一主服务器的其他 Sentinel
**发现并连接从服务器**
Sentinel 通过向主服务器发送 INFO 命令来自动获得所有从服务器的地址
跟主服务器一样Sentinel 会与每个被发现的从服务器创建命令连接和订阅连接
<img src="https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20230228223352987.png" style="zoom:33%;" />
#### 4.Redis Sentinel 命令操作
| **命令** | **描述** |
| ---------------------------------------------- | ------------------------------------------------------------ |
| PING | 返回 PONG |
| SENTINEL masters | 列出所有被监视的主服务器 |
| SENTINEL slaves <master name> | 列出所有被监视的从服务器 |
| SENTINEL get-master-addr-by-name <master name> | 返回给定名字的主服务器的 IP 地址和端口号。 |
| SENTINEL reset <pattern> | 重置所有名字和给定模式 pattern 相匹配的主服务器 |
| SENTINEL failover <master name> | 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下,强制开始一次自动故障迁移。 |
#### 5.Redis Sentinel哨兵
**环境说明**
| **主机名称** | **IP地址** | **redis版本和角色说明** |
| ------------- | --------------------- | ----------------------- |
| redis-master | 192.168.152.133:6379 | redis 6.0.5(主) |
| redis-slave01 | 192.168.152.134:6379 | redis 6.0.5(从) |
| redis-slave02 | 192.168.152.135:6379 | redis 6.0.5(从) |
| redis-master | 192.168.152.133:26379 | Sentinel01 |
| redis-slave01 | 192.168.152.134:26379 | Sentinel02 |
| redis-slave02 | 192.168.152.135:26379 | Sentinel03 |
**安装(所有节点安装)**
```shell
[root@xingdian-server-23 /]# yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
[root@xingdian-server-23 /]# yum -y --enablerepo=remi install redis
```
**部署主从(略)**
**部署Sentinel**
```shell
[root@redis-master ~]# grep -Ev "^$|#" /etc/redis-sentinel.conf
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile /var/log/redis/sentinel.log
dir /tmp
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
# 端口
port 26379
# 是否后台启动
daemonize yes
# 保护模式如果开启只接受回环地址的ipv4和ipv6地址链接拒绝外部链接而且正常应该配置多个哨兵避免一个哨兵出现独裁情况如果配置多个哨兵那如果开启也会拒绝其他sentinel的连接。导致哨兵配置无法生效。
protected-mode no  
# pid文件路径
pidfile /var/run/redis-sentinel.pid
# 日志文件路径
logfile "/var/log/redis/sentinel.log"
# 定义工作目录
dir /tmp
# 定义Redis主的别名, IP, 端口这里的2指的是需要至少2个Sentinel认为主Redis挂了才最终会采取下一步行为
sentinel monitor mymaster 127.0.0.1 6379 2
#如果redis配置了密码,那这里必须配置认证,否则不能自动切换
sentinel auth-pass mymaster redispass   
# 如果mymaster 30秒内没有响应则认为其主观失效
sentinel down-after-milliseconds mymaster 30000
# 如果master重新选出来后其它slave节点能同时并行从新master同步数据的台数有多少个显然该值越大所有slave节点完成同步切换的整体速度越快但如果此时正好有人在访问这些slave可能造成读取失败影响面会更广。最保守的设置为1同一时间只能有一台干这件事这样其它slave还能继续服务但是所有slave全部完成缓存更新同步的进程将变慢。
sentinel parallel-syncs mymaster 1
# 该参数指定一个时间段,在该时间段内没有实现故障转移成功,则会再一次发起故障转移的操作,单位毫秒
sentinel failover-timeout mymaster 180000
# 不允许使用SENTINEL SET设置notification-script和client-reconfig-script。
sentinel deny-scripts-reconfig yes
```
配置文件:
```shell
[root@xingdian-server-23 /]# grep -Ev "^$|#" /etc/redis-sentinel.conf
port 26379
daemonize no
protected-mode no
pidfile /var/run/redis-sentinel.pid
logfile /var/log/redis/sentinel.log
dir /tmp
sentinel monitor mymaster 172.17.0.5 6379 2
sentinel auth-pass mymaster redis
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
```
启动的顺序主Redis --> 从Redis --> Sentinel1/2/3
```shell
[root@xingdian-server-23 /]# systemctl restart redis-sentinel.service
[root@xingdian-server-23 /]# systemctl status redis-sentinel.service
● redis-sentinel.service - Redis Sentinel
Loaded: loaded (/usr/lib/systemd/system/redis-sentinel.service; disabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/redis-sentinel.service.d
└─limit.conf
Active: active (running) since Wed 2020-12-16 14:07:18 UTC; 24s ago
Main PID: 202 (redis-sentinel)
Status: "Ready to accept connections"
CGroup: /docker/3976cfca1cf87ae43370f78ab3e2d26b68c0808e1e24178b12cddd8b3bd1fef5/system.slice/redis-sentinel.service
└─202 /usr/bin/redis-sentinel *:26379 [sentinel]
Dec 16 14:07:17 xingdian-server-23 systemd[1]: Starting Redis Sentinel...
Dec 16 14:07:18 xingdian-server-23 systemd[1]: Started Redis Sentinel.
```
**哨兵模式下的主从测试**
模拟停止master上的Redis查看Redis的主从变化如下
```shell
主服务器:
[root@xingdian-server-1 /]# systemctl stop redis
从服务器:
[root@xingdian-server-2 /]# tailf /var/log/redis/sentinel.log
270:X 16 Dec 2020 15:46:11.961 # +promoted-slave slave 172.17.0.4:6379 172.17.0.4 6379 @ mymaster 172.17.0.2 6379
270:X 16 Dec 2020 15:46:11.961 # +failover-state-reconf-slaves master mymaster 172.17.0.2 6379
270:X 16 Dec 2020 15:46:11.964 * +slave-reconf-sent slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.2 6379
270:X 16 Dec 2020 15:46:12.936 * +slave-reconf-inprog slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.2 6379
270:X 16 Dec 2020 15:46:13.134 # -odown master mymaster 172.17.0.2 6379
270:X 16 Dec 2020 15:46:13.964 * +slave-reconf-done slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.2 6379
270:X 16 Dec 2020 15:46:14.030 # +failover-end master mymaster 172.17.0.2 6379
270:X 16 Dec 2020 15:46:14.030 # +switch-master mymaster 172.17.0.2 6379 172.17.0.4 6379
270:X 16 Dec 2020 15:46:14.031 * +slave slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.4 6379
270:X 16 Dec 2020 15:46:14.031 * +slave slave 172.17.0.2:6379 172.17.0.2 6379 @ mymaster 172.17.0.4 6379
270:X 16 Dec 2020 15:46:44.105 # +sdown slave 172.17.0.2:6379 172.17.0.2 6379 @ mymaster 172.17.0.4 6379
从上面的日志可以看到master已经sdown并切换为192.168.152.1343为master节点下面查看slave01上的配置会自动的更改replicaof配置项如下
[root@xingdian-server-2 /]# grep "replicaof" /etc/redis.conf |grep -vE "#"
replicaof 172.17.0.4 6379
回到master.查看是否切换成功
[root@xingdian-server-1 /]# redis-cli -p 26379
127.0.0.1:26379> sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "172.17.0.4"
5) "port"
6) "6379"
7) "runid"
8) "074997b30d9e08339cbd27f6f478e83ffd03d13d"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
127.0.0.1:26379> sentinel slaves mymaster
1) 1) "name"
2) "172.17.0.2:6379"
3) "ip"
4) "172.17.0.2"
5) "port"
6) "6379"
7) "runid"
8) ""
9) "flags"
10) "s_down,slave,disconnected" # 提示该节点为从并且状态为s_down无法链接的状态
11) "link-pending-commands"
12) "3"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "173956"
17) "last-ok-ping-reply"
18) "173956"
19) "last-ping-reply"
20) "173956"
21) "s-down-time"
22) "143918"
23) "down-after-milliseconds"
24) "30000"
25) "info-refresh"
26) "1608133745921"
27) "role-reported"
28) "slave"
29) "role-reported-time"
30) "173956"
31) "master-link-down-time"
32) "0"
33) "master-link-status"
34) "err"
35) "master-host"
36) "?"
37) "master-port"
38) "0"
39) "slave-priority"
40) "100"
41) "slave-repl-offset"
42) "0"
2) 1) "name"
2) "172.17.0.3:6379"
3) "ip"
4) "172.17.0.3"
5) "port"
6) "6379"
7) "runid"
8) "fdce07036b5a1b435ee5a7bbe4b39231e5554756"
9) "flags"
10) "slave"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "1024"
19) "last-ping-reply"
20) "1024"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "2200"
```
注意:
如果旧主重新加入后数据不同步解决方案
可能之前是主节点,没有配置从节点的连接信息 如masterauth 连接密码当master转变为slave后由于他没有密码所以他不能从新的master同步数据随之导致 info replication 的时候,同步状态为 down ,所以只需要修改 redis.conf 中的 masterauth 为 对应的密码