redis

缓存技术:

redis
2.jpg
NoSQL,泛指非关系型的数据库。NoSQL=Not Only SQLcss

缓存:缓存(cache)cache是一个很是大的概念。html

1、CPU的Cachejava

CPU的Cache,它中文名称是高速缓冲存储器,读写速度很快,几乎与CPU同样。因为CPU的运算速度太快,内存的数据存取速度没法跟上CPU的速度,因此在cpu与内存间设置了cache为cpu的数据快取区。当计算机执行程序时,数据与地址管理部件会预测可能要用到的数据和指令,并将这些数据和指令预先从内存中读出送到Cache。一旦须要时,先检查Cache,如有就从Cache中读取,若无再访问内存,如今的CPU还有一级cache,二级cache。简单来讲,Cache就是用来解决CPU与内存之间速度不匹配的问题,避免内存与辅助内存频繁存取数据,这样就提升了系统的执行效率。node

2、磁盘cache
磁盘也有cache,硬盘的cache做用就相似于CPU的cache,它解决了总线接口的高速需求和读写硬盘的矛盾以及对某些扇区的反复读取。python

3、浏览器缓存mysql

浏览器缓存(Browser Caching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就能够从本地磁盘显示文档,这样就能够加速页面的阅览,而且能够减小服务器的压力。这个过程与下载很是相似,不过下载是用户的主动过程,而且下载的数据通常是长时间保存,游览器的缓存的数据只是短期保存,能够人为的清空linux

缓冲:缓冲区(buffer),它是内存空间的一部分。也就是说,在内存空间中预留了必定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫作缓冲区,显然缓冲区是具备必定大小的。git

缓存(cache)与缓冲(buffer)的主要区别程序员

Buffer的核心做用是用来缓冲,缓和冲击。好比你每秒要写100次硬盘,对系统冲击很大,浪费了大量时间在忙着处理开始写和结束写这两件事嘛。用个buffer暂存起来,变成每10秒写一次硬盘,对系统的冲击就很小,写入效率高了,日子过得爽了。极大缓和了冲击。github

Cache的核心做用是加快取用的速度。好比你一个很复杂的计算作完了,下次还要用结果,就把结果放手边一个好拿的地方存着,下次不用再算了。加快了数据取用的速度。

buffer偏重于写,而cache偏重于读

参考文档:https://www.sohu.com/a/246498483_468626

[root@c7-77]#cat /proc/sys/vm/drop_caches 
0
[root@c7-77]#echo 3 >/proc/sys/vm/drop_caches 
[root@c7-77]#cat /proc/sys/vm/drop_caches 
3

[root@c7-77]#man proc
 Because this is a nondestructive operation and dirty objects are not freeable, the user should run sync(8) first.

       /proc/sys/vm/legacy_va_layout (since Linux 2.6.9)

[root@c7-77]#man 5 proc

redis
1.jpg

缓存保存的位置

用户层:浏览器dns缓存 应用程序dns缓存 
代理层 : cdn
web层 :web服务器缓存
数据层:分布式缓存:redis  数据库;mysql
系统层:操做系统 cache
物理层:磁盘cache raid cache  CPU缓存

用户层缓存

浏览器的dns默认是60秒

缓存的特性:

1 自动过时,例如DNS的TTL ,微信红包

2 强制过时

3 命中率

浏览器的缓存:

redis
3.jpg

缓存过时机制

设置浏览器缓存有下面几种方法

Last-Modified:服务器上文件的最后修改时间

Etag:文件标识

Expires:本地缓存目录中,文件过时的时间(由服务器指定具体的时间)

Cache-control:本地缓存目录中,文件过时的时间(由服务器指定过时的间隔时间,因为浏览器根据间隔生成具体的时间)

Last-Modified

通常状况下,iis会在访问css、js等静态文件时,返回给浏览器Last-Modified和Etag标记,浏览器再次访问服务器的时候会在带上两个标记

If-Modified-Since和If-None-Match,服务器检查参数值,若是文件没有改变则返回304,此时浏览器就访问本地缓存了。若是服务器上该文件被修改过,那么参数值就不同,服务器就把最后的文件返回给浏览器。

在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是客户端请求的资源,同时有一个Last-Modified的属性标记此文件在服务器端最后被修改的时间。
Last-Modified格式相似这样:
Last-Modified : Fri , 12 May 2006 18:53:33 GMT
客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头,询问该时间以后文件是否有被修改过:
If-Modified-Since : Fri , 12 May 2006 18:53:33 GMT
若是服务器端的资源没有变化,则自动返回 HTTP 304(Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则从新发出资源,返回和第一次请求时相似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端可以获得最新的资源。

Etag

ETag 是 Entity Tag 的缩写,中文译过来就是实体标签的意思。在HTTP1.1协议中其实就是请求HEAD中的一个属性而已

ETag是HTTP1.1中才加入的一个属性,用来帮助服务器控制Web端的缓存验证。它的原理是这样的,当浏览器请求服务器的某项资源(A)时, 服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并经过 ETag 返回给浏览器,浏览器把"3f80f-1b6-3e1cb03b" 和 A 同时缓存在本地,当下次再次向服务器请求A时,会经过相似 If-None-Match: "3f80f-1b6-3e1cb03b" 的请求头把ETag发送给服务器,服务器再次计算A的哈希值并和浏览器返回的值作比较,若是发现A发生了变化就把A返回给浏览器(200),若是发现A没有变化就给浏览器返回一个304未修改。这样经过控制浏览器端的缓存,能够节省服务器的带宽,由于服务器不须要每次都把全量数据返回给客户端。

Expires:过时时间

expires是给一个资源设定一个过时时间,也就是说无需去服务端验证,直接经过浏览器自身确认是否过时便可,因此不会产生额外的流量。此种方法很是适合不常常变更的资源。若是文件变更较频繁,不要使用expires来缓存。
expires起到控制页面缓存的做用,合理的配置expires能够减小不少服务器的请求。

以上的两种均须要请求。即,无论资源过时已否都须要请求协商,消耗没必要要的时间,所以有了缓存的过时时间。expires由服务器设置,若是带有
expires 那么过时前不须要请求。直接从缓存里面读取。ctrl + F5 强制除外

Expires能够下降网站购买的带宽,节约成本,同时提高了用户访问体验,减轻服务器的压力,
是web服务很是重要的功能。
缺点:
被缓存的页面或数据更新了,用户看到的可能仍是旧的内容,反而影响用户体验。

混合使用和缓存刷新

last-modified 和 expire 一块儿使用,若没有过时就无需发起http请求。当浏览器强制F5的时候才有last-modified ,很好的达到缓存的效果

Etag 和expire一块儿使用,先判断是否过时,若过时就发起http请求,此时若etag 发生变化,那么返回200的响应,若是Etag没有发生变化就返回403

last-modified  Etag  expire 三个一块儿使用:
#先expire 判断是否过时。若过时才发起http请求
#若expire已过时,服务器会先判断 last-modified 其次是Etag  必须都没有发生变化才返回304

缓存刷新

第一次访问,获取最新的数据,返回200
鼠标点击第二次访问,浏览器对全部没有过时的内容直接使用本地的缓存
F5或刷新,会像服务器发送请求协商,last-modified 和 Etag 会有影响,可是expires 本地的过时时间是不受影响的,无变化,返回304
按Ctrl+F5 全部缓存不在使用,直接返回200

cookie和session

会话(Session)跟踪是Web程序中经常使用的技术,用来跟踪用户的整个会话。经常使用的会话跟踪技术是Cookie与Session。Cookie经过在客户端记录信息肯定用户身份

Session经过在服务器端记录信息肯定用户身份。

redis
4.jpg

CDN 缓存

CDN(Content Delivery Network)是指内容分发网络,也称为内容传送网络
CDN负载均衡系统实现CDN的内容路由功能。它的做用是将用户的请求导向整个CDN网络中的最佳节点。最佳节点的选定能够根据多种策略,例如距离最近、节点负载最轻等。负载均衡系统是整个CDN的核心,负载均衡的准确性和效率直接决定了整个CDN的效率和性能。一般负载均衡能够分为两个层次:全局负载均衡(GSLB)和本地负载均衡(SLB)。全局负载均衡主要的目的是在整个网络范围内将用户的请求定向到最近的节点(或者区域)。所以,就近性判断是全局负载均衡的主要功能。本地负载均衡通常局限于必定的区域范围内,其目标是在特定的区域范围内寻找一台最适合的节点提供服务,所以,CDN节点的健康性、负载状况、支持的媒体格式等运行状态是本地负载均衡进行决策的主要依据。

redis
5.png

302 临时重定向

redis
6.png

redis

关系型数据库和NoSQL数据库数据库

关系型数据库和NoSQL数据库数据库主要分为两大类:关系型数据库与NoSQL数据库。
关系型数据库,是创建在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据。主流的MySQL、Oracle、MS SQL Server和DB2都属于这类传统数据库。
NoSQL数据库,全称为Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,能够考虑使用更加合适的数据存储。主要分为临时性键值存储(memcached、Redis)、永久性键值存储(ROMA、Redis)、面向文档的数据库
(MongoDB、CouchDB)、面向列的数据库(Cassandra、HBase),每种NoSQL都有其特有的使用场景及优势。
Oracle,mysql等传统的关系数据库很是成熟而且已大规模商用,为何还要用NoSQL数据库呢?主要是因为随着互联网发展,数据量愈来愈大,对性能要求愈来愈高,传统数据库存在着先天性的缺陷,即单机(单库)性能瓶颈,而且扩展困难。这样既有单机单库瓶颈,却又扩展困难,天然没法知足日益增加的海量数据存储及其性能要求,因此才会出现了各类不一样的NoSQL产品,NoSQL根本性的优点在于在云计算时代,简单、易于大规模分布式扩展,而且读写性能很是高

非关系型数据库

并发性能够达到10万

Redis的特色:
内存数据库,速度快,也支持数据的持久化,能够将内存中的数据保存在磁盘中,重启的时候能够再次加载进行使用。
Redis不只仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
Redis支持数据的备份,即master-slave模式的数据备份。
支持事务
Redis的优点:
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操做。
原子 – Redis的全部操做都是原子性的,同时Redis还支持对几个操做合并后的原子性执行。(事务)
丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过时等等特性。
Redis与其余key-value存储有什么不一样?
Redis有着更为复杂的数据结构而且提供对他们的原子性操做,这是一个不一样于其余数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
Redis运行在内存中可是能够持久化到磁盘,因此在对不一样数据集进行高速读写时须要权衡内存,由于数据量不能大于硬件内存。在内存数据库方面的另外一个优势是,相比在磁盘上相同的复杂的数据结构,在内存中操做起来很是简单,这样Redis能够作不少内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,由于他们并不须要进行随机访问。

Redis的特色:

redis
7.jpg

单线程

redis

redis
8.png9.png

redis对比memcached

redis

10.jpg

redis 典型应用场景

  • Session 共享:常见于web集群中的Tomcat或者PHP中多web服务器session共享缓存:数据查询、电商网站商品信息、新闻内容
  • 计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景微博/微信社交场合:共同好友,粉丝数,关注,点赞评论等
  • 消息队列:ELK的日志缓存、部分业务的订阅发布系统
  • 地理位置:基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能

yum 安装redis

官方下载地址:http://download.redis.io/releases/

[root@C8-58]#yum install redis -y
[root@C8-58]#id redis 
uid=993(redis) gid=990(redis) groups=990(redis)
[root@C8-58]#systemctl enable --now redis
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         128              127.0.0.1:6379             0.0.0.0:* 
#监听在127.0.0.1 只能是为本身服务,因此要改配置文件
[root@C8-58]#grep '^bind' /etc/redis.conf 
bind 0.0.0.0
[root@C8-58]#grep '^bind' /etc/redis.conf 
bind 0.0.0.0
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         128                0.0.0.0:6379             0.0.0.0:* 

[root@centos8 ~]#dnf -y insta17 redis
[root@centos8 ~]#systemct1 enab1e --now redis
[root@centos8 ~]#pstree -plgrep redis
l-redis-server(3383)-+-{redis-server}(3384)
l-iredis-server} (3385)`-{redis-server} (3386)
[root@centos8 ~]#redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info
# server
redis_version :5.0.3redis_git_sha1: 000000ooredis_git_dirty : 0
redis_bui1d_id:8c0bf22bfba82c8fredis_mode :standalone
os :Linux 4.18.0-147.e18.x86_64 x86_64

日志

[root@C8-58]#tail /var/log/redis/redis.log  -f

查看日志三个警告报错

第一次安装Redis之后看日志会报警:

redis
11.png

#改第一个内核参数
[root@C8-58]#cat /proc/sys/net/core/somaxconn
128
[root@C8-58]#vim /etc/sysctl.conf 
[root@C8-58]#sysctl -p
net.core.somaxconn = 1024
[root@C8-58]#tail -1 /etc/sysctl.conf 
 net.core.somaxconn=1024
[root@C8-58]#cat /proc/sys/net/core/somaxconn
1024

 #改第二个内核参数
[root@C8-58]#tail -2 /etc/sysctl.conf 
 net.core.somaxconn=1024
 vm.overcommit_memory=1 
[root@C8-58]#cat /proc/sys/vm/overcommit_memory 
1

[root@C8-58]#tail /var/log/redis/redis.log  -f
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

3128:M 04 Aug 2021 20:45:20.535 # Server initialized
3128:M 04 Aug 2021 20:45:20.535 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
3128:M 04 Aug 2021 20:45:20.535 * DB loaded from disk: 0.000 seconds
3128:M 04 Aug 2021 20:45:20.535 * Ready to accept connections

#修改第三个警告报错:
[root@C8-58]#echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.d/rc.local 
[root@C8-58]#chmod +x /etc/rc.d/rc.local 
[root@C8-58]#/etc/rc.d/rc.local 
[root@C8-58]#

启动服务的文件

[root@C8-58]#ps -ef |grep  redis |grep -v 'grep'
redis       3211       1  0 20:52 ?        00:00:00 /usr/bin/redis-server 0.0.0.0:6379

#该文件做为启动redis的文件

前台启动redis

yum安装Redis之后前台执行该命令,由于没有修改配置文件为后台的

redis
12.png

编译安装redis

官网https://redis.io/download

[root@C8-58]# wget https://download.redis.io/releases/redis-6.2.5.tar.gz
[root@C8-58]#yum install gcc jemalloc-devel -y
[root@C8-58]#tar xf redis-6.2.5.tar.gz 
[root@C8-58]#cd redis-6.2.5/
[root@C8-58]#ls
00-RELEASENOTES  CONDUCT       COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  src    TLS.md
BUGS             CONTRIBUTING  deps     Makefile  README.md  runtest     runtest-moduleapi  sentinel.conf     tests  utils
#指定安装路径
[root@C8-58]#make PREFIX=/apps/redis install
#配置变量:
[root@C8-58]#echo 'PATH=/apps/redis/bin:$PATH' >/etc/profile.d/redis.sh
[root@C8-58]#. /etc/profile.d/redis.sh

[root@C8-58]#mkdir /apps/redis/{etc,log,data,run}
[root@C8-58]#useradd -r -s /sbin/nologin redis
[root@C8-58]#chown -R redis.redis /apps/redis/

[root@C8-58]#redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --replicaof 127.0.0.1 8888
       ./redis-server /etc/myredis.conf --loglevel verbose -
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel

#复制配置文件
[root@C8-58]#ls      
00-RELEASENOTES  CONDUCT       COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  src    TLS.md
BUGS             CONTRIBUTING  deps     Makefile  README.md  runtest     runtest-moduleapi  sentinel.conf     tests  utils
[root@C8-58]#pwd
/root/redis-6.2.5
[root@C8-58]#ll redis.conf 
-rw-rw-r-- 1 root root 93724 Jul 22 02:06 redis.conf
#准备配置文件:
[root@C8-58]#cp redis.conf /apps/redis/etc/
[root@C8-58]#ll /apps/redis/etc/redis.conf 
-rw-r--r-- 1 root root 93724 Aug  4 21:28 /apps/redis/etc/redis.conf
[root@C8-58]#chown -R redis.redis /apps/redis/

#前台运行redis
[root@C8-58]#redis-server   /apps/redis/etc/redis.conf 
8875:C 04 Aug 2021 21:31:49.083 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8875:C 04 Aug 2021 21:31:49.083 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=8875, just started
8875:C 04 Aug 2021 21:31:49.083 # Configuration loaded
8875:M 04 Aug 2021 21:31:49.084 * monotonic clock: POSIX clock_gettime
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.2.5 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 8875
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           https://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

8875:M 04 Aug 2021 21:31:49.085 # Server initialized

#修改成后台台执行
[root@C8-58]#grep '^daem' /apps/redis/etc/redis.conf 
daemonize yes #修改此项改成后台执行

#重启服务
[root@C8-58]#killall redis-server 
[root@C8-58]#redis-server /apps/redis/etc/redis.conf 
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         511                0.0.0.0:6379             0.0.0.0:* 

[root@C8-58]#pstree -p |grep redis
           |-redis-server(9097)-+-{redis-server}(9098)
           |                    |-{redis-server}(9099)
           |                    |-{redis-server}(9100)
           |                    `-{redis-server}(9101)

#建立命令软链接
[root@centos7 ~]#1n -sv /apps/redis/bin/redis-* /usr/bin/
'/usr/bin/redis-benchmark’ ->'/apps/redis/bin/redis-benchmark'
'/usr/bin/redis-check-aof’-> ‘/apps/redis/bin/redis-check-aof'
'/usr/bin/redis-check-rdb’-> ‘/apps/redis/bin/redis-check-rdb'
'/usr/bin/ redis-cli' -> ' / apps/redis/bin/redis-cli'
'/usr/bin/redis-sentinel’->‘/apps /redis/bin/redis-sentine7'
'/usr/bin/redis-server’-> ' / apps/redis/bin/redis-server'

#编译安装后的命令:
[root@centos7 ~]#ll /apps / redis/bin/
tota7 32772
-rwWXr-xr-x 1 root root 4366792 Feb 16 21:12 redis-benchmark #redis性能测试工具
-rwxr-xr-x 1 root root 8125184 Feb 16 21:12 redis-check-aof #AOF文件检查工具
-rwXr-Xr-x 1 root root 8125184 Feb 16 21:12 redis-check-rdb #RDB文件检查工具
-rwxr-xr-x 1 root root 4807856 Feb 16 21:12 redi s-c1i
-rwxrwXrwx 1 root root  12 Feb 16 21:12 redis-sentinel -> redis-server #哨兵,软链接到server
-rWxr-Xr-x 1 root root 8125184 Feb 16 21:12 redis-server #redis服务启动命令

redis多实例

[root@C8-58]#grep '^[^#]' redis_6379.conf 
 bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /apps/redis/run/redis_6379.pid
loglevel notice
logfile "/apps/redis/log/redis_6379.log"
databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump_6379.rdb
rdb-del-sync-files no
dir /apps/redis/data
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
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
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

#建立实例配置文件
root@C8-58]#sed 's/6379/6380/g' redis_6379.conf >redis_6380.conf 
[root@C8-58]#sed 's/6379/6381/g' redis_6379.conf >redis_6381.conf 
[root@C8-58]#ll
total 276
-rw-r--r-- 1 redis redis 93829 Aug  4 21:55 redis_6379.conf
-rw-r--r-- 1 root  root  93829 Aug  4 21:57 redis_6380.conf
-rw-r--r-- 1 root  root  93829 Aug  4 21:57 redis_6381.conf
#修改属组属主
useradd -r -s  /sbin/nologin redis
[root@C8-58]#chown -R redis:redis /apps/redis/
[root@C8-58]#tree /apps/redis/
/apps/redis/
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof -> redis-server
│   ├── redis-check-rdb -> redis-server
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── data
├── etc
│   ├── redis_6379.conf
│   ├── redis_6380.conf
│   └── redis_6381.conf
├── log
└── run

5 directories, 9 files

#开启redis多实例:
[root@C8-58]#killall redis-server 
[root@C8-58]#redis-server /apps/redis/etc/redis_6379.conf 
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         511                0.0.0.0:6379             0.0.0.0:*       
[root@C8-58]#redis-server /apps/redis/etc/redis_6380.conf    
[root@C8-58]#ss -tnl |grep 6380
LISTEN    0         511                0.0.0.0:6380             0.0.0.0:*       
[root@C8-58]#redis-server /apps/redis/etc/redis_6381.conf 
[root@C8-58]#ss -tnl |grep 6381
LISTEN    0         511                0.0.0.0:6381             0.0.0.0:*       
[root@C8-58]#

[root@C8-58]#tree /apps/redis/
/apps/redis/
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof -> redis-server
│   ├── redis-check-rdb -> redis-server
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── data
├── etc
│   ├── redis_6379.conf
│   ├── redis_6380.conf
│   └── redis_6381.conf
├── log
│   ├── redis_6379.log
│   ├── redis_6380.log
│   └── redis_6381.log
└── run
    ├── redis_6379.pid
    ├── redis_6380.pid
    └── redis_6381.pid

5 directories, 15 files

#开启三个实例
[root@C8-58]#redis-server /apps/redis/etc/redis_6379.conf 
[root@C8-58]#redis-server /apps/redis/etc/redis_6380.conf 
[root@C8-58]#redis-server /apps/redis/etc/redis_6381.conf 
[root@C8-58]#ss -tnl |grep "redis"
[root@C8-58]#ss -tnl 
State             Recv-Q            Send-Q                       Local Address:Port                       Peer Address:Port           
LISTEN            0                 511                                0.0.0.0:6379                            0.0.0.0:*              
LISTEN            0                 511                                0.0.0.0:6380                            0.0.0.0:*              
LISTEN            0                 511                                0.0.0.0:6381                                      

#加入到systemd 管理:
[root@C8-58]#cp  /usr/lib/systemd/system/redis6379.service  /usr/lib/systemd/system/redis6380.service 
[root@C8-58]#cp  /usr/lib/systemd/system/redis6379.service  /usr/lib/systemd/system/redis6381.service 

[root@C8-58]#sed -i 's/6379/6380/'  /usr/lib/systemd/system/redis6380.service
[root@C8-58]#sed -i 's/6379/6381/'  /usr/lib/systemd/system/redis6381.service

[root@C8-58]#cat /usr/lib/systemd/system/redis6379.service 
[Unit]
Description=redis
After=network.target

