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
用户层:浏览器dns缓存 应用程序dns缓存 代理层 : cdn web层 :web服务器缓存 数据层:分布式缓存:redis 数据库;mysql 系统层:操做系统 cache 物理层:磁盘cache raid cache CPU缓存
浏览器的dns默认是60秒
1 自动过时,例如DNS的TTL ,微信红包
2 强制过时
3 命中率
设置浏览器缓存有下面几种方法
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
会话(Session)跟踪是Web程序中经常使用的技术,用来跟踪用户的整个会话。经常使用的会话跟踪技术是Cookie与Session。Cookie经过在客户端记录信息肯定用户身份 Session经过在服务器端记录信息肯定用户身份。
CDN(Content Delivery Network)是指内容分发网络,也称为内容传送网络 CDN负载均衡系统实现CDN的内容路由功能。它的做用是将用户的请求导向整个CDN网络中的最佳节点。最佳节点的选定能够根据多种策略,例如距离最近、节点负载最轻等。负载均衡系统是整个CDN的核心,负载均衡的准确性和效率直接决定了整个CDN的效率和性能。一般负载均衡能够分为两个层次:全局负载均衡(GSLB)和本地负载均衡(SLB)。全局负载均衡主要的目的是在整个网络范围内将用户的请求定向到最近的节点(或者区域)。所以,就近性判断是全局负载均衡的主要功能。本地负载均衡通常局限于必定的区域范围内,其目标是在特定的区域范围内寻找一台最适合的节点提供服务,所以,CDN节点的健康性、负载状况、支持的媒体格式等运行状态是本地负载均衡进行决策的主要依据。
关系型数据库和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能够作不少内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,由于他们并不须要进行随机访问。
官方下载地址: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之后看日志会报警:
#改第一个内核参数 [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的文件
yum安装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服务启动命令
[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
[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"
[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
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-cli #跨主机无密码链接: redis-cli -h HOSTNAME/IP -p port #跨主机密码链接: redis-cli -h HOSTNAME/IP -p port -a PASSWORD
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)
[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 :免报警提示
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命令用于查看当前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"
#永久修改,改配置文件 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
临时修改的没法永久保存
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秒
两点说明:
(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 专门提供了一组命令来查询慢查询日志:
获取慢查询日志: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是Redis用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中全部键值对数据)。恢复时是将快照文件直接读到内存里。RDB其实就是把数据以快照的形式保存在磁盘上。RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
RDB 有两种触发方式,分别是自动触发和手动触发
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提供了bgsave方式
二、bgsave 异步后台执行
执行该命令时,Redis会在后台异步进行快照操做,快照同时还能够响应客户端请求。具体操做是Redis进程执行fork操做建立子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,通常时间很短。
基本上 Redis 内部全部的RDB操做都是采用 bgsave 命令。
执行执行 flushall 命令,也会产生dump.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 #路径
save:同步,会阻赛其它命令,不推荐使用 bgsave:异步后台执行,不影响其它命令的执行 自动:制定规则,自动执行
RDB快照保存了某个时间点的数据,能够经过脚本执行redis指令bgsave(非阻塞,后台执行)或者save(会阻塞写操做,不推荐)命令自定义时间点备份,能够保留多个备份,当出现问题能够恢复到不一样时间点的版本,很适合备份,而且此文件格式也支持有很多第三方工具能够进行后续的数据分析
好比:能够在最近的24小时内,每小时备份一次RDB文件,而且在每月的每一天,也备份一个ROB文件。这样的话,即便赶上问题,也能够随时将数据集还原到不一样的版本。
RDB能够最大化Redis的性能,父进程在保存RDB文件时惟一要作的就是fork出一个子进程,而后这个子进程就会处理接下来的全部保存工做,父进程无须执行任何磁盘 I/O操做。
RDB在大量数据,好比几个G的数据,恢复的速度比AOF的快
不能实时保存数据,可能会丢失自上一次执行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)
[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
[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 ]
优先级高于rdb
将一些重复的能够合并的,过时的数据从新写入一个新的AOF文件,从而节约AOF备份占用的硬盘空间,也能加速恢复过程
能够手动执行bgrewriteaof触发AOF,或定义自动rewrite策略
AOF rewrite过程
#开启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
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仅仅用于手动触发重写操做。
数据安全性相对较高,根据所使用的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的文件大小要大于RDB格式的文件 AOF在恢复大数据集时的速度比RDB的恢复速度要慢 根据fsync策略不一样,AOF速度可能会慢于RDB bug 出现的可能性更多
若是主要充当缓存功能,或者能够承受数分钟数据的丢失, 一般生产环境通常只需启用RDB可,此也是默认值
注意!!!: 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
[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都设为同样的值,让其自动选择
官方文档:https://redis.io/commands
参考连接: http://redisdoc.com/
#设置有效期: 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"
显示当前节点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
切换数据库,至关于在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
查看当前库下的全部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''
手动在后台执行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
返回当前库下的全部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
强制清空当前库中的全部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>
强制清空当前redis服务器全部数据库中的全部key,即删除全部数据,此命令慎用! 127.0.0.1:6379>FLUSHALL OK #生产建议修改配置/etc/redis.confrename-command FLUSHALL ""
可用版本:>= 1.0.0 时间复杂度:O(N),其中 N为关机时须要保存的数据库键数量。SHUTDOWN命令执行如下操做: 中止全部客户端 若是有至少一个保存点在等待,执行SAVE命令 若是AOF选项被打开,更新AOF文件 关闭redis 服务器(server) 若是持久化被打开的话,SHUTDOWN命令会保证服务器正常关闭而不丢失任何数据。 另外一方面,假如只是单纯地执行SAVE命令,而后再执行QUIT命令,则没有这一保证--由于在执行SAVE以后、执行 QUIT以前的这段时间中间,其余客户端可能正在和服务器进行通信,这时若是执行QUIT就会形成数据丢失。
参考资料: http://www.redis.cn/topics/data-types.html
相关命令参考: http://redisdoc.com/
字符串是全部编程语言中最多见的和最经常使用的数据类型,并且也是redis最基本的数据类型之一,并且redis 中全部的key的类型都是字符串。经常使用于保存Session信息场景,此数据类型比较经常使用
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)
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
127.0.0.1:6379> DEL key1 (integer) 1 127.0.0.1:6379>DEL key1 key2 (integer) 2
127.0.0.1:6379>MSET key1 value1 key2 value2 oK
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
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
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"
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>
#即永不过时 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
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"
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是一个string类型的字段(field)和值(value)的映射表,Redis 中每一个hash能够存储2^32-1键值对,相似于字典,存放了多个k/v对,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"
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>
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"
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"
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>
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"
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"
127.0.0.1:6379> HGETALL 9527 1) "name" 2) "zhouxingxing" 3) "age" 4) "50" 5) "city" 6) "hongkong" 127.0.0.1: 6379>
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等。
队列当中的消息由不一样的生产者写入,也会有不一样的消费者取出进行消费处理,可是一个消息必定是只能被取出一次也就是被消费一次。
[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能够实现单机的数据持久化,但不管是RDB也好或者AOF也好,都解决不了单点宕机问题,即一旦单台redis服务器自己出现系统故障、硬件故障等问题后,就会直接形成数据的丢失
此外单机的性能也是有极限的,所以须要使用另外的技术来解决单点故障和性能扩展的问题。
主从模式(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
[root@C8-34 ~]# vim /etc/redis.conf replicaof 10.0.0.24 6379 masterauth 123456 [root@C8-34 ~]# systemctl restart redis
#从服务器查看状态 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>
主服务器关闭之后从服务器没法在同步主服务器了
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
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>
即实现基于Slave节点的Slave
master和slave1节点无需修改,只须要修改slave2及slave3指向slave1作为mater便可
<img src="D:\云计算\31redis\30.png" style="zoom:200%;" />
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 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.
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>
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密码不对,致使验证不经过而没法创建主从同步关系。 [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大版本之间存在兼容性问题,好比:3和4,4和5之间,所以各master和slave之间必须保持版本一致
#在开启了安全模式状况下,没有设置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>'
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%;" />
[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状态中尤为是最后一行,涉及到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
[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
[root@C8-34 ~]# grep '^replicaof' /etc/redis.conf replicaof 10.0.0.58 6379
[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
[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
[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
手动让主节点下线
命令行修改优先级
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
[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'
在哨兵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
[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
[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
-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"
官方文档: 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 ~]#
[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.
[root@redis-node1 ~]#redis-cli -a 123456 CLUSTER NODES
#通过算法计算,当前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
[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"
[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 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 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
[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#注意须要从新登陆
[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模块
[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]#
[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集群运行以后,不免因为硬件故障、网络规划、业务增加等缘由对已有集群进行相应的调整,好比:增长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
使用如下命令添加新节点,要添加的新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节点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
#将一台新的主机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.
新的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#若是迁移失败使用此命令修复集群
[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,不然其默认角色为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 的
#把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
[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
#验证是否成功 [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
[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
#删除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 ~]#