From f28a2cf49b2533cabd59f1dab0c69cb7c1c81bdc Mon Sep 17 00:00:00 2001 From: wxin <15253413025@163.com> Date: Wed, 14 Aug 2024 21:21:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Redis扩展部分.md | 178 +++++++++++ redis数据库缓存技术.md | 688 ++++++++++++++++++++++++++++++++++++++++ redis集群技术.md | 701 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1567 insertions(+) create mode 100644 Redis扩展部分.md create mode 100644 redis数据库缓存技术.md create mode 100644 redis集群技术.md diff --git a/Redis扩展部分.md b/Redis扩展部分.md new file mode 100644 index 0000000..d31b02a --- /dev/null +++ b/Redis扩展部分.md @@ -0,0 +1,178 @@ +

Redis扩展部分

+ + + +------ + +## 一:分布式锁简介 + +#### 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,则表示他抢到了锁,那么他去执行业务,然后再删除锁,退出锁逻辑,没有抢到锁的,等待一定时间后重试即可 + +image-20231007220404622 + +#### 6.锁的基本接口 + +image-20231007220504083 + +## 二: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提供了多种数据持久化策略,包括RDB(Redis Database)和AOF(Append 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的雪崩、击穿、穿透(见文档) \ No newline at end of file diff --git a/redis数据库缓存技术.md b/redis数据库缓存技术.md new file mode 100644 index 0000000..f85b77e --- /dev/null +++ b/redis数据库缓存技术.md @@ -0,0 +1,688 @@ +

Redis数据库缓存技术

+ +------ + + + +## 一:缓存服务器简介 + +#### 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 + +​ 中文网站1:http://redis.cn + +​ 中文网站2:http://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提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File仅追加文件) + +方式一:RDB + +​ RDB(Redis DataBase):是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上 + +特点: + +​ 1.周期性 + +​ 2.不影响数据写入 ;RDB会启动子进程,备份所有数据。当前进程,继续提供数据的读写。当备份完成,才替换老的备份文件 + +​ 3.高效;一次性还原所有数据 + +​ 4.完整性较差 #故障点到上一次备份,之间的数据无法恢复 + +方式二:AOF + +​ AOF(Append 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 +##如下为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 @" to get a list of commands in + "help " for help on + "help " 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 @” to get a list of commands in , + +”help ” for help on , + +”help ” to get a list of possible help topics +``` + +**help @ 查看命令组的帮助** + +​ help [@generic](https://my.oschina.net/generic) 查看通用组的命令包括del,dump…等等通用命令 + +​ 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 提示 + +``` +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 diff --git a/redis集群技术.md b/redis集群技术.md new file mode 100644 index 0000000..94f18c9 --- /dev/null +++ b/redis集群技术.md @@ -0,0 +1,701 @@ +

Redis集群技术

+ +------ + + + +## 一: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 在任何时候都可以发起全同步 + +主从同步的机制: + +image-20230526094614286 + +​ 从服务器向主服务器发送 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 +min-slaves-max-lag +``` + +​ 要求至少有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 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作 + +image-20230526150237928 + +#### 1.Redis Sentinel 功能 + +​ Sentinel的主要功能包括主节点存活检测、主从运行情况检测、自动故障转移(failover)、主从切换。Redis的Sentinel最小配置是一主一从;Redis的Sentinel系统可以用来管理多个Redis服务器 + +监控 + +​ Sentinel会不断的检查主服务器和从服务器是否正常运行 + +通知 + +​ 当被监控的某个Redis服务器出现问题,Sentinel通过API脚本向管理员或者其他的应用程序发送通知 + +自动故障转移 + +​ 当主节点不能正常工作时,Sentinel会开始一次自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点, 并且将其他的从节点指向新的主节点 + +配置提供者 + +​ 在Redis Sentinel模式下,客户端应用在初始化时连接的是Sentinel节点集合,从中获取主节点的信息 + +#### 2.Redis Sentinel的工作流程 + +​ 由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求 + +image-20230228223209112 + +​ Sentinel负责监控集群中的所有主、从Redis,当发现主故障时,Sentinel会在所有的从中选一个成为新的主。并且会把其余的从变为新主的从。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从 + +​ 在Redis高可用架构中,Sentinel往往不是只有一个,而是有3个或者以上。目的是为了让其更加可靠,毕竟主和从切换角色这个过程还是蛮复杂的 + +#### 3.Redis Sentinel 服务器连接 + +**发现并连接主服务器** + +​ Sentinel 通过用户给定的配置文件来发现主服务器 + +image-20230228223309007 + +​ Sentinel 会与被监视的主服务器创建两个网络连接 + +​ 命令连接用于向主服务器发送命令 + +​ 订阅连接用于订阅指定的频道,从而发现监视同一主服务器的其他 Sentinel + +**发现并连接从服务器** + +​ Sentinel 通过向主服务器发送 INFO 命令来自动获得所有从服务器的地址 + +​ 跟主服务器一样,Sentinel 会与每个被发现的从服务器创建命令连接和订阅连接 + + + +#### 4.Redis Sentinel 命令操作 + +| **命令** | **描述** | +| ---------------------------------------------- | ------------------------------------------------------------ | +| PING | 返回 PONG | +| SENTINEL masters | 列出所有被监视的主服务器 | +| SENTINEL slaves | 列出所有被监视的从服务器 | +| SENTINEL get-master-addr-by-name | 返回给定名字的主服务器的 IP 地址和端口号。 | +| SENTINEL reset | 重置所有名字和给定模式 pattern 相匹配的主服务器 | +| SENTINEL failover | 当主服务器失效时, 在不询问其他 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 为 对应的密码 \ No newline at end of file