[Service]
Type=forking
#PIDFile=/apps/redis/run/redis_6379.pid 
ExecStart=/apps/redis/bin/redis-server  /apps/redis/etc/redis_6379.conf 
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
[root@C8-58]#cat /usr/lib/systemd/system/redis6380.service 
[Unit]
Description=redis
After=network.target

[Service]
Type=forking
#PIDFile=/apps/redis/run/redis_6379.pid 
ExecStart=/apps/redis/bin/redis-server  /apps/redis/etc/redis_6380.conf 
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
[root@C8-58]#cat /usr/lib/systemd/system/redis6381.service 
[Unit]
Description=redis
After=network.target

[Service]
Type=forking
#PIDFile=/apps/redis/run/redis_6379.pid 
ExecStart=/apps/redis/bin/redis-server  /apps/redis/etc/redis_6381.conf  --supervised systemd 
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

[root@C8-58]#killall redis-server 
#修改属组属主为redis
[root@C8-58]#ll /apps/redis/log/
total 12
-rw-r--r-- 1 root root 902 Aug  4 22:19 redis_6379.log
-rw-r--r-- 1 root root 902 Aug  4 22:19 redis_6380.log
-rw-r--r-- 1 root root 902 Aug  4 22:19 redis_6381.log
[root@C8-58]#chown -R redis:redis /apps/redis

[root@centos7 ~]#systemctl daemon-reload
[root@centos7 ~]#systemctl start redis_6379  redis_6380  redis_6381

使用客户端链接redis

[root@centos7~]#/apps/redis/bin/redis-cli   -h IP/HOSTNAME   -p PORT   -a PASSWORD
#查看版本信息
127.0.0.1:6379> info [section]

#远程链接别人的redis
[root@C8-58]#redis-cli -h 10.0.0.33
10.0.0.33:6379> 

127.0.0.1:6379> set hello m42
OK
127.0.0.1:6379> get hello
"m42"
[root@C8-33 ~]# redis-cli get hello
"m42"

[root@C8-58]#redis-cli -h 10.0.0.33 get hello
"m42"

一键安装redis脚本

[root@C8-24 ~]# cat redis_instll.sh 
#!/bin/bash
#
#*******************************************************************************
#Author:            hwang
#Data:              2021-08-05-10:46:47
#Description:       redis_instll.sh
#Copyright (C):        2021 All rights reserved
#*******************************************************************************
#Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37)
#Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47)
#*******************************************************************************
. /etc/init.d/functions
VERSION=redis-6.2.5
PASSWORD=123456
INSTALL_DIR=/apps/redis
install(){
yum -y install wget make  gcc jemalloc-devel || { action "软件安装失败,检查网络配置" false;exit;}
wget https://download.redis.io/releases/${VERSION}.tar.gz  || { action "Redis reload faild" false;exit; }
tar xf ${VERSION}.tar.gz
cd ${VERSION}
make PREFIX=${INSTALL_DIR} install && action "Redis 编译完成" || { action "Redis 编译安装失败" false;exit; }
ln -s ${INSTALL_DIR}/bin/redis-* /usr/bin/
mkdir -p ${INSTALL_DIR}/{etc,log,data,run}
cp redis.conf ${INSTALL_DIR}/etc/
sed -i  's/bind 127.0.0.1/bind 0.0.0.0/'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/# requirepass/a requirepass $PASSWORD"'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^dir .*/c dir ${INSTALL_DIR}/data/'     ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/logfile .*/c logfile ${INSTALL_DIR}/log/redis-6397.log'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis-6393.pid'  ${INSTALL_DIR}/etc/redis.conf
sed -i  's/daemonize .*/c  daemonize  yes'  ${INSTALL_DIR}/etc/redis.conf

if id redis &> /dev/null;then
    action "redis 用户存在" false
else
    useradd -r -s /sbin/nologin redis
    action "redis 用户建立成功"
fi

chown -R redis.redis ${INSTALL_DIR}
cat >>/etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
sysctl -p
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.d/rc.local 
chmod +x /etc/rc.d/rc.local
/etc/rc.d/rc.local 
cat > /usr/lib/systemd/system/redis6379.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf  --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
#Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemct  enable --now redis &>/dev/null && action "Redis 启动成功,信息以下:" || { action "redis 启动失败" false;exit; }
redis-cli -a $PASSWORD INFO  server 2>/dev/null
}
install

[root@C8-24 ~]# /usr/local/bin/redis-server  /apps/redis/etc/redis.conf

windows安装redis

https://github.com/MicrosoftArchive/redis/releases

Windows版 Redis下载地址: https://github.com/MicrosoftArchive/redis/releases
不推荐在生产环境使用Windows系统运行Redis服务

[root@C8-33 ~]# wc -l /etc/redis.conf
1378 /etc/redis.conf

#验证Red is服务端口
C: \Program Files\Redis>netstat -na|findstr 6666

图像工具

https://github.com/uglide/RedisDesktopManager/releases/tag/0.9.3

链接到redis

#本机无密码链接:
redis-cli
#跨主机无密码链接:
redis-cli -h HOSTNAME/IP -p port
#跨主机密码链接:
redis-cli -h HOSTNAME/IP -p port -a PASSWORD

python链接方式

python多种开发库,能够支持链接redis

使用redis-py链接redis
官方github :
https://github.com/andymccurdy/redis-py

yum  -y install python3 python3-redis
[root@C8-24 ~]# cat redis_test.py 
#!/bin/env python3
import redis
pool = redis.ConnectionPool(host="127.0.0.1",port="6379",password="")
r = redis.Redis(connection_pool=pool)
for i in range(5000000):
    r.set("k%d" % i,"v%d" % i)
    data=r.get("k%d" % i)
    print(data)

shell脚本写入数据到redis

[root@C8-58]#cat  redis-test.sh
#!/bin/bash
NUM=100
PASS=""
for i in `seq 100`;do
    redis-cli -h 10.0.0.33 -a "PASS" --no-auth-warning set key${i} value${i}
    echo "key${i} value${i}" 写入完成
done
echo "$NUM个key写入到REDIS完成"

 --no-auth-warning :免报警提示

redis主要配置项

bind 0.0.0.0 #监听地址,能够用空格隔开后多个监听IP

protected-mode yes #redis3.2 以后加入的新特性,在没有设置bind IP和密码的时候,redis只容许访问127.0.0.1:6379,远程访问将提示警告信息并拒绝远程访问

port 6379 #监听端口

tcp-backlog 511 #三次握手的时候server端收到client ack确认号以后的队列值。

timeout 0 #客户端和Redis服务端的链接超时时间,默认是0,表示永不超时。

tcp-keepalive 300 #tcp 会话保持时间

daemonize n #认状况下 redis 不是做为守护进程运行的,若是你想让它在后台运行,你就把它改为 yes,当redis做为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面

supervised no #和操做系统相关参数,能够设置经过upstart和systemd管理Redis守护进程,centos 7之后都使用systemd

pidfile /var/run/redis_6379.pid #pid文件路径

loglevel notice #日志级别

logfile "" #日志路径

databases 16 #设置db 库数量,默认16个库

always-show-logo yes #在启动redis 时是否显示log

save 900 1 #在900秒内有一个键内容发生更改就出就快照机制
save 300 10 #300秒以内有10个就存一次
save 60 10000

stop-writes-on-bgsave-error no #快照出错时是否禁止redis 写入操做

rdbcompression yes #持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之

rdbchecksum yes #是否开启RC64校验,默认是开启

dbfilename dump.rdb #快照文件名

dir ./ #快照文件保存路径

replica-serve-stale-data yes #当从库同主库失去链接或者复制正在进行,从机库有两种运行方式:
一、若是replica-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的读请求。
二、若是replica-serve-stale-data设置为no,除去指定的命令以外的任何请求都会返回一个错误"SYNC with master in progress"。

replica-read-only yes #是否设置从库只读

repl-diskless-sync no #是否使用socket方式复制数据(无盘同步),新slave链接链接时候须要作数据的全量同步,redis server就要从内存dump出新的RDB文件,而后从master传到slave,有两种方式把RDB文件传输给客户端:
一、基于硬盘(disk-backed):master建立一个新进程dump RDB,RDB完成以后由父进程(即主进程)传给slaves。
二、基于socket(diskless):master建立一个新进程直接dump RDB到slave的socket,不通过主进程,不通过硬盘。
基于硬盘的话,RDB文件建立后,一旦建立完毕,能够同时服务更多的slave,可是基于socket的话, 新slave链接到master以后得逐个同步数据。
在较慢而且网络较快的时候,能够用diskless(yes),不然使用磁盘(no)

repl-diskless-sync-delay 30 #diskless**复制的延迟时间**,设置0为关闭,在延迟时间内链接的新客户端,会一块儿经过disk方式同步数据,可是一旦复制开始尚未结束以前,master节点不会再接收新slave的复制请求,直到下一次同步开始。

repl-ping-slave-period 10 #slave根据master指定的时间进行周期性的PING 监测

repl-timeout 60 #复制链接的超时时间,须要大于repl-ping-slave-period,不然会常常报超时

repl-disable-tcp-nodelay no #在socket模式下是否在slave套接字发送SYNC以后禁用 TCP_NODELAY,若是选择“yesRedis将使用更少的TCP包和带宽来向slaves发送数据,可是这将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒,若是你选择了 "no"** 数据传输到salve**的延迟将会减小但要使用更多的带宽。

repl-backlog-size 512mb #复制缓冲区内存大小,只有在slave链接以后才分配内存。

repl-backlog-ttl 3600 #屡次时间master没有slave链接,就清空backlog缓冲区。

replica-priority 100 #当master不可用,Sentinel会根据slave的优先级选举一个master,最低的优先级的slave,当选master,而配置成0,永远不会被选举。

requirepass foobared #设置redis 链接密码

rename-command #重命名一些高危命令

maxclients 10000 #Redis最大链接客户端

maxmemory #最大内存,单位为bytes字节,8G内存的计算方式8(G)1024(MB)1024(KB)*1024(Kbyte),须要注意的是slave的输出缓冲区是不计算在maxmemory内。

appendonly no #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,可是redis若是中途宕机,会致使可能有几分钟的数据丢失(取决于dumpd数据的间隔时间),根据save来策略进行持久化,Append Only File是另外一种持久化方式,能够提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。

appendfilename "appendonly.aof" #AOF文件名

appendfsync everysec #aof持久化策略的配置,no表示不执行fsync,由操做系统保证数据同步到磁盘,always表示每次写入都执行fsync,以保证数据同步到磁盘,everysec表示每秒执行一次fsync,可能会致使丢失这1s数据。

no-appendfsync-on-rewrite no在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。默认为no,表示"不暂缓",新的aof记录仍然会被当即同步,Linux的默认fsync策略是30秒,若是为yes 可能丢失30秒数据,但因为yes性能较好并且会避免出现阻塞所以比较推荐。

auto-aof-rewrite-percentage 100 # 当Aof log增加超过指定百分比例时,重写AOF文件, 设置为0表示不自动重写Aof 日志,重写是为了使aof体积保持最小,可是还能够确保保存最完整的数据,

auto-aof-rewrite-min-size 64mb #触发aof rewrite的最小文件大小

aof-load-truncated yes #是否加载因为其余缘由致使的末尾异常的AOF文件(主进程被kill/断电等)

aof-use-rdb-preamble no #redis4.0新增RDB-AOF混合持久化格式,在开启了这个功能以后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB格式的内容用于记录已有的数据,而AOF格式的内存则用于记录最近发生了变化的数据,这样Redis就能够同时兼有RDB持久化和AOF持久化的优势(既可以快速地生成重写文件,也可以在出现问题时,快速地载入数据)。

lua-time-limit 5000 #lua脚本的最大执行时间,单位为毫秒

cluster-enabled yes #是否开启集群模式,默认是单机模式

cluster-config-file nodes-6379.conf #由node节点自动生成的集群配置文件

cluster-node-timeout 15000 #集群中node节点链接超时时间

cluster-replica-validity-factor 10 #在执行故障转移的时候可能有些节点和master断开一段时间数据比较旧,这些节点就不适用于选举为master,超过这个时间的就不会被进行故障转移

cluster-migration-barrier 1 #集群迁移屏障,一个主节点拥有的至少正常工做的从节点,即若是主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。

cluster-require-full-coverage no #集群请求槽位所有覆盖,若是一个主库宕机且没有备库就会出现集群槽位不全,那么yes状况下redis集群槽位验证不全就再也不对外提供服务,而no则能够继续使用可是会出现查询数据查不到的状况(由于有数据丢失)。

#Slow log 是 Redis 用来记录查询执行时间的日志系统,slow log 保存在内存里面,读写速度很是快,所以你能够放心地使用它,没必要担忧由于开启 slow log 而损害 Redis 的速度。

slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每一个命令操做。

slowlog-max-len 128 #记录多少条慢日志保存在队列,超出后会删除最先的,以此滚动删除

127.0.0.1:6379> slowlog len
(integer) 14
127.0.0.1:6379> slowlog get
1) 1) (integer) 14
2) (integer) 1544690617
3) (integer) 4
4) 1) "slowlog"
127.0.0.1:6379> SLOWLOG reset
OK

CONFIG动态修改配置

config命令用于查看当前redis配置、以及不重启redis服务实现动态更改redis配置等

注意:不是全部配置均可以动态修改,且此方式没法持久保存

CONFIG SET parameter value
时间复杂度:o(1)
CONFIG SET命令能够动态地调整Redis 服务器的配置(configuration)而无须重启。

你能够使用它修改配置参数,或者改变 Redis 的持久化(Persistence)方式。
CONFIG SET能够修改的配置参数能够使用命令CONFIG GET*来列出,全部被CONFIG SET修改的配置参数都会当即生效。

CONFIG GET parameter
时间复杂度:o(N),其中 N为命令返回的配置选项数量。
CONFIG GET命令用于取得运行中的 Redis 服务器的配置参数(configuration parameters),在Redis 2.4版本中,有部分参数没有办法用CONFIG GET访问,可是在最新的 Redis 2.6 版本中,全部配置参数都已经能够用CONFIG GET访问了。

CONFTG GET接受单个参数 parameter做为搜索关键字,查找全部匹配的配置参数,其中参数和值以“键-值对”(key-value pairs)的方式排列。

好比执行CONFIG GET s*命令,服务器就会返回全部以s开头的配置参数及参数的值:

设置链接密码

#设置链接密码
127.0.0.1:6379>CONFIG SET requirepass 123456
oK
#查看链接密码
127.0.0.1:6379>CONFIG GET requirepass
1) "requirepass"
2) "123456"

获取当前配置

#奇数行为键,偶数行为值
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> CONFIG GET *
  1) "rdbchecksum"
  2) "yes"
  3) "daemonize"
  4) "no"
  5) "io-threads-do-reads"
  6) "no"
  7) "lua-replicate-commands"
  8) "yes"
  9) "always-show-logo"
 10) "no"
 11) "protected-mode"
 12) "yes"
 13) "rdbcompression"
 14) "yes"
 15) "rdb-del-sync-files"
 16) "no"
 17) "activerehashing"
 18) "yes"

#查看bind
127.0.0.1:6379>CONFIG GET bind
1) "bind"
2) "0.0.0.o"
#有些设置没法修改
127.0.0.1:6379>CONFIG SET bind 127.0.0.1
(error)ERR Unsupported CONFIG parameter: bind

更改最大内存

[root@C8-33 ~]# echo 2^20*512|bc #512M
536870912

maxmemory 536870912

127.0.0.1:6379>CONFIG SET maxmemory 8589934592
oK
127.0.0.1:6379> CONFIG GET maxmemory
1)"maxmemory"
2) "8589934592"

redis密码的设置

#永久修改,改配置文件
vim  /etc/redis.conf 
requirepass 123456

[root@C8-33 ~]# systemctl restart redis
[root@C8-33 ~]# redis-cli 
127.0.0.1:6379> info
NOAUTH Authentication required.
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> 

#查看本机的info
[root@C8-33 ~]# redis-cli -a 123456 info

config动态修改配置

临时修改的没法永久保存

127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "536870912"

 #查看是否开启了集群
127.0.0.1:6379> CONFIG GET cluster_enabled 
(empty list or set)

#查看修改密码
127.0.0.1:6379> CONFIG GET requirepass
1) "requirepass"
2) "123456"

#修改内存
127.0.0.1:6379> CONFIG set maxmemory 209715200
OK
127.0.0.1:6379> 

#创建一个rdb后缀文件
127.0.0.1:6379> config  set  dir /tmp/
OK
127.0.0.1:6379> save
OK
#查看里面的内容
[root@C8-33 ~]# ll /tmp -t
total 4
-rw-r--r-- 1 redis redis 1593 Aug  5 08:43 dump.rdb

127.0.0.1:6379> config  get bind
1) "bind"
2) "0.0.0.0"
127.0.0.1:6379> config  get port
1) "port"
2) "6379"

慢查询

redis慢查询以微秒为单位 mysql的慢查询是默认10秒

redis
14.jpg

两点说明:
(1)慢查询发生在第3阶段

(2〉客户端超时不必定慢查询,但慢查询是客户端超时的一个可能因素

和不少关系型数据库(例如:MySQL)同样, Redis 也提供了慢查询日志记录,Redis 会把命令执行时间超过 slowlog-log-slower-than 的都记录在 Reids 内部的一个列表(list)中,该列表的长度最大为 slowlog-max-len 。须要注意的是,慢查询记录的只是命令的执行时间,不包括网络传输和排队时间:

Redis 慢查询的配置有两个,分别是 slowlog-log-slower-than 和 slowlog-max-len。
1.slowlog-log-slower-than,用来控制慢查询的阈值,全部执行时间超过该值的命令都会被记录下来。该值的单位为微秒,默认值为 10000,若是设置为 0,那么全部的记录都会被记录下来,若是设置为小于 0 的值,那么对于任何命令都不会记录,即关闭了慢查询。能够经过在配置文件中设置,或者用 config set 命令来设置:

config set slowlog-log-slower-than 10000 #超过10000微秒就算慢查询

2.slowlog-max-len,用来设置存储慢查询记录列表的大小,默认值为 128,当该列表满了时,若是有新的记录进来,那么 Redis 会把队最旧的记录清理掉,而后存储新的记录。在生产环境咱们能够适当调大,好比调成 1000,这样就能够缓冲更多的记录,方便故障的排查。配置方法和 slowlog-log-slower-than 相似,能够在配置文件中指定,也能够在命令行执行 config set 来设置:

config set slowlog-max-len 1000 #记录的慢查询的条数

查看慢查询日志

尽管 Redis 把慢查询日志记录到了内部的列表,但咱们不能直接操做该列表,Redis 专门提供了一组命令来查询慢查询日志:

  1. 获取慢查询日志:
    slowlog get [n]

    1000微秒-1毫秒

    1000毫秒=1秒

[root@C8-33 ~]# vim /etc/redis.conf   微秒
# The following time is expressed in microseconds, so 1000000 is equivalent
# to one second. Note that a negative number disables the slow log, while
# a value of zero forces the logging of every command.
slowlog-log-slower-than 10000 #微秒为单位,即超过10000微秒就算慢查询

127.0.0.1:6379> slowlog get   #查看有哪些慢的操做
 1) 1) (integer) 456
    2) (integer) 1531632044
    3) (integer) 3
    4) 1) "get"
       2) "m"
    5) "127.0.0.1:50106"
    6) ""
 2) 1) (integer) 455
    2) (integer) 1531632037
    3) (integer) 14
    4) 1) "keys"
       2) "*"
    5) "127.0.0.1:50106"
    6) ""

结果说明:
1) 慢查询记录 id;
2) 发起命令的时间戳;
3) 命令耗时,单位为微秒;
4) 该条记录的命令及参数;
5) 客户端网络套接字(ip: port);
6) “”
.获取当前慢查询日志记录数
slowlog len
127.0.0.1:6379> slowlog len
(integer) 458
.慢查询日志重置
slowlog reset
其实是对慢查询列表作清理操做:
127.0.0.1:6379> slowlog len  #查看慢查询的记录数
(integer) 461
127.0.0.1:6379> slowlog reset #清空慢查询
OK
127.0.0.1:6379> slowlog len
(integer) 1

持久化 RDB和AOF

 RDB是Redis用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中全部键值对数据)。恢复时是将快照文件直接读到内存里。RDB其实就是把数据以快照的形式保存在磁盘上。RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb

RDB 有两种触发方式,分别是自动触发和手动触发

RDB

①、自动触发

redis
17.jpg

save 900 1:表示900 秒内若是至少有 1 个 key 的值变化,则保存
save 300 10:表示300 秒内若是至少有 10 个 key 的值变化,则保存
save 60 10000:表示60 秒内若是至少有 10000 个 key 的值变化,则保存

①、save:这里是用来配置触发 Redis的 RDB 持久化条件,也就是何时将内存中的数据保存到硬盘。好比“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave

  固然若是你只是用Redis的缓存功能,不须要持久化,那么你能够注释掉全部的 save 行来停用保存功能。能够直接一个空字符串来实现停用:save ""

  ②、stop-writes-on-bgsave-error :默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否中止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,不然没有人会注意到灾难(disaster)发生了。若是Redis重启了,那么又能够从新开始接收数据了

  ③、rdbcompression ;默认值是yes。对于存储到磁盘中的快照,能够设置是否进行压缩存储。若是是的话,redis会采用LZF算法进行压缩。若是你不想消耗CPU来进行压缩的话,能够设置为关闭此功能,可是存储在磁盘上的快照会比较大。

  ④、rdbchecksum :默认值是yes。在存储快照后,咱们还可让redis使用CRC64算法来进行数据校验,可是这样作会增长大约10%的性能消耗,若是但愿获取到最大的性能提高,能够关闭此功能。

  ⑤、dbfilename :设置快照的文件名,默认是 dump.rdb

  ⑥、dir:设置快照文件的存放路径,这个配置项必定是个目录,而不能是文件名。默认是和当前配置文件保存在同一目录。

  也就是说经过在配置文件中配置的 save 方式,当实际操做知足该配置形式时就会进行 RDB 持久化,将当前的内存快照保存在 dir 配置的目录中,文件名由配置的 dbfilename 决定。

②、手动触发

  手动触发Redis进行RDB持久化的命令有两种:

  一、save

  该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其余命令,直到RDB过程完成为止。

redis
16.jpg
  

