# prototype-redis **Repository Path**: cllyl/prototype-redis ## Basic Information - **Project Name**: prototype-redis - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-12-05 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Redis学习记录 ## 官网说明 #### 官网地址 [https://redis.io](https://redis.io/) #### Gitee地址 https://gitee.com/mirrors/redis #### 官网下载地址 https://redis.io/download ## 安装 #### 环境说明 ###### 操作系统 ```shell [root@YL-MASTER ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@YL-MASTER ~]# uname -a Linux YL-MASTER 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux [root@YL-MASTER ~]# cat /proc/version Linux version 3.10.0-862.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) ) #1 SMP Fri Apr 20 16:44:24 UTC 2018 ``` ###### Redis版本 ``` 6.0.9最新的稳定版本 ``` #### 操作记录 ###### 进入下载目录 ``` [root@YL-MASTER install]# pwd /usr/local/custom-util/redis/install ``` ###### 配置本地yum源 > 建立挂载点 ```shell mkdir /mnt/cdrom ``` > 备份自带的yum源仓库配置文件 ```shell [root@YL-MASTER /]# cd /etc/yum.repos.d/ [root@YL-MASTER yum.repos.d]# pwd /etc/yum.repos.d # 创建备份目录 mkdir repo-back # 移动配置文件到备份目录 mv ./*.repo ./repo-back ``` > 创建本地yum源配置文件 ```shell touch local.repo [root@YL-MASTER yum.repos.d]# ls local.repo repo-back vim local.repo [root@YL-MASTER yum.repos.d]# cat local.repo [local] name=local baseurl=file:///mnt/cdrom/ enable=1 gpgcheck=0 ``` > 挂载本地镜像文件 ```shell mount /dev/cdrom /mnt/cdrom ``` > 清除yum缓存 ```shell yum clean all [root@YL-MASTER yum.repos.d]# yum makecache 已加载插件:fastestmirror Loading mirror speeds from cached hostfile local | 3.6 kB 00:00:00 (1/2): local/other_db | 1.3 MB 00:00:00 (2/2): local/filelists_db | 3.1 MB 00:00:00 元数据缓存已建立 [root@YL-MASTER yum.repos.d]# yum repolist 已加载插件:fastestmirror Loading mirror speeds from cached hostfile 源标识 源名称 状态 local local 3,971 repolist: 3,971 ``` ###### 安装wget命令 ```shell yum install -y wget ``` ###### 下载安装包 > 使用wget下载安装包 ```shell wget https://download.redis.io/releases/redis-6.0.9.tar.gz ``` > 本地下载安装包之后上传到虚拟机 ```shell [root@YL-MASTER install]# pwd /usr/local/custom-util/redis/install [root@YL-MASTER install]# ls redis-6.0.9.tar.gz ``` ###### 解压缩安装包 ```shell tar -zxvf install/redis-6.0.9.tar.gz -C station/ [root@YL-MASTER redis-6.0.9]# pwd /usr/local/custom-util/redis/station/redis-6.0.9 [root@YL-MASTER redis-6.0.9]# ll 总用量 288 -rw-rw-r--. 1 root root 108806 10月 27 15:12 00-RELEASENOTES -rw-rw-r--. 1 root root 51 10月 27 15:12 BUGS -rw-rw-r--. 1 root root 2499 10月 27 15:12 CONTRIBUTING -rw-rw-r--. 1 root root 1487 10月 27 15:12 COPYING drwxrwxr-x. 6 root root 124 10月 27 15:12 deps -rw-rw-r--. 1 root root 11 10月 27 15:12 INSTALL -rw-rw-r--. 1 root root 151 10月 27 15:12 Makefile -rw-rw-r--. 1 root root 6888 10月 27 15:12 MANIFESTO -rw-rw-r--. 1 root root 21099 10月 27 15:12 README.md -rw-rw-r--. 1 root root 84841 10月 27 15:12 redis.conf -rwxrwxr-x. 1 root root 275 10月 27 15:12 runtest -rwxrwxr-x. 1 root root 280 10月 27 15:12 runtest-cluster -rwxrwxr-x. 1 root root 795 10月 27 15:12 runtest-moduleapi -rwxrwxr-x. 1 root root 281 10月 27 15:12 runtest-sentinel -rw-rw-r--. 1 root root 10744 10月 27 15:12 sentinel.conf drwxrwxr-x. 3 root root 4096 10月 27 15:12 src drwxrwxr-x. 11 root root 182 10月 27 15:12 tests -rw-rw-r--. 1 root root 3055 10月 27 15:12 TLS.md drwxrwxr-x. 9 root root 4096 10月 27 15:12 utils ``` ###### 安装gcc环境 因为Redis是由C编写的,所以需要C的编译环境 ````shell [root@YL-MASTER redis-6.0.9]# yum install -y gcc 已加载插件:fastestmirror Loading mirror speeds from cached hostfile 正在解决依赖关系 --> 正在检查事务 ---> 软件包 gcc.x86_64.0.4.8.5-28.el7 将被 安装 --> 正在处理依赖关系 cpp = 4.8.5-28.el7,它被软件包 gcc-4.8.5-28.el7.x86_64 需要 --> 正在处理依赖关系 glibc-devel >= 2.2.90-12,它被软件包 gcc-4.8.5-28.el7.x86_64 需要 --> 正在处理依赖关系 libmpfr.so.4()(64bit),它被软件包 gcc-4.8.5-28.el7.x86_64 需要 --> 正在处理依赖关系 libmpc.so.3()(64bit),它被软件包 gcc-4.8.5-28.el7.x86_64 需要 --> 正在检查事务 ---> 软件包 cpp.x86_64.0.4.8.5-28.el7 将被 安装 ---> 软件包 glibc-devel.x86_64.0.2.17-222.el7 将被 安装 --> 正在处理依赖关系 glibc-headers = 2.17-222.el7,它被软件包 glibc-devel-2.17-222.el7.x86_64 需要 --> 正在处理依赖关系 glibc-headers,它被软件包 glibc-devel-2.17-222.el7.x86_64 需要 ---> 软件包 libmpc.x86_64.0.1.0.1-3.el7 将被 安装 ---> 软件包 mpfr.x86_64.0.3.1.1-4.el7 将被 安装 --> 正在检查事务 ---> 软件包 glibc-headers.x86_64.0.2.17-222.el7 将被 安装 --> 正在处理依赖关系 kernel-headers >= 2.2.1,它被软件包 glibc-headers-2.17-222.el7.x86_64 需要 --> 正在处理依赖关系 kernel-headers,它被软件包 glibc-headers-2.17-222.el7.x86_64 需要 --> 正在检查事务 ---> 软件包 kernel-headers.x86_64.0.3.10.0-862.el7 将被 安装 --> 解决依赖关系完成 依赖关系解决 ====================================================================================================================================== Package 架构 版本 源 大小 ====================================================================================================================================== 正在安装: gcc x86_64 4.8.5-28.el7 local 16 M 为依赖而安装: cpp x86_64 4.8.5-28.el7 local 5.9 M glibc-devel x86_64 2.17-222.el7 local 1.1 M glibc-headers x86_64 2.17-222.el7 local 678 k kernel-headers x86_64 3.10.0-862.el7 local 7.1 M libmpc x86_64 1.0.1-3.el7 local 51 k mpfr x86_64 3.1.1-4.el7 local 203 k 事务概要 ====================================================================================================================================== 安装 1 软件包 (+6 依赖软件包) 总下载量:31 M 安装大小:60 M Downloading packages: -------------------------------------------------------------------------------------------------------------------------------------- 总计 59 MB/s | 31 MB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction 正在安装 : mpfr-3.1.1-4.el7.x86_64 1/7 正在安装 : libmpc-1.0.1-3.el7.x86_64 2/7 正在安装 : cpp-4.8.5-28.el7.x86_64 3/7 正在安装 : kernel-headers-3.10.0-862.el7.x86_64 4/7 正在安装 : glibc-headers-2.17-222.el7.x86_64 5/7 正在安装 : glibc-devel-2.17-222.el7.x86_64 6/7 正在安装 : gcc-4.8.5-28.el7.x86_64 7/7 验证中 : gcc-4.8.5-28.el7.x86_64 1/7 验证中 : cpp-4.8.5-28.el7.x86_64 2/7 验证中 : mpfr-3.1.1-4.el7.x86_64 3/7 验证中 : glibc-devel-2.17-222.el7.x86_64 4/7 验证中 : kernel-headers-3.10.0-862.el7.x86_64 5/7 验证中 : glibc-headers-2.17-222.el7.x86_64 6/7 验证中 : libmpc-1.0.1-3.el7.x86_64 7/7 已安装: gcc.x86_64 0:4.8.5-28.el7 作为依赖被安装: cpp.x86_64 0:4.8.5-28.el7 glibc-devel.x86_64 0:2.17-222.el7 glibc-headers.x86_64 0:2.17-222.el7 kernel-headers.x86_64 0:3.10.0-862.el7 libmpc.x86_64 0:1.0.1-3.el7 mpfr.x86_64 0:3.1.1-4.el7 完毕! [root@YL-MASTER redis-6.0.9]# gcc -v 使用内建 specs。 COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper 目标:x86_64-redhat-linux 配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux 线程模型:posix gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) ```` ###### 安装Redis ```shell # 安装redis 6.0.9失败。尝试安装Redis 5.0.10 [root@YL-MASTER redis-5.0.10]# pwd /usr/local/custom-util/redis/station/redis-5.0.10 # 使用Makefile文件进行安装,默认安装在当前目录下 make ``` ###### 启动Redis ```` ################################# GENERAL ##################################### # By default Redis does not run as a daemon. Use 'yes' if you need it. # Note that Redis will write a pid file in /var/run/redis.pid when daemonized. # daemonize no daemonize yes [root@YL-MASTER redis-5.0.10]# ./src/redis-server redis.conf 9867:C 30 Nov 2020 21:54:39.444 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 9867:C 30 Nov 2020 21:54:39.444 # Redis version=5.0.10, bits=64, commit=00000000, modified=0, pid=9867, just started 9867:C 30 Nov 2020 21:54:39.444 # Configuration loaded [root@YL-MASTER redis-5.0.10]# ps -ef | grep redis root 9868 1 0 21:54 ? 00:00:00 ./src/redis-server 127.0.0.1:6379 root 9881 1213 0 21:54 pts/0 00:00:00 grep --color=auto redis ```` ###### 命令行连接 ``` [root@YL-MASTER redis-5.0.10]# ./src/redis-cli 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> exit [root@YL-MASTER redis-5.0.10]# ./src/redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> ``` ###### 关闭Redis ``` [root@YL-MASTER redis-5.0.10]# ps -ef | grep redis root 9868 1 0 21:54 ? 00:00:01 ./src/redis-server 127.0.0.1:6379 root 10452 1213 0 22:06 pts/0 00:00:00 grep --color=auto redis [root@YL-MASTER redis-5.0.10]# ./src/redis-cli shutdown [root@YL-MASTER redis-5.0.10]# ps -ef | grep redis root 10466 1213 0 22:06 pts/0 00:00:00 grep --color=auto redis ``` ###### 开机自启动 > 查看MySQL服务文件 ``` [root@YL-MASTER redis-5.0.10]# find / -name "mysqld.service" -type f /usr/lib/systemd/system/mysqld.service [root@YL-MASTER redis-5.0.10]# cat /usr/lib/systemd/system/mysqld.service # Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2.0, # as published by the Free Software Foundation. # # This program is also distributed with certain software (including # but not limited to OpenSSL) that is licensed under separate terms, # as designated in a particular file or component or in included license # documentation. The authors of MySQL hereby grant you an additional # permission to link the program and your derivative works with the # separately licensed software that they have included with MySQL. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License, version 2.0, for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # systemd service file for MySQL forking server # [Unit] Description=MySQL Server Documentation=man:mysqld(8) Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html After=network.target After=syslog.target [Install] WantedBy=multi-user.target [Service] User=mysql Group=mysql Type=forking PIDFile=/var/run/mysqld/mysqld.pid # Disable service start and stop timeout logic of systemd for mysqld service. TimeoutSec=0 # Execute pre and post scripts as root PermissionsStartOnly=true # Needed to create system tables ExecStartPre=/usr/bin/mysqld_pre_systemd # Start main service ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS # Use this to switch malloc implementation EnvironmentFile=-/etc/sysconfig/mysql # Sets open_files_limit LimitNOFILE = 5000 Restart=on-failure RestartPreventExitStatus=1 PrivateTmp=false ``` > 仿照MySQL服务文件编写Redis的服务文件 ```shell # 服务标识 [Unit] # 描述信息 Description=redis-server # 在网络服务和日志服务启动之后再启动 After=network.target After=syslog.target # 服务信息 [Service] # 进程启动方式 # 如果设为"forking",那么表示 ExecStart= 所设定的进程将会在启动过程中使用 fork() 系统调用。这是传统UNIX守护进程的经典做法。 # 也就是当所有的通信渠道都已建好、启动亦已成功之后,父进程将会退出,而子进程将作为该服务的主进程继续运行。 对于此种进程,建议同时 # 设置 PIDFile= 选项,以帮助 systemd 准确定位该服务的主进程,进而加快后继单元的启动速度。 Type=forking PIDFile=/var/run/redis_6379.pid ExecStart=/usr/local/custom-util/redis/station/redis-5.0.10/src/redis-server /usr/local/custom-util/redis/station/redis-5.0.10/redis.conf # 隔离服务的私有临时目录 PrivateTmp=true [Install] WantedBy=multi-user.target ``` > 设置开机自启动 ```shell [root@YL-MASTER redis-5.0.10]# systemctl daemon-reload [root@YL-MASTER redis-5.0.10]# echo $? 0 [root@YL-MASTER redis-5.0.10]# systemctl start redis [root@YL-MASTER redis-5.0.10]# ps -ef | grep redis root 11682 1 0 22:30 ? 00:00:00 /usr/local/custom-util/redis/station/redis-5.0.10/src/redis-server 127.0.0.1:6379 root 11691 1213 0 22:30 pts/0 00:00:00 grep --color=auto redis [root@YL-MASTER redis-5.0.10]# src/redis-cli 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> exit [root@YL-MASTER redis-5.0.10]# clear [root@YL-MASTER redis-5.0.10]# systemctl enable redis Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service. [root@YL-MASTER redis-5.0.10]# systemctl stop redis [root@YL-MASTER redis-5.0.10]# ps -ef | grep redis root 11795 1213 0 22:31 pts/0 00:00:00 grep --color=auto redis # 重启电脑尝试是否可以开机自启动 [root@YL-MASTER redis-5.0.10]# shutdown -r now [root@YL-MASTER ~]# ps -ef | grep redis root 900 1 0 22:32 ? 00:00:00 /usr/local/custom-util/redis/station/redis-5.0.10/src/redis-server 127.0.0.1:6379 root 1222 1203 0 22:32 pts/0 00:00:00 grep --color=auto redis ``` > 创建redis-cli的软连接 ``` [root@YL-MASTER redis-5.0.10]# ln -s /usr/local/custom-util/redis/station/redis-5.0.10/src/redis-cli /usr/bin/redis-cli [root@YL-MASTER redis-5.0.10]# ls /usr/bin/ | grep redis redis-cli [root@YL-MASTER redis-5.0.10]# ll /usr/bin/ | grep redis lrwxrwxrwx. 1 root root 63 11月 30 22:34 redis-cli -> /usr/local/custom-util/redis/station/redis-5.0.10/src/redis-cli [root@YL-MASTER redis-5.0.10]# redis-cli 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> ``` ###### Nginx服务 ``` [Unit] Description=nginx server daemon Documentation=man:nginx(8) After=network.target [Service] Type=forking ExecStart=/usr/local/nginx1.8.1/sbin/nginx ExecReload=/usr/local/nginx1.8.1/sbin/nginx -s reload ExecStop=/usr/local/nginx1.8.1/sbin/nginx -s quit PrivateTmp=true ``` ## 基础使用 Redis是一种key - value的存储系统,用**ANSI**编码的**C**语言编写的。Redis中命令,比如**keys、set、get**等是忽略大小写的,但是key是区分大小写的。 **ANSI**是一种字符代码,通常使用**0x00~0x7f**的一个字节表示一个英文字母。超过**0x00~0x7f**范围的使用**0x80~0xFFFF**来进行编码,即扩展的**ASCII**编码。存储中文汉字至少需要两个字节。 1个字节 **byte** 是8个二进制的 **bit** 位。8个bit位最多代表2 ^ 7 = 128中情况。 进制到10进制的转换。 数值 * 进制 ^ (位置 - 1) 0x表示16进制。16进制的字符位0~9这10位数字 + [a,b,c,d,e,f]这6个英文字母。 0x00表示十进制的0 0x7f表示十进制的7 * 16 ^ (2-1) + 15 = 112 + 15 = 127 代表**0~127**这128中情况 0x7f表示的二进制是0111 1111刚好表示的1个字节能够存储的最大的正整数。 #### 数据类型 key的类型是字符串 value的数据类型如下 ###### 字符串类型 Redis中字符串能表答三种类型的数据。 字符串中value大于10K就算是BigKey了 - int整数类型。比如:**1** - string类型。比如:**abc123** - double类型。比如:**100.01** ###### list列表类型 存储有序的、可重复的元素。 获取头部或者尾部的元素是很快的。 最多可以存放2 ^ 32 - 1个(40多亿)元素。 先进先出是队列,先进后出是栈。 底层是quickList快速双向链表 列表中的元素是字符串类型,也就是说存储string类型、int整数类型、double浮点数类型都可以。 列表中元素个数大于5000个,就算是BigKey了,按照每个元素10K,就是50M. 适用场景 - 排队队列或者栈 - 各种列表,比如用户列表,商品列表,试题列表 ###### set集合类型 无须的,唯一的元素。 最多存放2 ^ 32 - 1(40多亿)个元素。 适用场景 - 随机对关注用户进行抽奖 - 随机抽取令牌 ###### sortedset(zset)有序集合类型 元素本身是无序不重复的。但是需要给每个元素分配一个分值score,可以按照分数score来进行排序,score是可以重复的。也叫做zset。 适用场景 - 各类排行榜 ###### hash类型 散列表 存储的是field value类型的数据,可以理解为数据库中的字段和其对应的值。 每个hash可以最多存储2 ^ 32 - 1(40多亿)个键值对 适用场景 - 数据库中热点表的记录的缓存 ###### bitmap位图类型 ###### geo()地理位置类型 ###### stream流数据类型(**Redis 5.0新增**) #### 数据结构 #### 常用命令 - flushdb 删除当前数据库中所有得key - flushall 删除Redis所有库中得key - type key 查看key的数据类型 - ###### 字符串类型 - set key value [ex seconds | px milliseconds] [nx|xx] 设置key 的value值,并指明过期时间,什么情况下进行赋值。 ex设置秒单位的过期时间。px设置毫秒单位的过期时间。 nx:表示不存在的时候进行赋值。xx:表示key存在的时候才进行赋值。 ```sql -- 设置key为cll的value值是chenlinlin,指明存活时间为2秒 127.0.0.1:6379> set cll chenlinlin ex 2 OK ``` - get key 获取key对应的value值 ```sql 127.0.0.1:6379> get cll "chenlinlin" -- 返回(nil)表示key不存在 127.0.0.1:6379> get cll (nil) ``` - keys pattern 根据指定模式匹配key,查询所有匹配该模式的key。支持正则匹配 ```sql 127.0.0.1:6379> keys user* 1) "user:cll" 127.0.0.1:6379> keys * (empty list or set) ``` - getset key value 先取出key的值,然后再进行赋值 ```sql 127.0.0.1:6379> getset user:cll chengang "chenlinlin" 127.0.0.1:6379> get user:cll "chengang" ``` - setnx key value 当key不存在的时候进行赋值,当key存在的时候才不进行赋值。 key不存在赋值之后返回1,key存在不进行赋值,返回0。 等同于set key value ```sql 127.0.0.1:6379> setnx user:cll cll (integer) 0 127.0.0.1:6379> setnx user:yl yangliu (integer) 1 127.0.0.1:6379> get user:cll "chengang" 127.0.0.1:6379> set user:cll cll nx (nil) 127.0.0.1:6379> set user:cll chenlinlin OK 127.0.0.1:6379> get user:cll "chenlinlin" 127.0.0.1:6379> set user:cll chengang xx OK 127.0.0.1:6379> get user:cll "chengang" 127.0.0.1:6379> set user:yl yangliu xx (nil) ``` - append key value 向key的value的尾部追加值。key存在的时候,向value的尾部追加值,当key不存在的时候,就创建key,并进行赋值 ```sql 127.0.0.1:6379> append user:cxy chenxiaoying (integer) 12 127.0.0.1:6379> append user:cll cll (integer) 11 127.0.0.1:6379> get user:cxy "chenxiaoying" 127.0.0.1:6379> get user:cll "chengangcll" ``` - strlen key 获取字符串类型的value的长度。key存在时返回key的value的长度,key不存在时返回0 ```sql 127.0.0.1:6379> strlen user:cll (integer) 11 127.0.0.1:6379> get user:cll "chengangcll" 127.0.0.1:6379> strlen user:yl (integer) 0 127.0.0.1:6379> strlen user:cxy (integer) 12 ``` - incr key 将字符串表示的整数类型的值,自增1,并返回自增之后的值。 ```sql -- 如果key对应的value不是整数类型会报错 127.0.0.1:6379> incr user:cll (error) ERR value is not an integer or out of range 127.0.0.1:6379> set a 1 OK 127.0.0.1:6379> get a "1" -- 自增1,并返回自增之后的值 127.0.0.1:6379> incr a (integer) 2 127.0.0.1:6379> get a "2" ``` - incrby key increment 指定key的value(整数类型),自增指定得步长。如果不是整数类型会报错,如果是整数类型,返回自增之后的值。 ```sql 127.0.0.1:6379> incrby user:cll 3 (error) ERR value is not an integer or out of range 127.0.0.1:6379> incrby a 3 (integer) 5 ``` - decr key 将字符串表示的整数类型的值,自减1,并返回自减之后的值。 ```sql 127.0.0.1:6379> decr user:cll (error) ERR value is not an integer or out of range 127.0.0.1:6379> decr a (integer) 4 ``` - decrby key increment 指定key的value(整数类型),自减指定得步长。如果不是整数类型会报错,如果是整数类型,返回自减之后的值。 ```sql 127.0.0.1:6379> decrby a 2 (integer) 2 127.0.0.1:6379> decrby user:cll 2 (error) ERR value is not an integer or out of range ``` ###### 列表类型 - lpush key value1 value2 value3 ... 命令解析 lpush中l表示left,从左边列表的左边进行操作。push表示推进去,进行插入操作 从列表左边插入元素。先从左边写入value1,再从左边写入value2,再从左边写入value3。 返回当前列表的长度。 使用get命令获取列表会报类型错误。 ```sql 127.0.0.1:6379> lpush user cll yl cxy (integer) 3 127.0.0.1:6379> get user (error) WRONGTYPE Operation against a key holding the wrong kind of value ``` - lpushx key value 将值插入列表的头部,返回列表的长度 ```sql 127.0.0.1:6379> lpushx numbers 8 (integer) 4 127.0.0.1:6379> llen numbers (integer) 4 127.0.0.1:6379> rpop numbers "4" 127.0.0.1:6379> lpop numbers "8" ``` - lpop key 从列表的左边取出一个元素,也就是最后放进去的元素。列表中元素取出完之后,key也就不存在了 ```sql 127.0.0.1:6379> lpop user "cxy" 127.0.0.1:6379> lpop user "yl" 127.0.0.1:6379> lpop user "cll" 127.0.0.1:6379> lpop user (nil) ``` - blpop key [key2 key3] timeout 阻塞式获取key的值,可以指定多个key,因为是阻塞式获取,所以必须指定超时时间,单位是秒。如果第一个key获取不到值,就获取第二个key的,以此类推,如果所有的key都获取不到值,就进行阻塞等待,达到超时时间之后,返回(nil)空和超时时间。如果能获取到值,会返回是那个key,以及对应的值。 ```sql 127.0.0.1:6379> keys * 1) "user:cxy" 2) "user:cll" 3) "numbers" 4) "a" 5) "user:yl" 127.0.0.1:6379> blpop numbers str 10 1) "numbers" 2) "1" 127.0.0.1:6379> llen numbers (integer) 0 127.0.0.1:6379> keys * 1) "user:cxy" 2) "user:cll" 3) "a" 4) "user:yl" 127.0.0.1:6379> blpop numbers str 10 (nil) (10.04s) ``` - rpush key value1 value2 value3 ... 从列表的右侧插入元素,并返回插入元素的数量 ```sql 127.0.0.1:6379> rpush numbers 1 2 3 4 5 (integer) 5 ``` - rpushx key value 将值插入key的尾部,返回列表的长度 ```sql 127.0.0.1:6379> rpushx numbers 10 (integer) 3 127.0.0.1:6379> lpop numbers "2" 127.0.0.1:6379> rpop numbers "10" ``` - rpop key 从列表的右侧取出元素 ```sql 127.0.0.1:6379> rpop numbers "5" 127.0.0.1:6379> lpop numbers "1" ``` - brpop key [key2 key3] timeout 从列表的右侧阻塞式获取一组key对应的值。 - llen key 获取列表的长度。列表key不存在时返回0。 ```sql 127.0.0.1:6379> llen numbers (integer) 0 ``` - lindex key index 获取列表指定index处的值。index是从0开始的。只是获取指定索引的值,并不会将元素从列表中取出,移除。所以列表的长度不会发生变化。 ```sql 127.0.0.1:6379> lpush numbers 1 2 3 4 5 (integer) 5 127.0.0.1:6379> llen numbers (integer) 5 127.0.0.1:6379> lindex numbers 2 "3" 127.0.0.1:6379> lindex numbers 2 "3" 127.0.0.1:6379> lindex numbers 3 "2" 127.0.0.1:6379> llen numbers (integer) 5 ``` - lrange key start end 获取列表中索引从start到end之间的所有值。0 到 -1表示查询列表中的所有元素。start到end为左闭右开区间。包含start索引处的元素,不包含end索引处的元素 ```sql 127.0.0.1:6379> lrange numbers 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" 127.0.0.1:6379> lindex numbers 0 "5" 127.0.0.1:6379> lrange numbers 0 2 1) "5" 2) "4" 3) "3" ``` - lrem key count value 根据value的值,删除列表中与value相等的元素。如果count > 0,从列表的左侧删除1个。如果count < 0,从元素的右侧删除一个。如果count = 0,删除所有匹配的元素。返回删除的元素的个数。 ```sql 127.0.0.1:6379> lrange numbers 0 -1 1) "0" 2) "5" 3) "4" 4) "3" 5) "2" 6) "1" 127.0.0.1:6379> rpushx numbers 0 (integer) 7 127.0.0.1:6379> lrange numbers 0 -1 1) "0" 2) "5" 3) "4" 4) "3" 5) "2" 6) "1" 7) "0" 127.0.0.1:6379> lrem numbers 1 0 (integer) 1 127.0.0.1:6379> lrange numbers 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" 6) "0" 127.0.0.1:6379> lpushx numbers 0 (integer) 7 127.0.0.1:6379> lrange numbers 0 -1 1) "0" 2) "5" 3) "4" 4) "3" 5) "2" 6) "1" 7) "0" 127.0.0.1:6379> lrem numbers -1 0 (integer) 1 127.0.0.1:6379> lrange numbers 0 -1 1) "0" 2) "5" 3) "4" 4) "3" 5) "2" 6) "1" 127.0.0.1:6379> rpush numbers 0 (integer) 7 127.0.0.1:6379> lrange numbers 0 -1 1) "0" 2) "5" 3) "4" 4) "3" 5) "2" 6) "1" 7) "0" 127.0.0.1:6379> lrem numbers 0 0 (integer) 2 127.0.0.1:6379> lrange numbers 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" ``` - lset key index value 设置列表的索引为index出的值为value。注意是设置,并不是添加。列表中元素的个数不会发生变化。 ```sql 127.0.0.1:6379> lrange numbers 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" -- 将索引为3的位置的元素设置为4 127.0.0.1:6379> lset numbers 3 4 OK 127.0.0.1:6379> lrange numbers 0 -1 1) "5" 2) "4" 3) "3" 4) "4" 5) "1" ``` - ltrim key start end 对列表中元素进行修剪,只保留start 到 end区间的元素。注意这里是左闭右闭得区间。 ``` 127.0.0.1:6379> lrange numbers 0 -1 1) "abc" 2) "5" 3) "4" 4) "3" 5) "4" 6) "1" 127.0.0.1:6379> ltrim numbers 1 3 OK 127.0.0.1:6379> lrange numbers 0 -1 1) "5" 2) "4" 3) "3" ``` - rpoplpush key1 key2 从key1列表右侧取出元素,插入到key2列表左侧。返回移动得元素得值。 ```sql 127.0.0.1:6379> lrange str 0 -1 1) "f" 2) "e" 3) "d" 4) "c" 5) "b" 6) "a" 127.0.0.1:6379> lrange num 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" 127.0.0.1:6379> rpoplpush str num "a" 127.0.0.1:6379> lrange str 0 -1 1) "f" 2) "e" 3) "d" 4) "c" 5) "b" 127.0.0.1:6379> lrange num 0 -1 1) "a" 2) "5" 3) "4" 4) "3" 5) "2" 6) "1" ``` - brpoplpush key1 key2 timeout 阻塞式从key1右侧中取出元素,放置到key2得左侧。因为是阻塞式取出插入,所以必须指定超时时间。 ```sql 127.0.0.1:6379> brpoplpush num str 10 "1" 127.0.0.1:6379> lrange num 0 -1 1) "a" 2) "5" 3) "4" 4) "3" 5) "2" 127.0.0.1:6379> lrange str 0 -1 1) "1" 2) "f" 3) "e" 4) "d" 5) "c" 6) "b" ``` - linsert key before | after pivot value 将value值插入到key得从左侧匹配到的第一个指定支点的前面或者后面。 ```sql 127.0.0.1:6379> lrange num 0 -1 1) "a" 2) "5" 3) "4" 4) "3" 5) "2" 127.0.0.1:6379> linsert num before 1 0 (integer) -1 127.0.0.1:6379> lrange num 0 -1 1) "a" 2) "5" 3) "4" 4) "3" 5) "2" -- 将值0插入到值3的前面 127.0.0.1:6379> linsert num before 3 0 (integer) 6 127.0.0.1:6379> lrange num 0 -1 1) "a" 2) "5" 3) "4" 4) "0" 5) "3" 6) "2" 127.0.0.1:6379> lrange num 0 -1 1) "0" 2) "a" 3) "5" 4) "4" 5) "0" 6) "3" 7) "2" -- 虽然有俩个0,但是只会插入到从左侧匹配到的第一个0的后面 127.0.0.1:6379> linsert num after 0 9 (integer) 8 127.0.0.1:6379> lrange num 0 -1 1) "0" 2) "9" 3) "a" 4) "5" 5) "4" 6) "0" 7) "3" 8) "2" ``` ###### 集合类型 - sadd key member1 [member2 member1 member3] 向集合key中添加成员,重复添加的成员无效,返回添加的成员的个数。 ```sql 127.0.0.1:6379> sadd name cll yl wn suf szf lsq (integer) 6 127.0.0.1:6379> sadd name cll (integer) 0 ``` - smembers key 查询集合中所有的成员。 ```sql 127.0.0.1:6379> smembers name 1) "lsq" 2) "yl" 3) "wn" 4) "suf" 5) "szf" 6) "cll" 127.0.0.1:6379> sadd name cll (integer) 0 127.0.0.1:6379> sadd name zyj (integer) 1 127.0.0.1:6379> smembers name 1) "lsq" 2) "yl" 3) "wn" 4) "suf" 5) "szf" 6) "zyj" 7) "cll ``` - srem key member1 [member2] 删除集合中指定的成员。返回删除元素的个数 ```sql 127.0.0.1:6379> srem name cxy (integer) 0 127.0.0.1:6379> srem name zyj (integer) 1 127.0.0.1:6379> smembers name 1) "lsq" 2) "yl" 3) "wn" 4) "suf" 5) "szf" 6) "cll" 127.0.0.1:6379> smembers names (empty list or set) 127.0.0.1:6379> srem name cll yl (integer) 2 ``` - spop key 随机从集合中取出一个成员。因为集合是无须的,所以是随机取出。取出之后集合中就不在拥有该成员。 ```sql 127.0.0.1:6379> spop name "suf" 127.0.0.1:6379> smembers name 1) "lsq" 2) "wn" 3) "szf" 127.0.0.1:6379> spop name "szf" 127.0.0.1:6379> smembers name 1) "lsq" 2) "wn" ``` - srandmember key 随机从集合中获取一个成员。因为集合是无须的,所以是随机获取。获取之后,集合中还拥有该成员。 ```sql 127.0.0.1:6379> srandmember name "lsq" 127.0.0.1:6379> srandmember name "lsq" 127.0.0.1:6379> srandmember name "lsq" 127.0.0.1:6379> srandmember name "wn" 127.0.0.1:6379> smembers name 1) "lsq" 2) "wn" ``` - scard key 获取集合中成员的数量。 ```sql 127.0.0.1:6379> scard name (integer) 2 ``` - sismember key member 判断成员member是否在集合key中。返回1表示存在,0表示不存在。 ```sql 127.0.0.1:6379> sismember name wn (integer) 1 127.0.0.1:6379> sismember name cll (integer) 0 ``` - sinter key1 [key2 key3] 求多个集合之间的交集的成员。这些成员在所有的集合中都必须存在,所以和集合的顺序无关。 ```sql 127.0.0.1:6379> keys * 1) "friend" 2) "name" 3) "family" 127.0.0.1:6379> smembers friend 1) "lsq" 2) "wn" 127.0.0.1:6379> smembers name 1) "lsq" 2) "suf" 3) "wn" 4) "szf" 5) "cll" 127.0.0.1:6379> smembers family 1) "cll" 2) "yl" 127.0.0.1:6379> sinter name 1) "lsq" 2) "suf" 3) "wn" 4) "szf" 5) "cll" 127.0.0.1:6379> sinter name friend 1) "lsq" 2) "wn" 127.0.0.1:6379> sinter name friend family (empty list or set) ``` - sdiff key1 [key2 key3] 求集合之间的差集。会先求出key1中的,不再key2中的成员。然后将结果看作一个集合,在查询不再key3中的成员。所以和集合的顺序有关。 ```sql 127.0.0.1:6379> sdiff name friend 1) "szf" 2) "cll" 3) "suf" 127.0.0.1:6379> sdiff name friend family 1) "szf" 2) "suf" 127.0.0.1:6379> sdiff friend family name (empty list or set) ``` - sunion key1 [key2 key3] 求多个集合中成员的并集。只要再任意一个集合中存在,都进行返回。所以和集合的顺序没有关系。 ```sql 127.0.0.1:6379> sunion name friend family 1) "lsq" 2) "yl" 3) "suf" 4) "wn" 5) "szf" 6) "cll" 127.0.0.1:6379> sunion friend name family 1) "suf" 2) "wn" 3) "lsq" 4) "yl" 5) "szf" 6) "cll" ``` ###### 有序集合类型 - zadd key [nx | xx] [ch] [incr] score1 member1 [socre2 member2] 向有序集合中添加指定分值的成员 ```sql 127.0.0.1:6379> zadd zset:1 1 cll 2 cll 3 yl (integer) 2 -- zset:1集合存在,成员wn不存在,插入成功 127.0.0.1:6379> zadd zset:1 nx 2 wn (integer) 1 127.0.0.1:6379> zrange zset:1 0 -1 1) "cll" 2) "wn" 3) "yl" -- zset:2集合不存在,插入suf成员失败 127.0.0.1:6379> zadd zset:2 xx 2 suf (integer) 0 127.0.0.1:6379> zadd zset:2 nx 2 suf (integer) 1 127.0.0.1:6379> zadd zset:2 xx 2 suf (integer) 0 127.0.0.1:6379> type zset:1 zset ``` - zcard key 统计集合中成员数量 ```sql 127.0.0.1:6379> zcard zset:1 (integer) 3 127.0.0.1:6379> zcard zset:2 (integer) 1 ``` - zrange key start end 查询有序集合中start到end索引处的成员。 ``` 127.0.0.1:6379> zrange zset:1 0 -1 1) "cll" 2) "wn" 3) "yl" 127.0.0.1:6379> zrem zset:1 wn (integer) 1 127.0.0.1:6379> zrange zset:1 0 -1 1) "cll" 2) "yl" ``` - zrem key member1 [member2] 从有序集合中删除成员。 ```sql 127.0.0.1:6379> zrange zset:1 0 -1 1) "cll" 2) "wn" 3) "yl" 127.0.0.1:6379> zrem zset:1 wn (integer) 1 127.0.0.1:6379> zrange zset:1 0 -1 1) "cll" 2) "yl" 127.0.0.1:6379> zcard zset:1 (integer) 2 ``` - zscore key member 获取集合中元素的分值。 ``` 127.0.0.1:6379> zscore zset:1 cll "2" 127.0.0.1:6379> zscore zset:1 yl "3" ``` - zcount key min max 统计集合中元素的分值再min到max之间的成员的数量。左闭右闭区间 ``` 127.0.0.1:6379> zcount zset:1 0 2 (integer) 1 127.0.0.1:6379> zcount zset:1 3 5 (integer) 1 127.0.0.1:6379> zcount zset:1 2 3 (integer) 2 ``` - zincrby key increment member 增加集合中成员的分值。返回增加之后的分值。 ```sql 127.0.0.1:6379> zincrby zset:1 3 cll "5" 127.0.0.1:6379> zscore zset:1 cll "5" ``` - zrank key member 计算成员在集合中的排名(索引)。排名从小到大,返回的排名最小为0 ```sql 127.0.0.1:6379> zcard zset:1 (integer) 4 127.0.0.1:6379> zrange zset:1 0 -1 1) "wn" 2) "yl" 3) "cxy" 4) "cll" 127.0.0.1:6379> zscore zset:1 wn "3" 127.0.0.1:6379> zscore zset:1 yl "3" 127.0.0.1:6379> zscore zset:1 cxy "4" 127.0.0.1:6379> zscore zset:1 cll "5" 127.0.0.1:6379> zrank zset:1 cll (integer) 3 127.0.0.1:6379> zrank zset:1 wn (integer) 0 127.0.0.1:6379> zrank zset:1 yl (integer) 1 ``` - zrevrank key member 计算索引,按照分值从大到小进行排序。 ```sql 127.0.0.1:6379> zrevrank zset:1 yl (integer) 2 127.0.0.1:6379> zrevrank zset:1 cll (integer) 0 ``` - zrange key start end 按照分值从小到大的顺序进行排序,查询索引在start到end之间的成员。左闭右闭区间。 ```sql 127.0.0.1:6379> zrange zset:1 0 5 1) "wn" 2) "yl" 3) "cxy" 4) "cll" 127.0.0.1:6379> zrange zset:1 0 3 1) "wn" 2) "yl" 3) "cxy" 4) "cll" 127.0.0.1:6379> zrange zset:1 0 2 1) "wn" 2) "yl" 3) "cxy" ``` - zrevrange key start end 按照分值从大到小的顺序进行排序,查询索引在start到end之间的成员。左闭右闭区间。 ```sql 127.0.0.1:6379> zrevrange zset:1 0 2 1) "cll" 2) "cxy" 3) "yl" 127.0.0.1:6379> zrevrange zset:1 0 -1 1) "cll" 2) "cxy" 3) "yl" 4) "wn" ``` ###### 散列表类型 - type key 查询key的数据类型 ``` 127.0.0.1:6379> type user:1 hash ``` - hgetall key 查询key的所有字段值,返回字段名及其对应的值 ```sql 127.0.0.1:6379> hgetall user:1 1) "username" 2) "cll" 127.0.0.1:6379> hgetall user:1 1) "username" 2) "cll" 3) "age" 4) "26" ``` - hmget key field1 field2 一次查询多个字段值 ```sql 127.0.0.1:6379> hmget user:1 username age 1) "cll" 2) "26" ``` - hget key field 获取key中指定字段的值 ``` 127.0.0.1:6379> hget user:1 age "26" 127.0.0.1:6379> hget user:1 username "cll" ``` - hset key field value 设置key中的字段及其对应的值 ```sql 127.0.0.1:6379> hset user:1 agent mail (integer) 1 127.0.0.1:6379> hget user:1 agent "mail" ``` - hsetnx key field value key的字段不存在的时候设置值。存在不操作 ```sql 127.0.0.1:6379> hsetnx user:1 agent fomail (integer) 0 127.0.0.1:6379> hget user:1 agent "mail" ``` - hmset key field1 value1 field2 value2 批量设置散列表的多个字段及其对应的值 ```sql 127.0.0.1:6379> hmset user:2 username yl age 25 agent fomail OK 127.0.0.1:6379> hgetall user:2 1) "username" 2) "yl" 3) "age" 4) "25" 5) "agent" 6) "fomail" ``` - hexists key field 查询散列表中是否存在指定字段 ```sql 127.0.0.1:6379> hexists user:1 birthday (integer) 0 127.0.0.1:6379> hexists user:1 username (integer) 1 ``` - hlen key 获取散列表中字段数量 ```sql 127.0.0.1:6379> hlen user:1 (integer) 3 ``` - hdel key field 删除散列表中指定字段 ```sql 127.0.0.1:6379> hdel user:1 agent (integer) 1 127.0.0.1:6379> hdel user:1 birthday (integer) 0 ``` - hincrby key field increment 指定散列表中指定字段的值自增 ```sql 127.0.0.1:6379> hincrby user:1 age 30 (integer) 56 127.0.0.1:6379> hget user:1 age "56" ``` ## Cluster分片集群搭建 #### 版本说明 > Redis版本5.0.10 #### Cluster搭建计划 计划搭建三主进行数据库分片,每一个分片主节点后面挂两个从节点。共有9个Redis实例。 ###### 服务器准备 | 服务器IP | 描述信息 | | ------------- | -------------------------------------------------- | | 192.168.0.120 | 主节点端口6380;从节点端口6381,6382 | | 192.168.0.121 | 主节点端口6380;从节点端口6381,6382 | | 192.168.0.122 | 主节点端口6380;从节点端口6381,6382 | | 192.168.0.123 | 主节点端口6380;从节点端口6381,6382.测试Redis扩容 | #### 搭建实操 ###### 120三个Redis实例搭建 - Redis安装 ```shell [root@YL-MASTER redis-5.0.10]# make install prefix=/usr/local/custom-util/redis/station/redis-cluster/6380/ cd src && make install make[1]: 进入目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” CC Makefile.dep make[1]: 离开目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” make[1]: 进入目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” Hint: It's a good idea to run 'make test' ;) INSTALL install INSTALL install INSTALL install INSTALL install INSTALL install make[1]: 离开目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” ``` - 安装完成之后查看是否安装目录是否安装成功 ```shell [root@YL-MASTER redis-5.0.10]# ls /usr/local/custom-util/redis/station/redis-cluster/6380/ # 查看安装目录为空,说明安装失败 ``` - 运行make test进行安装测试 ```shell [root@YL-MASTER redis-5.0.10]# make test cd src && make test make[1]: 进入目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” You need tcl 8.5 or newer in order to run the Redis test make[1]: *** [test] 错误 1 make[1]: 离开目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” make: *** [test] 错误 2 [root@YL-MASTER redis-5.0.10]# rpm -qa | grep tcl # 提示需要安装tcl 8.5以上版本 ``` - yum安装tcl ```shell [root@YL-MASTER redis-5.0.10]# yum install -y tcl 已加载插件:fastestmirror Loading mirror speeds from cached hostfile local | 3.6 kB 00:00:00 正在解决依赖关系 --> 正在检查事务 ---> 软件包 tcl.x86_64.1.8.5.13-8.el7 将被 安装 --> 解决依赖关系完成 依赖关系解决 ====================================================================================================================================== Package 架构 版本 源 大小 ====================================================================================================================================== 正在安装: tcl x86_64 1:8.5.13-8.el7 local 1.9 M 事务概要 ====================================================================================================================================== 安装 1 软件包 总下载量:1.9 M 安装大小:4.4 M Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction 正在安装 : 1:tcl-8.5.13-8.el7.x86_64 1/1 验证中 : 1:tcl-8.5.13-8.el7.x86_64 1/1 已安装: tcl.x86_64 1:8.5.13-8.el7 完毕! [root@YL-MASTER redis-5.0.10]# rpm -qa | grep tcl tcl-8.5.13-8.el7.x86_64 # 如果发现当前的yum仓库中版本过低,就去官网下载rpm包,或者下载tar.gz的安装包,以下是未测试的下载链接 wget http://mirror.centos.org/centos/7/os/x86_64/Packages/tcl-8.5.13-8.el7.x86_64.rpm wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz ``` - 重新执行make test进行安装测试 ```shell Execution time of different units: 3 seconds - unit/printver 打印测试 3 seconds - unit/type/incr incr数据类型测试 5 seconds - unit/keyspace key空间测试 7 seconds - unit/auth 认证测试 9 seconds - unit/protocol 协议测试 11 seconds - unit/type/stream-cgroups 分组流数据类型测试 3 seconds - unit/quit 退出测试 5 seconds - unit/multi 事务测试 19 seconds - unit/expire 超时测试 25 seconds - unit/type/list list数据类型测试 34 seconds - unit/other 其它测试 41 seconds - unit/type/hash hash数据类型测试 38 seconds - integration/block-repl 阻塞副本测试 55 seconds - unit/scan 扫描测试 59 seconds - unit/type/set 集合数据类型测试 64 seconds - unit/type/string string字符串数据类型测试 5 seconds - integration/logging 集成测试,日志测试 14 seconds - integration/convert-zipmap-hash-on-load 集成测试,压缩转换测试 20 seconds - integration/rdb 集成测试 rdb持久化测试 3 seconds - unit/pubsub 单元测试,publish subscribe测试 77 seconds - unit/sort 单元测试,排序测试 6 seconds - unit/slowlog 单元测试,慢日志测试 35 seconds - integration/aof 集成测试,aof持久化测试 89 seconds - unit/type/zset 单元测试,zset数据类型 4 seconds - unit/introspection 单元测试,自省测试 5 seconds - unit/limits 单元测试,limits测试 76 seconds - integration/replication-2 集成测试,主从副本 10 seconds - unit/introspection-2 单元测试,自省测试2 33 seconds - integration/psync2-reg 集成测试 12 seconds - unit/bitfield 单元测试bit字段测试 44 seconds - integration/psync2 集成测试 43 seconds - unit/scripting 单元测试,LUA脚本测试 27 seconds - unit/bitops 单元测试,bit ops 9 seconds - unit/lazyfree 单元测试,延迟释放 136 seconds - unit/type/list-2 单元测试,数据类型list-2测试 137 seconds - unit/dump 单元测试,备份测试 15 seconds - unit/wait 单元测试,wait 148 seconds - unit/type/stream 单元测试 stream流数据类型测试 139 seconds - unit/aofrw 单元测试,aof读写测试 46 seconds - unit/pendingquerybuf 单元测试,等待查询缓存测试 179 seconds - unit/type/list-3 单元测试 list-3数据类型测试 152 seconds - integration/replication-4 集成测试 副本 177 seconds - integration/replication-3 集成测试 副本 179 seconds - integration/replication-psync 114 seconds - unit/geo 单元测试 geo地理位图测试 121 seconds - unit/hyperloglog 单元测试,hyper日志的日志 171 seconds - unit/maxmemory 单元测试,最大内存测试 164 seconds - unit/memefficiency 单元测试,性能测试 274 seconds - integration/replication 集成测试,副本测试 198 seconds - unit/obuf-limits 单元测试 \o/ All tests passed without errors! 所有测试都通过了 Cleanup: may take some time... OK make[1]: 离开目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” # 执行测试通过,共执行了50个单元测试 ``` - 重新执行安装 ```shell [root@YL-MASTER redis-5.0.10]# make install prefix=/usr/local/custom-util/redis/station/redis-cluster/6380/ cd src && make install make[1]: 进入目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” Hint: It's a good idea to run 'make test' ;) INSTALL install INSTALL install INSTALL install INSTALL install INSTALL install make[1]: 离开目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” # 还是提示执行安装测试,应该是安装不成功。 ``` - 去安装目录查看是否安装成功 ```shell [root@YL-MASTER redis-5.0.10]# ls /usr/local/custom-util/redis/station/redis-cluster/6380/ # 发现还是没有安装成功,就回头想想是不是安装的过程出现问题了 ``` - 清除make记录,重新进行安装 ```shell [root@YL-MASTER redis-5.0.10]# make distclean ``` - 重新进行安装 ```shell [root@YL-MASTER redis-5.0.10]# make install PREFIX=/usr/local/custom-util/redis/station/redis-cluster/6380/ ``` - 查看安装目录 ```shell [root@YL-SLAVE1 redis-5.0.10]# ls /usr/local/custom-util/redis/station/redis-cluster/6380/ bin # 发现安装目录下出现了bin目录 ``` - 重新执行make test ```shell The End Execution time of different units: 2 seconds - unit/printver 2 seconds - unit/type/incr 3 seconds - unit/keyspace 5 seconds - unit/auth 6 seconds - unit/protocol 8 seconds - unit/type/stream-cgroups 3 seconds - unit/quit 5 seconds - unit/multi 18 seconds - unit/expire 22 seconds - unit/type/list 30 seconds - unit/other 36 seconds - unit/type/hash 37 seconds - integration/block-repl 47 seconds - unit/type/string 48 seconds - unit/scan 15 seconds - integration/convert-zipmap-hash-on-load 65 seconds - unit/type/set 21 seconds - integration/rdb 5 seconds - integration/logging 4 seconds - unit/pubsub 71 seconds - unit/sort 5 seconds - unit/slowlog 34 seconds - integration/aof 81 seconds - unit/type/zset 4 seconds - unit/introspection 5 seconds - unit/limits 10 seconds - unit/introspection-2 72 seconds - integration/replication-2 33 seconds - integration/psync2-reg 15 seconds - unit/bitfield 43 seconds - integration/psync2 43 seconds - unit/scripting 35 seconds - unit/bitops 12 seconds - unit/lazyfree 135 seconds - unit/dump 14 seconds - unit/wait 142 seconds - unit/type/list-2 158 seconds - unit/type/stream 55 seconds - unit/pendingquerybuf 183 seconds - unit/aofrw 192 seconds - unit/type/list-3 164 seconds - integration/replication-4 188 seconds - integration/replication-3 185 seconds - integration/replication-psync 129 seconds - unit/geo 127 seconds - unit/hyperloglog 179 seconds - unit/maxmemory 169 seconds - unit/memefficiency 276 seconds - integration/replication 203 seconds - unit/obuf-limits \o/ All tests passed without errors! Cleanup: may take some time... OK make[1]: 离开目录“/usr/local/custom-util/redis/station/redis-5.0.10/src” # 测试通过 ``` - 进入安装目录 ```shell [root@YL-MASTER redis-5.0.10]# cd /usr/local/custom-util/redis/station/redis-cluster/6380/ [root@YL-MASTER 6380]# ``` - 创建配置文件目录 ``` [root@YL-MASTER 6380]# mkdir conf [root@YL-MASTER 6380]# ls bin conf ``` - 拷贝示例的redis.conf文件到配置文件目录 ```shell [root@YL-SLAVE1 redis-5.0.10]# mkdir /usr/local/custom-util/redis/station/redis-cluster/6380/conf [root@YL-SLAVE1 redis-5.0.10]# cp redis.conf /usr/local/custom-util/redis/station/redis-cluster/6380/ bin/ conf/ [root@YL-SLAVE1 redis-5.0.10]# cp redis.conf /usr/local/custom-util/redis/station/redis-cluster/6380/conf/ [root@YL-SLAVE1 redis-5.0.10]# cd /usr/local/custom-util/redis/station/redis-cluster/6380/conf/ [root@YL-SLAVE1 conf]# ls redis.conf ``` - redis.conf配置文件解析 ```shell # Redis configuration file example. # Redis配置文件示例 # # Note that in order to read the configuration file, Redis must be # started with the file path as first argument: # # ./redis-server /path/to/redis.conf # 为了能读取到配置文件,在启动Redis的时候,必须指定一个参数是配置文件路径 # Note on units: when memory size is needed, it is possible to specify # it in the usual form of 1k 5GB 4M and so forth: # 关于内存单位的注意事项:当需要指定内存大小时,可以用通常的1k 5GB 4M格式指定,以此类推: # # 1k => 1000 bytes # 1kb => 1024 bytes # 1m => 1000000 bytes # 1mb => 1024*1024 bytes # 1g => 1000000000 bytes # 1gb => 1024*1024*1024 bytes # # units are case insensitive so 1GB 1Gb 1gB are all the same. # 内存单位是不区分大小写的。 ################################## INCLUDES ################################### # INCLUDES包含多个配置文件的配置 # Include one or more other config files here. This is useful if you # have a standard template that goes to all Redis servers but also need # to customize a few per-server settings. Include files can include # other files, so use this wisely. # 在此包含一个或多个其他配置文件。如果你有一个标准的模板,去所有的Redis服务器, # 但也需要为每个服务器自定义一些设置。 # 包含文件可以包括其他文件,所以要明智地使用它。 # 总体来说,就是不要适用通用的模板配置文件,根据每个redis的实例进行定制化配置 # # Notice option "include" won't be rewritten by command "CONFIG REWRITE" # from admin or Redis Sentinel. Since Redis always uses the last processed # line as value of a configuration directive, you'd better put includes # at the beginning of this file to avoid overwriting config change at runtime. # 注意选项“include”不会被来自admin或Redis Sentinel的命令“CONFIG REWRITE”重写。 # 由于Redis总是使用最后处理的行作为配置指令的值, # 所以最好将includes放在这个文件的开头,以避免在运行时覆盖配置更改。 # # If instead you are interested in using includes to override configuration # options, it is better to use include as the last line. # # 如果您对使用include重写配置选项感兴趣,那么最好使用include作为最后一行。 # 如果需要对配置文件进行重写,就放到最后一行。 # include /path/to/local.conf # include /path/to/other.conf ################################## MODULES ##################################### # MODULES模块配置 # Load modules at startup. If the server is not able to load modules # it will abort. It is possible to use multiple loadmodule directives. # Redis会在启动的时候加载指定的模块。如果加载模块失败,启动就失败了。 # 如果有需要,就适用loadmodule指令,指定需要加载的模块。 # # loadmodule /path/to/my_module.so # loadmodule /path/to/other_module.so ################################## NETWORK ##################################### # NETWORK网络配置 # By default, if no "bind" configuration directive is specified, Redis listens # for connections from all the network interfaces available on the server. # It is possible to listen to just one or multiple selected interfaces using # the "bind" configuration directive, followed by one or more IP addresses. # 默认情况下,如果没有指定“bind”配置指令, # Redis将侦听服务器上所有可用网络接口的连接。 # 使用“bind”配置指令,后跟一个或多个IP地址,可以只监听一个或多个选定的网卡接口。 # # Examples: # # bind 192.168.1.100 10.0.0.1 # bind 127.0.0.1 ::1 # # ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the # internet, binding to all the interfaces is dangerous and will expose the # instance to everybody on the internet. So by default we uncomment the # following bind directive, that will force Redis to listen only into # the IPv4 loopback interface address (this means Redis will be able to # accept connections only from clients running into the same computer it # is running). # 警告信息。如果运行Redis的计算机直接暴露在internet上,绑定到所有接口是危险的, # 并且会将实例暴露给internet上的每个人。 # 因此,默认情况下,我们取消注释下面的bind指令, # 这将强制Redis只监听IPv4环回接口地址 # (这意味着Redis只能接受来自运行在同一台计算机上的客户端的连接)。 # 就是说,bind 127.0.0.1就只能通过本机的网卡进行连接 # bind 192.168.*.*只能通过局域网内的网卡进行连接 # bind 公网IP,就只能通过公网IP的网卡进行连接 # # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES # JUST COMMENT THE FOLLOWING LINE. # 如果想要让所有能访问到Redis服务器的都能访问Redis就注释掉下面的bind指令 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bind 127.0.0.1 # Protected mode is a layer of security protection, in order to avoid that # Redis instances left open on the internet are accessed and exploited. # # When protected mode is on and if: # # 1) The server is not binding explicitly to a set of addresses using the # "bind" directive. # 2) No password is configured. # # The server only accepts connections from clients connecting from the # IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain # sockets. # # By default protected mode is enabled. You should disable it only if # you are sure you want clients from other hosts to connect to Redis # even if no authentication is configured, nor a specific set of interfaces # are explicitly listed using the "bind" directive. # Protected mode是一个安全保护层, # 目的是避免在internet上开放的Redis实例被访问和利用。 # 当保护模式开启时,如果: # 1) 服务器没有使用“bind”指令显式绑定到一组地址。 # 2) 未配置密码。 # 服务器只接受来自IPv4和IPv6环回地址127.0.0.1和::1的客户端 # 以及来自Unix域套接字的连接。 # 默认情况下,已启用保护模式。 # 只有当您确定希望其他主机的客户机连接到Redis时,才应该禁用它, # 即使没有配置身份验证,也没有使用“bind”指令显式列出一组特定的接口。 # 开启保护模式之后,要么使用bind的网卡进行连接,要么使用密码进行连接 # 要么只能本机和Unix系统下的socket套接字进行连接 protected-mode yes # Accept connections on the specified port, default is 6379 (IANA #815344). # If port 0 is specified Redis will not listen on a TCP socket. # 指定要绑定的接收请求的端口,默认实6379. # 如果指定的端口是0,那么Redis不会监听Tcp下的socket连接。 port 6379 # TCP listen() backlog. # TCP 监听存储 # # In high requests-per-second environments you need an high backlog in order # to avoid slow clients connections issues. Note that the Linux kernel # will silently truncate it to the value of /proc/sys/net/core/somaxconn so # make sure to raise both the value of somaxconn and tcp_max_syn_backlog # in order to get the desired effect. # 在高并发的情况下,为了解决客户端访问慢的情况,需要高backlog配置。 # 注意,Linux内核会默认最大连接数不能超过 # /proc/sys/net/core/somaxconn文件中设定的值,如果想要达到效果, # 需要调整somaxconn和tcp_max_syn_backlog这两个参数 tcp-backlog 511 # Unix socket. # Unix系统下的socket套接字配置 # # Specify the path for the Unix socket that will be used to listen for # incoming connections. There is no default, so Redis will not listen # on a unix socket when not specified. # 指定将用于侦听传入连接的Unix套接字的路径。 # 没有默认值,因此未指定时,Redis将不会侦听unix套接字。 # 如果需要进行socket连接,就使用下面的配置 # # unixsocket /tmp/redis.sock # unixsocketperm 700 # Close the connection after a client is idle for N seconds (0 to disable) # 客户端连接空闲时间配置,当超过这个时间之后就断开连接。 timeout 0 # TCP keepalive. # TCP保活机制,心跳检测 # # If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence # of communication. This is useful for two reasons: # # 1) Detect dead peers. # 2) Take the connection alive from the point of view of network # equipment in the middle. # # On Linux, the specified value (in seconds) is the period used to send ACKs. # Note that to close the connection the double of the time is needed. # On other kernels the period depends on the kernel configuration. # # A reasonable value for this option is 300 seconds, which is the new # Redis default starting with Redis 3.2.1. # 如果不为零,请使用SO\u KEEPALIVE在没有通信的情况下向客户端发送TCP ack。 # 这有两个原因: # 1) 检测死机。 # 2)从中间网络设备的角度进行连接。 # 在Linux上,指定的值(以秒为单位)是用于发送确认的周期。 # 请注意,要关闭连接,需要加倍的时间。在其他内核上,周期取决于内核配置。 # 此选项的合理值为300秒,这是从Redis 3.2.1开始的新Redis默认值。 tcp-keepalive 300 ################################# GENERAL ##################################### # 常用配置 # By default Redis does not run as a daemon. Use 'yes' if you need it. # Note that Redis will write a pid file in /var/run/redis.pid when daemonized. # 默认情况下,Redis不作为守护进程运行。 # 如果需要,请使用“yes”它。 # 注意Redis将在/var/run中写入一个pid文件/redis.pid文件,作为守护进程的时候。 daemonize no # If you run Redis from upstart or systemd, Redis can interact with your # supervision tree. Options: # supervised no - no supervision interaction # supervised upstart - signal upstart by putting Redis into SIGSTOP mode # supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET # supervised auto - detect upstart or systemd method based on # UPSTART_JOB or NOTIFY_SOCKET environment variables # Note: these supervision methods only signal "process is ready." # They do not enable continuous liveness pings back to your supervisor. # 如果您从upstart或systemd运行Redis,那么Redis可以与您的监督树进行交互。选项: # supervised no:不进行监督交互 # supervised upstart:把Redis放入到SIGSTOP模式中 # supervised systemd:将READY=1的就绪状态写入到$NOTIFY_SOCKET通知的套接字中 # supervised auto:基于配置的环境变量是UPSTART_JOB还是NOTIFY_SOCKET自动使用 # 注意,只是发送“进程就绪”的信号,不会持续进行心跳检测 supervised no # If a pid file is specified, Redis writes it where specified at startup # and removes it at exit. # # When the server runs non daemonized, no pid file is created if none is # specified in the configuration. When the server is daemonized, the pid file # is used even if not specified, defaulting to "/var/run/redis.pid". # # Creating a pid file is best effort: if Redis is not able to create it # nothing bad happens, the server will start and run normally. # 如果指定了pid文件,Redis会在启动时将其写入指定的位置,并在退出时将其删除。 # 非守护进程启动的时候,如果配置中未指定任何pid文件,则不会创建任何pid文件。 # 守护进程模式下,即使未指定pid文件,也会创建,默认为“/var/run”/redis.pid文件". # 虽然不创建也不影响使用,但是最好配置上。 pidfile /var/run/redis_6379.pid # Specify the server verbosity level. # This can be one of: # debug (a lot of information, useful for development/testing) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) # 指明服务日志的级别,类似于开发中log的级别。可以是以下几种只一 # debug级别(很多信息,开发、测试使用) # verbose级别 (many rarely useful info, but not a mess like the debug level) # notice级别 (moderately verbose, what you want in production probably) # warning级别 (only very important / critical messages are logged) loglevel notice # Specify the log file name. Also the empty string can be used to force # Redis to log on the standard output. Note that if you use standard # output for logging but daemonize, logs will be sent to /dev/null # 指明日志文件。可以通过设置""字符串,在控制台输出。 # 注意,后台进程模式下启动,将不会记录日志 logfile "" # To enable logging to the system logger, just set 'syslog-enabled' to yes, # and optionally update the other syslog parameters to suit your needs. # 是否开启redis日志,yes表示开启,no表示不开启,开启之后配置其它参数即可。 # syslog-enabled no # Specify the syslog identity. # 指明系统日志的标识 # syslog-ident redis # Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. # 指明系统日志的场所。必须是LOCAL0-LOCAL7之间 # syslog-facility local0 # Set the number of databases. The default database is DB 0, you can select # a different one on a per-connection basis using SELECT where # dbid is a number between 0 and 'databases'-1 # 设置数据库的数量。默认数据库是db0,数据库数量是16,也就是0到15. # 您可以使用select在每个连接的基础上选择一个不同的数据库, # 其中dbid是0和“databases”-1之间的数字 databases 16 # By default Redis shows an ASCII art logo only when started to log to the # standard output and if the standard output is a TTY. Basically this means # that normally a logo is displayed only in interactive sessions. # # However it is possible to force the pre-4.0 behavior and always show a # ASCII art logo in startup logs by setting the following option to yes. # 是否显示打印redis的logo。 always-show-logo yes ################################ SNAPSHOTTING ################################ # 快照相关配置 # Save the DB on disk: # 存储数据到磁盘。快照存储的标准是多少秒之内有多少个key发生了变化 # # save # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # 900秒之内有一个key发生变化 # after 900 sec (15 min) if at least 1 key changed # 300秒内10key发生变化 # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving completely by commenting out all "save" lines. # 注意:可以通过注释save指令,禁用快照存储 # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # 可以通过配置执行save是""空字符串,来清除原来的保存点的快照 # # save "" save 900 1 save 300 10 save 60 10000 # By default Redis will stop accepting writes if RDB snapshots are enabled # (at least one save point) and the latest background save failed. # This will make the user aware (in a hard way) that data is not persisting # on disk properly, otherwise chances are that no one will notice and some # disaster will happen. # # If the background saving process will start working again Redis will # automatically allow writes again. # # However if you have setup your proper monitoring of the Redis server # and persistence, you may want to disable this feature so that Redis will # continue to work as usual even if there are problems with disk, # permissions, and so forth. # 后台存储失败的时候是否停止客户端写入 # 默认情况下,如果启用了RDB快照(至少有一个保存点), # 并且最新的后台保存失败,则Redis将停止接受写入。 # 这将使用户意识到(以一种硬的方式)数据没有正确地保存在磁盘上, # 否则很可能没有人会注意到,并且会发生一些灾难。 # 如果后台保存进程重新开始工作,Redis将自动允许再次写入。 # 但是,如果您已经设置了对Redis服务器和持久性的适当监视, # 那么您可能希望禁用此功能,以便即使磁盘、权限等出现问题,Redis也将继续正常工作。 stop-writes-on-bgsave-error yes # Compress string objects using LZF when dump .rdb databases? # For default that's set to 'yes' as it's almost always a win. # If you want to save some CPU in the saving child set it to 'no' but # the dataset will likely be bigger if you have compressible values or keys. # rdb进行数据库持久化的时候,是否使用LZF压缩字符串对象。默认使用yes就行了。 # 如果想保存CPU的一些信息到文件中,就配置未no。但是如果有需要压缩的key或者value # 的话,文件就会变得很大。 rdbcompression yes # Since version 5 of RDB a CRC64 checksum is placed at the end of the file. # This makes the format more resistant to corruption but there is a performance # hit to pay (around 10%) when saving and loading RDB files, so you can disable it # for maximum performances. # 从RDB5开始,会在rdb文件的末尾添加CRC64格式的checksum。用来校验文件是否损坏! # 会带来大约10%的性能损耗。 # # RDB files created with checksum disabled have a checksum of zero that will # tell the loading code to skip the check. # 禁用的情况下会写入checksum为0,表示不校验。 rdbchecksum yes # The filename where to dump the DB # rdb备份文件的名称 dbfilename dump.rdb # The working directory. # 指定工作目录(工作空间) # # The DB will be written inside this directory, with the filename specified # above using the 'dbfilename' configuration directive. # rdb的备份文件会存储在当前指定的工作目录下面 # The Append Only File will also be created inside this directory. # 追加的备份文件也会存储在这个目录下面 # Note that you must specify a directory here, not a file name. # 注意,这里指定是目录,而不是文件名称 dir ./ ################################# REPLICATION ################################# # 主从复制配置 # Master-Replica replication. Use replicaof to make a Redis instance a copy of # another Redis server. A few things to understand ASAP about Redis replication. # 主从复制架构下使用。replicaof表明redis实例作为另外一个redis服务的副本。 # 想要了解Redis的主从复制,就需要理解ASAP模型 # # +------------------+ +---------------+ # | Master | ---> | Replica | # | (receive writes) | | (exact copy) | # +------------------+ +---------------+ # # 1) Redis replication is asynchronous, but you can configure a master to # stop accepting writes if it appears to be not connected with at least # a given number of replicas. # 2) Redis replicas are able to perform a partial resynchronization with the # master if the replication link is lost for a relatively small amount of # time. You may want to configure the replication backlog size (see the next # sections of this file) with a sensible value depending on your needs. # 3) Replication is automatic and does not need user intervention. After a # network partition replicas automatically try to reconnect to masters # and resynchronize with them. # 1) Redis复制是异步的,但是您可以配置一个主服务器, # 使其停止接受写入,如果它似乎没有连接到至少给定数量的副本。 # 2) 如果复制链接丢失的时间相对较短,则Redis副本能够与主服务器执行部分重新同步。 # 根据实际情况配置backlog的大小(请参阅此文件的下一节)。 # 3) 复制是自动的,不需要用户干预。 # 在网络分区之后,复制副本会自动尝试重新连接到主机并与它们重新同步。 # # replicaof # If the master is password protected (using the "requirepass" configuration # directive below) it is possible to tell the replica to authenticate before # starting the replication synchronization process, otherwise the master will # refuse the replica request. # 如果主机受密码保护(使用下面的“requirepass”配置指令), # 则可以在开始复制同步过程之前通知副本进行身份验证,否则主服务器将拒绝副本请求。 # 如果主库配置密码了,这里也需要配置上密码 # # masterauth # When a replica loses its connection with the master, or when the replication # is still in progress, the replica can act in two different ways: # # 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will # still reply to client requests, possibly with out of date data, or the # data set may just be empty if this is the first synchronization. # # 2) if replica-serve-stale-data is set to 'no' the replica will reply with # an error "SYNC with master in progress" to all the kind of commands # but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, # SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, # COMMAND, POST, HOST: and LATENCY. # 从库在主从复制的过程中,断开了与主库的连接,会出现以下两种情况。 # 1) 如果replica-serve-stale-data设置为“yes”(默认值), # 则复制副本仍将响应客户端请求,数据可能已过期, # 或者如果这是第一次同步,则数据集可能为空。 # 如果replica serve stale data设置为“no”,除了上述命令之外,其它的命令都会返回 # “SYNC with master in progress”进程正在同步主库的错误信息 # replica-serve-stale-data yes # You can configure a replica instance to accept writes or not. Writing against # a replica instance may be useful to store some ephemeral data (because data # written on a replica will be easily deleted after resync with the master) but # may also cause problems if clients are writing to it because of a # misconfiguration. # 可以配置从库是否支持写入操作。 # # Since Redis 2.6 by default replicas are read-only. # 从Redis 2.6开始,默认从库是只读的,不能进行写入操作。 # # Note: read only replicas are not designed to be exposed to untrusted clients # on the internet. It's just a protection layer against misuse of the instance. # Still a read only replica exports by default all the administrative commands # such as CONFIG, DEBUG, and so forth. To a limited extent you can improve # security of read only replicas using 'rename-command' to shadow all the # administrative / dangerous commands. # 注意:只读副本不是为暴露在internet上的不可信客户端而设计的。 # 它只是防止实例被滥用的保护层。 # 默认情况下,只读副本仍会导出所有管理命令,如CONFIG、DEBUG等。 # 可以使用“rename command”来隐藏所有管理/危险命令来提高从库的安全性。 replica-read-only yes # Replication SYNC strategy: disk or socket. # 主从同步策略:磁盘或者socket连接 # # ------------------------------------------------------- # WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY # ------------------------------------------------------- # 注意:diskless复制还在测试阶段。测试阶段的东西最好不用 # New replicas and reconnecting replicas that are not able to continue the replication # process just receiving differences, need to do what is called a "full # synchronization". An RDB file is transmitted from the master to the replicas. # The transmission can happen in two different ways: # # 1) Disk-backed: The Redis master creates a new process that writes the RDB # file on disk. Later the file is transferred by the parent # process to the replicas incrementally. # 2) Diskless: The Redis master creates a new process that directly writes the # RDB file to replica sockets, without touching the disk at all. # # With disk-backed replication, while the RDB file is generated, more replicas # can be queued and served with the RDB file as soon as the current child producing # the RDB file finishes its work. With diskless replication instead once # the transfer starts, new replicas arriving will be queued and a new transfer # will start when the current one terminates. # # When diskless replication is used, the master waits a configurable amount of # time (in seconds) before starting the transfer in the hope that multiple replicas # will arrive and the transfer can be parallelized. # # With slow disks and fast (large bandwidth) networks, diskless replication # works better. repl-diskless-sync no # diskless主从同步的延迟 # When diskless replication is enabled, it is possible to configure the delay # the server waits in order to spawn the child that transfers the RDB via socket # to the replicas. # # This is important since once the transfer starts, it is not possible to serve # new replicas arriving, that will be queued for the next RDB transfer, so the server # waits a delay in order to let more replicas arrive. # # The delay is specified in seconds, and by default is 5 seconds. To disable # it entirely just set it to 0 seconds and the transfer will start ASAP. repl-diskless-sync-delay 5 # Replicas send PINGs to server in a predefined interval. It's possible to change # this interval with the repl_ping_replica_period option. The default value is 10 # seconds. # 指定从库向主库发送心跳包的时间间隔 # repl-ping-replica-period 10 # The following option sets the replication timeout for: # 配置主从复制的超时时间。超过设置的时间,就认为是主从复制超时了。 # # 1) Bulk transfer I/O during SYNC, from the point of view of replica. # 大量的I/O传输 # 2) Master timeout from the point of view of replicas (data, pings). # 没有接收到主句的pong # 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). # 没有接收到从库的ping # # It is important to make sure that this value is greater than the value # specified for repl-ping-replica-period otherwise a timeout will be detected # every time there is low traffic between the master and the replica. # 必须保证这个时间值大于设置的心跳检测的时间值。要不然,没有发送心跳包,就肯定超时。 # repl-timeout 60 # Disable TCP_NODELAY on the replica socket after SYNC? # 同步结束之后,是否禁用从库的socket连接的TCP_NODELAY? # # If you select "yes" Redis will use a smaller number of TCP packets and # less bandwidth to send data to replicas. But this can add a delay for # the data to appear on the replica side, up to 40 milliseconds with # Linux kernels using a default configuration. # 如果选择“是”,Redis将使用较少的TCP数据包和较少的带宽将数据发送到副本。 # 但这可能会增加数据在副本端出现的延迟,对于Linux内核使用默认配置,最长为40毫秒。 # # If you select "no" the delay for data to appear on the replica side will # be reduced but more bandwidth will be used for replication. # 如果选择“否”,则数据出现在副本端的延迟将减少,但复制将使用更多带宽。 # # By default we optimize for low latency, but in very high traffic conditions # or when the master and replicas are many hops away, turning this to "yes" may # be a good idea. # 默认一致性优先,但是高并发情况下,或者带宽受限的情况下,可用性优先! # 因为Redis是AP模型 repl-disable-tcp-nodelay no # Set the replication backlog size. The backlog is a buffer that accumulates # replica data when replicas are disconnected for some time, so that when a replica # wants to reconnect again, often a full resync is not needed, but a partial # resync is enough, just passing the portion of data the replica missed while # disconnected. # 从库的backlog大小设置。backlog是一个缓冲区,如果主从复制端口,可以先存到 # backlog缓冲区,等从库连接之后,只需要进行增量同步就可以了。 # # The bigger the replication backlog, the longer the time the replica can be # disconnected and later be able to perform a partial resynchronization. # backlog越大,断开连接时间越长,增量同步就越耗时!因为数据不一致的数据多了。 # # The backlog is only allocated once there is at least a replica connected. # 至少有一个从库连接才会分配backlog。 # # repl-backlog-size 1mb # After a master has no longer connected replicas for some time, the backlog # will be freed. The following option configures the amount of seconds that # need to elapse, starting from the time the last replica disconnected, for # the backlog buffer to be freed. # # Note that replicas never free the backlog for timeout, since they may be # promoted to masters later, and should be able to correctly "partially # resynchronize" with the replicas: hence they should always accumulate backlog. # # A value of 0 means to never release the backlog. # 配置backlog的存活时间。主从断开连接之后多长时间释放backlog空间。 # # repl-backlog-ttl 3600 # The replica priority is an integer number published by Redis in the INFO output. # It is used by Redis Sentinel in order to select a replica to promote into a # master if the master is no longer working correctly. # # A replica with a low priority number is considered better for promotion, so # for instance if there are three replicas with priority 10, 100, 25 Sentinel will # pick the one with priority 10, that is the lowest. # # However a special priority of 0 marks the replica as not able to perform the # role of master, so a replica with priority of 0 will never be selected by # Redis Sentinel for promotion. # # By default the priority is 100. # 副本优先级配置。sentinel哨兵模式下,从库升级主库的选取标准。越低越容易升级为主库。 # 注意0不为被选举为主库。 replica-priority 100 # It is possible for a master to stop accepting writes if there are less than # N replicas connected, having a lag less or equal than M seconds. # # The N replicas need to be in "online" state. # # The lag in seconds, that must be <= the specified value, is calculated from # the last ping received from the replica, that is usually sent every second. # # This option does not GUARANTEE that N replicas will accept the write, but # will limit the window of exposure for lost writes in case not enough replicas # are available, to the specified number of seconds. # # For example to require at least 3 replicas with a lag <= 10 seconds use: # # min-replicas-to-write 3 # min-replicas-max-lag 10 # # Setting one or the other to 0 disables the feature. # # By default min-replicas-to-write is set to 0 (feature disabled) and # min-replicas-max-lag is set to 10. # 如果连接的副本少于N个,并且延迟小于或等于M秒,则主服务器可能停止接受写入。 # N个副本需要处于“联机”状态。 # 延迟时间(以秒为单位)必须<=指定值,根据从副本接收的最后一次ping计算,该ping通常每秒发送一次。 # 此选项不保证N个副本将接受写入,但将在没有足够的副本可用的情况下将丢失写入的暴露时间限制在指定的秒数内。 # 例如,要要求至少3个延迟<=10秒的复制副本,请使用: # 最少写入3个副本 # 最小副本最大延迟10 # 将其中一个设置为0将禁用该功能。 # 默认情况下,要写入的最小副本数设置为0(禁用功能),最小副本最大延迟设置为10。 # A Redis master is able to list the address and port of the attached # replicas in different ways. For example the "INFO replication" section # offers this information, which is used, among other tools, by # Redis Sentinel in order to discover replica instances. # Another place where this info is available is in the output of the # "ROLE" command of a master. # Redis主机能够以不同的方式列出所连接副本的地址和端口。 # 例如,“INFO replication”部分提供了这个信息, # 除了其他工具外,Redis Sentinel使用这些信息来发现副本实例。 # 此信息的另一个可用位置是主控形状的“ROLE”命令的输出。 # # The listed IP and address normally reported by a replica is obtained # in the following way: # 从库通常报告的列出的IP和地址是通过以下方式获得的: # IP: The address is auto detected by checking the peer address # of the socket used by the replica to connect with the master. # IP:通过检查复制副本用于与主服务器连接的套接字的对等地址来自动检测该地址。 # Port: The port is communicated by the replica during the replication # handshake, and is normally the port that the replica is using to # listen for connections. # 端口:在复制握手期间,该端口由副本通信,通常是从库用于侦听连接的端口。 # # However when port forwarding or Network Address Translation (NAT) is # used, the replica may be actually reachable via different IP and port # pairs. The following two options can be used by a replica in order to # report to its master a specific set of IP and port, so that both INFO # and ROLE will report those values. # 然而,当使用端口转发或网络地址转换(NAT)时, # 从库实际上可以通过不同的IP和端口对访问。 # 从库可以使用以下两个选项向其主服务器报告一组特定的IP和端口, # 以便INFO和ROLE都报告这些值。 # # There is no need to use both the options if you need to override just # the port or the IP address. # 如果只需要覆盖端口或IP地址,则不需要同时使用这两个选项。 # 这两个指令不是必须同时配置的 # replica-announce-ip 5.5.5.5 # replica-announce-port 1234 ################################## SECURITY ################################### # 安全相关配置 # Require clients to issue AUTH before processing any other # commands. This might be useful in environments in which you do not trust # others with access to the host running redis-server. # # This should stay commented out for backward compatibility and because most # people do not need auth (e.g. they run their own servers). # # Warning: since Redis is pretty fast an outside user can try up to # 150k passwords per second against a good box. This means that you should # use a very strong password otherwise it will be very easy to break. # 配置了安全认证密码之后,客户端在执行任何命令之前必须进行密码认证。 # 警告:由于Redis速度很快,外部用户可以尝试在一个好的机器上每秒输入150k个密码。 # 这意味着你应该使用一个非常强的密码,否则很容易被破解。 # # requirepass foobared # Command renaming. # Redis支持对命令的重命名 # It is possible to change the name of dangerous commands in a shared # environment. For instance the CONFIG command may be renamed into something # hard to guess so that it will still be available for internal-use tools # but not available for general clients. # 可以将重要的命令重命名为自定义名称的命令,这样其他人就不好才出来是命令 # 猜不出来,就没有办法执行,保护安全性。 # Example: # # rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 # # It is also possible to completely kill a command by renaming it into # an empty string: # 如果重命名命令之后为""空字符串,那么该命令就不能再使用了 # rename-command CONFIG "" # # Please note that changing the name of commands that are logged into the # AOF file or transmitted to replicas may cause problems. # 注意,重命名命令之后,AOF进行持久化或主从复制的时候可能会出现问题。 # 因为AOF就是对命令执行过程的记录,所以可能会出现问题。 ################################### CLIENTS #################################### # 客户端连接相关配置 # Set the max number of connected clients at the same time. By default # this limit is set to 10000 clients, however if the Redis server is not # able to configure the process file limit to allow for the specified limit # the max number of allowed clients is set to the current file limit # minus 32 (as Redis reserves a few file descriptors for internal uses). # 设置客户端最大连接数。默认10000个。如果Redis服务器不允许在进程文件中配置限制的 # 访问的最大的连接数,就会设置为当前文件数量-32. # Once the limit is reached Redis will close all the new connections sending # an error 'max number of clients reached'. # 超过设置的最大连接数,就会关闭所有的连接,新连接会返回连接数过多的错误提示! # # maxclients 10000 ############################## MEMORY MANAGEMENT ################################ # 内存管理 # Set a memory usage limit to the specified amount of bytes. # When the memory limit is reached Redis will try to remove keys # according to the eviction policy selected (see maxmemory-policy). # 当内存使用达到上限之后,Redis会根据配置的驱逐策略移除key。 # # If Redis can't remove keys according to the policy, or if the policy is # set to 'noeviction', Redis will start to reply with errors to commands # that would use more memory, like SET, LPUSH, and so on, and will continue # to reply to read-only commands like GET. # 如果不能移除key,或者配置为noevication(永不驱逐,Redis作为DB使用), # 执行写入命令会报错。 # # This option is usually useful when using Redis as an LRU or LFU cache, or to # set a hard memory limit for an instance (using the 'noeviction' policy). # 当用作LRU或者LFU的缓存的时候,作为DB使用noevication策略,配置maxmemory有用。 # 因为Redis本来就是在内存里面工作的,如果内存不够,会和磁盘进行swap, # 交换分区获得虚拟内存,但是一旦和磁盘进行交互,Redis的性能会很差。 # # WARNING: If you have replicas attached to an instance with maxmemory on, # the size of the output buffers needed to feed the replicas are subtracted # from the used memory count, so that network problems / resyncs will # not trigger a loop where keys are evicted, and in turn the output # buffer of replicas is full with DELs of keys evicted triggering the deletion # of more keys, and so forth until the database is completely emptied. # # In short... if you have replicas attached it is suggested that you set a lower # limit for maxmemory so that there is some free RAM on the system for replica # output buffers (but this is not needed if the policy is 'noeviction'). # 如果配置了主从复制,不要将最大内存设置的太大, # 要预留出来一部分空间供做主复制使用。 # maxmemory # MAXMEMORY POLICY: how Redis will select what to remove when maxmemory # is reached. You can select among five behaviors: # 内存达到上限之后的key的驱逐策略。 # volatile-lru -> Evict using approximated LRU among the keys with an expire set. # 根据最近最少使用原则,驱逐设置了过期时间的key # allkeys-lru -> Evict any key using approximated LRU. # 根据最近最少使用远测,从所有key中随机选取进行驱逐 # volatile-lfu -> Evict using approximated LFU among the keys with an expire set. # 根据最少使用原则,驱逐设置了过期时间的key # allkeys-lfu -> Evict any key using approximated LFU. # 根据最少使用远测,从所有key中随机选取进行驱逐 # volatile-random -> Remove a random key among the ones with an expire set. # 从设置了过期时间的key中随机选取进行驱逐 # allkeys-random -> Remove a random key, any key. # 从所有的key中随机选取进行驱逐 # volatile-ttl -> Remove the key with the nearest expire time (minor TTL) # 通过监控TTL(Time To Live),删除最接近过去时间的key # noeviction -> Don't evict anything, just return an error on write operations. # 永不驱逐 # # LRU means Least Recently Used # LFU means Least Frequently Used # # Both LRU, LFU and volatile-ttl are implemented using approximated # randomized algorithms. # LRU,LFU,TTL都是使用的近似的随机算法,都是随机选取移除 # # Note: with any of the above policies, Redis will return an error on write # operations, when there are no suitable keys for eviction. # # At the date of writing these commands are: set setnx setex append # incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd # sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby # zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby # getset mset msetnx exec sort # 注意,如果不能根据驱逐策略移除key,那么在进行写入操作的时候会报错。 # The default is: # 默认为永不驱逐 # maxmemory-policy noeviction # LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated # algorithms (in order to save memory), so you can tune it for speed or # accuracy. For default Redis will check five keys and pick the one that was # used less recently, you can change the sample size using the following # configuration directive. # LRU,LFU,TTL不是精准移除,是为了节省内存。如果有需要可以调整 # The default of 5 produces good enough results. 10 Approximates very closely # true LRU but costs more CPU. 3 is faster but not very accurate. # 默认的5,是权衡精度和性能之后的配置。10接近真实的LRU等,3会导致精度有偏差 # maxmemory-samples 5 # Starting from Redis 5, by default a replica will ignore its maxmemory setting # (unless it is promoted to master after a failover or manually). It means # that the eviction of keys will be just handled by the master, sending the # DEL commands to the replica as keys evict in the master side. # 从Redis 5 开始,默认忽略从库配置的maxmemory(除非在进行故障转移或者手动生主)。 # This behavior ensures that masters and replicas stay consistent, and is usually # what you want, however if your replica is writable, or you want the replica to have # a different memory setting, and you are sure all the writes performed to the # replica are idempotent, then you may change this default (but be sure to understand # what you are doing). # # Note that since the replica by default does not evict, it may end using more # memory than the one set via maxmemory (there are certain buffers that may # be larger on the replica, or data structures may sometimes take more memory and so # forth). So make sure you monitor your replicas and make sure they have enough # memory to never hit a real out-of-memory condition before the master hits # the configured maxmemory setting. # 一般就不用配置,使用默认的就行了 # replica-ignore-maxmemory yes ############################# LAZY FREEING #################################### # 延迟释放配置 # Redis has two primitives to delete keys. One is called DEL and is a blocking # deletion of the object. It means that the server stops processing new commands # in order to reclaim all the memory associated with an object in a synchronous # way. If the key deleted is associated with a small object, the time needed # in order to execute the DEL command is very small and comparable to most other # O(1) or O(log_N) commands in Redis. However if the key is associated with an # aggregated value containing millions of elements, the server can block for # a long time (even seconds) in order to complete the operation. # del:删除key,释放内存空间,阻塞删除 # unling:断开key与value的连接,异步删除 # For the above reasons Redis also offers non blocking deletion primitives # such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and # FLUSHDB commands, in order to reclaim memory in background. Those commands # are executed in constant time. Another thread will incrementally free the # object in the background as fast as possible. # # DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. # It's up to the design of the application to understand when it is a good # idea to use one or the other. However the Redis server sometimes has to # delete keys or flush the whole database as a side effect of other operations. # Specifically Redis deletes objects independently of a user call in the # following scenarios: # # 1) On eviction, because of the maxmemory and maxmemory policy configurations, # in order to make room for new data, without going over the specified # memory limit. # 2) Because of expire: when a key with an associated time to live (see the # EXPIRE command) must be deleted from memory. # 3) Because of a side effect of a command that stores data on a key that may # already exist. For example the RENAME command may delete the old key # content when it is replaced with another one. Similarly SUNIONSTORE # or SORT with STORE option may delete existing keys. The SET command # itself removes any old content of the specified key in order to replace # it with the specified string. # 4) During replication, when a replica performs a full resynchronization with # its master, the content of the whole database is removed in order to # load the RDB file just transferred. # # In all the above cases the default is to delete objects in a blocking way, # like if DEL was called. However you can configure each case specifically # in order to instead release memory in a non-blocking way like if UNLINK # was called, using the following configuration directives: lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no ############################## APPEND ONLY MODE ############################### # 增量追加的模式 # By default Redis asynchronously dumps the dataset on disk. This mode is # good enough in many applications, but an issue with the Redis process or # a power outage may result into a few minutes of writes lost (depending on # the configured save points). # # The Append Only File is an alternative persistence mode that provides # much better durability. For instance using the default data fsync policy # (see later in the config file) Redis can lose just one second of writes in a # dramatic event like a server power outage, or a single write if something # wrong with the Redis process itself happens, but the operating system is # still running correctly. # # AOF and RDB persistence can be enabled at the same time without problems. # If the AOF is enabled on startup Redis will load the AOF, that is the file # with the better durability guarantees. # # Please check http://redis.io/topics/persistence for more information. appendonly no # The name of the append only file (default: "appendonly.aof") appendfilename "appendonly.aof" # The fsync() call tells the Operating System to actually write data on disk # instead of waiting for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP. # # Redis supports three different modes: # # no: don't fsync, just let the OS flush the data when it wants. Faster. # always: fsync after every write to the append only log. Slow, Safest. # everysec: fsync only one time every second. Compromise. # # The default is "everysec", as that's usually the right compromise between # speed and data safety. It's up to you to understand if you can relax this to # "no" that will let the operating system flush the output buffer when # it wants, for better performances (but if you can live with the idea of # some data loss consider the default persistence mode that's snapshotting), # or on the contrary, use "always" that's very slow but a bit safer than # everysec. # # More details please check the following article: # http://antirez.com/post/redis-persistence-demystified.html # # If unsure, use "everysec". # 执行一个命令,就刷新一次 # appendfsync always # 每一秒刷新一次 appendfsync everysec # 操作系统控制刷新,就是满了才刷新 # appendfsync no # When the AOF fsync policy is set to always or everysec, and a background # saving process (a background save or AOF log background rewriting) is # performing a lot of I/O against the disk, in some Linux configurations # Redis may block too long on the fsync() call. Note that there is no fix for # this currently, as even performing fsync in a different thread will block # our synchronous write(2) call. # # In order to mitigate this problem it's possible to use the following option # that will prevent fsync() from being called in the main process while a # BGSAVE or BGREWRITEAOF is in progress. # # This means that while another child is saving, the durability of Redis is # the same as "appendfsync none". In practical terms, this means that it is # possible to lose up to 30 seconds of log in the worst scenario (with the # default Linux settings). # # If you have latency problems turn this to "yes". Otherwise leave it as # "no" that is the safest pick from the point of view of durability. no-appendfsync-on-rewrite no # Automatic rewrite of the append only file. # Redis is able to automatically rewrite the log file implicitly calling # BGREWRITEAOF when the AOF log size grows by the specified percentage. # # This is how it works: Redis remembers the size of the AOF file after the # latest rewrite (if no rewrite has happened since the restart, the size of # the AOF at startup is used). # # This base size is compared to the current size. If the current size is # bigger than the specified percentage, the rewrite is triggered. Also # you need to specify a minimal size for the AOF file to be rewritten, this # is useful to avoid rewriting the AOF file even if the percentage increase # is reached but it is still pretty small. # # Specify a percentage of zero in order to disable the automatic AOF # rewrite feature. auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # An AOF file may be found to be truncated at the end during the Redis # startup process, when the AOF data gets loaded back into memory. # This may happen when the system where Redis is running # crashes, especially when an ext4 filesystem is mounted without the # data=ordered option (however this can't happen when Redis itself # crashes or aborts but the operating system still works correctly). # # Redis can either exit with an error when this happens, or load as much # data as possible (the default now) and start if the AOF file is found # to be truncated at the end. The following option controls this behavior. # # If aof-load-truncated is set to yes, a truncated AOF file is loaded and # the Redis server starts emitting a log to inform the user of the event. # Otherwise if the option is set to no, the server aborts with an error # and refuses to start. When the option is set to no, the user requires # to fix the AOF file using the "redis-check-aof" utility before to restart # the server. # # Note that if the AOF file will be found to be corrupted in the middle # the server will still exit with an error. This option only applies when # Redis will try to read more data from the AOF file but not enough bytes # will be found. aof-load-truncated yes # When rewriting the AOF file, Redis is able to use an RDB preamble in the # AOF file for faster rewrites and recoveries. When this option is turned # on the rewritten AOF file is composed of two different stanzas: # # [RDB file][AOF tail] # # When loading Redis recognizes that the AOF file starts with the "REDIS" # string and loads the prefixed RDB file, and continues loading the AOF # tail. aof-use-rdb-preamble yes ################################ LUA SCRIPTING ############################### # lua脚本配置 # Max execution time of a Lua script in milliseconds. # # If the maximum execution time is reached Redis will log that a script is # still in execution after the maximum allowed time and will start to # reply to queries with an error. # # When a long running script exceeds the maximum execution time only the # SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be # used to stop a script that did not yet called write commands. The second # is the only way to shut down the server in the case a write command was # already issued by the script but the user doesn't want to wait for the natural # termination of the script. # # Set it to 0 or a negative value for unlimited execution without warnings. lua-time-limit 5000 ################################ REDIS CLUSTER ############################### # cluster集群配置 # Normal Redis instances can't be part of a Redis Cluster; only nodes that are # started as cluster nodes can. In order to start a Redis instance as a # cluster node enable the cluster support uncommenting the following: # 集群模式开关 # cluster-enabled yes # Every cluster node has a cluster configuration file. This file is not # intended to be edited by hand. It is created and updated by Redis nodes. # Every Redis Cluster node requires a different cluster configuration file. # Make sure that instances running in the same system do not have # overlapping cluster configuration file names. # 集群模式下,主从,slote槽分配等配置信息的配置文件 # cluster-config-file nodes-6379.conf # Cluster node timeout is the amount of milliseconds a node must be unreachable # for it to be considered in failure state. # Most other internal time limits are multiple of the node timeout. # # cluster-node-timeout 15000 # A replica of a failing master will avoid to start a failover if its data # looks too old. # # There is no simple way for a replica to actually have an exact measure of # its "data age", so the following two checks are performed: # # 1) If there are multiple replicas able to failover, they exchange messages # in order to try to give an advantage to the replica with the best # replication offset (more data from the master processed). # Replicas will try to get their rank by offset, and apply to the start # of the failover a delay proportional to their rank. # # 2) Every single replica computes the time of the last interaction with # its master. This can be the last ping or command received (if the master # is still in the "connected" state), or the time that elapsed since the # disconnection with the master (if the replication link is currently down). # If the last interaction is too old, the replica will not try to failover # at all. # # The point "2" can be tuned by user. Specifically a replica will not perform # the failover if, since the last interaction with the master, the time # elapsed is greater than: # # (node-timeout * replica-validity-factor) + repl-ping-replica-period # # So for example if node-timeout is 30 seconds, and the replica-validity-factor # is 10, and assuming a default repl-ping-replica-period of 10 seconds, the # replica will not try to failover if it was not able to talk with the master # for longer than 310 seconds. # # A large replica-validity-factor may allow replicas with too old data to failover # a master, while a too small value may prevent the cluster from being able to # elect a replica at all. # # For maximum availability, it is possible to set the replica-validity-factor # to a value of 0, which means, that replicas will always try to failover the # master regardless of the last time they interacted with the master. # (However they'll always try to apply a delay proportional to their # offset rank). # # Zero is the only value able to guarantee that when all the partitions heal # the cluster will always be able to continue. # # cluster-replica-validity-factor 10 # Cluster replicas are able to migrate to orphaned masters, that are masters # that are left without working replicas. This improves the cluster ability # to resist to failures as otherwise an orphaned master can't be failed over # in case of failure if it has no working replicas. # # Replicas migrate to orphaned masters only if there are still at least a # given number of other working replicas for their old master. This number # is the "migration barrier". A migration barrier of 1 means that a replica # will migrate only if there is at least 1 other working replica for its master # and so forth. It usually reflects the number of replicas you want for every # master in your cluster. # # Default is 1 (replicas migrate only if their masters remain with at least # one replica). To disable migration just set it to a very large value. # A value of 0 can be set but is useful only for debugging and dangerous # in production. # # cluster-migration-barrier 1 # By default Redis Cluster nodes stop accepting queries if they detect there # is at least an hash slot uncovered (no available node is serving it). # This way if the cluster is partially down (for example a range of hash slots # are no longer covered) all the cluster becomes, eventually, unavailable. # It automatically returns available as soon as all the slots are covered again. # # However sometimes you want the subset of the cluster which is working, # to continue to accept queries for the part of the key space that is still # covered. In order to do so, just set the cluster-require-full-coverage # option to no. # # cluster-require-full-coverage yes # This option, when set to yes, prevents replicas from trying to failover its # master during master failures. However the master can still perform a # manual failover, if forced to do so. # # This is useful in different scenarios, especially in the case of multiple # data center operations, where we want one side to never be promoted if not # in the case of a total DC failure. # # cluster-replica-no-failover no # In order to setup your cluster make sure to read the documentation # available at http://redis.io web site. ########################## CLUSTER DOCKER/NAT support ######################## # 集群下docker或者nat网络的支持 # In certain deployments, Redis Cluster nodes address discovery fails, because # addresses are NAT-ted or because ports are forwarded (the typical case is # Docker and other containers). # # In order to make Redis Cluster working in such environments, a static # configuration where each node knows its public address is needed. The # following two options are used for this scope, and are: # # * cluster-announce-ip # * cluster-announce-port # * cluster-announce-bus-port # # Each instruct the node about its address, client port, and cluster message # bus port. The information is then published in the header of the bus packets # so that other nodes will be able to correctly map the address of the node # publishing the information. # # If the above options are not used, the normal Redis Cluster auto-detection # will be used instead. # # Note that when remapped, the bus port may not be at the fixed offset of # clients port + 10000, so you can specify any port and bus-port depending # on how they get remapped. If the bus-port is not set, a fixed offset of # 10000 will be used as usually. # # Example: # # cluster-announce-ip 10.1.1.5 # cluster-announce-port 6379 # cluster-announce-bus-port 6380 ################################## SLOW LOG ################################### # 慢查询日志配置 # The Redis Slow Log is a system to log queries that exceeded a specified # execution time. The execution time does not include the I/O operations # like talking with the client, sending the reply and so forth, # but just the time needed to actually execute the command (this is the only # stage of command execution where the thread is blocked and can not serve # other requests in the meantime). # # You can configure the slow log with two parameters: one tells Redis # what is the execution time, in microseconds, to exceed in order for the # command to get logged, and the other parameter is the length of the # slow log. When a new command is logged the oldest one is removed from the # queue of logged commands. # 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. # 慢查询的时间,默认超过10秒中算是慢查询,就会进行记录 slowlog-log-slower-than 10000 # There is no limit to this length. Just be aware that it will consume memory. # You can reclaim memory used by the slow log with SLOWLOG RESET. slowlog-max-len 128 ################################ LATENCY MONITOR ############################## # 延迟监视器配置 # The Redis latency monitoring subsystem samples different operations # at runtime in order to collect data related to possible sources of # latency of a Redis instance. # # Via the LATENCY command this information is available to the user that can # print graphs and obtain reports. # # The system only logs operations that were performed in a time equal or # greater than the amount of milliseconds specified via the # latency-monitor-threshold configuration directive. When its value is set # to zero, the latency monitor is turned off. # # By default latency monitoring is disabled since it is mostly not needed # if you don't have latency issues, and collecting data has a performance # impact, that while very small, can be measured under big load. Latency # monitoring can easily be enabled at runtime using the command # "CONFIG SET latency-monitor-threshold " if needed. latency-monitor-threshold 0 ############################# EVENT NOTIFICATION ############################## # 事件通知配置 # Redis can notify Pub/Sub clients about events happening in the key space. # This feature is documented at http://redis.io/topics/notifications # # For instance if keyspace events notification is enabled, and a client # performs a DEL operation on key "foo" stored in the Database 0, two # messages will be published via Pub/Sub: # # PUBLISH __keyspace@0__:foo del # PUBLISH __keyevent@0__:del foo # # It is possible to select the events that Redis will notify among a set # of classes. Every class is identified by a single character: # # K Keyspace events, published with __keyspace@__ prefix. # E Keyevent events, published with __keyevent@__ prefix. # g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... # $ String commands # l List commands # s Set commands # h Hash commands # z Sorted set commands # x Expired events (events generated every time a key expires) # e Evicted events (events generated when a key is evicted for maxmemory) # A Alias for g$lshzxe, so that the "AKE" string means all the events. # # The "notify-keyspace-events" takes as argument a string that is composed # of zero or multiple characters. The empty string means that notifications # are disabled. # # Example: to enable list and generic events, from the point of view of the # event name, use: # # notify-keyspace-events Elg # # Example 2: to get the stream of the expired keys subscribing to channel # name __keyevent@0__:expired use: # # notify-keyspace-events Ex # # By default all notifications are disabled because most users don't need # this feature and the feature has some overhead. Note that if you don't # specify at least one of K or E, no events will be delivered. notify-keyspace-events "" ############################### ADVANCED CONFIG ############################### # 高级配置 # Hashes are encoded using a memory efficient data structure when they have a # small number of entries, and the biggest entry does not exceed a given # threshold. These thresholds can be configured using the following directives. hash-max-ziplist-entries 512 hash-max-ziplist-value 64 # Lists are also encoded in a special way to save a lot of space. # The number of entries allowed per internal list node can be specified # as a fixed maximum size or a maximum number of elements. # For a fixed maximum size, use -5 through -1, meaning: # -5: max size: 64 Kb <-- not recommended for normal workloads # -4: max size: 32 Kb <-- not recommended # -3: max size: 16 Kb <-- probably not recommended # -2: max size: 8 Kb <-- good # -1: max size: 4 Kb <-- good # Positive numbers mean store up to _exactly_ that number of elements # per list node. # The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), # but if your use case is unique, adjust the settings as necessary. list-max-ziplist-size -2 # Lists may also be compressed. # Compress depth is the number of quicklist ziplist nodes from *each* side of # the list to *exclude* from compression. The head and tail of the list # are always uncompressed for fast push/pop operations. Settings are: # 0: disable all list compression # 1: depth 1 means "don't start compressing until after 1 node into the list, # going from either the head or tail" # So: [head]->node->node->...->node->[tail] # [head], [tail] will always be uncompressed; inner nodes will compress. # 2: [head]->[next]->node->node->...->node->[prev]->[tail] # 2 here means: don't compress head or head->next or tail->prev or tail, # but compress all nodes between them. # 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] # etc. list-compress-depth 0 # Sets have a special encoding in just one case: when a set is composed # of just strings that happen to be integers in radix 10 in the range # of 64 bit signed integers. # The following configuration setting sets the limit in the size of the # set in order to use this special memory saving encoding. set-max-intset-entries 512 # Similarly to hashes and lists, sorted sets are also specially encoded in # order to save a lot of space. This encoding is only used when the length and # elements of a sorted set are below the following limits: zset-max-ziplist-entries 128 zset-max-ziplist-value 64 # HyperLogLog sparse representation bytes limit. The limit includes the # 16 bytes header. When an HyperLogLog using the sparse representation crosses # this limit, it is converted into the dense representation. # # A value greater than 16000 is totally useless, since at that point the # dense representation is more memory efficient. # # The suggested value is ~ 3000 in order to have the benefits of # the space efficient encoding without slowing down too much PFADD, # which is O(N) with the sparse encoding. The value can be raised to # ~ 10000 when CPU is not a concern, but space is, and the data set is # composed of many HyperLogLogs with cardinality in the 0 - 15000 range. hll-sparse-max-bytes 3000 # Streams macro node max size / items. The stream data structure is a radix # tree of big nodes that encode multiple items inside. Using this configuration # it is possible to configure how big a single node can be in bytes, and the # maximum number of items it may contain before switching to a new node when # appending new stream entries. If any of the following settings are set to # zero, the limit is ignored, so for instance it is possible to set just a # max entires limit by setting max-bytes to 0 and max-entries to the desired # value. stream-node-max-bytes 4096 stream-node-max-entries 100 # Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in # order to help rehashing the main Redis hash table (the one mapping top-level # keys to values). The hash table implementation Redis uses (see dict.c) # performs a lazy rehashing: the more operation you run into a hash table # that is rehashing, the more rehashing "steps" are performed, so if the # server is idle the rehashing is never complete and some more memory is used # by the hash table. # # The default is to use this millisecond 10 times every second in order to # actively rehash the main dictionaries, freeing memory when possible. # # If unsure: # use "activerehashing no" if you have hard latency requirements and it is # not a good thing in your environment that Redis can reply from time to time # to queries with 2 milliseconds delay. # # use "activerehashing yes" if you don't have such hard requirements but # want to free memory asap when possible. activerehashing yes # The client output buffer limits can be used to force disconnection of clients # that are not reading data from the server fast enough for some reason (a # common reason is that a Pub/Sub client can't consume messages as fast as the # publisher can produce them). # # The limit can be set differently for the three different classes of clients: # # normal -> normal clients including MONITOR clients # replica -> replica clients # pubsub -> clients subscribed to at least one pubsub channel or pattern # # The syntax of every client-output-buffer-limit directive is the following: # # client-output-buffer-limit # # A client is immediately disconnected once the hard limit is reached, or if # the soft limit is reached and remains reached for the specified number of # seconds (continuously). # So for instance if the hard limit is 32 megabytes and the soft limit is # 16 megabytes / 10 seconds, the client will get disconnected immediately # if the size of the output buffers reach 32 megabytes, but will also get # disconnected if the client reaches 16 megabytes and continuously overcomes # the limit for 10 seconds. # # By default normal clients are not limited because they don't receive data # without asking (in a push way), but just after a request, so only # asynchronous clients may create a scenario where data is requested faster # than it can read. # # Instead there is a default limit for pubsub and replica clients, since # subscribers and replicas receive data in a push fashion. # # Both the hard or the soft limit can be disabled by setting them to zero. client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 # Client query buffers accumulate new commands. They are limited to a fixed # amount by default in order to avoid that a protocol desynchronization (for # instance due to a bug in the client) will lead to unbound memory usage in # the query buffer. However you can configure it here if you have very special # needs, such us huge multi/exec requests or alike. # # client-query-buffer-limit 1gb # In the Redis protocol, bulk requests, that are, elements representing single # strings, are normally limited ot 512 mb. However you can change this limit # here. # # proto-max-bulk-len 512mb # Redis calls an internal function to perform many background tasks, like # closing connections of clients in timeout, purging expired keys that are # never requested, and so forth. # # Not all tasks are performed with the same frequency, but Redis checks for # tasks to perform according to the specified "hz" value. # # By default "hz" is set to 10. Raising the value will use more CPU when # Redis is idle, but at the same time will make Redis more responsive when # there are many keys expiring at the same time, and timeouts may be # handled with more precision. # # The range is between 1 and 500, however a value over 100 is usually not # a good idea. Most users should use the default of 10 and raise this up to # 100 only in environments where very low latency is required. hz 10 # Normally it is useful to have an HZ value which is proportional to the # number of clients connected. This is useful in order, for instance, to # avoid too many clients are processed for each background task invocation # in order to avoid latency spikes. # # Since the default HZ value by default is conservatively set to 10, Redis # offers, and enables by default, the ability to use an adaptive HZ value # which will temporary raise when there are many connected clients. # # When dynamic HZ is enabled, the actual configured HZ will be used as # as a baseline, but multiples of the configured HZ value will be actually # used as needed once more clients are connected. In this way an idle # instance will use very little CPU time while a busy instance will be # more responsive. dynamic-hz yes # When a child rewrites the AOF file, if the following option is enabled # the file will be fsync-ed every 32 MB of data generated. This is useful # in order to commit the file to the disk more incrementally and avoid # big latency spikes. aof-rewrite-incremental-fsync yes # When redis saves RDB file, if the following option is enabled # the file will be fsync-ed every 32 MB of data generated. This is useful # in order to commit the file to the disk more incrementally and avoid # big latency spikes. rdb-save-incremental-fsync yes # Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good # idea to start with the default settings and only change them after investigating # how to improve the performances and how the keys LFU change over time, which # is possible to inspect via the OBJECT FREQ command. # # There are two tunable parameters in the Redis LFU implementation: the # counter logarithm factor and the counter decay time. It is important to # understand what the two parameters mean before changing them. # # The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis # uses a probabilistic increment with logarithmic behavior. Given the value # of the old counter, when a key is accessed, the counter is incremented in # this way: # # 1. A random number R between 0 and 1 is extracted. # 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). # 3. The counter is incremented only if R < P. # # The default lfu-log-factor is 10. This is a table of how the frequency # counter changes with a different number of accesses with different # logarithmic factors: # # +--------+------------+------------+------------+------------+------------+ # | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | # +--------+------------+------------+------------+------------+------------+ # | 0 | 104 | 255 | 255 | 255 | 255 | # +--------+------------+------------+------------+------------+------------+ # | 1 | 18 | 49 | 255 | 255 | 255 | # +--------+------------+------------+------------+------------+------------+ # | 10 | 10 | 18 | 142 | 255 | 255 | # +--------+------------+------------+------------+------------+------------+ # | 100 | 8 | 11 | 49 | 143 | 255 | # +--------+------------+------------+------------+------------+------------+ # # NOTE: The above table was obtained by running the following commands: # # redis-benchmark -n 1000000 incr foo # redis-cli object freq foo # # NOTE 2: The counter initial value is 5 in order to give new objects a chance # to accumulate hits. # # The counter decay time is the time, in minutes, that must elapse in order # for the key counter to be divided by two (or decremented if it has a value # less <= 10). # # The default value for the lfu-decay-time is 1. A Special value of 0 means to # decay the counter every time it happens to be scanned. # # lfu-log-factor 10 # lfu-decay-time 1 ########################### ACTIVE DEFRAGMENTATION ####################### # 活动碎片空间整理 # WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested # even in production and manually tested by multiple engineers for some # time. # # What is active defragmentation? # ------------------------------- # # Active (online) defragmentation allows a Redis server to compact the # spaces left between small allocations and deallocations of data in memory, # thus allowing to reclaim back memory. # # Fragmentation is a natural process that happens with every allocator (but # less so with Jemalloc, fortunately) and certain workloads. Normally a server # restart is needed in order to lower the fragmentation, or at least to flush # away all the data and create it again. However thanks to this feature # implemented by Oran Agra for Redis 4.0 this process can happen at runtime # in an "hot" way, while the server is running. # # Basically when the fragmentation is over a certain level (see the # configuration options below) Redis will start to create new copies of the # values in contiguous memory regions by exploiting certain specific Jemalloc # features (in order to understand if an allocation is causing fragmentation # and to allocate it in a better place), and at the same time, will release the # old copies of the data. This process, repeated incrementally for all the keys # will cause the fragmentation to drop back to normal values. # # Important things to understand: # # 1. This feature is disabled by default, and only works if you compiled Redis # to use the copy of Jemalloc we ship with the source code of Redis. # This is the default with Linux builds. # # 2. You never need to enable this feature if you don't have fragmentation # issues. # # 3. Once you experience fragmentation, you can enable this feature when # needed with the command "CONFIG SET activedefrag yes". # # The configuration parameters are able to fine tune the behavior of the # defragmentation process. If you are not sure about what they mean it is # a good idea to leave the defaults untouched. # Enabled active defragmentation # activedefrag yes # Minimum amount of fragmentation waste to start active defrag # active-defrag-ignore-bytes 100mb # Minimum percentage of fragmentation to start active defrag # active-defrag-threshold-lower 10 # Maximum percentage of fragmentation at which we use maximum effort # active-defrag-threshold-upper 100 # Minimal effort for defrag in CPU percentage # active-defrag-cycle-min 5 # Maximal effort for defrag in CPU percentage # active-defrag-cycle-max 75 # Maximum number of set/hash/zset/list fields that will be processed from # the main dictionary scan # active-defrag-max-scan-fields 1000 ``` - 集群模式下需要修改的配置参数 ```shell # 绑定局域网网卡IP bind 192.168.0.120 # 如果有需要可以关闭保护模式 protected-mode no # 修改绑定的监听端口 port 6380 # 修改为后台守护进行运行 daemonize yes # 修改pid文件 pidfile /var/run/redis_6380.pid # 修改dump.rdb文件的工作空间 dir /usr/local/custom-util/redis/station/redis-cluster/6380/ # 启用日志记录 syslog-enabled yes # 指明系统日志的标识 syslog-ident redis6380 # 指明日志文件 logfile /usr/local/custom-util/redis/station/redis-cluster/6380/sys.log # 指明系统日志的场所。必须是LOCAL0-LOCAL7之间 syslog-facility local0 # 集群模式开关 cluster-enabled yes # 集群模式下,主从,slots槽分配等配置信息的配置文件 cluster-config-file nodes-6380.conf ``` - 编写启动脚本startcluster.sh ```shell [root@YL-MASTER redis-cluster]# touch startcluster.sh [root@YL-MASTER redis-cluster]# ls 6380 6381 6382 startcluster.sh ``` ```shell /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-server /usr/local/custom-util/redis/station/redis-cluster/6380/conf/redis-cluster6380.conf /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-server /usr/local/custom-util/redis/station/redis-cluster/6381/conf/redis-cluster6381.conf /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-server /usr/local/custom-util/redis/station/redis-cluster/6382/conf/redis-cluster6382.conf ``` - 给启动脚本添加写和执行的权限 ``` [root@YL-MASTER redis-cluster]# chmod u+x startcluster.sh ``` - 脚本启动测试 ```shell [root@YL-MASTER redis-cluster]# ./startcluster.sh [root@YL-MASTER redis-cluster]# ps -ef | grep redis root 1317 1 0 10:47 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-server 192.168.0.120:6380 [cluster] root 1322 1 0 10:47 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-server 192.168.0.120:6381 [cluster] root 1327 1 0 10:47 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-server 192.168.0.120:6382 [cluster] root 1332 1217 0 10:47 pts/0 00:00:00 grep --color=auto redis ``` - 编写关闭脚本 ```shell /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-cli -h 192.168.0.120 -p 6380 shutdown /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-cli -h 192.168.0.120 -p 6381 shutdown /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-cli -h 192.168.0.120 -p 6382 shutdown ``` ###### 121三个Redis实例搭建 - Redis的安装 跟上述120上一样 - Redis配置文件编写 只需要将原来的redis-cluster.conf中的bind配置指令修改为 ``` bind 192.168.0.121 ``` - 启动脚本编写 和上述120服务器上一样 ```shell [root@YL-SLAVE1 redis-cluster]# ./startcluster.sh 2020-12-05 11:22:36 starting redis cluster 2020-12-05 11:22:36 starting redis cluster success! [root@YL-SLAVE1 redis-cluster]# ps -ef | grep redis root 1320 1 0 11:22 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-server 192.168.0.121:6380 [cluster] root 1325 1 0 11:22 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-server 192.168.0.121:6381 [cluster] root 1327 1 0 11:22 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-server 192.168.0.121:6382 [cluster] root 1337 1231 0 11:22 pts/0 00:00:00 grep --color=auto redis [root@YL-SLAVE1 redis-cluster]# ./stopcluster.sh ``` - 关闭脚本编写 需要修改连接的Redis的IP ```shell /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-cli -h 192.168.0.121 -p 6380 shutdown /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-cli -h 192.168.0.121 -p 6381 shutdown /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-cli -h 192.168.0.121 -p 6382 shutdown ``` ###### 122三个Redis实例搭建 和121上面完全一样 - 安装Redis实例 - Redis实例拷贝 ```shell [root@YL-SLAVE2 redis-cluster]# cp -r 6380 6381 [root@YL-SLAVE2 redis-cluster]# cp -r 6380 6382 [root@YL-SLAVE2 redis-cluster]# ls 6380 6381 6382 ``` - 上传Redis配置文件 ```shell sftp:/usr/local/custom-util/redis/station/redis-cluster> cd 6380/conf/ sftp:/usr/local/custom-util/redis/station/redis-cluster/6380/conf> Uploading redis-cluster6380.conf to remote:/usr/local/custom-util/redis/station/redis-cluster/6380/conf/redis-cluster6380.conf sftp: sent 77.2 KB in 0.02 seconds sftp:/usr/local/custom-util/redis/station/redis-cluster/6380/conf> cd ../../6381/conf/ sftp:/usr/local/custom-util/redis/station/redis-cluster/6381/conf> Uploading redis-cluster6381.conf to remote:/usr/local/custom-util/redis/station/redis-cluster/6381/conf/redis-cluster6381.conf sftp: sent 77.2 KB in 0.01 seconds sftp:/usr/local/custom-util/redis/station/redis-cluster/6381/conf> cd ../../6382/conf/ sftp:/usr/local/custom-util/redis/station/redis-cluster/6382/conf> Uploading redis-cluster6382.conf to remote:/usr/local/custom-util/redis/station/redis-cluster/6382/conf/redis-cluster6382.conf sftp: sent 77.2 KB in 0.02 seconds ``` - 修改配置文件 ```shell [root@YL-SLAVE2 redis-cluster]# vim 6380/conf/redis-cluster6380.conf [root@YL-SLAVE2 redis-cluster]# vim 6381/conf/redis-cluster6381.conf [root@YL-SLAVE2 redis-cluster]# vim 6382/conf/redis-cluster6382.conf bind 192.168.0.122 ``` - 上传脚本文件 ```shell sftp:/usr/local/custom-util/redis/station/redis-cluster> Uploading startcluster.sh to remote:/usr/local/custom-util/redis/station/redis-cluster/startcluster.sh sftp:/usr/local/custom-util/redis/station/redis-cluster> Uploading stopcluster.sh to remote:/usr/local/custom-util/redis/station/redis-cluster/stopcluster.sh sftp: sent 312 字节 in 0.00 seconds ``` - 给脚本添加执行权限 ```shell [root@YL-SLAVE2 redis-cluster]# chmod +x startcluster.sh [root@YL-SLAVE2 redis-cluster]# chmod +x stopcluster.sh [root@YL-SLAVE2 redis-cluster]# ls 6380 6381 6382 startcluster.sh stopcluster.sh ``` - 修改关闭脚本 ``` /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-cli -h 192.168.0.122 -p 6380 shutdown /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-cli -h 192.168.0.122 -p 6381 shutdown /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-cli -h 192.168.0.122 -p 6382 shutdown ``` - 执行启动脚本测试 ```shell [root@YL-SLAVE2 redis-cluster]# ./startcluster.sh [root@YL-SLAVE2 redis-cluster]# ps -ef | grep redis root 2294 1 0 11:36 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-server 192.168.0.122:6380 [cluster] root 2296 1 0 11:36 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-server 192.168.0.122:6381 [cluster] root 2301 1 0 11:36 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-server 192.168.0.122:6382 [cluster] root 2309 1232 0 11:36 pts/0 00:00:00 grep --color=auto redis ``` - 执行关闭脚本测试 ```shell [root@YL-SLAVE2 redis-cluster]# ./stopcluster.sh [root@YL-SLAVE2 redis-cluster]# ps -ef | grep redis root 2315 1232 0 11:36 pts/0 00:00:00 grep --color=auto redis ``` ###### 分区集群搭建 - 分区配置文件查看 ```shell 192.168.0.120 [root@YL-MASTER redis-cluster]# cat 6380/nodes-6380.conf a3cac1c19469ad85bc59f13579dd0df0a3b588cd :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 [root@YL-MASTER redis-cluster]# cat 6381/nodes-6381.conf fce563734d4d5cd1ca46b347d541b95a8367d4bb :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 [root@YL-MASTER redis-cluster]# cat 6382/nodes-6382.conf dc5de96950d88d02c3f303a66097c274ceaa1a19 :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 [root@YL-MASTER redis-cluster]# ifconfig ens33: flags=4163 mtu 1500 inet 192.168.0.120 netmask 255.255.255.0 broadcast 192.168.0.255 192.168.0.121 [root@YL-SLAVE1 redis-cluster]# ifconfig ens33: flags=4163 mtu 1500 inet 192.168.0.121 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::b319:23cf:53ff:7d04 prefixlen 64 scopeid 0x20 ether 00:0c:29:4e:4a:d8 txqueuelen 1000 (Ethernet) RX packets 3567 bytes 584271 (570.5 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2335 bytes 316313 (308.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 57 bytes 3994 (3.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 57 bytes 3994 (3.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@YL-SLAVE1 redis-cluster]# cat 6380/nodes-6380.conf 8d7eaf14ab9c30eff991b96fc86f6021ae0138df :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 [root@YL-SLAVE1 redis-cluster]# cat 6381/nodes-6381.conf c044367292f1399906a827aadb89230661c7996e :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 [root@YL-SLAVE1 redis-cluster]# cat 6382/nodes-6382.conf 7eab70ac0090c4bba64871eea60731e585bbbcd1 :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 192.168.0.122 [root@YL-SLAVE2 redis-cluster]# ifconfig ens33: flags=4163 mtu 1500 inet 192.168.0.122 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::2f49:d15b:11df:d0d4 prefixlen 64 scopeid 0x20 ether 00:0c:29:60:70:64 txqueuelen 1000 (Ethernet) RX packets 2487 bytes 478858 (467.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1565 bytes 175093 (170.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 74 bytes 5342 (5.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 74 bytes 5342 (5.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@YL-SLAVE2 redis-cluster]# cat 6380/nodes-6380.conf b698be686bad9dc10e79c8a46b7f11d9651cba2b :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 [root@YL-SLAVE2 redis-cluster]# cat 6381/nodes-6381.conf ee5108176e17b658bb11fbb712dcb6dd34a4b218 :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 [root@YL-SLAVE2 redis-cluster]# cat 6382/nodes-6382.conf 769409fa0ef89381632cfee58df55c0e703c48c3 :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0 ``` ###### 随机创建集群 创建集群的时候,可以指定哪些是主节点,哪些是从节点,但是不能保证从节点归属于那个主节点。 - 创建集群,并分配插槽slots Redis下有0到16383,供16384个插槽 主节点才会占用插槽,从节点不会占用插槽。从节点只会根据主节点的数据进行同步。 进入任意一个节点下面,执行下述命令 ```shell [root@YL-MASTER bin]# pwd /usr/local/custom-util/redis/station/redis-cluster/6380/bin [root@YL-MASTER bin]# ./redis-cli --cluster create 192.168.0.120:6380 192.168.0.121:6380 192.168.0.122:6380 192.168.0.122:6381 192.168.0.120:6381 192.168.0.121:6381 --cluster-replicas 1 >>> Performing hash slots allocation on 6 nodes... # 分配三个主节点 Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 # 给每个主节点分配了一个从节点 Adding replica 192.168.0.121:6381 to 192.168.0.120:6380 Adding replica 192.168.0.122:6381 to 192.168.0.121:6380 Adding replica 192.168.0.120:6381 to 192.168.0.122:6380 # 主节点 M: a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380 slots:[0-5460] (5461 slots) master # 主节点 M: 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380 slots:[5461-10922] (5462 slots) master # 主节点 M: b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380 slots:[10923-16383] (5461 slots) master # 从节点 S: ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381 replicates 8d7eaf14ab9c30eff991b96fc86f6021ae0138df # 从节点 S: fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381 replicates b698be686bad9dc10e79c8a46b7f11d9651cba2b # 从节点 S: c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381 replicates a3cac1c19469ad85bc59f13579dd0df0a3b588cd # 是否允许自动分配插槽slots 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 192.168.0.120:6380) # 一主插槽分配 M: a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380 slots:[0-5460] (5461 slots) master 1 additional replica(s) # 二主插槽分配 M: 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381 slots: (0 slots) slave replicates b698be686bad9dc10e79c8a46b7f11d9651cba2b S: ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381 slots: (0 slots) slave replicates 8d7eaf14ab9c30eff991b96fc86f6021ae0138df # 三主插槽分配 M: b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381 slots: (0 slots) slave replicates a3cac1c19469ad85bc59f13579dd0df0a3b588cd [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. ``` - 从集群配置文件查看节点信息 ```shell [root@YL-MASTER bin]# pwd /usr/local/custom-util/redis/station/redis-cluster/6380/bin [root@YL-MASTER bin]# cat ../nodes-6380.conf 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380@16380 master - 0 1607141524000 2 connected 5461-10922 fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381@16381 slave b698be686bad9dc10e79c8a46b7f11d9651cba2b 0 1607141524000 5 connected ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381@16381 slave 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 0 1607141526347 4 connected b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380@16380 master - 0 1607141525338 3 connected 10923-16383 a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380@16380 myself,master - 0 1607141524000 1 connected 0-5460 c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381@16381 slave a3cac1c19469ad85bc59f13579dd0df0a3b588cd 0 1607141525000 6 connected vars currentEpoch 6 lastVoteEpoch 0 ``` - 连接Redis集群 **注意**:这里连接的是**Redis集群**,而不是**Redis的实例** ```shell [root@YL-MASTER bin]# pwd /usr/local/custom-util/redis/station/redis-cluster/6380/bin [root@YL-MASTER bin]# ./redis-cli -h 192.168.0.120 -p 6380 -c 192.168.0.120:6380> ``` - 查看集群信息 ```shell 192.168.0.120:6380> 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:682 发送的ping消息的次数 cluster_stats_messages_pong_sent:638 接收到pong消息的次数,心跳检测 cluster_stats_messages_sent:1320 发送总数 cluster_stats_messages_ping_received:633 ping接收到返回的pong的次数 cluster_stats_messages_pong_received:682 pong接收到的ping次数 cluster_stats_messages_meet_received:5 会议添加节点次数,一共6个节点,除了初始创建一个,所以开了5次会议 cluster_stats_messages_received:1320 接收到消息总数 ``` - 查看集群节点信息 这里查询到的信息和在nodes.conf中信息一样 ```shell 192.168.0.120:6380> cluster nodes 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380@16380 master - 0 1607142469395 2 connected 5461-10922 fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381@16381 slave b698be686bad9dc10e79c8a46b7f11d9651cba2b 0 1607142467377 5 connected ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381@16381 slave 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 0 1607142468386 4 connected b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380@16380 master - 0 1607142469000 3 connected 10923-16383 a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380@16380 myself,master - 0 1607142466000 1 connected 0-5460 c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381@16381 slave a3cac1c19469ad85bc59f13579dd0df0a3b588cd 0 1607142468000 6 connected ``` - 分片集群测试 ```shell 192.168.0.120:6380> set name:1 cll # 说明对当前key进行hash之后,不再当前节点上,重定向到122节点进行写入操作 -> Redirected to slot [12501] located at 192.168.0.122:6380 OK 192.168.0.122:6380> set name:2 yl # 说明对当前key进行hash之后,不再当前节点上,重定向到120节点进行写入操作 -> Redirected to slot [182] located at 192.168.0.120:6380 OK 192.168.0.120:6380> set name:3 wn # 当前key进行hash之后,刚好在当前节点,直接进行插入 OK 192.168.0.120:6380> set name:4 lsq # 说明对当前key进行hash之后,不再当前节点上,重定向到121节点进行写入操作 -> Redirected to slot [8304] located at 192.168.0.121:6380 OK ``` ```shell # 查询节点的时候,集群同样首先对key进行hash,hash之后对16384进行取模,然后根据nodes.conf中的插槽的信息,确定当前key存储在那个插槽,就重定向到拥有该插槽的节点 192.168.0.121:6380> get name:1 -> Redirected to slot [12501] located at 192.168.0.122:6380 "cll" 192.168.0.122:6380> get name:2 -> Redirected to slot [182] located at 192.168.0.120:6380 "yl" 192.168.0.120:6380> get name:3 "wn" 192.168.0.120:6380> get name:4 -> Redirected to slot [8304] located at 192.168.0.121:6380 "lsq" ``` ###### 集群扩容 集群扩容,也就是添加新的主节点。 需要做两件事情 1、将新的Redis加入到Redis的集群中 2、给新加入的主节点分配插槽 ​ 给主节点分配插槽,可以从一个节点分配,也可以从所有的主节点进行分配。 搭建Redis实例的过程就不再重复描述了。搭建Redis实例之后,启动Redis实例。 ```shell [root@CLL-MASTER redis-cluster]# ps -ef | grep redis root 6314 1 0 13:02 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6380/bin/redis-server 192.168.0.123:6380 [cluster] root 6316 1 0 13:02 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6381/bin/redis-server 192.168.0.123:6381 [cluster] root 6321 1 0 13:02 ? 00:00:00 /usr/local/custom-util/redis/station/redis-cluster/6382/bin/redis-server 192.168.0.123:6382 [cluster] root 6344 1894 0 13:03 pts/0 00:00:00 grep --color=auto redis [root@CLL-MASTER redis-cluster]# ifconfig ens33: flags=4163 mtu 1500 inet 192.168.0.123 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::9729:15c7:bb72:9056 prefixlen 64 scopeid 0x20 ether 00:0c:29:46:ff:bd txqueuelen 1000 (Ethernet) RX packets 46088 bytes 62164472 (59.2 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8911 bytes 1023463 (999.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ``` - 添加主节点 ```shell # 添加节点命令的格式如下 ./redis-cli --cluster add-node [新添加节点] [集群中原来的节点] # 集群中原来的节点,可以是任意的节点,但是一般习惯使用最小的主节点 [root@CLL-MASTER bin]# pwd /usr/local/custom-util/redis/station/redis-cluster/6380/bin [root@CLL-MASTER bin]# ./redis-cli --cluster add-node 192.168.0.123:6380 192.168.0.120:6380 # 向集群中添加节点 >>> Adding node 192.168.0.123:6380 to cluster 192.168.0.120:6380 # 执行集群检测,主要是节点的检测和插槽的检测 >>> Performing Cluster Check (using node 192.168.0.120:6380) M: a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381 slots: (0 slots) slave replicates b698be686bad9dc10e79c8a46b7f11d9651cba2b S: ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381 slots: (0 slots) slave replicates 8d7eaf14ab9c30eff991b96fc86f6021ae0138df M: b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381 slots: (0 slots) slave replicates a3cac1c19469ad85bc59f13579dd0df0a3b588cd [OK] All nodes agree about slots configuration. # 所有节点配置正常 >>> Check for open slots... >>> Check slots coverage... # 所有的插槽配置正常 [OK] All 16384 slots covered. # 开会讨论新加入主节点 >>> Send CLUSTER MEET to node 192.168.0.123:6380 to make it join the cluster. # 加入新的主节点成功 [OK] New node added correctly. ``` - 查看集群信息 ```shell 192.168.0.120:6380> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:7 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:3452 cluster_stats_messages_pong_sent:3265 cluster_stats_messages_sent:6717 cluster_stats_messages_ping_received:3259 cluster_stats_messages_pong_received:3452 cluster_stats_messages_meet_received:6 cluster_stats_messages_received:6717 ``` - 查看集群节点插槽 ```shell # 这个时候新加入的节点,还不能称之为主节点,因为还没有分配插槽信息 192.168.0.120:6380> cluster nodes 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380@16380 master - 0 1607145036998 2 connected 5461-10922 fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381@16381 slave b698be686bad9dc10e79c8a46b7f11d9651cba2b 0 1607145035000 5 connected ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381@16381 slave 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 0 1607145036000 4 connected b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380@16380 master - 0 1607145035000 3 connected 10923-16383 f4c39c492a9026b3b33b845a880b80a6a4e86157 192.168.0.123:6380@16380 master - 0 1607145038006 0 connected a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380@16380 myself,master - 0 1607145035000 1 connected 0-5460 c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381@16381 slave a3cac1c19469ad85bc59f13579dd0df0a3b588cd 0 1607145037000 6 connected ``` - 分配插槽slots 重新分配插槽,意味的两件事情。 1、需要给主节点重新配置插槽的归属 2、重新分配插槽归属之后,原来插槽对应的数据的迁移 ```sql # 重新分配插槽,就相当于重新修改分片算法 # 语法格式如下,集群中的任意一个节点,表示可以是原来的旧的节点,可以是主节点,也可以是从节点。也可以是新添加的没有分配插槽的节点。 # 但是我个人习惯于使用新添加的未分配插槽的节点,这里就是192.168.0.123:6380 ./redis-cli --cluster reshard [集群中的任意一个节点] 1. 需要输入给那个节点分配插槽 2. 需要数据给节点分配的插槽的数量 3. 需要输入从哪些源节点从分配插槽 4. 确认分配插槽的结果 ``` - 重新查看集群的信息 ``` 192.168.0.120:6380> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:7 cluster_size:4 这里由原来的3变为了4,说明主节点已经变成了4个 cluster_current_epoch:7 cluster_my_epoch:1 cluster_stats_messages_ping_sent:4297 cluster_stats_messages_pong_sent:4052 cluster_stats_messages_update_sent:9 cluster_stats_messages_sent:8358 cluster_stats_messages_ping_received:4046 cluster_stats_messages_pong_received:4297 cluster_stats_messages_meet_received:6 cluster_stats_messages_update_received:1 cluster_stats_messages_received:8350 ``` - 查看集群节点分片配置 ```shell 192.168.0.120:6380> cluster nodes 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380@16380 master - 0 1607145917510 2 connected 6462-10922 fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381@16381 slave b698be686bad9dc10e79c8a46b7f11d9651cba2b 0 1607145913478 5 connected ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381@16381 slave 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 0 1607145914485 4 connected b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380@16380 master - 0 1607145915494 3 connected 11922-16383 f4c39c492a9026b3b33b845a880b80a6a4e86157 192.168.0.123:6380@16380 master - 0 1607145917000 7 connected 0-998 5461-6461 10923-11921 # 发现123上面的主节点,使用了三个插槽组,这三个插槽组就是从原来其它三个主节点中分配过来的 a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380@16380 myself,master - 0 1607145914000 1 connected 999-5460 c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381@16381 slave a3cac1c19469ad85bc59f13579dd0df0a3b588cd 0 1607145917000 6 connected ``` ###### 集群添加从节点 给集群中添加从节点,同样是添加节点,所以用的还是添加节点的命令。只不过是需要指明添加的节点是从节点,然后指定当前从节点归属的主节点是那个。 - 添加从节点 ```shell # 命令格式如下 ./redis-cli --cluster add-node [新添加的节点] [集群中的旧节点] --cluster-slave --cluster-master-id [归属的主节点的ID] # 命令解析 ./redis-cli : 客户端连接 --cluster: 表示集群操作 add-node: 表示添加节点 [新节点的ip:port]: 声明添加的节点信息 [旧节点的ip:port]: 指明向那个集群中添加节点,所以可以是集群中的任意一个现有节点 --cluster-slave: 表明添加的是从节点 --cluster-master-id [主节点ID]: 表明当前从节点归属的主节点 [root@YL-MASTER bin]# ./redis-cli --cluster add-node 192.168.0.123:6381 192.168.0.123:6380 --cluster-slave --cluster-master-id f4c39c492a9026b3b33b845a880b80a6a4e86157 # 这里的f4c39c492a9026b3b33b845a880b80a6a4e86157是192.168.0.123:6380节点的ID # 添加节点到集群 >>> Adding node 192.168.0.123:6381 to cluster 192.168.0.123:6380 # 执行集群检测,从192.168.0.123:6380节点 >>> Performing Cluster Check (using node 192.168.0.123:6380) M: f4c39c492a9026b3b33b845a880b80a6a4e86157 192.168.0.123:6380 slots:[0-998],[5461-6461],[10923-11921] (2999 slots) master S: fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381 slots: (0 slots) slave replicates b698be686bad9dc10e79c8a46b7f11d9651cba2b M: 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380 slots:[6462-10922] (4461 slots) master 1 additional replica(s) M: b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380 slots:[11922-16383] (4462 slots) master 1 additional replica(s) M: a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380 slots:[999-5460] (4462 slots) master 1 additional replica(s) S: ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381 slots: (0 slots) slave replicates 8d7eaf14ab9c30eff991b96fc86f6021ae0138df S: c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381 slots: (0 slots) slave replicates a3cac1c19469ad85bc59f13579dd0df0a3b588cd # 节点正常 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... # 插槽正常 [OK] All 16384 slots covered. # 开会讨论加入新的节点 >>> Send CLUSTER MEET to node 192.168.0.123:6381 to make it join the cluster. # 等待节点加入集群 Waiting for the cluster to join # 配置加入的节点属于那个节点的副本 >>> Configure node as replica of 192.168.0.123:6380. # 节点加入成功 [OK] New node added correctly. ``` - 查看集群信息 ```shell 192.168.0.120:6380> cluster info 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 cluster_current_epoch:7 开会讨论的次数增加了1次 cluster_my_epoch:1 cluster_stats_messages_ping_sent:5164 cluster_stats_messages_pong_sent:4846 cluster_stats_messages_update_sent:9 cluster_stats_messages_sent:10019 cluster_stats_messages_ping_received:4840 cluster_stats_messages_pong_received:5164 cluster_stats_messages_meet_received:6 cluster_stats_messages_update_received:1 cluster_stats_messages_received:10011 ``` - 查看集群中分片节点信息 ```shell 192.168.0.120:6380> cluster nodes 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380@16380 master - 0 1607146754000 2 connected 6462-10922 fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381@16381 slave b698be686bad9dc10e79c8a46b7f11d9651cba2b 0 1607146754603 5 connected ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381@16381 slave 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 0 1607146756000 4 connected b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380@16380 master - 0 1607146753000 3 connected 11922-16383 f4c39c492a9026b3b33b845a880b80a6a4e86157 192.168.0.123:6380@16380 master - 0 1607146756617 7 connected 0-998 5461-6461 10923-11921 a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380@16380 myself,master - 0 1607146757000 1 connected 999-5460 # 加入的节点是从节点正常,归属的主节点正常 789d5bd46eb9f021bd6bac0acdd755e85f5fd464 192.168.0.123:6381@16381 slave f4c39c492a9026b3b33b845a880b80a6a4e86157 0 1607146755000 7 connected c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381@16381 slave a3cac1c19469ad85bc59f13579dd0df0a3b588cd 0 1607146756000 6 connected ``` > 为了完成Redis Cluster计划,再给每个主节点添加一台本地的从节点 - 120添加从节点6382 ```shell ./redis-cli --cluster add-node 192.168.0.120:6382 192.168.0.120:6380 --cluster-slave --cluster-master-id a3cac1c19469ad85bc59f13579dd0df0a3b588cd ``` - 121添加从节点6382 ```shell ./redis-cli --cluster add-node 192.168.0.121:6382 192.168.0.121:6380 --cluster-slave --cluster-master-id 8d7eaf14ab9c30eff991b96fc86f6021ae0138df ``` - 122添加从节点6382 ```shell ./redis-cli --cluster add-node 192.168.0.122:6382 192.168.0.122:6380 --cluster-slave --cluster-master-id b698be686bad9dc10e79c8a46b7f11d9651cba2b ``` - 123添加从节点6382 ```shell ./redis-cli --cluster add-node 192.168.0.123:6382 192.168.0.123:6380 --cluster-slave --cluster-master-id f4c39c492a9026b3b33b845a880b80a6a4e86157 ``` - 重新查看集群信息 ```shell 192.168.0.120:6380> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:12 共有12个节点,代表12个Redis实例 cluster_size:4 cluster_current_epoch:7 cluster_my_epoch:1 cluster_stats_messages_ping_sent:6153 cluster_stats_messages_pong_sent:5825 cluster_stats_messages_update_sent:9 cluster_stats_messages_sent:11987 cluster_stats_messages_ping_received:5818 cluster_stats_messages_pong_received:6153 cluster_stats_messages_meet_received:7 cluster_stats_messages_update_received:1 cluster_stats_messages_received:11979 ``` - 重新查看集群节点信息 ```shell 192.168.0.120:6380> cluster nodes dc5de96950d88d02c3f303a66097c274ceaa1a19 192.168.0.120:6382@16382 slave a3cac1c19469ad85bc59f13579dd0df0a3b588cd 0 1607147888518 1 connected fce563734d4d5cd1ca46b347d541b95a8367d4bb 192.168.0.120:6381@16381 slave b698be686bad9dc10e79c8a46b7f11d9651cba2b 0 1607147887915 5 connected b698be686bad9dc10e79c8a46b7f11d9651cba2b 192.168.0.122:6380@16380 master - 0 1607147888926 3 connected 11922-16383 c044367292f1399906a827aadb89230661c7996e 192.168.0.121:6381@16381 slave a3cac1c19469ad85bc59f13579dd0df0a3b588cd 0 1607147886000 6 connected 7eab70ac0090c4bba64871eea60731e585bbbcd1 192.168.0.121:6382@16382 slave 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 0 1607147886506 2 connected 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 192.168.0.121:6380@16380 master - 0 1607147890000 2 connected 6462-10922 ee5108176e17b658bb11fbb712dcb6dd34a4b218 192.168.0.122:6381@16381 slave 8d7eaf14ab9c30eff991b96fc86f6021ae0138df 0 1607147887000 4 connected 769409fa0ef89381632cfee58df55c0e703c48c3 192.168.0.122:6382@16382 slave b698be686bad9dc10e79c8a46b7f11d9651cba2b 0 1607147887000 3 connected a3cac1c19469ad85bc59f13579dd0df0a3b588cd 192.168.0.120:6380@16380 myself,master - 0 1607147888000 1 connected 999-5460 f4c39c492a9026b3b33b845a880b80a6a4e86157 192.168.0.123:6380@16380 master - 0 1607147889929 7 connected 0-998 5461-6461 10923-11921 16b80a826d9823d5da981c42714ffbfac42ece3f 192.168.0.123:6382@16382 slave f4c39c492a9026b3b33b845a880b80a6a4e86157 0 1607147890000 7 connected 789d5bd46eb9f021bd6bac0acdd755e85f5fd464 192.168.0.123:6381@16381 slave f4c39c492a9026b3b33b845a880b80a6a4e86157 0 1607147890000 7 connected # 查询出来共有12个节点,Redis实例 ``` ###### 集群缩容 1、需要将准备移除集群的主节点的插槽分配给其它的节点 2、删除主节点 - 重新分配插槽 ```shell ./redis-cli --cluster reshard [集群中任意一个节点IP:PORT] ``` - 删除主节点 ```shell ./redis-cli --cluster del-node [集群中任意一个节点IP:PORT] [要移除的主节点的ID] ``` ## Java使用Redis Cluster - 项目构建 ```xml 4.0.0 com.cll.prototype prototype-redis pom 1.0-SNAPSHOT redis-java redis-spring redis-springboot redis-cluster UTF-8 UTF-8 1.8 1.8 1.18.16 3.3.0 5.2.5.RELEASE 4.12 2.4.1 org.springframework.boot spring-boot-starter-parent 2.3.5.RELEASE pom import org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 1.8 1.8 ``` - 模块构建 ```xml prototype-redis com.cll.prototype 1.0-SNAPSHOT 4.0.0 redis-cluster org.springframework spring-context ${spring.version} org.springframework spring-test ${spring.version} junit junit ${junit.version} test org.springframework.data spring-data-redis ${spring-data-redis.version} redis.clients jedis ${jedis.version} ``` - Spring配置文件 ```xml classpath:redis.properties ``` - Redis连接池配置文件 ```properties redis.pool.maxTotal=100 redis.pool.minIdle=2 redis.pool.maxIdle=50 redis.pool.maxWaitMillis=1000 redis.pool.testOnBorrow=true ``` - 测试类编写 ```java package com.cll.prototype.redis.cluster; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/12/5 20:19 */ @ContextConfiguration("classpath:spring-redis-cluster.xml") public class RedisTemplateTest extends AbstractJUnit4SpringContextTests { @Autowired private RedisTemplate redisTemplate; @Test public void testSetAndGet(){ redisTemplate.opsForValue().set("name:author", "cll-cluster"); System.out.println(redisTemplate.opsForValue().get("name:author")); } } ``` - 控制台截图 ![](D:\workSpace\mineGitWorkSpace\oneselft-learn\prototype-redis\java-console.jpg) - Redis命令行截图 ![](D:\workSpace\mineGitWorkSpace\oneselft-learn\prototype-redis\redis-console.jpg)