redis
20.png
显然该命令对于内存比较大的实例会形成长时间阻塞,这是致命的缺陷,为了解决此问题,Redis提供了bgsave方式

redis
18.jpg
二、bgsave 异步后台执行

redis
19.png

执行该命令时,Redis会在后台异步进行快照操做,快照同时还能够响应客户端请求。具体操做是Redis进程执行fork操做建立子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,通常时间很短。

  基本上 Redis 内部全部的RDB操做都是采用 bgsave 命令。

  执行执行 flushall 命令,也会产生dump.rdb文件,但里面是空的.

rdb相关配置

save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir  ./     #编泽编译安装,默认RDB文件存放在启动redis的工做目录,建议明确指定存入目录
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes

手动保存

[root@C8-24 ~]# vim /apps/redis/etc/redis.conf 

save ""           #将此项设置为空
 #save 3600 1     #关闭
 #save 300 100    #关闭
 #save 60 10000   #关闭

dbfilename dump_6379.rdb      #保存文件的名字

 dir /data/redis             #路径

实现RDB方式

save:同步,会阻赛其它命令,不推荐使用

bgsave:异步后台执行,不影响其它命令的执行

自动:制定规则,自动执行

RDB模式优势

RDB快照保存了某个时间点的数据,能够经过脚本执行redis指令bgsave(非阻塞,后台执行)或者save(会阻塞写操做,不推荐)命令自定义时间点备份,能够保留多个备份,当出现问题能够恢复到不一样时间点的版本,很适合备份,而且此文件格式也支持有很多第三方工具能够进行后续的数据分析

好比:能够在最近的24小时内,每小时备份一次RDB文件,而且在每月的每一天,也备份一个ROB文件。这样的话,即便赶上问题,也能够随时将数据集还原到不一样的版本。

RDB能够最大化Redis的性能,父进程在保存RDB文件时惟一要作的就是fork出一个子进程,而后这个子进程就会处理接下来的全部保存工做,父进程无须执行任何磁盘 I/O操做。

RDB在大量数据,好比几个G的数据,恢复的速度比AOF的快

RDB模式缺点

不能实时保存数据,可能会丢失自上一次执行RDB备份到当前的内存数据

若是你须要尽可能避免在服务器故障时丢失数据,那么RDB不适合你。虽然Redis容许你设置不一样的保存点(save point)来控制保存RDB文件的频率,可是,由于ROB文件须要保存整个数据集的状态,因此它并非一个轻松的操做。所以你可能会至少5分钟才保存一次RDB文件。在这种状况下,一旦发生故障停机,你就可能会丢失好几分钟的数据。

当数据量很是大的时候,从父进程fork子进程进行保存至RDB文件时须要一点时间,多是毫秒或者秒,取决于磁盘IO性能

在数据集比较庞大时,fork()可能会很是耗时,形成服务器在必定时间内中止处理客户端﹔若是数据集很是巨大,而且CPU时间很是紧张的话,那么这种中止时间甚至可能会长达整整一秒或更久。虽然AOF重写也须要进行fork(),但不管AOF重写的执行间隔有多长,数据的持久性都不会有任何损失。

RDB每次在fork子进程来执行RDB快照数据文件生成的时候,若是数据文件特别大,可能会致使对客户端提供的服务暂停数毫秒,或者甚至数秒;

通常不要让RDB的间隔太长,不然每次生成的RDB文件太大了,对Redis自己的性能可能会有影响的;

RDB没法实现实时或者秒级持久化

RDB是间隔一段时间进行持久化,若是持久化之间Redis发生故障,会发生数据丢失。

[root@C8-24 ~]# mkdir /data/redis -p
[root@C8-24 ~]# chown redis.redis /data/redis/

yum  -y install  python3  python3-redis
[root@C8-58]#cat redis_test.py 
#!/bin/env python3
import redis
pool = redis.ConnectionPool(host="127.0.0.1",port="6379",password="")
r = redis.Redis(connection_pool=pool)
for i in range(5000000):
    r.set("k%d" % i,"v%d" % i)
    data=r.get("k%d" % i)
    print(data)

手动备份RDB文件脚本(一)

[root@C8-24 ~]# cat redis_rdb.sh 
#!/bin/bash
redis-cli -h 127.0.0.1 save &> /dev/null
DATE=`date +%F-%T`
[ -e /backup/redis-rdb ] || mkdir -p /backup/redis-rdb/
mv /data/redis/dump_6379.rdb   /backup/redis-rdb/dump_6379-${DATE}.rdb

[root@C8-24 ~]# ll /backup/redis-rdb/dump_6379-2021-08-05-22\:34\:44.rdb 
-rw-r--r-- 1 redis redis 59742638 Aug  5 22:34 /backup/redis-rdb/dump_6379-2021-08-05-22:34:44.rdb

手动备份RDB文件脚本(二)

[root@C8-24 ~]# cat  redis_rdb.2.sh 
#!/bin/bash
#Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37)
#Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47)
#******************************************************************************
. /etc/init.d/functions
BACKUP=/backup/redis-rdb
DIR=/data/redis
FILE=dump_6379.rdb
redis-cli -h 127.0.0.1 --no-auth-warning bgsave
result=`redis-cli --no-auth-warning info Persistence |grep rdb_bgsave_in_progress |sed -nr 's/.*:([0-9]+).*/\1/p'`  #结果为0就备份完毕了,备份完毕就要更名字了
until [ $result -eq 0 ];do
    sleep 1
    result=`redis-cli --no-auth-warning info Persistence |grep rdb_bgsave_in_progress |sed -nr 's/.*:([0-9]+).*/\1/p'`
done
DATE=`date +%F-%T`
[ -e $BACKUP ] ||{ mkdir -p $BACKUP ;chown -R redis:redis $BACKUP; }
mv $DIR/$FILE   $BACKUP/dump_6379-${DATE}.rdb
action "BACK redis RDB"

#执行
[root@C8-24 ~]# bash redis_rdb.2.sh 
Background saving started
BACK redis RDB                                             [  OK  ]

AOF 模式

优先级高于rdb

redis
22.png

AOF rewrite重写

将一些重复的能够合并的,过时的数据从新写入一个新的AOF文件,从而节约AOF备份占用的硬盘空间,也能加速恢复过程

能够手动执行bgrewriteaof触发AOF,或定义自动rewrite策略

AOF rewrite过程

redis

23.png

#开启aof的配置文件

[root@C8-24 ~]# vim /apps/redis/etc/redis.conf   
appendonly yes       #改成yes                                                                                 appendfilename  "appendonly.aof"

#或者:
[root@centos8 ~]#redis-cli
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
oK

手动执行AOF重写BGREWRITEAOF命令

BGREWRITEAOF
时间复杂度:o(N),N为要追加到AOF文件中的数据数量。
执行一个AOF文件重写操做。重写会建立一个当前AOF文件的体积优化版本。

即便BGREWRITEAOF 执行失败,也不会有任何数据丢失,由于旧的 AOF 文件在BGREWRITEAOF成功以前不会被修改。

重写操做只会在没有其余持久化工做在后台执行时被触发,也就是说:
若是 Redis 的子进程正在执行快照的保存工做,那么、AOF重写的操做会被预约(scheduled),等到保存工做完成以后再执行AOF重写。在这种状况下,BGREWRITEAOF的返回值仍然是 OK,但还会加上一条额外的信息,说明BGREWRITEAOF 要等到保存操做完成以后才能执行。在 Redis 2.6或以上的版本,能够使用工NFO [section]命令查看 BGREWR工TEAOF 是否被预约。

若是已经有别的 AOF文件重写在执行,那么BGREWRITEAOF返回一个错误,而且这个新的BGREWRITEAOF 请求也不会被预约到下次执行。

从 Redis 2.4开始,AOF重写由 Redis自行触发,BGREWRITEAOF仅仅用于手动触发重写操做。

AOF的优势

数据安全性相对较高,根据所使用的fsync策略(fsync是同步内存中redis全部已经修改的文件到存储设备),默认是appendfsync everysec,即每秒执行一次fsync,在这种配置下,Redis仍然能够保持良好的性能,而且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync会在后台线程执行,因此主线程能够继续努力地处理命令请求)

因为该机制对日志文件的写入操做采用的是append模式,所以在写入过程当中不须要seek,即便出现宕机现象,也不会破坏日志文件中已经存在的内容。然而若是本次操做只是写入了一半数据就出现了系统崩溃问题,不用担忧,在Redis下一次启动以前,能够经过redis-check-aof 工具来解决数据一致性的问题

Redis能够在AOF文件体积变得过大时,自动地在后台对AOF进行重写,重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操做是绝对安全的,由于Redis在建立新AOF文件的过程当中,append模式不断的将修改数据追加到现有的AOF文件里面,即便重写过程当中发生停机,现有的AOF文件也不会丢失。而一旦新AOF文件建立完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操做。

AOF包含一个格式清晰、易于理解的日志文件用于记录全部的修改操做。事实上,也能够经过该文件完成数据的重建

AOF文件有序地保存了对数据库执行的全部写入操做,这些写入操做以Redis协议的格式保存,所以AOF文件的内容很是容易被人读懂,对文件进行分析(parse)也很轻松。导出 (export)AOF文件也很是简单:举个例子,若是你不当心执行了FLUSHALL.命令,但只要AOF文件未被重写,那么只要中止服务器,移除AOF文件末尾的FLUSHAL命令,并重启Redis ,就能够将数据集恢复到FLUSHALL执行以前的状态。

AOF缺点

即便有些操做是重复的也会所有记录,AOF的文件大小要大于RDB格式的文件
AOF在恢复大数据集时的速度比RDB的恢复速度要慢
根据fsync策略不一样,AOF速度可能会慢于RDB
bug 出现的可能性更多

RDB和AOF 的选择

  • 若是主要充当缓存功能,或者能够承受数分钟数据的丢失, 一般生产环境通常只需启用RDB可,此也是默认值

  • 若是数据须要持久保存,一点不能丢失,能够选择同时开启RDB和AOF,通常不建议只开启AOF

注意!!!: AOF 模式默认是关闭的,第一次开启AOF后,并重启服务生效后,会由于AOF的优先级高于RDB,而AOF默认没有文件存在,从而致使全部数据丢失

[root@C8-24 ~]# vim /apps/redis/etc/redis.conf   同时开启:
appendonly yes                                                                                                appendfilename "appendonly.aof"

dbfilename dump_6379.rdb
dir /data/redis  

[root@C8-24 ~]# ll /data/redis/
total 90604
-rw-r--r-- 1 redis redis        0 Aug  6 06:42 appendonly.aof
-rw-r--r-- 1 root  root  92777881 Aug  6 06:45 dump_6379.rdb
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> set a haha
OK
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> 
[root@C8-24 ~]# ll /data/redis/
total 8
-rw-r--r-- 1 redis redis  53 Aug  6 06:49 appendonly.aof
-rw-r--r-- 1 redis redis 105 Aug  6 06:50 dump_6379.rdb   #数据丢失了

[root@C8-24 ~]# cp  /backup/redis-rdb/dump_6379-2021-08-06-06\:38\:19.rdb /data/redis/dump_6379.rdb
cp: overwrite '/data/redis/dump_6379.rdb'? y
[root@C8-24 ~]# ll /data/redis/
total 90608
-rw-r--r-- 1 redis redis       53 Aug  6 06:49 appendonly.aof
-rw-r--r-- 1 redis redis 92777881 Aug  6 06:54 dump_6379.rdb
[root@C8-24 ~]# 

#正确的启用方法:用命令启用,而不是直接在配置文件修改
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
OK
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"

以后再去改配置文件
appendonly yes  #改成yes

删除数据之后恢复

#删除数据之后恢复:
127.0.0.1:6379> get java
"verygood"
127.0.0.1:6379> del java
(integer) 1
127.0.0.1:6379> get java
(nil)

#编辑此项将verygood^M后面的内容所有删除
vim /data/redis/appendonly.aof
verygood^M  
*2^M
$6^M
SELECT^M
$1^M
 0^M
 *2^M
 $3^M
 del^M
 $4^M
 java^M

 [root@C8-24 ~]# systemctl start redis #重启服务数据恢复
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> get java
"verygood"

127.0.0.1:6379> DBSIZE  #查看大小
(integer) 5000004
127.0.0.1:6379> FLUSHALL #删库
OK
(3.37s)
127.0.0.1:6379> DBSIZE
(integer) 0

bgrewriteaof

[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> DBSIZE
(integer) 5000000
127.0.0.1:6379> FLUSHALL
OK
(5.04s)
127.0.0.1:6379> DBSIZE
(integer) 0
127.0.0.1:6379>  
[root@C8-24 ~]# ll /data/redis/
total 181208
-rw-r--r-- 1 redis redis 92777922 Aug  6 10:01 appendonly.aof
-rw-r--r-- 1 redis redis 92777881 Aug  6 09:51 dump_6379.rdb
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> BGREWRITEAOF   #清理磁盘
Background append only file rewriting started
127.0.0.1:6379> 
[root@C8-24 ~]# ll /data/redis/
total 90608
-rw-r--r-- 1 redis redis       92 Aug  6 10:02 appendonly.aof
-rw-r--r-- 1 redis redis 92777881 Aug  6 09:51 dump_6379.rdb
[root@C8-24 ~]#
bind o.0.0.0 #监听地址,能够用空格隔开后多个监听IP
protected-mode yes #redis3.2以后加入的新特性,在没有设置bind IP和密码的时候, redis只容许访问127.0.0.1:6379,能够远程链接,但当访问将提示警告信息并拒绝远程访问
port 6379 #监听端口,默认6379/tcp
tcp-backlog 511 #三次握手的时候server端收到client ack确认号以后的队列值,即全链接队列长度
timeout 0#客户端和Redis服务端的链接超时时间,默认是0,表示永不超时
tcp-keepalive 300 #tcp会话保持时间300s
daemonize no #默认no,即直接运行redis-server程序时,不做为守护进程运行,而是之前台方式运行,若是想在后台运行需改为yes,当redis做为守护进程运行的时候,它会写一个pid到
/var/ run /redis.pid 文件
supervised no #和os相关参数,可设置经过upstart和systemd管理Redis守护进程,centos7后都使用systemd
pidfile /var/run/redis_6379.pid #pid文件路径,能够修改成/apps/redi s/run/ redis_6379.pid
logleve1 notice #日志级别
logfile "/path/redis.log”#日志路径,示例:1ogfile " /apps/redis/log/redis_6379.log"
databases 16 #设置数据库数量,默认:0-15,共16个库
a1way s-show-7ogo yes #在启动redis 时是否显示或在日志中记录记录redis的1ogo
save 900 1 #在900秒内有1个key内容发生更改,就执行快照机制
save 300 10 #在:300秒内有10个key内容发生更改,就执行快照机制
save 60 10000#60秒内若是有10000个key以上的变化,就自动快照备份
stop-writes-on-bgsave-error yes #默认为yes时,可能会因空间满等缘由快照没法保存出错时,会禁止redi s写入操做,生产建议为no
#此项只针对配置文件中的自动s ave有效

rdbcompression yes #持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之
rdbchecksum yes #是否对备份文件开启RC64校验,默认是开启
dbfilename dump . rdb #快照文件名
dir ./#快照文件保存路径,示例: dir " / apps/redis/data"
#主从复制相关
# replicaof <masterip> <masterport>#指定复制的master主机地址和端口,5.0版以前的指令为s1aveof
# masterauth <master-password>#指定复制的master主机的密码
replica-serve-stale-data yes #当从库同主库失去链接或者复制正在进行,从机库有两种运行方式:一、设置为yes(默认设置),从库会继续响应客户端的读请求,此为建议值
二、设置为no,除去特定命令外的任何请求都会返回一个错误"sYc with master in progress"。
rep7ica-read-only yes #是否设置从库只读,建议值为yes,不然主库同步从库时可能会覆盖数据,形成数据丢失

rep7-diskless-sync no #是否使用socket方式复制数据(无盘同步),新s7ave第一次链接master时须要作数据的全量同步,redis server就要从内存dump出新的RDB文件,而后从master传到s7ave,有两种方式把RDB文件传输给客户端:
一、基于硬盘(disk-backed):为no时,master建立一个新进程dump生成RDB磁盘文件,RDB完成以后由父进程(即主进程)将RDB文件发送给s1aves,此为默认值
二、基于socket(diskless) : master建立一个新进程直接dump RDB至slave的网络socket,不通过主进程和硬盘
#推荐使用基于硬盘(为no),是由于RDB文件建立后,能够同时传输给更多的s1ave,可是基于socket(为yes),新s1ave链接到master以后得逐个同步数据。只有当磁盘I/o较慢且网络较快时,可用
diskless(yes),不然通常建议使用磁盘(no)
rep7-diskless-sync-delay 5 #diskless时复制的服务器等待的延迟时间,设置0为关闭,在延迟时间内到达的客户端,会一块儿经过diskless方式同步数据,可是一旦复制开始,master节点不会再接收新slave的复制请求,直到下一次同步开始才再接收新请求。即没法为延迟时间后到达的新副本提供服务,新副本将排队等待下一次RDB传输,所以服务器会等待一段时间才能让更多副本到达。推荐值:30-60
rep7-ping-replica-period 10 #s7ave根据master指定的时间进行周期性的PING master,用于监测master状态,默认10s
rep7-timeout 60#复制链接的超时时间,须要大于rep7-ping-slave-period,不然会常常报超时
rep7-disable-tcp-nodelay no #是否在slave套接字发送SYNC以后禁用TCP_NODELAY,若是选择"yes",Redis将合并多个报文为一个大的报文,从而使用更少数量的包向s1aves发送数据,可是将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒,若是“no”,数据传输到slave的延迟将会减小,但要使用更多的带宽
rep7-backlog-size 512mb #复制缓冲区内存大小,当s1ave断开链接一段时间后,该缓冲区会累积复制副本数据,所以当slave从新链接时,一般不须要彻底从新同步,只需传递在副本中的断开链接后没有同步的部分数据便可。只有在至少有一个slave链接以后才分配此内存空间,建议创建主从时此值要调大一些或在低峰期配置,不然会致使同步到s1ave失败
rep7-back7og-tt1 3600 #多长时间内master没有s1ave链接,就清空backlog缓冲区

rep7ica-priority 100 #当master不可用,哨兵sentine1会根据slave的优先级选举一个master,此值最低的slave会优先当选master,而配置成0,永远不会被选举,通常多个slave都设为同样的值,让其自动选择

Redis经常使用命令

官方文档:https://redis.io/commands

参考连接: http://redisdoc.com/

set

#设置有效期:
127.0.0.1:6379> set hongbaos 100 EX 10
OK
127.0.0.1:6379> ttl hongbaos
(integer) 6
127.0.0.1:6379> ttl hongbaos
(integer) 3
127.0.0.1:6379> ttl hongbaos
(integer) 1
127.0.0.1:6379> ttl hongbaos
(integer) 1
127.0.0.1:6379> ttl hongbaos
(integer) -2
127.0.0.1:6379> ttl hongbaos
(integer) -2
127.0.0.1:6379> 

127.0.0.1:6379> set class python NX
(nil)
127.0.0.1:6379> set class2 python NX #class2 不存在就改
OK
127.0.0.1:6379> get class2
"python"
127.0.0.1:6379> get class
"linux"
127.0.0.1:6379> set class python XX  #class存在就改
OK
127.0.0.1:6379> get class
"python"

127.0.0.1:6379> mset city zhengzhou gender male
OK
127.0.0.1:6379> mget city gender
1) "zhengzhou"
2) "male"

127.0.0.1:6379> del city
(integer) 1
127.0.0.1:6379> mget city gender
1) (nil)
2) "male"

#追加内容
127.0.0.1:6379> set content wangyu
OK
127.0.0.1:6379> APPEND content "is very good"
(integer) 18  #追加的字节数
127.0.0.1:6379> get content
"wangyuis very good"

#设新值返回旧值
127.0.0.1:6379> get name
"linux"
127.0.0.1:6379> getset name wangge
"linux"
127.0.0.1:6379> get name
"wangge"

info

显示当前节点redis运行状态信息

[root@C8-24 ~]# redis-cli info cluster
# Cluster
cluster_enabled:0
[root@C8-24 ~]# redis-cli info cpu
# CPU
used_cpu_sys:1.069754
used_cpu_user:12.740768
used_cpu_sys_children:0.140771
used_cpu_user_children:3.620287
used_cpu_sys_main_thread:1.047010
used_cpu_user_main_thread:12.744783

select

切换数据库,至关于在MySQL的USE DBNAME指令

[root@centos8 ~]#redis-cli
127.0.0.1:6379> info cluster
# cluster
cluster_enab1ed:0
127.0.0.1:6379[15]>SELECT ooK
127.0.0.1:6379>SELECT 1OK
127.0.0.1:6379[1]>SELECT 15OK
127.0.0.1:6379[15]>SELECT 16
(error) ERR DB index is out of range127.0.0.1:6379[15]>

注意:在redis cluster模式下不支持多个数据库,会出现下面错误

[root@centos8 ~]#redis-cli
127.0.0.1:6379> info cluster
# cluster
cluster_enabled: 1
127.0.0.1:6379> select 0
oK
127.0.0.1:6379> select 1
(error) ERR SELECT is not a77owed in cluster mode

KEYS

查看当前库下的全部key,此命令慎用!

127.0.0.1:6379[15]>SELECT 0
oK
127.0.0.1:6379> KEYS *
1) "9527"
2)"9526"
3) "paihangbang"
4)"7ist1"
127.0.0.1:6379>SELECT 1
oK
127.0.0.1:6379[1]>KEYS *
(empty list or set)
127.0.0.1:6379[1]>
redis>MSET one 1 two 2 three 3 four 4#一次设置4个 key
OK
redis> KEYS *o*
1) "four"
2) "two"
3) "one"
redis> KEYS t??
1) "two"
redis> KEYS t[w]*
1) "two"
redis> KEYS *   #匹配数据库内全部key
1) "four"
2) "three"
3)''two''
4)''one''

bgsave

手动在后台执行RDB持久化操做

#交互式执行
127.0.0.1:6379[1]>BGSAVE
Background saving started
#非交互式执行
[root@centos8 ~]#ll /var/lib/redis/
total 4
-rw-r--r-- 1 redis redis 326 Feb 18 22:45 dump .rdb
[root@centos8 ~]#redis-cli -h 127.0.0.1 -a '123456' BGSAVE
warning: using a password with '-a' or '-u’ option on the command line interfacemay not be safe.
Background saving started
[root@centos8 ~]#ll /var /lib/redis/
total 4
-rw-r--r-- 1 redis redis 92 Feb 18 22:54 dump.rdb

DBSIZE

返回当前库下的全部key数量

127.0.0.1:6379> DBSIZE
(integer) 4
127.0.0.1:6379>SELECT  1
oK
127.0.0.1:6379[1]>DBSIZE
(integer) 0

FLUSHDB

强制清空当前库中的全部key,此命令慎用!
127.0.0.1:6379[1]>SELECT 0
oK
127.0.0.1:6379> DBSIZE
(integer) 4
127.0.0.1:6379> FLUSHDB
oK
127.0.0.1:6379>DBSIZE
(integer) 0
127.0.0.1:6379>

FLUSHALL

强制清空当前redis服务器全部数据库中的全部key,即删除全部数据,此命令慎用!
127.0.0.1:6379>FLUSHALL
OK
#生产建议修改配置/etc/redis.confrename-command FLUSHALL ""

SHUTDOwN

可用版本:>= 1.0.0
时间复杂度:O(N),其中 N为关机时须要保存的数据库键数量。SHUTDOWN命令执行如下操做:
中止全部客户端
若是有至少一个保存点在等待,执行SAVE命令
若是AOF选项被打开,更新AOF文件
关闭redis 服务器(server)
若是持久化被打开的话,SHUTDOWN命令会保证服务器正常关闭而不丢失任何数据。
另外一方面,假如只是单纯地执行SAVE命令,而后再执行QUIT命令,则没有这一保证--由于在执行SAVE以后、执行 QUIT以前的这段时间中间,其余客户端可能正在和服务器进行通信,这时若是执行QUIT就会形成数据丢失。

redis数据类型

参考资料: http://www.redis.cn/topics/data-types.html

相关命令参考: http://redisdoc.com/

字符串string

字符串是全部编程语言中最多见的和最经常使用的数据类型,并且也是redis最基本的数据类型之一,并且redis 中全部的key的类型都是字符串。经常使用于保存Session信息场景,此数据类型比较经常使用

添加一个key

set 指令能够建立一个key并赋值,使用格式

SET key value [Ex seconds] [Px mi17iseconds] [NX |xX]时间复杂度:o(1)

将字符串值 value关联到key 。
若是key 已经持有其余值,SET就覆写旧值,无视类型。
当SET命令对一个带有生存时间(TTL)的键进行设置以后,该键原有的 TTL将被清除。
从Redis 2.6.12版本开始,SET命令的行为能够经过一系列参数来修改;
Ex seconds :将键的过时时间设置为 seconds秒。执行 SET key value Ex seconds的效果等同于执行SETEx key seconds value .
Px milliseconds :将键的过时时间设置为 mil7iseconds毫秒。执行 SET key value PXmi7liseconds 的效果等同于执行PSETEx key milliseconds value .
NX:只在键不存在时,才对键进行设置操做。执行SET key value NX的效果等同于执行SETNXkey value .
XX:只在键已经存在时,才对键进行设置操做。
#不论key是否存在.都设置
127.0.0.1:6379>set key1 value1
OK
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> TYPE key1 #判断类型
string
127.0.0.1:6379> SET title ceo ex 3 #设置自动过时时间3s
oK
127.0.0.1:6379> set NAME wang
OK
127.0.0.1:6379> get NAME
'wang"

#大小写敏感
127.0.0.1:6379> get name
(ni1)
127.0.0.1:6379>set name mage
oK
127.0.0.1:6379> get name
"mage"
127.0.0.1:6379> get NAME
'wang"

#key不存在,才设置,至关于add
127.0.0.1:6379> get title
"ceo"
127.0.0.1:6379> setnx title coo  #set key value nx
(integer) 0
127.0.0.1:6379>get title
"ceo"

#key存在,才设置,至关于update
127.0.0.1:6379>get title
"ceo"
127.0.0.1:6379> set title coo xx
oK
127.0.0.1:6379>get title
"coo"
127.0.0.1:6379> get age
(ni1)
127.0.0.1:6379> set age 20 xx
(ni1)
127.0.0.1:6379>get age
(ni1)

获取一个key的内容

127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> get name age
(error) ERR wrong number of arguments for 'get' command

删除一个和多个key

127.0.0.1:6379> DEL key1
(integer) 1
127.0.0.1:6379>DEL key1 key2
(integer) 2

批量设置多个key

127.0.0.1:6379>MSET key1 value1 key2 value2
oK

批量获取多个key

127.0.0.1:6379> MGET key1 key2
1) "value1"
2) "value2"
127.0.0.1:6379>KEYS n*
1) "n1"
2) "name"
127.0.0.1:6379>KEYS*
1)"k2"
2)"k1"
3) "key1"
4)"key2"
5) "n1"
6) "name"
7) "k3"
8) "title"

追加数据

127.0.0.1:6379> APPEND key1 " append new value"
(integer) 12  #添加数据后,key1总共9个字
127.0.0.1:6379> get key1
"value1 append new value"

设置新值并返回旧值

#set key newvalue并返回旧的value
127.0.0.1:6379> set name wang
oK
127.0.0.1:6379> getset name magedu
"wang"
127.0.0.1:6379> get name
"magedu"

返回字符串对应的字节数

127.0.0.1:6379[1]> set name wang
OK
127.0.0.1:6379[1]> strlen name   #返回的字节数
(integer) 4
127.0.0.1:6379[1]> APPEND name wangyu
(integer) 10
127.0.0.1:6379[1]> GET name
"wangwangyu"
127.0.0.1:6379[1]> APPEND name "  yu"
(integer) 14

判断key是否存在

127.0.0.1:6379>SET name wang ex 10
OK
127.0.0.1:6379> set age 20
oK
127.0.0.1:6379> EXISTS NAME #key的大小写敏感
(integer) 0

127.0.0.1:6379>EXISTS name age #返回值为1,表示存在2个key ,0表示不存在
(integer) 2
127.0.0.1:6379> EXISTS name#过几秒再看
(integer) 0

查看key 的过时时间

tt1 key #查看key的剩余生存时间,若是key过时后,会自动删除

-1#返回值表示永不过时,默认建立的key是永不过时,从新对key赋值,也会从有剩余生命周期变成永不过时
-2#返回值表示没有此key
num #key的剩余有效期
127.0.0.1:6379> TTL key1(integer)
-1
127.0.0.1:6379>SET name wang EX 100
OK
127.0.0.1:6379> TTL name
(integer) 96
127.0.0.1:6379> TTL name
(integer) 93
127.0.0.1:6379>SET name mage #从新设置,默认永不过时oK
127.0.0.1:6379> TTL name
(integer) -1
127.0.0.1:6379>SET name wang EX 200
OK
127.0.0.1:6379> TTL name
(integer) 198
127.0.0.1:6379>GET name
"wang"

从新设置key的过时时间

127.0.0.1:6379> TTL name
(integer)148
127.0.0.1:6379> EXPIRE name 1000
(integer) 1
127.0.0.1:6379>TTL name
(integer) 999
127.0.0.1:6379>

取消key的过时时间

#即永不过时
127.0.0.1:6379> TTL name
(integer) 999
127.0.0.1:6379> PERSIST name
(integer) 1
127.0.0.1:6379> TTL name
(integer) -1

数值递增

利用INCR命令簇(INCR, DECR, INCRBY,DECRBY)来把字符串看成原子计数器使用。
127.0.0.1:6379> set num 10 #设置初始值
oK
127.0.0.1:6379> INCR num
(integer) 11
127.0.0.1:6379> get num
"11"

数值递减

127.0.0.1:6379> set num 10
OK
127.0.0.1:6379>DECR num
(integer) 9
127.0.0.1:6379> get num
"9"

数值增长

将key对应的数字加decrement(能够是负数)。若是key不存在,操做以前,key就会被置为0。若是key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操做最多支持64位有符号的正型数字。
redis> sET mykey 10
OK
redis> INCRBY mykey 5
(integer) 15
127.0.0.1:6379> get mykey
"15"
127.0.0.1:6379> INCRBY mykey -10
(integer) 5
127.0.0.1:6379> get mykey
"5"
127.0.0.1:6379> INCRBY nokey 5
(integer) 5
127.0.0.1:6379> get nokey
"5"

数据减小

decrby能够减少数值(也能够增长)
127.0.0.1:6379>SET mykey 10
oK
127.0.0.1:6379> DECRBY mykey 8
(integer) 2
127.0.0.1:6379> get mykey
"2"
127.0.0.1:6379> DECRBY mykey -20
(integer) 22
127.0.0.1:6379> get mykey
"22"
127.0.0.1:6379> DECRBY nokey 3
(integer) -3
127.0.0.1:6379> get nokey
"-3"

列表

列表是一个双向可读写的管道,其头部是左侧,尾部是右侧,一个列表最多能够包含2^32-
1 (4294967295)个元素,下标0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。也能够使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,元素值能够重复,经常使用于存入日志等场景,此数据类型比较经常使用
列表特色
有序·可重复
左右均可以操做

lpush 和rpush 均可以插入列表:

LPUSH key value [value ....时间复杂度:O(1)
将一个或多个值value插入到列表 key 的表头
若是有多个value值,那么各个value值按从左到右的顺序依次插入到表头:好比说,对空列表mylist 执行命令LPUSH mylist a b c ,列表的值将是 c b a ,这等同于原子性地执行LPUSHmy7ist a . LPUSH mylist b 和 LPUSH mylist c三个命令。
若是key不存在,一个空列表会被建立并执行LPUSH操做。
当key存在但不是列表类型时,返回一个错误。
RPUSH key value [value ...]
时间复杂度:o(1)
将一个或多个值 value插入到列表key 的表尾(最右边)。
若是有多个value值,那么各个value值按从左到右的顺序依次插入到表尾:好比对一个空列表
my1ist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c ,等同于执行命令RPUSH mylista 、 RPUSH my1ist b 、RPUSH mylist c 。
若是key不存在,一个空列表会被建立并执行RPUSH操做。当key存在但不是列表类型时,返回一个错误。
#从左边添加数据,已添加的需向右移
127.0.0.1:6379>LPUSH name mage wang zhang#根据顺序逐个写入name,最后的zhang会在列表的最左侧。
(integer) 3
127.0.0.1:6379> TYPE name
list
#从右边添加数据
127.0.0.1:6379>RPUSH course 1inux python go
(integer) 3
127.0.0.1:6379> type course
list

向列表追加数据

#向列表追加数据
127.0.0.1:6379> LPUSH list1 tom
(integer) 2
#从右边添加数据,已添加的向左移
127.0.0.1:6379> RPUSH 1ist1 jack
(integer) 3

获取列表长度(元素个数)

127.0.0.1:6379> LLEN list1
(integer) 3

获取列表指定位置数据

redis
24.jpg

127.0.0.1:6379> LPUSH list1 a b c d
(integer) 4
127.0.0.1:6379>LINDEX list1 0#获取0编号的元素
"d""
127.0.0.1:6379>LINDEX list1 3 #获取3编号的元素
"a"
127.0.0.1:6379>LINDEX list1 -1 #获取最后一个的元素
"a"
#元素从0开始编号
127.0.0.1:6379>LPUSH list1 a b c d
(integer) 4
127.0.0.1:6379> LRANGE list1 1 2
1)"c”
2)"b”
127.0.0.1:6379> LRANGE list1 0 3 #全部元素
1) "d""
2) "c"
3) "b"
4) "a"
127.0.0.1:6379>LRANGE list1 0 -1#全部元素
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> RPUSH list2 zhang wang 1i zhao
(integer) 4
127.0.0.1:6379>LRANGE list2 1 2#指定范围
1) "wang"
2)"li"
127.0.0.1:6379>LRANGE list2 2 2#指定位置
1)"li"
127.0.0.1:6379> LRANGE 7ist2 0 -1#全部元素
1) "zhang"
2) "wang"
3)"li"
4) "zhao"

修改列表指定索引值

127.0.0.1:6379>RPUSH listkey a b c d e f
(integer) 6
127.0.0.1:6379> 1range 1istkey 0 -1
1) "a"
2)"b"
3) "c"
4) "d"
5) "e"
6)"f"
127.0.0.1:6379> lset listkey 2 java
oK
127.0.0.1:6379> lrange listkey 0 -1
1)"a"
2)"b"
3) "java"
4) "d"
5)"e"
6)"f"
127.0.0.1:6379>

移除列表数据

127.0.0.1:6379> LPUSH list1 a b c d
(integer) 4
127.0.0.1:6379>LRANGE list1 0 3
1) "d"
2) "c"
3)"b"
4)"a"
127.0.0.1:6379>LPOP list1 #弹出左边第一个元素,即删除第一个
"d"
127.0.0.1:6379> LLEN 1ist1
(integer) 3
127.0.0.1:6379>LRANGE list1 0 2
1)"c"
2)"b"
3) "a"
127.0.0.1:6379> RPOP 1ist1#弹出右边第一个元素,即删除最后一个
"a"
127.0.0.1:6379> LLEN 1ist1
(integer)2
127.0.0.1:6379> LRANGE 1ist1 0 1
1)"c"
2)"b"

#LTRIM对一个列表进行修剪(trim),让列表只保留指定区间内的元素,不在指定区间以内的元素都将被删除
127.0.0.1:6379> LLEN 1ist1
(integer) 4
127.0.0.1:6379>LRANGE list1 0 3
1)"d"
2) "c"
3)"b"
4) "a"
127.0.0.1:6379> LTRIM list1 1 2#只保留1,2号元素
OK
127.0.0.1:6379> LLEN list1
(integer) 2
127.0.0.1:6379>LRANGE list1 0 1
1)"c"
2)"b"
#删除list
127.0.0.1:6379>DEL list1
(integer) 1
127.0.0.1:6379>EXISTS list1
(integer) 0

集合

生成集合

Set是String类型的无序集合,集合中的成员是惟一的,这就意味着集合中不能出现重复的数据,能够在两个不一样的集合中对数据进行对比并取值,经常使用于取值判断,统计,交集等场景
集合特色
无序
无重复
集合间操做

127.0.0.1:6379> sadd set1 v1
(integer) 1
127.0.0.1:6379> sadd set2 v2 v4
(integer) 2
127.0.0.1:6379> TYPE set1
set
127.0.0.1:6379> TYPE set2
set

追加数值

#追加时,只能追加不存在的数据,不能追加已经存在的数值
127.0.0.1:6379> SADD set1 v2 v3 v4
(integer) 3
127.0.0.1:6379> SADD set1 v2#已存在的value,没法再次添加
(integer) 0
127.0.0.1:6379> TYPE set1
set
127.0.0.1:6379> TYPE set2
set

查看集合的全部数据

127.0.0.1:6379>SMEMBERS set1
1) "v4"
2)"v1"
3) "v3"
4) "v2"
127.0.0.1:6379>SMEMBERS set2
1)"v4"
2) "v2"

删除集合中的元素

127.0.0.1:6379> sadd goods mobile laptop car
(integer) 3
127.0.0.1:6379> srem goods car
(integer) 1
127.0.0.1:6379> SMEMBERS goods
1) "mobile"
2) "laptop"
127.0.0.1:6379>

获取集合的交集

交集:已属于A且属于B的元素称为A与B的交(集)
127.0.0.1:6379> SINTER set1 set2
1) "v4"
2) "v2"

获取集合的并集

并集:已属于A或属于B的元素为称为A与B的并(集)
127.0.0.1:6379>SUNION set1 set2
1) "v2"
2) "v4"
3) "v1"
4) "v3"

获取集合的差集

差集:已属于A而不属于B的元素称为A与B的差(集)
127.0.0.1:6379>SDIFF set1 set2
1) "v1"
2) "v3"

有序集合sorted set

Redis有序集合和集合同样也是string类型元素的集合,且不容许重复的成员,不一样的是每一个元素都会关联一个double(双精度浮点型)类型的分数,redis正是经过该分数来为集合中的成员进行从小到大的排序,有序集合的成员是惟一的;但分数(score)却能够重复,集合是经过哈希表实现的,因此添加,删除,查找的复杂度都是O⑴),集合中最大的成员数为2^32-1(4294967295,每一个集合可存储40多亿个成员),常常用于排行榜的场景

有序集合特色
有序
无重复元素
每一个元素是由score和value组成
score 能够重复
value 不能够重复

生成有序集合

127.0.0.1:6379>ZADD zset1 1  v1 #分数为1
(integer) 1
127.0.0.1:6379> ZADD zset1 2  v2
(integer) 1
127.0.0.1:6379>ZADD zset1 2    v3 #分数可重复,元素值不能够重复
(integer) 1
127.0.0.1:6379> ZADD zset1 3   v4
(integer) 1
127.0.0.1:6379> TYPE zset1
zset
127.0.0.1:6379> TYPE zset2
zset
#一次生成多个数据:
127.0.0.1:6379>ZADD zset2 1 v1 2 v2 3 v3 4 v4 5 v5
(integer) 5

有序集合实现排行榜

127.0.0.1:6379> ZADD paihangbang 90 nezha 199 zhan1ang 60 zhuluoji 30 gangtiexia
(integer)4
127.0.0.1:6379> ZRANGE paihangbang 0 -1 #正序排序后显示集合内全部的key , score从小到大显示
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
4) "zhan1ang"
127.0.0.1:6379>ZREVRANGE paihangbang 0 -1 #倒序排序后显示集合内全部的key, score从大到小显示
1) "zhan1ang"
2) "nezha"
3) "zhuluoji"
4) "gangtiexia"
127.0.0.1:6379> ZRANGE paihangbang 0 -1 wITHSCORES#正序显示指定集合内全部key和得分状况
1) "gangtiexia"
2) "30"
3)"zhu1uoji"
4) "60"
5) "nezha"
6)"90"
7)"zhan1ang"
8)"199"
127.0.0.1:6379> ZREVRANGE paihangbang 0 -1 WITHSCORES#倒序显示指定集合内全部key和得分状况
1) "zhan1ang"
2)"199"
3) "nezha"
4) "90"
5)"zhuluoji"
6)"60"
7) "gangtiexia"
8)"30"
127.0.0.1:6379>

获取集合的个数

127.0.0.1:6379>ZCARD paihangbang
(integer) 4
127.0.0.1:6379>ZCARD zset1
(integer) 4
127.0.0.1:6379>ZCARD zset2
(integer) 4

基于索引返回数值

127.0.0.1:6379>ZRANGE pai hangbang 0 2
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
127.0.0.1:6379>ZRANGE pai hangbang 0 10  #超出范围不报错
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
4) "zhanlang"

127.0.0.1:6379>ZRANGE zset1 1 3
1) "v2"
2)"v3"
3) "v4"
127.0.0.1:6379>ZRANGE zset1 0 2
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379>ZRANGE zset1 2 2
1) "v3"

返回某个数值的索引(排名)

127.0.0.1:6379>ZADD paihangbang 90 nezha 199 zhan1ang 60 zhuluoji 30 gangtiexia
(integer)4
127.0.0.1:6379>ZRANK paihangbang zhan1ang
(integer) 3#第4个
127.0.0.1:6379>ZRANK paihangbang zhuluoji
(integer) 1#第2个

获取分数

127.0.0.1:6379> zscore paihangbang gangtiexia
"30"

删除元素

127.0.0.1:6379>ZADD paihangbang 90 nezha 199 zhanlang 60 zhuluoji 30 gangtiexia
(integer) 4
127.0.0.1:6379>ZRANGE pai hangbang 0 -1
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
4) "zhan1ang"
127.0.0.1:6379>ZREM pai hangbang zhuluoji zhan1ang
(integer) 2
127.0.0.1:6379>ZRANGE pai hangbang 0 -1
1) "gangtiexia"
2) "nezha"

哈希hash

hash是一个string类型的字段(field)和值(value)的映射表,Redis 中每一个hash能够存储2^32-1键值对,相似于字典,存放了多个k/v对,hash特别适合用于存储对象场景

生成hash

HSET hash field value时间复杂度:o(1)
将哈希表hash中域fie1d 的值设置为value 。
若是给定的哈希表并不存在,那么一个新的哈希表将被建立并执行HSET操做。若是域fie1d 已经存在于哈希表中,那么它的旧值将被新值 value覆盖。

127.0.0.1:6379> HSET 9527 name zhouxingxing age 20
(integer) 2
127.0.0.1:6379>TYPE 9527
hash
#查看全部字段的值
127.0.0.1:6379> hgetal1 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "20"
#增长字段
127.0.0.1:6379>HSET 9527 gender male
(integer) 1
127.0.0.1:6379> hgetall 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "20"
5) "gender"
6) "male"

获取hash key的对应字段的值

127.0.0.1:6379> HGET 9527 name
"zhouxingxing"
127.0.0.1:6379> HGET 9527 age
"20"
127.0.0.1:6379>HMGET 9527 name age#获取多个值
1) "zhouxingxing"
2) "20"
127.0.0.1:6379>

删除一个hash key的对应字段

127.0.0.1:6379>HDEL 9527 age
(integer) 1
127.0.0.1:6379>HGET 9527 age
(ni1)
127.0.0.1:6379> hgetal1 9527
1) "name"
2) "zhouxingxing"
127.0.0.1:6379> HGET 9527 name
"zhouxingxing"

批量设置hash key的多个field和value

127.0.0.1:6379> HMSET 9527 name zhouxingxing age 50 city hongkong
OK
127.0.0.1:6379> HGETALL 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "50"
5) "city"
6) "hongkong"

获取hash中指定字段的值

127.0.0.1:6379> HMSET 9527 name zhouxingxing age 50 city hongkong
OK
127.0.0.1:6379> HMGET 9527 name age
1) "zhouxingxing"
2) "50"
127.0.0.1:6379>

获取hash中的全部字段名field

127.0.0.1:6379>HMSET 9527 name zhouxingxing age 50 city hongkong #从新设置OK
127.0.0.1:6379> HKEYS 9527
1) "name"
2) "age"3) "city"

获取hash key对应全部field的value

127.0.0.1:6379> HMSET 9527 name zhouxingxing age 50 city hongkongoK
127.0.0.1:6379> HVALS 9527
1) "zhouxingxing"
2) "50"
3) "hongkong"

获取指定hash key的全部field和value

127.0.0.1:6379> HGETALL 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "50"
5) "city"
6) "hongkong"
127.0.0.1: 6379>

删除hash

127.0.0.1:6379> DEL9527
(integer) 1
127.0.0.1:6379> HMGET 9527 name city
1) (ni1)
2) (ni1)
127.0.0.1:6379> EXISTS 9527
(integer) 0

消息队列

消息队列:把要传输的数据放在队列中
功能:能够实现多个系统之间的解耦,异步,削峰/限流等经常使用的消息队列应用: kafka,rabbitMQ,redis

消息队列主要分为两种,这两种模式Redis都支持
生产者/消费者模式
发布者/订阅者模式

生产者/消费者模式

在生产者/消费者(ProducerlConsumer)模式下,上层应用接收到的外部请求后开始处理其当前步骤的操做,在执行完成后将已经完成的操做发送至指定的频道(channel,逻辑队列)当中,并由其下层的应用监听该频道并继续下一步的操做,若是其处理完成后没有下一步的操做就直接返回数据给外部请求,若是还有下一步的操做就再将任务发布到另一个频道,由另一个消费者继续监听和处理。此模式应用普遍
2.6.1.1模式介绍
生产者消费者模式下,多个消费者同时监听一个队列,可是一个消息只能被最早抢到消息的消费者消费,即消息任务是一次性读取和处理,此模式在分布式业务架构中很经常使用,比较经常使用的消息队列软件还有RabbitMQ、Kafka、RocketMQ、ActiveMQ等。

队列介绍

队列当中的消息由不一样的生产者写入,也会有不一样的消费者取出进行消费处理,可是一个消息必定是只能被取出一次也就是被消费一次。

redis

redis
25.jpg26.jpg

生产者发布消息

[root@redis ~]# redis-cli 
127.0.0.1:6379> AUTH 123456oK
127.0.0.1:6379> LPUSH channe11 msg1 #从管道的左侧写入
(integer) 1
127.0.0.1:6379> LPUSH channe11 msg2
(integer) 2
127.0.0.1:6379> LPUSH channe11 msg3
(integer) 3
127.0.0.1:6379> LPUSH channe11 msg4
(integer) 4
127.0.0.1:6379> LPUSH channe11 msg5
(integer) 5

查看消息队列消息

127.0.0.1:6379> lrange channe11 0 -1
1) "msg5"
2) "msg4"
3) "msg3"
4) "msg2"
5) "msg1"

消费者消费消息

127.0.0.1:6379> rpop channe11    #从管道右侧消费,用于消息先进先出
"msg1"
127.0.0.1:6379> rpop channe11
"msg2"
127.0.0.1:6379> rpop channe11
"msg3"
127.0.0.1:6379> rpop channe11
"msg4"
127.0.0.1:6379> rpop channe11
"msg5"
127.0.0.1:6379> rpop channe11
(nil)

再次验证队列消息

127.0.0.1:6379> lrange channe11  0 -1
(empty array)

发布者订阅模式

在发布者订阅者模式下,发布者将消息发布到指定的channel里面,凡是监听该channel的消费者都会收到一样的
一份消息,这种模式相似因而收音机的广播模式,即凡是收听某个频道的听众都会收到主持人发布的相同的消息内
容。此模式经常使用语群聊天、群通知、群公告等场景
Publisher:发布者
Subscriber:订阅者
Channel:频道

订阅者监听频道

[root@redis ~]# redis-cli
127.0.0.1:6379> AUTH 123456oK
127.0.0.1:6379>SUBSCRIBE channe11  #订阅者事先订阅指定的频道,以后发布的消息才 能收到
Readi ng messages. . . (press ctr1-c to quit)
1) "subscribe"
2) "channe11"
3) (integer) 1

发布者发布消息

127.0.0.1:6379> PUBLISH channe11 test1  #发布者发布消息
(integer) 1
127.0.0.1:6379> PUBLISH channe11 test1
(integer) 2  #订阅者个数

订阅者收到消息

[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> SUBSCRIBE channe11
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channe11"
3) (integer) 1
1) "message"
2) "channe11"
3) "test1"
#订阅指定的多个频道
127.0.0.1:6379>SUBSCRIBE channe11 channe12

#订阅全部频道
127.0.0.1:6379> PSUBSCRIBE *#支持通配符*

#订阅匹配的频道
127.0.0.1:6379> PSUBSCRIBE chann*#匹配订阅多个频道

#取消订阅
127.0.0.1:6379> unsubscribe channe11
1) "unsubscribe"
2) "channe11"3)(integer) 0

redis集群与高可用

虽然Redis能够实现单机的数据持久化,但不管是RDB也好或者AOF也好,都解决不了单点宕机问题,即一旦单台redis服务器自己出现系统故障、硬件故障等问题后,就会直接形成数据的丢失
此外单机的性能也是有极限的,所以须要使用另外的技术来解决单点故障和性能扩展的问题。

redis主从复制

redis

27.jpg

主从模式(master/slave) ,能够实现Redis数据的跨主机备份。

程序端链接到高可用负载的VIP,而后链接到负载服务器设置的Redis后端real server,此模式不须要在程序里面配置Redis服务器的真实IP地址,当后期Redis服务器IP地址发生变动只须要更改redis相应的后端real server便可,可避免更改程序中的IP地址设置。

主从复制特色
一个master能够有多个slave一个slave只能有一个master
数据流向是单向的,master到slave

主从复制实现

Redis Slave也要开启持久化并设置和master一样的链接密码,由于后期slave会有提高为master的可能,Slave端切换master同步后会丢失以前的全部数据,而经过持久化能够恢复数据
一旦某个Slave成为一个master的slave,Redis Slave服务会清空当前redis服务器上的全部数据并将master的数据导入到本身的内存,可是若是只是断开同步关系后,则不会删除当前已经同步过的数据。

当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。不然的话,因为延迟等问题,部署的服务应该要避免自动启动。
参考案例:致使主从服务器数据所有丢失

1.假设节点A为主服务器,而且关闭了持久化。而且节点B和节点c从节点A复制数据

2.节点A崩溃,而后由自动拉起服务重启了节点A.因为节点A的持久化被关闭了,因此重启以后没有任何数据

3.节点B和节点c将从节点A复制数据,可是A的数据是空的,因而就把自身保存的数据副本删除。

在关闭主服务器上的持久化,并同时开启自动拉起进程的状况下,即使使用Sentinel来实现Redis的高可用性,也是很是危险的。由于主
服务器可能拉起得很是快,以致于Sentinel在配置的心跳时间间隔内没有检测到主服务器已被重启,而后仍是会执行上面的数据丢失的流程。不管什么时候,数据安全都是极其重要的,因此应该禁止主服务器关闭持久化的同时自动启动。

命令行配置

启用主从同步
默认redis 状态为master,须要转换为slave角色并指向master服务器的IP+PORT+Password

REPLICAOF MASTER_IP PORT指令能够启用主从同步复制功能,早期版本使用SLAVEOF指令

127.0.0.1:6379>REPLICAOF MASTER_IP PORT
127.0.0.1:6379> CONFIG SET masterauth <masterpass>
#主服务器上设置密码,便于从服务器链接
127.0.0.1:6379> CONFIG SET requirepass 123456
OK

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:d5959a9e7fdfba312bf00e3a410a30a08891b98c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> set key1 v1-master
OK
127.0.0.1:6379> get key1
"v1-master"

#slave 设置:
[root@C8-34 ~]# 
[root@C8-34 ~]# redis-cli 
127.0.0.1:6379> set key1  v1-slave-34
OK
127.0.0.1:6379> get key1
"v1-slave-34"

127.0.0.1:6379> REPLICAOF 10.0.0.24  6379   #指向主服务器的IP和端口
OK
127.0.0.1:6379> CONFIG SET masterauth 123456 #设置master的密码才能够
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave             #变为从服务器了
master_host:10.0.0.24  #指向master的IP
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:42
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42
127.0.0.1:6379> 
127.0.0.1:6379> get key1   #查看已经同步成功
"v1-master"    

#在master上能够看到slave的信息
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.34,port=6379,state=online,offset=560,lag=1
master_failover_state:no-failover
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:560
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:560
127.0.0.1:6379> 

[root@C8-35 ~]# redis-cli 
127.0.0.1:6379> set key1 v1-slave-28
OK
127.0.0.1:6379> get key1
"v1-slave-28"

删除主从同步

REPLIATOF NO ONE指令能够取消主从复制

#取消复制,在sTave上执行REPLIATOF NO ONE,会断开和master的链接再也不主从复制,但不会清除slave上已有的数据

同步日志

#在master上观察日志
[root@C8-24 ~]# tail /var/log/messages -f
Aug  6 20:44:45 C8-24 systemd[1]: Started dnf makecache.
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Replica 10.0.0.34:6379 asks for synchronization
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Full resync requested by replica 10.0.0.34:6379
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Replication backlog created, my new replication IDs are '2ce4131d3563e9ac2ecef1130fa00b46f6f578a5' and '0000000000000000000000000000000000000000'
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Starting BGSAVE for SYNC with target: disk
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.306 * Background saving started by pid 116940
Aug  6 21:12:38 C8-24 redis-server[4834]: 116940:C 06 Aug 2021 21:12:38.465 * DB saved on disk
Aug  6 21:12:38 C8-24 redis-server[4834]: 116940:C 06 Aug 2021 21:12:38.466 * RDB: 0 MB of memory used by copy-on-write
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.521 * Background saving terminated with success
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.542 * Synchronization with replica 10.0.0.34:6379 succeeded

#在从服务器上看日志
[root@C8-34 ~]# tail /var/log/redis/redis.log -f
22508:S 06 Aug 2021 21:12:38.713 * Full resync from master: 2ce4131d3563e9ac2ecef1130fa00b46f6f578a5:0
22508:S 06 Aug 2021 21:12:38.928 * MASTER <-> REPLICA sync: receiving 3967032 bytes from master
22508:S 06 Aug 2021 21:12:38.952 * MASTER <-> REPLICA sync: Flushing old data
22508:S 06 Aug 2021 21:12:38.952 * MASTER <-> REPLICA sync: Loading DB in memory
22508:S 06 Aug 2021 21:12:39.129 * MASTER <-> REPLICA sync: Finished with success
22508:S 06 Aug 2021 21:17:35.034 * 1 changes in 900 seconds. Saving...
22508:S 06 Aug 2021 21:17:35.039 * Background saving started by pid 22524
22524:C 06 Aug 2021 21:17:35.164 * DB saved on disk
22524:C 06 Aug 2021 21:17:35.165 * RDB: 6 MB of memory used by copy-on-write
22508:S 06 Aug 2021 21:17:35.251 * Background saving terminated with success

修改slave节点配置文件

[root@C8-34 ~]# vim /etc/redis.conf 
replicaof   10.0.0.24 6379
 masterauth 123456

[root@C8-34 ~]# systemctl restart redis

master和slave查看状态

#从服务器查看状态
127.0.0.1:6379> get key1        #同步成功后,slave上的key1信息丢失,从master复制过来新的值
"v1-master"
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:2436
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2436
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2073
repl_backlog_histlen:364

#master上查看状态
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.34,port=6379,state=online,offset=2338,lag=0
master_failover_state:no-failover
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2338
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2338

[root@C8-24 ~]# systemctl stop redis 
#中止master的redis服务: systemct7 stop redis,在s7ave上能够观察到如下现象
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:down      #显示down,表示没法链接master
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:2688
master_link_down_since_seconds:65
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2688
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2073
repl_backlog_histlen:616
127.0.0.1:6379>

slave日志观察

主服务器关闭之后从服务器没法在同步主服务器了

redis
28.jpg

slave状态只读没法写入数据

127.0.0.1:6379> get key1
"v1-master"
127.0.0.1:6379> set key1 v1-slave
(error) READONLY You can't write against a read only replica.

配置不一致

主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据
rename-command命令不一致,如在主节点定义了lfushall,flushdb,从节点没定义,结果执行flushdb,不一样步

#master有一个rename-command flushdb "magedu" ,而islave没有这个配置,则同步时从节点能够看到如下同步错误
3181:S 21 oct 2020 17:34:50.581 # == CRITICAL == This replica is sending anerror to its master: 'unknown command magedu ', with args beginning with: 'after processing the command '<unknown>'

主从复制故障恢复

须要提高新的slave为master

redis
29.jpg

master故障后,只能手动提高一个slave为新master,不支持自动切换。Master的切换会致使
master_replid发生变化, slave以前的master_replid就和当前master不一致从而会引起全部slave的全量同步。

手动提高从节点为主节点

假设当前主节点10.0.0.24故障,提高10.0.0.34为新的master

中止slave同步并提高为新的master

#提高为新主:
127.0.0.1:6379> replicaof no one
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:36e741346c800d3e741affff50bc69b4be7332c7
master_replid2:59e582a48445cd539281c3282ab518b17c285aaf
master_repl_offset:2100
second_repl_offset:2101
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2100
127.0.0.1:6379> 
#测试能够写入数据了
127.0.0.1:6379> set keytest1 vtest1
OK
#添加密码:
127.0.0.1:6379> CONFIG SET requirepass 123456
OK

#修改全部的从节点指向新的master (10.0.0.34)
以10.0.0.38 为例:
127.0.0.1:6379> get key1
"v1-slave-38"
127.0.0.1:6379> SLAVEOF 10.0.0.34 6379
OK
127.0.0.1:6379> CONFIG SET masterauth 123456
OK
127.0.0.1:6379> GET key1
"v1-master"
#查看日志
[root@C8-35 ~]# tail -f /var/log/redis/redis.log 
1977:S 06 Aug 2021 22:38:03.691 * Connecting to MASTER 10.0.0.34:6379
1977:S 06 Aug 2021 22:38:03.691 * MASTER <-> REPLICA sync started
1977:S 06 Aug 2021 22:38:03.691 * Non blocking connect for SYNC fired the event.
1977:S 06 Aug 2021 22:38:03.691 * Master replied to PING, replication can continue...
1977:S 06 Aug 2021 22:38:03.692 * Partial resynchronization not possible (no cached master)
1977:S 06 Aug 2021 22:38:03.696 * Full resync from master: 36e741346c800d3e741affff50bc69b4be7332c7:2162
1977:S 06 Aug 2021 22:38:03.899 * MASTER <-> REPLICA sync: receiving 3967050 bytes from master
1977:S 06 Aug 2021 22:38:03.923 * MASTER <-> REPLICA sync: Flushing old data
1977:S 06 Aug 2021 22:38:03.923 * MASTER <-> REPLICA sync: Loading DB in memory
1977:S 06 Aug 2021 22:38:04.103 * MASTER <-> REPLICA sync: Finished with success

在新的master 10.0.0.34上看slave的状态

[root@C8-34 ~]# redis-cli -a 123456
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:1
slave0:ip=10.0.0.35,port=6379,state=online,offset=2706,lag=0
master_replid:36e741346c800d3e741affff50bc69b4be7332c7
master_replid2:59e582a48445cd539281c3282ab518b17c285aaf
master_repl_offset:2706
second_repl_offset:2101
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2706
127.0.0.1:6379>

实现redis的级联复制

即实现基于Slave节点的Slave

master和slave1节点无需修改,只须要修改slave2及slave3指向slave1作为mater便可

<img src="D:\云计算\31redis\30.png" style="zoom:200%;" />
30.png
master 和slave1无须要修改,只须要修改slave2 和slave3 将slave1做为master便可:

slave1:

[root@C8-34 ~]# sed -rn '287p' /etc/redis.conf  #所链接的masterIP
 replicaof   10.0.0.24 6379
[root@C8-34 ~]# sed -rn '295p' /etc/redis.conf  #所链接的IP的密码
 masterauth 123456

[root@C8-34 ~]# grep 'requirepass *123456'  /etc/redis.conf  #本身主机的密码
requirepass 123456

slave 2 和slave3上执行

[root@C8-23 ~]#  sed -rn '287p' /etc/redis.conf 
 replicaof  10.0.0.34 6379
[root@C8-23 ~]# sed -rn '295p' /etc/redis.conf
 masterauth  123456

或者用命令的方式:

127.0.0.1:6379> REPLICAOF 10.0.0.34 6379
OK
127.0.0.1:6379> CONFIG sET masterauth 123456
OK

在master设置key,观察是否同步

#在master新建key
127.0.0.1:6379> set key2 
v2
OK
127.0.0.1:6379> get key2
"v2"
#在slave1和s1ave和slave3验证key127.0.0.1:6379> get key2
"v2"
#在slave1和s1ave2和slave3都没法新建key127.0.0.1:6379> set key3 v3
(error) READONLY You can't write against a read only replica.

查看master的信息

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:1715
slave_priority:100
slave_read_only:1
connected_slaves:2
slave0:ip=10.0.0.35,port=6379,state=online,offset=1715,lag=0
slave1:ip=10.0.0.23,port=6379,state=online,offset=1715,lag=0
master_replid:cf8b971aa09f6a8cf0b7b969bf3b4054b491ccec
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1715
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1715
127.0.0.1:6379>

查看中间那个slave查看状态

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2 #最近一次与master通讯已通过去多少秒。master_sync_in_progress:0#是否正在与master通讯。
master_sync_in_progress:0
slave_repl_offset:1715 #当前同步的偏移量
slave_priority:100 #s1ave优先级,master故障后值越小越优先同步。s1ave_read_on1y :1
slave_read_only:1
connected_slaves:2
slave0:ip=10.0.0.35,port=6379,state=online,offset=1715,lag=0  #slave的slave节点
slave1:ip=10.0.0.23,port=6379,state=online,offset=1715,lag=0   #slave的slave节点
master_replid:cf8b971aa09f6a8cf0b7b969bf3b4054b491ccec
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1715
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1715
127.0.0.1:6379>

主从复制优化

Redis主从复制分为全量同步和增量同步

首次同步是全量同步,主从同步可让从服务器从主服务器同步数据,并且从服务器还可再有其它的从服务器,即另一台redis服务器能够从一台从服务器进行数据同步,redis的主从同步是非阻塞的,master收到从服务器的psync(2.8版本以前是SYNC)命令,会fork一个子进程在后台执行bgsave命令,并将新写入的数据写入到一个缓冲区中,bgsave执行完成以后,将生成的RDB文件发送给slave,而后master再将缓冲区的内容以redis协议格式再所有发送给slave,slave先删除旧数据,slave将收到后的RDB文件载入本身的内存,再加载全部收到缓冲区的内容从而这样一次完整的数据同步
Redis全量复制通常发生在Slave首次初始化阶段,这时Slave须要将Master上的全部数据都复制一份。

全量同步以后再次须要同步时,从服务器只要发送当前的offset位置(等同于My5QL的binlog的位置)给主服务器,而后主服务器根据相应的位置将以后的数据(包括写在缓冲区的积压数据)发送给从服务器,再次其保存到其内存便可。

主从同步完整过程具体主从同步过程以下:
1)从服务器链接主服务器,发送PSYNC命令
2)主服务器接收到PSYNC命令后,开始执行BGSAVE命令生成RDB快照文件并使用缓冲区记录此后执行的全部写命令
3)主服务器BGSAVE执行完后,向全部从服务器发送RDB快照文件,并在发送期间继续记录被执行的写命令

4)从服务器收到快照文件后丢弃全部旧数据,载入收到的快照至内存
5)主服务器快照发送完毕后,开始向从服务器发送缓冲区中的写命令
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令7〉)后期同步会先发送本身s1ave_repl_offset位置,只同步新增长的数据,再也不全量同步

复制缓冲区(环形队列)配置参数:
#复制缓冲区大小,建议要设置足够大rep1-backlog-size 1mb
#Redis同时也提供了当没有s1ave须要同步的时候,多久能够释放环形队列:rep1-back1og-ttl3600

避免全量复制
·第一次全量复制不可避免,后续的全量复制能够利用小主节点(内存小),业务低峰时进行全量
节点运行ID不匹配:主节点重启会致使RUNID变化,可能会触发全量复制,能够利用故障转移,例如哨兵或集群,而从节点重启动,不会致使全量复制
复制积压缓冲区不足:当主节点生成的新数据大于缓冲区大小,从节点恢复和主节点链接后,会致使全量复制.解决方法将repl-backlog-size 调大

避免复制风暴
单主节点复制风暴
当主节点重启,多从节点复制解决方法:更换复制拓扑

单机器复制风暴
机器宕机后,大量全量复制解决方法:主节点分散多机器

主从同步优化配置

Redis在2.8版本以前没有提供增量部分复制的功能,当网络闪断或者slave Redis重启以后会致使主从之间的全量同步,即从2.8版本开始增长了部分复制的功能。
性能相关配置

rep7-diskless-sync no #是否使用无盘同步RDB文件,默认为no,no为不使用无盘,须要将RDB文件保存到磁盘后再发送给slave,yes为支持无盘,支持无盘就是RDB文件不须要保存至本地磁盘,并且直接经过socket文件发送给s1ave
repl-diskless-sync-delay 5 #diskless时复制的服务器等待的延迟时间
rep7-ping-slave-period 10 #s1ave端向server端发送ping的时间间隔,默认为10秒
rep7-timeout 60 #设置主从ping链接超时时间,超过此值没法链接,master_link_status显示为down,并记录错误日志
rep7-disable-tcp-nodelay no #是否启用TCP_NODELAY,如设置成yes,则redis会合并小的TCP包从而节省带宽,但会增长同步延迟(40ms),形成master与slave数据不一致,假如设置成no,则redismaster会当即发送同步数据,没有延迟,yes关注性能,no关注redis服务中的数据一致性
rep7-backlog-size 1mb #master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程当中间的写入命令,计算公式: rep7-backlog-size = 容许从节点最大中断时长*主实例offset每秒写入量,好比master每秒最大写入64mb,最大容许60秒,那么就要设置为64mb*60秒=3840MB(3.8G),建议此值是设置的足够大
rep7-backlog-tt1 3600#若是一段时间后没有slave链接到master,则backlog size的内存将会被释放。若是值为0则表示永远不释放这部分内存。
slave-priority 100 #s7ave端的优先级设置,值是一个整数,数字越小表示优先级越高。当master故障时将会按照优先级来选择s7ave端进行恢复,若是值设置为0,则表示该s1ave永远不会被选择。
min-rep7icas-to-write 1 #设置一个master的可用s7Tave不能少于多少个,不然master没法执行写
min-s7aves-max-7ag 20 #设置至少有上面数量的slave延迟时间都大于多少秒时,master不接收写操做(拒绝写入)

常见主从复制故障汇总

master密码不对

即配置的master密码不对,致使验证不经过而没法创建主从同步关系。
[root@centos8 ~]#tail -f /var /log /redis/redis .1og
24930:S 20 Feb 2020 13:53:57.029 * connecting to MASTER 10.0.0.8:637924930:S 20 Feb 2020 13:53:57.030 * MASTER <-> REPLICA sync started
24930:S 20 Feb 2020 13:53:57.030 * Non blocking connect for sYNc fired theevent.
24930:s 20 Feb 2020 13:53:57.030 * Master replied to PING,replication cancontinue. . .
24930:S 20 Feb 2020 13:53:57.031 # unable to AUTH to MASTER: -ERR invalidpassword

Redis版本不一致

不一样的redis大版本之间存在兼容性问题,好比:3和4,4和5之间,所以各master和slave之间必须保持版本一致

redis
31.png

没法远程链接

#在开启了安全模式状况下,没有设置bind地址或者密码
[root@centos8 ~]#vim /etc/redis.conf
#bind 127.0.0.1#将此行注释
[root@centos8 ~]#systemctl restart redis

配置不一致

主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据
rename-command命令不一致,如在主节点定义了lfushall,flushdb,从节点没定义,结果执行flushdb,不一样步
#master有一个rename-command flushdb "magedu" ,而is1ave没有这个配置,则同步时从节点能够看到如下同步错误
3181:s 21 oct 2020 17:34:50.581 # == CRITICAL == This replica is sending anerror to its master: 'unknown command magedu ', with args beginning with: 'after processing the command '<unknown>'

redis哨兵(Sentinel)

redis
32.png

3.2.1 redis集群介绍
主从架构没法实现master和slave角色的自动切换,即当master出现redis服务异常、主机断电、磁盘损坏等问题致使master没法使用,而redis主从复制没法实现自动的故障转移(将slave自动提高为新
master),须要手动修改环境配置,才能切换到slave redis服务器,另外也没法横向扩展Redis服务的并行写入性能,当单台Redis服务器性能没法知足业务写入需求的时候,也须要解决以上的两个核心问题,即: 1.master和slave角色的无缝切换,让业务无感知从而不影响业务使用2.可横向动态扩展Redis服务器,从而实现多台服务器并行写入以实现更高并发的目的。
Redis 集群实现方式:
·客户端分片:由应用决定将不一样的KEY发送到不一样的Redis服务器
·代理分片:由代理决定将不一样的KEY发送到不一样的Redis服务器,代理程序如:codis,twemproxy等. Redis Cluster

Sentinel进程是用于监控redis集群中Master主服务器工做的状态,在Master主服务器发生故障的时候,能够实现Master和Slave服务器的切换,保证系统的高可用,此功能在redis2.6+的版本已引用,Redis的哨兵模式到了2.8版本以后就稳定了下来。通常在生产环境也建议使用Redis的2.8版本的之后版本
哨兵(Sentinel)是一个分布式系统,能够在一个架构中运行多个哨兵(sentinel)进程,这些进程使用流言协议(gossip protocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(AgreementProtocols)来决定是否执行自动故障迁移,以及选择哪一个Slave做为新的Master
每一个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master,Slave定时发送消息,以确认对方是否"活"着,若是发现对方在指定配置时间(此项可配置)内未获得回应,则暂时认为对方已离线,也就是所谓的”"主观认为宕机"”(主观:是每一个成员都具备的独自的并且可能相同也可能不一样的意识),英文名称:
Subjective Down,简称SDOWN
有主观宕机,对应的有客观宕机。当"哨兵群"中的多数Sentinel进程在对Master主服务器作出SDOWN的判断,而且经过SENTINEL is-master-down-by-addr命令互相交流以后,得出的Master Server下线判断,这种方式就是"客观宕机"(客观:是不依赖于某种意识而已经实际存在的一切事物),英文名称是:Objectively Down,简称ODOWN
经过必定的vote算法,从剩下的slave从服务器节点中,选一台提高为Master服务器节点,而后自动修改相关配置,并开启故障转移(failover)
Sentinel机制能够解决master和slave角色的自动切换问题,但单个Master的性能瓶颈问题没法解决,相似于MySQL中的MHA功能
Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数
客户端初始化时链接的是Sentinel节点集合,再也不是具体的Redis节点,但Sentinel只是配置中心不是代理。
Redis Sentinel节点与普通redis没有区别,要实现读写分离依赖于客户端程序
redis 3.0以前版本中,生产环境通常使用哨兵模式,但3.0后推出redis cluster功能后,能够支持更大规模的生产环境

sentinel中的三个定时任务
·每10秒每一个sentinel对master和slave执行info

发现slave节点
确认主从关系
·每2秒每一个sentinel经过master节点的channel交换信息(pub/sub)

经过sentinel_:hello频道交互
交互对节点的"见解"和自身信息
·每1秒每一个sentinel对其余sentinel和redis执行ping

实现哨兵

哨兵的准备实现主从复制架构

哨兵的前提是已经实现了一个redis的主从复制的运行环境,从而实现一个一主两从基于哨兵的高可用redis架构
注意: master的配置文件中masterauth 和slave都必须相同全部主从节点的redis.conf中关健配置
范例:

[root@C8-58]#sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf
[root@C8-58]#echo "replicaof 10.0.0.22 6379" >>/etc/redis.conf
[root@C8-58]#systemctl restart redis

<img src="D:\云计算\31redis\33.png" style="zoom: 80%;" />
33.png

[root@C8-22 ~]# grep -e "^bind 0" -e  "^masterauth"  -e "^requirepass" -e "^replicaof"  /etc/redis.conf 
bind 0.0.0.0
masterauth "123456"
requirepass "123456"

[root@C8-58]# grep -e "^bind 0" -e  "^masterauth"  -e "^requirepass" -e "^replicaof"  /etc/redis.conf 
bind 0.0.0.0
masterauth "123456"
requirepass "123456"
replicaof 10.0.0.22 6379

[root@C8-34 ~]# grep -e "^bind 0" -e  "^masterauth"  -e "^requirepass" -e "^replicaof"  /etc/redis.conf
bind 0.0.0.0
replicaof 10.0.0.22 6379
masterauth "123456"
requirepass "123456"

systemctl restart redis

编辑哨兵的配置文件

sentinel配置
Sentinel其实是一个特殊的redis服务器,有些redis指令支持,但不少指令并不支持.默认监听在26379/tcp端口.
哨兵能够不和Redis服务器部署在一块儿,但通常部署在一块儿,全部redis节点使用相同的如下示例的配置文件

#若是是编译安装,在源码目录有sentine1.conf,复制到安装目录便可,如: /apps/redis/etc/sentine1.conf

[root@C8-22 ~]# grep '^[^#]' /etc/redis-sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel.log"
dir "/tmp"   #工做目录
sentinel myid 5e152ed23f189a8a5e2337c7a6f73ccc0e139328  #自动生成的
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.22 6379 2  #指定当前mymaster集群中master服务器的地址和端口 #2为法定人数限制(quorum),即有几个sentine1认为master down了就进行故障转移,通常此值是全部sentine1节点(通常总数是>=3的奇数,如:3,5,7等)的一半以上的整数值,好比,总数是3,即3/2=1.5,取整为2,是master的ODOwN客观下线的依据
sentinel down-after-milliseconds mymaster 3000  #(SDOwN)判断mymaster集群中全部节点的主观下线的时间,单位:毫秒,建议3000
sentinel auth-pass mymaster 123456  #mymaster集群中master的密码,注意此行要在上面行的下面
sentinel config-epoch mymaster 2
protected-mode no
supervised systemd
sentinel leader-epoch mymaster 2
sentinel known-replica mymaster 10.0.0.34 6379
sentinel known-replica mymaster 10.0.0.58 6379
sentinel known-sentinel mymaster 10.0.0.58 26379 0906444c851c4a671d10696aabc4a1370b54dc9b
sentinel known-sentinel mymaster 10.0.0.34 26379 4c3e19074b91564ab99b66eb042913069e951c6f
sentinel current-epoch 2

三个哨兵的配置文件

[root@redis-master ~]#grep -vE "^#|^$"/etc/redis-sentinel.conf
port 26379
daemonize no
pidfile "/var/run/redis-sentinel.pid"
1ogfile "/var/log/redis/sentine1. log"
dir " / tmp"
sentinel monitor mymaster 10.0.0.22 6379 2      #增长此行
sentine1 auth-pass mymaster 123456             #增长此行
sentine1 down-after-mi77iseconds mymaster 3000 #增长此行
sentinel paral1e1-syncs mymaster 1
sentine7 failover-timeout mymaster 180000
sentine1 deny-scripts-reconfig yes
#如下内容自动生成,不须要修改
sentine1 myid 50547f34ed71fd48c197924969937e738a39975b #此行自动生成必须惟一,修改此值需重启redis和sentinel服务
.....
# Generated by CONFIG REWR工TEprotected-mode no
supervised systemd
sentinel 1eader-epoch mymaster 0
sentinel known-replica mymaster 10.0.0.28 6379
sentine1 known-replica mymaster 10.0.0.18 6379
sentinel current-epoch 0
[root@redis-22 ~]#scp /etc/redis-sentinel.conf 10.0.0.58:/etc/
[root@redis-22 ~]#scp /etc/redis-sentinel.conf 10.0.0.34:/etc/

启动哨兵

三台哨兵服务器都要启动

#确保每一个哨兵主机myid不一样,要注释
[root@redi s-s1ave1 ~]#vim /etc/redis-sentinel.conf
#sentine1 myid 50547f34ed71fd48c197924969937e738a39975
[root@redi s-slave2 ~]#vim /etc/redis-sentinel.conf
#sentine1 myid 50547f34ed71fd48c197924969937e738a39975
[root@redis-master ~]#systemctl enable --now redis-sentinel.service
[root@redis-s1ave1 ~]#systemctl enable --now redis-sentinel.service
[root@redis-slave2 ~]#systemctl enable --now redis-sentinel.service

若是是编译安装,在全部哨兵服务器执行下面操做启动哨兵

#vim /apps /redis/etc/sentine1.conf
bind 0.0.0.o
port 26379
daemonize yes
pidfile "redis-sentinel.pid"
logfi1e "sentine1_26379.1og"
dir " /apps/redis/data"
sentine1 monitor mymaster 10.0.0.8 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 15000
sentine1 para11e1-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
#/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf

验证哨兵:

ss -tnl |grep 26379

查看哨兵日志

[root@C8-58]#tail -f /var/log/redis/sentinel.log

当前sentinel状态

在sentinel状态中尤为是最后一行,涉及到masterlP是多少,有几个slave,有几个sentinels,必须是符合所有服务器数量

[root@C8-34 ~]# redis-cli  -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=2,sentinels=3
127.0.0.1:26379> 
#两个s1ave,三个sentine1服务器,若是sentine1s值不符合,检查myid可能冲突

[root@C8-22 ~]#  redis-cli  -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=2,sentinels=3

[root@C8-58]#
[root@C8-58]#redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=2,sentinels=3

中止Redis Master测试故障转移

[root@C8-22 ~]# redis-cli -a 123456 -p 26379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=4,sentinels=3
127.0.0.1:26379> 
#如今的10.0.0.22 是主服务器

[root@C8-22 ~]# systemctl stop redis
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=4,sentinels=3
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.58:6379,slaves=4,sentinels=3
127.0.0.1:26379> 
#10.0.0.22 关闭服务之后 10.0.0.58 变成 主服务了

#日志里面也记录了  10.0.0.58 成为新的主节点
[root@C8-22 ~]# tail -f -n0 /var/log/redis/sentinel.log 
2611:X 07 Aug 2021 18:45:55.427 # +sdown master mymaster 10.0.0.22 6379
2611:X 07 Aug 2021 18:45:55.501 # +new-epoch 8
2611:X 07 Aug 2021 18:45:55.502 # +vote-for-leader 4c3e19074b91564ab99b66eb042913069e951c6f 8
2611:X 07 Aug 2021 18:45:56.188 # +config-update-from sentinel 4c3e19074b91564ab99b66eb042913069e951c6f 10.0.0.34 26379 @ mymaster 10.0.0.22 6379
2611:X 07 Aug 2021 18:45:56.188 # +switch-master mymaster 10.0.0.22 6379 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.23:6379 10.0.0.23 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.34:6379 10.0.0.34 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:59.192 # +sdown slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:59.192 # +sdown slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379

故障转移后的redis配置文件会被自动修改

[root@C8-34 ~]# grep '^replicaof' /etc/redis.conf
replicaof 10.0.0.58 6379

哨兵配置文件的sentinel monitor lP一样也会被修改

[root@C8-34 ~]# grep '^[^#]' /etc/redis-sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel.log"
dir "/tmp"
sentinel myid 4c3e19074b91564ab99b66eb042913069e951c6f
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.58 6379 2   #自动被修改
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster 123456
protected-mode no
supervised systemd
sentinel config-epoch mymaster 8
sentinel leader-epoch mymaster 8
sentinel known-replica mymaster 10.0.0.22 6379
sentinel known-replica mymaster 10.0.0.34 6379
sentinel known-replica mymaster 10.0.0.23 6379
sentinel known-replica mymaster 10.0.0.35 6379
sentinel known-sentinel mymaster 10.0.0.22 26379 5e152ed23f189a8a5e2337c7a6f73ccc0e139328
sentinel known-sentinel mymaster 10.0.0.58 26379 0906444c851c4a671d10696aabc4a1370b54dc9b
sentinel current-epoch 8

[root@C8-22 ~]# grep '^[^#]' /etc/redis-sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel.log"
dir "/tmp"
sentinel myid 5e152ed23f189a8a5e2337c7a6f73ccc0e139328
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.58 6379 2       #自动被修改
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster 123456
sentinel config-epoch mymaster 8
protected-mode no
supervised systemd
sentinel leader-epoch mymaster 8
sentinel known-replica mymaster 10.0.0.23 6379
sentinel known-replica mymaster 10.0.0.22 6379
sentinel known-replica mymaster 10.0.0.34 6379
sentinel known-replica mymaster 10.0.0.35 6379
sentinel known-sentinel mymaster 10.0.0.34 26379 4c3e19074b91564ab99b66eb042913069e951c6f
sentinel known-sentinel mymaster 10.0.0.58 26379 0906444c851c4a671d10696aabc4a1370b54dc9b
sentinel current-epoch 8

当前的新master状态

[root@C8-58]#redis-cli  -a 123456
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   提高为新的master 
connected_slaves:2
slave0:ip=10.0.0.34,port=6379,state=online,offset=2470761,lag=1
slave1:ip=10.0.0.23,port=6379,state=online,offset=2470894,lag=0
master_replid:a0350e113544c867896f36eff8fe98fd9acefba1
master_replid2:bafd8cb985865b7666333ade0d8e53d0f1036b4b
master_repl_offset:2471160
second_repl_offset:2345236
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2290158
repl_backlog_histlen:181003

另外一个slave指向新的master

[root@C8-34 ~]# redis-cli  -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.58
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:2495667
slave_priority:100
slave_read_only:1
connected_slaves:1
slave0:ip=10.0.0.35,port=6379,state=online,offset=2495534,lag=0
master_replid:a0350e113544c867896f36eff8fe98fd9acefba1
master_replid2:bafd8cb985865b7666333ade0d8e53d0f1036b4b
master_repl_offset:2495667
second_repl_offset:2345236
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2288525
repl_backlog_histlen:207143

恢复故障的原master从新加入redis集群

[root@C8-22 ~]# systemctl restart redis
#哨兵自动修改下面的行,指向新的master
[root@C8-22 ~]# grep '^replicaof'  /etc/redis.conf 
replicaof 10.0.0.58 6379
#在原master上观察:
 [root@C8-22 ~]# redis-cli -a 123456  info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.58
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:2580348
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a0350e113544c867896f36eff8fe98fd9acefba1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2580348
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2527147
repl_backlog_histlen:53202
[root@C8-22 ~]# redis-cli -a 123456  -p 26379 info sentinel
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.58:6379,slaves=4,sentinels=3
[root@C8-22 ~]#

观察新master 上日志:

root@C8-58]#tail -f /var/log/redis/sentinel.log
1960:X 07 Aug 2021 18:45:56.256 # +config-update-from sentinel 4c3e19074b91564ab99b66eb042913069e951c6f 10.0.0.34 26379 @ mymaster 10.0.0.22 6379
1960:X 07 Aug 2021 18:45:56.256 # +switch-master mymaster 10.0.0.22 6379 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.34:6379 10.0.0.34 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.23:6379 10.0.0.23 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:59.293 # +sdown slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:59.293 # +sdown slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 19:01:09.748 # -sdown slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 19:01:19.705 * +reboot slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379

sentinel运维

手动让主节点下线redis
34.png
命令行修改优先级

127.0.0.1:6379> set a A
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379> 
[root@C8-58]#redis-cli -a 123456 -h 10.0.0.22
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.0.0.22:6379> set a A
OK

sentine1 failover <masterName>
范例:手动故障转移
[root@centos8 ~]#vim /etc/redis.conf
replica-priority 10 #指定优先级,值越小sentine1会优先将之选为新的master,默为值为100
[root@centos8 ~]#redis-cli -p 26379
127.0.0.1:26379> sentinel failover mymaster
oK
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=4,sentinels=3

#10.0.0.22 再次成为新的master

python链接Sentinel哨兵

[root@C8-34 ~]# vim sentinel_test.py

#!/usr/bin/python3 
import redis
from redis.sentinel import Sentinel
#链接哨兵的服务器
sentinel = Sentinel([('10.0.0.22',26379),('10.0.0.58',26379),('10.0.0.34',26379)],socket_timeout=0.5)
redis_auth_pass= "123456"

#mymaster是配置哨兵模式的redis集群名称,此为默认值,实际名称按照我的部署案例来填写
#获取主服务器地址
master = sentinel.discover_master('mymaster')
print(master)

#获取从服务器的地址
slave = sentinel.discover_slaves('mymaster')
print(slave)

#获取主服务器进行写入
master = sentinel.master_for('mymaster',socket_timeout=0.5,
password=redis_auth_pass,db=0)
w_ret = master.set('name','wang')

#获取从服务器读取(默认是route-roubin)
slave = sentinel.slave_for('mymaster',socket_timeout=0.5,password=redis_auth_pass,db=0)
r_ret = slave.get('name')
print(r_ret)
#输出wang

[root@C8-34 ~]# chmod +x sentinel_test.py 
[root@C8-34 ~]# ./sentinel_test.py 
('10.0.0.22', 6379)
[('10.0.0.23', 6379), ('10.0.0.58', 6379), ('10.0.0.34', 6379)]
b'wang'

redis cluster

redis
35.png
在哨兵sentinel机制中,能够解决redis高可用问题,即当master故障后能够自动将slave提高为
master,从而能够保证redis服务的正常使用,可是没法解决redis单机写入的瓶颈问题,即单机redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素。

早期Redis 分布式集群部署方案:
1.客户端分区︰由客户端程序决定key写分配和写入的redis node,可是须要客户端本身处理写入分配、高可用管理和故障转移等
2.代理方案:基于三方软件实现redis proxy,客户端先链接之代理层,由代理层实现key的写入分配,对客户端来讲是有比较简单,可是对于集群管节点增减相对比较麻烦,并且代理自己也是单点和性能瓶颈。
redis 3.0版本以后推出了无中心架构的redis cluster机制,在无中心的redis集群当中,其每一个节点保存当前节点数据和整个集群状态,每一个节点都和其余全部节点链接

Redis Cluster特色以下:
1.全部Redis节点使用(PING机制)互联
⒉集群中某个节点的是否失效,是由整个集群中超过半数的节点监测都失效,才能算真正的失效

3.客户端不须要proxy便可直接链接redis,应用程序中须要配置有所有的redis服务器IP
4.redis cluster把全部的redis node平均映射到0-16383个槽位(slot)上,读写须要到指定的redisnode上进行操做,所以有多少个redis node至关于redis并发扩展了多少倍,每一个redis node 承担16384/N个槽位
5.Redis cluster预先分配16384个(slot)槽位,当须要在redis集群中写入一个key-value的时候,会使用CRC16(key) mod 16384以后的值,决定将key写入值哪个槽位从而决定写入哪个Redis节点上,从而有效解决单机瓶颈。

[root@C8-22 ~]# sed  -i.bak '/# cluster-enabled yes/a cluster-enabled yes' /etc/redis.conf
[root@C8-22 ~]# sed  -i.bak  '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf'  /etc/redis.conf
[root@C8-22 ~]# sed -i.bak '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no' /etc/redis.conf

sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf

==========================================================================================
sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf

sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no' /etc/redis.conf

==============================================================================================
[root@C8-34 ~]# sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf

执行meet 各个节点之间相互ping 通

[root@C8-22 ~]# ps aux |grep redis
redis       2611  0.3  1.4  53520 11360 ?        Ssl  18:27   0:46 /usr/bin/redis-sentinel 0.0.0.0:26379 [sentinel]
redis       2921  0.1  1.2  56592  9972 ?        Ssl  22:10   0:02 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root        2935  0.0  0.1  12108   972 pts/1    R+   22:35   0:00 grep --color=auto redis
root        2937  0.0  0.1  12108  1072 pts/3    S+   22:35   0:00 grep --color=auto redis
[root@C8-22 ~]# redis-cli  -a 123456 --no-auth-warning cluster nodes
185c2ff48708fb65cfbcf445a7a60fc6ca508246 :6379@16379 myself,master - 0 0 0 connected 5649 5798 15495

root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.21 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.23 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.34 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.35 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.58 6379
OK

#各个节点之间相互的ping 通了
[root@C8-22 ~]# redis-cli  -a 123456 --no-auth-warning cluster nodes
715d2c7dded4d1b944a4ff894d205190a2e275c6 10.0.0.34:6379@16379 slave 92659fe7e61ab39c3db658bed90e534143703c78 0 1628347372228 3 connected
563cebc14be57e76c45ef3b3451218c7646930e4 10.0.0.58:6379@16379 slave 92659fe7e61ab39c3db658bed90e534143703c78 0 1628347373000 3 connected
92659fe7e61ab39c3db658bed90e534143703c78 10.0.0.35:6379@16379 master - 0 1628347370213 3 connected 5649 5798 15495
c7f8594a7e02724c159f2e7edc46cfca8b622f68 10.0.0.21:6379@16379 master - 0 1628347373235 0 connected
185c2ff48708fb65cfbcf445a7a60fc6ca508246 10.0.0.22:6379@16379 myself,slave 715d2c7dded4d1b944a4ff894d205190a2e275c6 0 1628347372000 1 connected
b000b3f13a4a93da220f3f206170db78bf49d04a 10.0.0.23:6379@16379 slave 185c2ff48708fb65cfbcf445a7a60fc6ca508246 0 1628347374243 3 connected

#因为没有创建槽位,没法建立Key
[root@centos8 ~]#redis-cli -a 123456--no-auth-warning set name wang
(error) CLUSTERDOWN Hash slot not served

[root@centos8~]#redis-c1i -h 10.0.0.8 -a 123456 --no-auth-warning clusterinfo
cluster_state:fai7
cluster_slots_assigned : 0
cluster_slots_ok : 0
cluster_slots_pfai1:0
cluster_slots_fai7:0
cluster_known_nodes : 6cluster_size:0
cluster_current_epoch : 5cluster_my_epoch : 3
cluster_stats_messages_ping_sent: 584
cluster_stats_messages_pong_sent : 145
cluster_stats_messages_meet_sent: 8
cluster_stats_messages_sent : 737
cluster_stats_messages_ping_received : 145
cluster_stats_messages_pong_received : 151

为各个master节点指派槽位范围

[root@C8-23 ~]# vim addsolt.sh
#!/bin/bash
host=$1
port=$2
starts=$3
end=$4
pass=123456
for slot in `seq ${starts} ${end}` ;do
        echo slot:$sort
        redis-cli -h ${host} -p ${port} -a ${pass} --no-auth-warning cluster addslots ${slot}
done

#为三个master分配槽位,共16364/3=5,461.333333333333,平均每一个master分配5,461个槽位
[root@centos8 ~]#bash addslot.sh 10.0.0.21  6379  0 5461
[root@centos8 ~]#bash adds1ot.sh 10.0.0.22  6379 5462 10922
[root@centos8 ~]#bash addslot.sh 10.0.0.23  6379 10923 16383

---------------------------------------------------------------------------------------------
root@C8-21 ~]#  redis-cli  -a 123456 --no-auth-warning cluster info 
cluster_state:ok
cluster_slots_assigned:5465
cluster_slots_ok:5465
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:2
cluster_current_epoch:3
cluster_my_epoch:0
cluster_stats_messages_ping_sent:4746
cluster_stats_messages_pong_sent:4013
cluster_stats_messages_meet_sent:1
cluster_stats_messages_fail_sent:4
cluster_stats_messages_update_sent:4
cluster_stats_messages_sent:8768
cluster_stats_messages_ping_received:4009
cluster_stats_messages_pong_received:4181
cluster_stats_messages_meet_received:4
cluster_stats_messages_fail_received:1
cluster_stats_messages_publish_received:2876
cluster_stats_messages_update_received:105
cluster_stats_messages_received:11176

[root@C8-22 ~]# redis-cli  -a 123456 --no-auth-warning cluster info 
cluster_state:ok
cluster_slots_assigned:10924
cluster_slots_ok:10924
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:1
cluster_current_epoch:3
cluster_my_epoch:3
cluster_stats_messages_ping_sent:3541
cluster_stats_messages_pong_sent:3631
cluster_stats_messages_update_sent:757
cluster_stats_messages_sent:7929
cluster_stats_messages_ping_received:3631
cluster_stats_messages_pong_received:3541
cluster_stats_messages_received:7172

[root@C8-23 ~]# redis-cli  -a 123456 --no-auth-warning cluster info
cluster_state:ok
cluster_slots_assigned:10925
cluster_slots_ok:10925
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:1
cluster_current_epoch:3
cluster_my_epoch:3
cluster_stats_messages_ping_sent:5393
cluster_stats_messages_pong_sent:4981
cluster_stats_messages_meet_sent:2
cluster_stats_messages_publish_sent:2869
cluster_stats_messages_update_sent:1
cluster_stats_messages_sent:13246
cluster_stats_messages_ping_received:4978
cluster_stats_messages_pong_received:4828
cluster_stats_messages_meet_received:3
cluster_stats_messages_fail_received:2
cluster_stats_messages_publish_received:2293
cluster_stats_messages_update_received:2
cluster_stats_messages_received:12106
[root@C8-23 ~]# 
------------------------------------------------------------------------------------

#分配槽位后能够建立key      -c 重定向
[root@C8-88-mariadb-bak ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning set a A
(error) MOVED 15495 10.0.0.98:6379
[root@C8-88-mariadb-bak ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  set a A
OK

#当全部的三个master分配完槽位后,能够看到下面信息
[root@C8-21 ~]# redis-cli -h 10.0.0.21 -a 123456  --no-auth-warning cluster nodes
92659fe7e61ab39c3db658bed90e534143703c78 10.0.0.35:6379@16379 master - 0 1628351780000 3 connected 5649 5798 15495
185c2ff48708fb65cfbcf445a7a60fc6ca508246 10.0.0.22:6379@16379 slave 715d2c7dded4d1b944a4ff894d205190a2e275c6 0 1628351783544 3 connected
c7f8594a7e02724c159f2e7edc46cfca8b622f68 10.0.0.21:6379@16379 myself,master - 0 1628351781000 0 connected 0-5461
b000b3f13a4a93da220f3f206170db78bf49d04a 10.0.0.23:6379@16379 slave 185c2ff48708fb65cfbcf445a7a60fc6ca508246 0 1628351780521 3 connected
563cebc14be57e76c45ef3b3451218c7646930e4 10.0.0.58:6379@16379 slave c7f8594a7e02724c159f2e7edc46cfca8b622f68 0 1628351783000 3 connected
715d2c7dded4d1b944a4ff894d205190a2e275c6 10.0.0.34:6379@16379 slave 92659fe7e61ab39c3db658bed90e534143703c78 0 1628351782000 3 connected
[root@C8-21 ~]# redis-cli -h 10.0.0.21 -a 123456  --no-auth-warning cluster info
cluster_state:ok
cluster_slots_assigned:5465
cluster_slots_ok:5465
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:2
cluster_current_epoch:3
cluster_my_epoch:0
cluster_stats_messages_ping_sent:5044
cluster_stats_messages_pong_sent:4298
cluster_stats_messages_meet_sent:1
cluster_stats_messages_fail_sent:4
cluster_stats_messages_update_sent:4
cluster_stats_messages_sent:9351
cluster_stats_messages_ping_received:4294
cluster_stats_messages_pong_received:4479
cluster_stats_messages_meet_received:4
cluster_stats_messages_fail_received:1
cluster_stats_messages_publish_received:2876
cluster_stats_messages_update_received:196
cluster_stats_messages_received:11850

指定各个节点的主从关系

#查看各个节点之间的主次关系:
[root@C8-68-DNS ~]# redis-cli -h 10.0.0.68 -a 123456  --no-auth-warning cluster nodes
73d0503e5289e1d975ea453833f37357b6a771cb 10.0.0.158:6379@16379 master - 0 1628381587000 5 connected
8968f3f46e326cb95d1a21b07d8d9c143c679608 10.0.0.138:6379@16379 master - 0 1628381588129 4 connected
46342d277e8f6d769e70e07061bce5ee652869f3 10.0.0.178:6379@16379 master - 0 1628381589138 3 connected
8a4dbebf4675d4433aa6225f63d99faf41703f8b 10.0.0.68:6379@16379 myself,master - 0 1628381588000 2 connected 0-5461
2453a2fa33c90b67bd36407bbc1dbc8fa713992a 10.0.0.88:6379@16379 master - 0 1628381586113 1 connected 5462-10922
95af9d679b1510c654d778a38155cfacbee4331d 10.0.0.98:6379@16379 master - 0 1628381588000 0 connected 10923-16383

[root@C8-68-DNS ~]# redis-cli -a 123456 --no-auth-warning -h 10.0.0.158  cluster replicate  8a4dbebf4675d4433aa6225f63d99faf41703f8b
OK
[root@C8-68-DNS ~]# redis-cli -a 123456 --no-auth-warning -h 10.0.0.138  cluster replicate 2453a2fa33c90b67bd36407bbc1dbc8fa713992a
OK
[root@C8-68-DNS ~]# redis-cli -a 123456 --no-auth-warning -h 10.0.0.178  cluster replicate 95af9d679b1510c654d778a38155cfacbee4331d
OK

#都成为从节点
10.0.0.158 
10.0.0.138
10.0.0.178 

[root@C8-68-DNS ~]#  redis-cli  -a 123456 --no-auth-warning cluster info 
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:2
cluster_stats_messages_ping_sent:4699
cluster_stats_messages_pong_sent:4487
cluster_stats_messages_meet_sent:9
cluster_stats_messages_sent:9195
cluster_stats_messages_ping_received:4487
cluster_stats_messages_pong_received:4499
cluster_stats_messages_received:8986

#确节点关系之后能够看到主从信息,例如:
[root@C8-88-mariadb-bak ~]# redis-cli -h 10.0.0.68 -a 123456 --no-auth-warning info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.158,port=6379,state=online,offset=1498,lag=0
master_replid:a8a4a351de058b1c9e878f9acf92d693077a790e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1512
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1512
[root@C8-88-mariadb-bak ~]# redis-cli -h 10.0.0.158 -a 123456 --no-auth-warning info replication
# Replication
role:slave
master_host:10.0.0.68
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:1526
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a8a4a351de058b1c9e878f9acf92d693077a790e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1526
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1526

查看主从节关系及槽位信息

[root@C8-98-slave-DNS ~]# redis-cli -a 123456 -h 10.0.0.98   --no-auth-warning  cluster slots
1) 1) (integer) 10923
   2) (integer) 16383
   3) 1) "10.0.0.98"
      2) (integer) 6379
      3) "95af9d679b1510c654d778a38155cfacbee4331d"
   4) 1) "10.0.0.178"
      2) (integer) 6379
      3) "46342d277e8f6d769e70e07061bce5ee652869f3"
2) 1) (integer) 0
   2) (integer) 5461
   3) 1) "10.0.0.158"
      2) (integer) 6379
      3) "73d0503e5289e1d975ea453833f37357b6a771cb"
   4) 1) "10.0.0.68"
      2) (integer) 6379
      3) "8a4dbebf4675d4433aa6225f63d99faf41703f8b"
3) 1) (integer) 5462
   2) (integer) 10922
   3) 1) "10.0.0.88"
      2) (integer) 6379
      3) "2453a2fa33c90b67bd36407bbc1dbc8fa713992a"
   4) 1) "10.0.0.138"
      2) (integer) 6379
      3) "8968f3f46e326cb95d1a21b07d8d9c143c679608"

或者不写主机IP
redis-cli -a 123456    --no-auth-warning  cluster slots

验证redis访问:

-c 表示以集群的方式

[root@C8-98-slave-DNS ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -c   -a 123456 -h 10.0.0.68  --no-auth-warning   set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -c   -a 123456 -h 10.0.0.68  --no-auth-warning   set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  get d
"D"

实战案例:基于Redis 5的redis cluster部署

官方文档: https://redis.io/topics/cluster-tutorial
redis cluster相关命令
范例:查看--cluster 选项帮助

[root@C8-98-slave-DNS ~]# redis-cli  --cluster help
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN
                 --cluster-replicas <arg>
  check          host:port
                 --cluster-search-multiple-owners
  info           host:port
  fix            host:port
                 --cluster-search-multiple-owners
  reshard        host:port
                 --cluster-from <arg>
                 --cluster-to <arg>
                 --cluster-slots <arg>
                 --cluster-yes
                 --cluster-timeout <arg>
                 --cluster-pipeline <arg>
                 --cluster-replace
  rebalance      host:port
                 --cluster-weight <node1=w1...nodeN=wN>
                 --cluster-use-empty-masters
                 --cluster-timeout <arg>
                 --cluster-simulate
                 --cluster-pipeline <arg>
                 --cluster-threshold <arg>
                 --cluster-replace
  add-node       new_host:new_port existing_host:existing_port
                 --cluster-slave
                 --cluster-master-id <arg>
  del-node       host:port node_id
  call           host:port command arg arg .. arg
  set-timeout    host:port milliseconds
  import         host:port
                 --cluster-from <arg>
                 --cluster-copy
                 --cluster-replace
  help           

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

#手动修改配置文件

[root@redis-node1 ~]vim /etc/redis.conf
bind 0.0.0.0
masterauth 123456#建议配置,不然后期的master和s7ave主从复制没法成功,还需再配置requirepass 123456
cluster-enabled yes #取消此行注释,必须开启集群,开启后redis进程会有cluster显示cluster-config-file nodes-6379.conf #取消此行注释,此为集群状态文件,记录主从关系及s7ot范围信息,由redis cluster集群自动建立和维护
cluster-require-ful7-coverage no#默认值为yes,设为no能够防止一个节点不可用致使整个cluster不可能

#或者执行命令:

#从新安装redis,修改配置文件
sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf
#重启服务
#此时的集群之间是没有任何关系的
[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456  cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,master - 0 0 0 connected

systemctl restart redis

meet --->设置槽位---->设置主从
如今一条命令搞定:

#注意进程有[cluster]状态
[root@C8-178-mariadb-slave-1 ~]# ps -ef |grep redis
redis      25848       1  0 09:32 ?        00:00:00 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root       25863   25024  0 09:42 pts/1    00:00:00 grep --color=auto redis

建立集群:

1.每一个redis 节点采用相同的硬件配置、相同的密码、相同的redis版本

⒉.全部redis服务器必须没有任何数据

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 --cluster create 10.0.0.68:6379 10.0.0.88:6379 10.0.0.98:6379 10.0.0.178:6379 10.0.0.138:6379  10.0.0.168:6379 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.178:6379 to 10.0.0.68:6379
Adding replica 10.0.0.138:6379 to 10.0.0.88:6379
Adding replica 10.0.0.168:6379 to 10.0.0.98:6379
M: a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379
   slots:[0-5460] (5461 slots) master
M: 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379
   slots:[5461-10922] (5462 slots) master
M: 4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379
   slots:[10923-16383] (5461 slots) master
S: 50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379
   replicates a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33
S: d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379
   replicates 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5
S: ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379
   replicates 4f5221ac1cce03a4f57807cb51b09f53ad154f02
Can I set the above configuration? (type 'yes' to accept): yes  #输入yes 建立槽位
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379     # M 为master
   slots:[0-5460] (5461 slots) master #当前槽位的起始位置    已经分配到得槽位
   1 additional replica(s)  #分配一个从节点
M: 4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379   # S为slave
   slots: (0 slots) slave
   replicates a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33
S: ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379
   slots: (0 slots) slave   #没有分配到槽位
   replicates 4f5221ac1cce03a4f57807cb51b09f53ad154f02  #对应的master的ID
M: 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5
[OK] All nodes agree about slots configuration.  #全部槽位分配完成
>>> Check for open slots... #检查打开的槽位
>>> Check slots coverage... #检查槽位的覆盖的范围
[OK] All 16384 slots covered.  #全部的槽位分配完成

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379@16379 master - 0 1628389147000 1 connected 0-5460
ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379@16379 slave 4f5221ac1cce03a4f57807cb51b09f53ad154f02 0 1628389148009 3 connected
d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379@16379 slave 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 0 1628389147000 5 connected
4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379@16379 master - 0 1628389144000 3 connected 10923-16383
5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379@16379 master - 0 1628389149016 2 connected 5461-10922
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,slave a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 0 1628389148000 4 connected

查看主从状态

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456  info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.68
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:448
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a45e1f15dd97baf651b38adad678bc8a62fbea09
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:448
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:448
[root@C8-178-mariadb-slave-1 ~]#

查看指定master节点的slave节点信息

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster info
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:220
cluster_stats_messages_pong_sent:227
cluster_stats_messages_meet_sent:2
cluster_stats_messages_sent:449
cluster_stats_messages_ping_received:224
cluster_stats_messages_pong_received:222
cluster_stats_messages_meet_received:3
cluster_stats_messages_received:449

如下命令查看指定master节点的slave节点信息,其中

a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 为主节点信息

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379@16379 master - 0 1628391529000 1 connected 0-5460
ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379@16379 slave 4f5221ac1cce03a4f57807cb51b09f53ad154f02 0 1628391531536 3 connected
d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379@16379 slave 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 0 1628391530000 5 connected
4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379@16379 master - 0 1628391530528 3 connected 10923-16383
5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379@16379 master - 0 1628391528512 2 connected 5461-10922
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,slave a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 0 1628391530000 4 connected
[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456   cluster slaves a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
1) "50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,slave a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 0 1628391537000 4 connected"
[root@C8-178-mariadb-slave-1 ~]#

验证群集状态

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster info
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6 #节点数
cluster_size:3       #三个群集
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:3254
cluster_stats_messages_pong_sent:3248
cluster_stats_messages_meet_sent:2
cluster_stats_messages_sent:6504
cluster_stats_messages_ping_received:3245
cluster_stats_messages_pong_received:3256
cluster_stats_messages_meet_received:3
cluster_stats_messages_received:6504
[root@C8-178-mariadb-slave-1 ~]# 

#查看容易节点的群集状态:

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 --cluster info 10.0.0.168:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.0.0.68:6379 (a0fe49b2...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.88:6379 (5cfc8c2f...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.98:6379 (4f5221ac...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.

查看集群node对应关系

[root@redis-node1 ~]#redis-cli -a 123456 CLUSTER NODES

验证集群写入key

redis

redis cluster写入key

#通过算法计算,当前key的槽位须要写入指定的node
[root@redis-node1 ~]#redis-cli -a 123456 -h 10.0.0.8 SET key1 values1
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
(error)MOVED 9189 10.0.0.18:6379#槽位不在当前node因此没法写入
[root@redis-node1 ~]#redis-cli -a 123456 -h 10.0.0.18 SET key1 values1
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
oK
#指定node可写入
[root@redis-node1 ~]#redis-c1i -a 123456 -h 10.0.0.18 GET key1
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
"values1"
#对应的slave节点能够KEYS*,但GET key1失败,能够到master上执行GET key1
[root@redis-node1 ~]#redis-cli -a 123456 -h 10.0.0.48 KEYS "*"
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
1) "key1"
[root@redis-nodel ~]#redis-cli -a 123456 -h 10.0.0.48 GET key1
warning: using a password with '-a' or '-u' option on the command 1ine interfacemay not be safe.
(error) MOVED 9189 10.0.0.18:6379

redis cluster 计算key 所属的 slot

[root@C8-178-mariadb-slave-1 ~]# 
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.178 -a 123456 --no-auth-warning cluster keyslot hello
(integer) 866  #查看所属的槽位
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.178 -a 123456 --no-auth-warning set hello magedu
(error) MOVED 866 10.0.0.68:6379
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.68 -a 123456 --no-auth-warning set hello magedu
OK
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.178 -a 123456 --no-auth-warning cluster keyslot name
(integer) 5798
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.68 -a 123456 --no-auth-warning set name wang
(error) MOVED 5798 10.0.0.88:6379
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.88 -a 123456 --no-auth-warning set name wang
OK
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.88 -a 123456 --no-auth-warning get name
"wang"

#使用-c 用集群模式
[root@C8-178-mariadb-slave-1 ~]# redis-cli  -c   -h 10.0.0.88 -a 123456 --no-auth-warning cluster keyslot linux
(integer) 12299
[root@C8-178-mariadb-slave-1 ~]# redis-cli  -c   -h 10.0.0.88 -a 123456 --no-auth-warning set linux love
OK
[root@C8-178-mariadb-slave-1 ~]# redis-cli  -c   -h 10.0.0.88 -a 123456 --no-auth-warning get linux
"love"

模拟master故障,对应的slave节点自动提高为新master

[root@C8-68-DNS ~]# redis-cli -a 123456 
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> shutdown   #关闭服务
not connected> exit
[root@C8-68-DNS ~]# ss -tnl
State                Recv-Q               Send-Q                             Local Address:Port                              Peer Address:Port               
LISTEN               0                    10                                     127.0.0.1:53                                     0.0.0.0:*                  
LISTEN               0                    128                                      0.0.0.0:22                                     0.0.0.0:*                  
LISTEN               0                    128                                    127.0.0.1:953                                    0.0.0.0:*                  
LISTEN               0                    10                                         [::1]:53                                        [::]:*                  
LISTEN               0                    128                                         [::]:22                                        [::]:*                  
LISTEN               0                    128                                            *:23                                           *:*                  
LISTEN               0                    128                                        [::1]:953                                       [::]:*                  

[root@C8-68-DNS ~]# redis-cli -a 123456 --cluster info 10.0.0.68:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.68:6379: Connection refused
[root@C8-68-DNS ~]# redis-cli -a 123456 --cluster info 10.0.0.88:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.68:6379: Connection refused
10.0.0.88:6379 (5cfc8c2f...) -> 2 keys | 5462 slots | 1 slaves.
10.0.0.178:6379 (50676f5d...) -> 2 keys | 5461 slots | 0 slaves.   #10.0.0.178成为新的master
10.0.0.98:6379 (4f5221ac...) -> 1 keys | 5461 slots | 1 slaves.
[OK] 5 keys in 3 masters.
0.00 keys per slot on average.

[root@C8-68-DNS ~]# redis-cli -a 123456 --cluster check  10.0.0.88:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.68:6379: Connection refused
10.0.0.88:6379 (5cfc8c2f...) -> 2 keys | 5462 slots | 1 slaves.
10.0.0.178:6379 (50676f5d...) -> 2 keys | 5461 slots | 0 slaves.
10.0.0.98:6379 (4f5221ac...) -> 1 keys | 5461 slots | 1 slaves.
[OK] 5 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.0.88:6379)
M: 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379
   slots:[0-5460] (5461 slots) master
S: ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 4f5221ac1cce03a4f57807cb51b09f53ad154f02
M: 4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

[root@C8-68-DNS ~]# redis-cli -a 123456 -h 10.0.0.178 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:0
master_replid:d5e9c0e26314f0fdf735e655f3342427b506ba3d
master_replid2:a45e1f15dd97baf651b38adad678bc8a62fbea09
master_repl_offset:7696
second_repl_offset:7697
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:7696
#重启以前的master
[root@C8-68-DNS ~]# systemctl start redis

#查看配置文件,10.0.0.68 自动成为10.0.0.178的slaves
[root@C8-68-DNS ~]# cat /var/lib/redis/nodes-6379.conf 
d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379@16379 slave 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 0 1628394804924 5 connected
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 master - 0 1628394804924 7 connected 0-5460
ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379@16379 slave 4f5221ac1cce03a4f57807cb51b09f53ad154f02 1628394804917 1628394804916 6 connected
a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379@16379 myself,slave 50676f5d541925735eb930dea4f706b5ef5b456c 0 1628394804916 1 connected
4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379@16379 master - 0 1628394804924 3 connected 10923-16383
5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379@16379 master - 1628394804917 1628394804916 2 connected 5461-10922
vars currentEpoch 7 lastVoteEpoch 0
[root@C8-68-DNS ~]# redis-cli -a 123456 -h 10.0.0.178 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.68,port=6379,state=online,offset=7934,lag=0
master_replid:d5e9c0e26314f0fdf735e655f3342427b506ba3d
master_replid2:a45e1f15dd97baf651b38adad678bc8a62fbea09
master_repl_offset:7934
second_repl_offset:7697
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:7934

实战案例:基于Redis 4的redis cluster部署

准备redis Cluster基本配置
1.每一个redis节点采用相同的硬件配置、相同的密码、相同的redis版本

2.全部redis服务器必须没有任何数据

3.准备三台CentOS7主机,已编译安装好redis,各启动两个redis实例,分别使用6379和6380端口,从而模拟实现6台redis实例

[root@C8-98-slave-DNS ~]# cat redis_instll.sh 
#!/bin/bash
#*****************************************************************************
#*******************************************************************************
. /etc/init.d/functions
#VERSION=redis-6.2.5
VERSION=redis-4.0.14
PASSWORD=123456
INSTALL_DIR=/apps/redis
install(){
yum -y install wget make  gcc jemalloc-devel || { action "软件安装失败,检查网络配置" false;exit;}
wget https://download.redis.io/releases/${VERSION}.tar.gz  || { action "Redis reload faild" false;exit; }
tar xf ${VERSION}.tar.gz
cd ${VERSION}
make PREFIX=${INSTALL_DIR} install && action "Redis 编译完成" || { action "Redis 编译安装失败" false;exit; }
ln -s ${INSTALL_DIR}/bin/redis-* /usr/bin/
mkdir -p ${INSTALL_DIR}/{etc,log,data,run}
cp redis.conf ${INSTALL_DIR}/etc/
sed -i  's/bind 127.0.0.1/bind 0.0.0.0/'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/# requirepass/a requirepass $PASSWORD"'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^dir .*/c dir ${INSTALL_DIR}/data/'     ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/logfile .*/c logfile ${INSTALL_DIR}/log/redis-6397.log'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis-6393.pid'  ${INSTALL_DIR}/etc/redis.conf
sed -i  's/daemonize .*/c  daemonize  yes'  ${INSTALL_DIR}/etc/redis.conf

if id redis &> /dev/null;then
    action "redis 用户存在" false
else
    useradd -r -s /sbin/nologin redis
    action "redis 用户建立成功"
fi

chown -R redis.redis ${INSTALL_DIR}
cat >>/etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
sysctl -p
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.d/rc.local 
chmod +x /etc/rc.d/rc.local
/etc/rc.d/rc.local 
cat > /usr/lib/systemd/system/redis6379.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf  --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
#Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemct  enable --now redis6379  &>/dev/null && action "Redis 启动成功,信息以下:" || { action "redis 启动失败" false;exit; }
redis-cli -a $PASSWORD INFO  server 2>/dev/null
}
install

[root@C8-98-slave-DNS ~]# sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /apps/redis/etc/redis.conf 

[root@C8-98-slave-DNS ~]# ps -ef |grep redis
root        7909       1  0 14:06 ?        00:00:00 /apps/redis/bin/redis-server 0.0.0.0:6379 [cluster]
root        7915    1672  0 14:06 pts/1    00:00:00 grep --color=auto redis

 /apps/redis/bin/redis-server  /apps/redis/etc/redis.conf  #启动服务

 #复制 redis-trib.rb
 [root@C8-68-DNS redis-4.0.14]# cp src/redis-trib.rb /usr/bin/

准备redis-trib.rb工具

Redis 3和4版本须要使用到集群管理工具redis-trib.rb,这个工具是redis官方推出的管理redis集群的工具,集成在redis的源码src目录下,是基于redis提供的集群命令封装成简单、便捷、实用的操做工具,redis-trib.rb是redis做者用ruby开发完成的,centos 7系统yum安装的ruby存在版本较低问题,以下:

[root@C8-68-DNS redis-4.0.14]# ll /usr/bin/redis-trib.rb 
-rwxr-xr-x 1 root root 65991 Aug  8 14:18 /usr/bin/redis-trib.rb
[root@C8-68-DNS redis-4.0.14]# /usr/bin/redis-trib.rb  #缺乏ruby环境没法运行rb脚本
/usr/bin/env: ‘ruby’: No such file or directory

#Centos 7带的ruby版本太低,没法运行上面ruby脚本,须要安装2.3以上版本,安装rubygems依赖ruby自动安装

[root@C8-68-DNS redis-4.0.14]# yum install rubygems -y
[root@C8-68-DNS redis-4.0.14]# gem install redis     #gem至关于python里pip和7inux的yum
Fetching: redis-4.4.0.gem (100%)
Successfully installed redis-4.4.0
1 gem installed

[root@C8-68-DNS redis-4.0.14]# yum install gcc openssl-devel zlib-devel -y

解决ruby版本较低问题:

[root@redis-node1 ~]#yum -y insta1l gcc openss7-deve1 zlib-deve1
[root@redis-node1 ~]#wget https:/ /cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.gz
[root@redis-node1 ~]#tar xf ruby-2.5.5.tar.gz[root@redis-node1 ~]#cd ruby-2.5.5
[root@redis-node1 ruby-2.5.5]# . / configure
[root@redis-node1 ruby-2.5.5]#make -j 2 && make insta77
[root@redis-node1 ruby-2.5.5]#which ruby
/usr/ loca1/bin/ ruby
[root@redis-node1 ruby-2.5.5]#ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260)[x86_64-7inux]
[root@redis-node1 ruby-2.5.5]#exit#注意须要从新登陆

redis-trib.rb仍没法运行错误

[root@redis-node1 ~]#redis-trib.rb -hTraceback (most recent ca17 last):
2 : from /usr/bin/redis-trib.rb:25:in '<main>'
1: from /usr/loca1/1ib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in'require '
/usr/loca1/1ib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in require ' :cannot load such file -- redis (LoadError)

解决上述错误:

[root@redis-node1 ~]#gem install redis -v 4.1.3 #注意须要从新登陆再执行,不然没法识别到新ruby版本
Fetching: redi s-4.1.3.gem (100%)successful1y insta1led redi s-4.1.3Parsing documentation for redis-4.1.3
Insta1ling ri documentation for redis-4.1.3
Done insta7ling documentation for redis after 1 seconds1 gem insta7led
#gem uninsta17 redis能够卸载已安装好redis模块

若是没法在线安装,能够下载redis模块安装包离线安装

#https: / /rubygems.org/gems/redis #先下载redis模块安装包
[root@redis-node1 ~]#gem instal1 -7 redis-4.1.3.gem #安装redis模块

redis-trib.rb命令用法

[root@C8-68-DNS redis-4.0.14]# /usr/bin/redis-trib.rb
Usage: redis-trib <command> <options> <arguments ...>

  create          host1:port1 ... hostN:portN  #建立集群
                  --replicas <arg><arg>#指定每一个master的副本数量,即对应s1ave数量,通常为1
  check           host:port #检查集群信息
  info            host:port #查看集群主机信息
  fix             host:port #修复集群
                  --timeout <arg>
  reshard         host:port  #在线热迁移集群指定主机的slots数据
                  --from <arg>
                  --to <arg>
                  --slots <arg>
                  --yes
                  --timeout <arg>
                  --pipeline <arg>
  rebalance       host:port   #平衡集群中各主机的slot数量
                  --weight <arg>
                  --auto-weights
                  --use-empty-masters
                  --timeout <arg>
                  --simulate
                  --pipeline <arg>
                  --threshold <arg>
  add-node        new_host:new_port existing_host:existing_port  #添加主机到集群
                  --slave
                  --master-id <arg>
  del-node        host:port node_id   #删除主机
  set-timeout     host:port milliseconds  #设置节点的超时时间
  call            host:port command arg arg .. arg #在集群的全部节点上执行命令
  import          host:port  #导入外部的redis服务器的数据到当前的集群
                  --from <arg>
                  --copy
                  --replace
  help            (show this help)

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
[root@C8-68-DNS redis-4.0.14]#

修改redis登陆的密码

[root@C8-68-DNS redis-4.0.14]# find / -name "client.rb"
/usr/local/share/gems/gems/redis-4.4.0/lib/redis/client.rb

[root@C8-68-DNS redis-4.0.14]# grep "password: 123456"  /usr/local/share/gems/gems/redis-4.4.0/lib/redis/client.rb
      password: 123456,

建立集群:

[root@C8-68-DNS redis-4.0.14]# redis-trib.rb create --replicas 1  10.0.0.68:6379 10.0.0.88:6379 10.0.0.98:6379  10.0.0.138:6379 10.0.0.158:6379 10.0.0.168:6379
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
10.0.0.68:6379
10.0.0.88:6379
10.0.0.98:6379
Adding replica 10.0.0.158:6379 to 10.0.0.68:6379
Adding replica 10.0.0.168:6379 to 10.0.0.88:6379
Adding replica 10.0.0.138:6379 to 10.0.0.98:6379
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:0-5460 (5461 slots) master
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:5461-10922 (5462 slots) master
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:10923-16383 (5461 slots) master
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   slots: (0 slots) slave
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

若是有以前的操做致使Redis集群建立报错,则执行清空数据和集群命令:
127.0.0.1:6379> FLUSHALL
127.0.0.1:6379>cluster resetOK

查看redis cluster集群状态

自动生成配置文件记录master/slave对应关系

[root@C8-68-DNS data]# find / -name "nodes-6379.conf"
/root/nodes-6379.conf
[root@C8-68-DNS data]# cat /root/nodes-6379.conf 
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave b8a9fdb19a529d36238eed905bcf7d251e34b059 0 1628407512309 5 connected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628407511000 2 connected 5461-10922
b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379@16379 myself,master - 0 1628407512000 1 connected 0-5460
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628407513000 4 connected
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 master - 0 1628407512000 3 connected 10923-16383
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave 83fb5104b17ab176b08b4679af77548ca9680a0f 0 1628407513318 6 connected
vars currentEpoch 6 lastVoteEpoch 0

查看状态:

[root@C8-68-DNS data]# redis-trib.rb info 10.0.0.168:6379
10.0.0.98:6379 (8dfe226b...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.88:6379 (83fb5104...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.68:6379 (b8a9fdb1...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
[root@C8-68-DNS data]# 

[root@C8-68-DNS data]# redis-cli -a 123456
Warning: Using a password with '-a' option on the command line interface may not be safe.
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:434
cluster_stats_messages_pong_sent:435
cluster_stats_messages_sent:869
cluster_stats_messages_ping_received:430
cluster_stats_messages_pong_received:434
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:869

[root@C8-68-DNS data]# redis-cli -a 123456 -p 6379 cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave b8a9fdb19a529d36238eed905bcf7d251e34b059 0 1628408002000 5 connected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628408004609 2 connected 5461-10922
b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379@16379 myself,master - 0 1628408002000 1 connected 0-5460
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628408001581 4 connected
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 master - 0 1628408002590 3 connected 10923-16383
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave 83fb5104b17ab176b08b4679af77548ca9680a0f 0 1628408003600 6 connected

[root@C8-68-DNS data]# redis-cli -a 123456 -p 6379 info replication
Warning: Using a password with '-a' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.158,port=6379,state=online,offset=756,lag=1
master_replid:3ce3556a1d59ad1d594da1c6900bf45e9d8d3342
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:756
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:756
[root@C8-68-DNS data]#

Redis cluster集群节点维护

redis集群运行以后,不免因为硬件故障、网络规划、业务增加等缘由对已有集群进行相应的调整,好比:增长Redis node节点、减小节点、节点迁移、更换服务器等。增长节点和删除节点会涉及到已有的槽位从新分配及数据迁移。

集群维护之动态扩容
实战案例:
因公司业务发展迅猛,现有的三主三从的redis cluster架构可能没法知足现有业务的并发写入需求,所以公司紧急采购两台服务器10.0.0.68,10.0.0.78,须要将其动态添加到集群当中,但不能影响业务使用和数据丢失。
注意:生产环境通常建议master节点为奇数个,好比:3,5,7,以防止脑裂现象

添加节点准备

增长Redis node节点,须要与以前的Redis node版本相同、配置一致,而后分别再启动两台Redis

node 要是一主一从

#配置两个从节点:

sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/'   /etc/redis.conf

/apps/redis/bin/redis-server /apps/redis/etc/redis.conf

[root@C8-68-DNS ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave,fail 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 1628417548785 1628417548785 4 disconnected
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave,fail b8a9fdb19a529d36238eed905bcf7d251e34b059 1628417548785 1628417548785 5 disconnected
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave,fail 83fb5104b17ab176b08b4679af77548ca9680a0f 1628417548798 1628417548785 6 disconnected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628417790437 2 connected 5461-10922
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 master - 0 1628417792463 3 connected 10923-16383
b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379@16379 myself,master - 0 1628417790000 1 connected 0-5460

添加新的master节点到集群

使用如下命令添加新节点,要添加的新redis节点IP和端口添加到的已有的集群中任意节点的IP:端口
add-node new_host:new_port existing_host:existing_port [--slave --master-id<arg>]
#说明:
new_host:new_port #为新添加的主机的IP和端口
existing_host:existing_port #为已有的集群中任意节点的IP和端口

Redis 3/4添加方式:

#把新的Redis节点10.0.0.19 和10.0.0.20 添加到当前Redis集群当中。
[root@C8-68-DNS ~]# redis-trib.rb add-node 10.0.0.20:6379  10.0.0.68:6379
[root@C8-68-DNS ~]# redis-trib.rb add-node 10.0.0.19:6379  10.0.0.68:6379

Redis 5添加方式:

#将一台新的主机10.0.0.68加入集群,如下示例中10.0.0.58能够是任意存在的集群节点

[root@redis-node1 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.68:6379  <当前任意集群节点>:6379

#观察到该节点已经加入成功,但此节点上没有s1ot位,也无从节点,并且新的节点是master
[root@redis-node1 ~]#redis-cli -a 123456 --cluster info 10.0.0.8:6379
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
10.0.0.8:6379 (cb028b83...) -> 6672 keys | 5461 slots | 1 slaves.10.0.0.68:6379 (d6e2eca6.. .) -> 0 keys | 0 slots | o s1aves.
10.0.0.48:6379 (d04e524d...) -> 6679 keys | 5462 slots | 1 slaves.10.0.0.28:6379 (d34da866...) -> 6649 keys | 5461 slots | 1 slaves.[OK] 20000 keys in 5 masters.

在新的master上从新分配槽位

新的node节点加到集群以后,默认是master节点,可是没有slots,须要从新分配
添加主机以后须要对添加至集群种的新主机从新分片,不然其没有分片也就没法写入数据。

注意:从新分配槽位须要清空数据,因此须要先备份数据,扩展后再恢复数据
Redis 3/4:

[root@redis-node1 ~]# redis-trib.rb check 10.0.0.67:6379   #当前状态
[root@redis-node1 ~]# redis-trib.rb reshard <集群中任意节点>:6379  #从新分片
[root@redis-node1 ~]# redis-trib.rb fix 10.0.0.68:6379#若是迁移失败使用此命令修复集群

Redis 5

[root@redis-node1 ~]#redis-cli -a 123456 --cluster reshard  <当前任意集群节点>:6379
warning: using a password with '-a’ or '-u' option on the command line interfacemay not be safe.
How many slots do you want to move (from 1 to 16384)?4096 #新分配多少个槽位=16384/master个数
what is the receiving node ID? d6e2eca6b338b717923f64866bd31d42e52edc98#新的master的ID
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.Type 'done' once you entered a17 the source nodes IDs.
source node #1: all #将哪些源主机的槽位分配给新的节点,a11是自动在全部的redis node选择划分,若是是从redis cluster删除某个主机能够使用此方式将指定主机上的槽位所有移动到别的redis主机

Do you want to proceed with the proposed reshard plan (yes/no)?yes #确认分配......
Moving slot 12280 from 10.0.0.28:6379 to 10.0.0.68:6379: .Moving slot 12281 from 10.0.0.28:6379 to 10.0.0.68:6379: .Moving slot 12282 from 10.0.0.28:6379 to 10.0.0.68:6379:Moving slot 12283 from 10.0.0.28:6379 to 10.0.0.68:6379: ..Moving slot 12284 from 10.0.0.28:6379 to 10.0.0.68:6379:Moving slot 12285 from 10.0.0.28:6379 to 10.0.0.68:6379: .Moving slot 12286 from 10.0.0.28:6379 to 10.0.0.68:6379:Moving slot 12287 from 10.0.0.28:6379 to 10.0.0.68:6379: ..
[root@redis-node1 ~]#

#肯定s1ot分配成功
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.8:6379
warning: using a password with '-a’or '-u' option on the command line interfacemay not be safe.
10.0.0.8:6379 (cb028b83...) ->5019 keys | 4096 slots | 1 slaves.10.0.0.68:6379 (d6e2eca6...) -> 4948 keys | 4096 slots | 0 slaves.

为新的master添加新的slave节点

先加入集群再修改成slave

须要手动将其指定为某个master的slave,不然其默认角色为master。

#加入到集群
redis-trib.rb add-node 10.0.0.20:6379  10.0.0.68:6379
#登陆到先添加的节点
redis-cli -h 10.0.0.20 -p 6379 -a 123456
#改其为slave
10.0.0.20:6380> CLUSTER NODES #查看当前集群节点,找到目标master的ID
10.0.0.20:6380> CLUSTER REPLICATE 886338acd50c3015be68a760502b239f4509881c #将其设置s1ave,命令格式为cluster replicate MASTERID
10.0.0.78:6380> CLUSTER NODES #再次查看集群节点状态,验证节点是否已经更改成指定master 的

Redis 5添加方式:

#把10.0.0.20:6379添加到集群中:
[root@redis-node1 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.20:6379  10.0.0.19:6379

验证

rides 3/4的验证方法:

[root@C8-68-DNS ~]#  redis-trib.rb   check 10.0.0.68:6379
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)
S: 74e446278d33e4235583f9f64c8c83d69b4d5d66 10.0.0.20:6379
   slots: (0 slots) slave
   replicates 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
M: 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 10.0.0.19:6379
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   1 additional replica(s)
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   slots: (0 slots) slave
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

[root@C8-68-DNS ~]# redis-cli -h 10.0.0.20 -a 123456  cluster info
Warning: Using a password with '-a' option on the command line interface may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:8 #8个节点
cluster_size:4  #4组主从
cluster_current_epoch:7
cluster_my_epoch:7
cluster_stats_messages_ping_sent:6272
cluster_stats_messages_pong_sent:6257
cluster_stats_messages_meet_sent:7
cluster_stats_messages_update_sent:12
cluster_stats_messages_sent:12548
cluster_stats_messages_ping_received:6257
cluster_stats_messages_pong_received:6279
cluster_stats_messages_received:12536

redis 5 的验证方法:

#验证是否成功
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.68:6379

集群维护之动态缩容

因为服务器使用年限已经超过三年,已经超过厂商质保期并且硬盘出现异常报警,经运维部架构师提交方案并同开发同事开会商议,决定将现有Redis集群的8台主服务器中的master 10.0.0.8和对应的slave 10.0.0.38临时下线,三台服务器的并发写入性能足够支出将来1-2年的业务需求
删除节点过程:
添加节点的时候是先添加node节点到集群,而后分配槽位,删除节点的操做与添加节点的操做正好相反,是先将被删除的Redis node上的槽位迁移到集群中的其余Redis node节点上,而后再将其删除,若是一个Redis node节点上的槽位没有被彻底迁移,删除该node的时候会提示有数据且没法删除。
迁移master的槽位之其余master

Redis 3/4版本

[root@redis-node1 ~]# redis-trib.rb reshard 10.0.0.8:6379
[root@redis-node1 ~]# redis-trib.rb fix 10.0.0.8:6379 #若是迁移失败使用此命令修复集群

移动槽位

[root@C8-68-DNS ~]# redis-trib.rb  reshard 10.0.0.68:6379
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)
S: 74e446278d33e4235583f9f64c8c83d69b4d5d66 10.0.0.20:6379
   slots: (0 slots) slave
   replicates 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
M: 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 10.0.0.19:6379
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   1 additional replica(s)
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   slots: (0 slots) slave
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 1365   #移动多少个槽位
What is the receiving node ID? 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25  #移动槽位的机器ID
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1:b8a9fdb19a529d36238eed905bcf7d251e34b059   #接受槽位的机器的ID
Source node #2:done
Do you want to proceed with the proposed reshard plan (yes/no)? yes
以上的步骤重复,将全部的槽位所有移走

root@C8-68-DNS ~]# redis-cli -a 123456 cluster nodes

redis

#删除10.0.0.68 这个节点
[root@C8-68-DNS ~]# redis-trib.rb del-node 10.0.0.98:6379 b8a9fdb19a529d36238eed905bcf7d251e34b059
>>> Removing node b8a9fdb19a529d36238eed905bcf7d251e34b059 from cluster 10.0.0.98:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

[root@C8-68-DNS ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
Could not connect to Redis at 127.0.0.1:6379: Connection refused

#查看如今的节点状态
[root@C8-68-DNS ~]# redis-cli -a 123456 -h 10.0.0.98  cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628481507268 9 connected
74e446278d33e4235583f9f64c8c83d69b4d5d66 10.0.0.20:6379@16379 slave 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 0 1628481508274 7 connected
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 myself,master - 0 1628481506000 9 connected 4095-5460 12288-16383
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628481505253 9 connected
21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 10.0.0.19:6379@16379 master - 0 1628481504245 7 connected 0-2729 5461-6826 10923-12287
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave 83fb5104b17ab176b08b4679af77548ca9680a0f 0 1628481506000 8 connected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628481506261 8 connected 2730-4094 6827-10922
[root@C8-68-DNS ~]#
相关文章
相关标签/搜索