千家信息网

Redis 的四种模式

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,主从模式redis主从模式,顾名思义。就是一主一从或一主多从。配置很简单,只需要在从的配置文件中写一个参数即可。slaveof # 例如# slaveof 192.168.1.197 6379优点:
千家信息网最后更新 2025年01月23日Redis 的四种模式

主从模式

redis主从模式,顾名思义。就是一主一从或一主多从。配置很简单,只需要在从的配置文件中写一个参数即可。

slaveof  # 例如# slaveof 192.168.1.197 6379

优点:

配置简单,使用灵活,数据安全性较高。

缺点:

无法实现故障切换,当master down后,slave无法自动切换为主接替后续任务。

哨兵模式

哨兵模式部署步骤也很简单,redis.conf的配置文件就不在阐述,跟普通redis配置文件一样,cp一份就行。

// vim sentinel.conf# 后台运行protected-mode yes  # 绑定的服务器ip,如果不写ip默认为127.0.0.1,只能本地连接bind 10.10.10.137# 后台运行daemonize yes# 开启端口,如果主从都在同一台机器,记得端口要改一下,别冲突port 26380# 需要监控的主的ip地址和端口,后面的1表示有一个哨兵发现master down后,就切换slave为 mastersentinel monitor mymaster 127.0.0.1 6379 1# sentinel会向master发送心跳PING来确认master是否存活,如果master在"一定时间范围"内不回应PING 或者是回复了一个错误消息,# 那么这个sentinel会主观地(单方面地)认为这个master已经不可用了(subjectively down, 也简称为SDOWN)。# 而这个down-after-milliseconds就是用来指定这个"一定时间范围"的,单位是毫秒。sentinel down-after-milliseconds mymaster 3000# failover过期时间。当failover开始后,在此时间内仍然没有触发任何failover操作,当前sentinel将会认为此次failoer失败。  sentinel failover-timeout mymaster 1800

分别启动redis进程和sentinel进程。

./redis-server redis.conf./redis-server sentinel.conf

高可用集群分片模式

重要讲解redis的官方集群安装方式是如何操作的。

需要用到的软件

redis-4.0.9.tar.gz 下载 (3.0开始支持集群功能)

ruby-2.5.7.tar.gz 下载 (一般我们选择2.4或2.5就行,尽量不要用yum安装,因为yum安装的ruby是2.0.0的,gem install redis ruby的版本必须是2.2.2以上)

redis-4.0.0.gem 下载

zlib-1.2.11.tar.gz 自行网上查找

openssl-1.1.1a.tar.gz 自行网上查找

启动端口:7001 7002 7003 7004 7005 7006

配置文件:/app/redis/redis-cluster

本文当中,我们在一台Linux上搭建6个节点的Redis集群(实际生产环境,需要3台Linux服务器分布存放3个Master)

使用root用户安装,因为普通用户没有创建目录及编译权限,需要授权

以下只讲述离线安装步骤

安装

第一步:安装gcc环境

查看gcc版本,如果没有安装则需要进行安装

[root@localhost ~]# gcc -v使用内建 specs。目标: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-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux线程模型:posixgcc 版本 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)

使用yum命令在线安装

yum -y install gcc gcc-c++

第二步:解压redis并编译安装

cd /app/redis/tar -xvf redis-4.0.9.tar.gzcd redis-4.0.9/make/app/redis/redis-4.0.9/srcmake install

安装成功提示

Hint: It's a good idea to run 'make test' ;)INSTALL installINSTALL installINSTALL installINSTALL installINSTALL install

redis安装完之后会在/usr/local/bin目录下多几个文件

[root@localhost ~]# ll /usr/local/bin总用量 35500-rwxr-xr-x. 1 root root 5600238 5月   6 20:54 redis-benchmark-rwxr-xr-x. 1 root root 8331277 5月   6 20:54 redis-check-aof-rwxr-xr-x. 1 root root 8331277 5月   6 20:54 redis-check-rdb-rwxr-xr-x. 1 root root 5739834 5月   6 20:54 redis-clilrwxrwxrwx. 1 root root      12 5月   6 20:54 redis-sentinel -> redis-server-rwxr-xr-x. 1 root root 8331277 5月   6 20:54 redis-server

第三步:解压ruby并编译安装

cd /app/redistar -xvf ruby-2.5.1.tar.gzcd ruby-2.5.1/./configure --prefix=/usr/local/ruby  --prefix是将ruby安装到指定目录,也可以自定义make && make install

安装成功后可以看到在ruby目录下多了四个目录

[root@localhost ~]# ll /usr/local/ruby总用量 16drwxr-xr-x. 2 root root 4096 10月 10 11:59 bindrwxr-xr-x. 3 root root 4096 10月 10 11:59 includedrwxr-xr-x. 4 root root 4096 10月 10 11:59 libdrwxr-xr-x. 5 root root 4096 10月 10 11:59 share

配置ruby环境变量

vi /etc/profileexport PATH=$PATH:/usr/local/ruby/bin:wqsource /etc/profileecho $PATH/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/openssh-7.5p1/bin:/root/bin:/usr/local/ruby/bin

查看ruby版本号

[root@localhost ~]# ruby -vruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-linux]

第四步:创建redis-cluster集群目录并拷贝redis的gem包以及在src下将redis-trib.rb 集群管理工具拷贝到集群目录

cd /app/redismkdir redis-clustercp redis-4.0.0.gem redis-cluster//app/redis/redis-4.0.9/srccp redis-trib.rb /app/redis/redis-cluster/

第五步:使用gem安装redis的gem包

cd /app/redis/redis-clustergem install redis-4.0.0.gem

如果安装没有任何问题会出现以下提示

Successfully installed redis-4.0.0Parsing documentation for redis-4.0.0Installing ri documentation for redis-4.0.0Done installing documentation for redis after 1 seconds1 gem installed

如在第五步报错需要zlib或者openssl

解决zlib报错问题

cd /app/redis/ruby-2.5.1/ext/zlibruby extconf.rb    --成功会出现creating Makefile
creating Makefile    --如果没有出现creating Makefile,执行下面的命令ruby extconf.rb --with-zlib-dir=/usr/local/zlib/
vi Makefile将     zlib.o: $(top_srcdir)/include/ruby.h修改为 zlib.o: ../../include/ruby.hmake# 成功显示linking shared-object zlib.somake install# 成功显示/usr/bin/install -c -m 0755 zlib.so /usr/local/ruby/lib/ruby/site_ruby/2.5.0/x86_64-linux
如果上面再执行make之前不修改Makefile,将会报下面的错误make: * No rule to make target /include/ruby.h', needed byzlib.o'. Stop.

解决openssl报错问题

首先要安装openssl,如果系统安装了,本步骤可以省略

cd /app/redistar -zxvf openssl-1.1.1a.tar.gz./config --prefix=/usr/local/openssl && make && make install

安装完成后继续解决openssl报错问题

cd /app/redis/ruby-2.5.1/ext/opensslruby extconf.rb    --成功会出现creating Makefile

如发现没有出现creating Makefile,请执行下面命令

vi Makefile将所有的$(top_srcdir)修改为 ../..$(top_srcdir)  # 注意(top_srcdir)不止有一个,所有的都要改make# 成功安装输出linking shared-object openssl.somake install# 成功安装输出/usr/bin/install -c -m 0755 openssl.so /usr/local/ruby/lib/ruby/site_ruby/2.5.0/x86_64-linuxinstalling default openssl libraries
如果上面再执行make之前不修改Makefile,将会报下面的错误make: * No rule to make target /include/ruby.h', needed byossl.o'. Stop.

再次使用gem安装redis的gem包

# 不出意外可以顺利安装 cd /app/redis/redis-clustergem install redis-4.0.0.gem

四.创建集群

之前讲到是我们需要6个节点的Redis作为集群,所以我们需要创建6个文件夹,分别存放6个节点的配置信息,6个节点需要对应6个端口号,比如7001~7006,这个端口号我们可以自行定义。

/app/redis/redis-cluster/mkdir 700{1,2,3,4,5,6}    --批量创建六个文件夹

将原先redis安装目录下的配置文件redis.conf拷贝到新创建的六个文件夹下面

cd /app/redis/redis-4.0.9cp redis.conf /app/redis/redis-cluster/7001/cp redis.conf /app/redis/redis-cluster/7002/cp redis.conf /app/redis/redis-cluster/7003/cp redis.conf /app/redis/redis-cluster/7004/cp redis.conf /app/redis/redis-cluster/7005/cp redis.conf /app/redis/redis-cluster/7006/

将redis安装之后生成的服务端与客户端拷贝到新创建的六个文件夹下面

cd /usr/local/bin/cp redis-server redis-cli /app/redis/redis-cluster/7001/cp redis-server redis-cli /app/redis/redis-cluster/7002/cp redis-server redis-cli /app/redis/redis-cluster/7003/cp redis-server redis-cli /app/redis/redis-cluster/7004/cp redis-server redis-cli /app/redis/redis-cluster/7005/cp redis-server redis-cli /app/redis/redis-cluster/7006/

修改新创建的六个文件夹下面的配置文件redis.conf的部分参数

cd /app/redis/redis-cluster/修改7001-7006中的redis.confbind 192.168.5.104    连入主机的ip地址,不修改外部无法连入你的redis缓存服务器中port 700X    x为文件夹名称,你在700几就填几daemonize yes    开启守护进程模式。在该模式下,redis会在后台运行,并将进程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将一直运行,除非手动kill该进程。pidfile /app/redis/redis-cluster/700x/redis_700x.pid    x为文件夹名称,你在700几就填几cluster-enabled yes    开启集群模式

cd /app/redis/redis-cluster

写个批处理 vim start-all.sh,如果vim不支持就用vi

vim start-all.sh

cd 7001  ./redis-server redis.confcd ..cd 7002  ./redis-server redis.confcd ..cd 7003  ./redis-server redis.confcd ..cd 7004  ./redis-server redis.confcd ..cd 7005  ./redis-server redis.confcd ..cd 7006  ./redis-server redis.confcd ..
并执行 chmod +x start-all.sh 命令进行授权

启动实例之前在根路径下配置多种环境

yum -y install gcc gcc-c++

启动集群实例

./start-all.sh[root@localhost redis]# ps -ef|grep redisroot     14253     1  0 Oct14 ?        00:03:27 ./redis-server 192.168.5.104:7001 [cluster]root     14262     1  0 Oct14 ?        00:03:38 ./redis-server 192.168.5.104:7006 [cluster]root     18571 13962  0 15:37 pts/0    00:00:00 grep redisroot     30364     1  0 Oct10 ?        00:15:55 ./redis-server 192.168.5.104:7002 [cluster]root     30372     1  0 Oct10 ?        00:15:51 ./redis-server 192.168.5.104:7003 [cluster]root     30374     1  0 Oct10 ?        00:15:31 ./redis-server 192.168.5.104:7004 [cluster]root     30379     1  0 Oct10 ?        00:15:17 ./redis-server 192.168.5.104:7005 [cluster]

配置集群

cd /app/redis/redis-cluster# 创建了三个主节点,三个从节点。其中-replicas1 表示每个主节点下面有1个从节点,从节点可以是任意多个。./redis-trib.rb create --replicas 1 192.168.4.212:7001 192.168.4.212:7002 192.168.4.212:7003 192.168.4.212:7004 192.168.4.212:7005 192.168.4.212:7006
>>> Creating cluster>>> Performing hash slots allocation on 6 nodes...Using 3 masters:192.168.5.104:7001    --主节点192.168.5.104:7002    --主节点192.168.5.104:7003    --主节点Adding replica 192.168.5.104:7005 to 192.168.5.104:7001    -主节点对应的从节点Adding replica 192.168.5.104:7006 to 192.168.5.104:7002    -主节点对应的从节点Adding replica 192.168.5.104:7004 to 192.168.5.104:7003    -主节点对应的从节点>>> Trying to optimize slaves allocation for anti-affinity[WARNING] Some slaves are in the same host as their masterM: ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589 192.168.5.104:7001   slots:0-5460 (5461 slots) master                        --主节点分配的hash槽M: 3d48e5f1dbb2640d96b4522ece9b8be430bca721 192.168.5.104:7002   slots:5461-10922 (5462 slots) master                    --主节点分配的hash槽M: dfa039f4cb9fed60b44e223a7afa462e34f904f7 192.168.5.104:7003   slots:10923-16383 (5461 slots) master                    --主节点分配的hash槽S: 4027313648b8615cec31b2b5c51e25bfc02ade59 192.168.5.104:7004   replicates 3d48e5f1dbb2640d96b4522ece9b8be430bca721      --从节点没有hash槽S: 57331ee1000d4ea652c7eda84b472a38bcd2e21d 192.168.5.104:7005   replicates dfa039f4cb9fed60b44e223a7afa462e34f904f7      --从节点没有hash槽S: 8ca8eeba19b0acba4fd6f1e9f7be3c4bdb5ea1e5 192.168.5.104:7006   replicates ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589      --从节点没有hash槽Can I set the above configuration? (type 'yes' to accept): yes   --选择yes, 意思是服从这种主从分配方式,我们也可以通过配置文件自己指定slave>>> Nodes configuration updated>>> Assign a different config epoch to each node>>> Sending CLUSTER MEET messages to join the clusterWaiting for the cluster to join....>>> Performing Cluster Check (using node 192.168.5.104:7001)        --以下是详细的主从节点分布M: ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589 192.168.5.104:7001   slots:0-5460 (5461 slots) master   1 additional replica(s)S: 4027313648b8615cec31b2b5c51e25bfc02ade59 192.168.5.104:7004   slots: (0 slots) slave   replicates 3d48e5f1dbb2640d96b4522ece9b8be430bca721S: 8ca8eeba19b0acba4fd6f1e9f7be3c4bdb5ea1e5 192.168.5.104:7006   slots: (0 slots) slave   replicates ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589M: 3d48e5f1dbb2640d96b4522ece9b8be430bca721 192.168.5.104:7002   slots:5461-10922 (5462 slots) master   1 additional replica(s)M: dfa039f4cb9fed60b44e223a7afa462e34f904f7 192.168.5.104:7003   slots:10923-16383 (5461 slots) master   1 additional replica(s)S: 57331ee1000d4ea652c7eda84b472a38bcd2e21d 192.168.5.104:7005   slots: (0 slots) slave   replicates dfa039f4cb9fed60b44e223a7afa462e34f904f7[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered

五.集群测试

测试主从高可用

停止7001(master),登录到7001的从上,查看发现状态为master,使用命令 info Replication

cd /app/redis/redis-cluster/7001./redis-cli -c -h 192.168.5.104 -p 7001./redis-cli -c -h 192.168.5.104 -p 7001 shutdown //关闭7001节点,如果没有-h参数,默认连接127.0.0.1,如果没有-p参数,默认连接6379端口(所有如果用默认的,就没有-h -p)说明:-h+host  -p+端口号  -c是要连接集群,注意坑,不加会报错的

当主master down后,重新上线后,原先的slave依旧是master,原先的master由原先的master变为slave了(亲测)

测试集群的分片性

通过java代码对3对redis进行循环写入,查看3个master上的是否都有数据(亲测所有master都有数据)

下面列出java连接redis的代码

 /*******************集群模式***********************/  JedisPoolConfig poolConfig = new JedisPoolConfig();     // 最大连接数     poolConfig.setMaxTotal(50);     // 最大空闲数     poolConfig.setMaxIdle(10);     // 最大允许等待时间,如果超过这个时间还未获取到连接,则会报JedisException异常:     // Could not get a resource from the pool     poolConfig.setMaxWaitMillis(1000);     Set nodes = new LinkedHashSet();     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7001")));     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7002")));     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7003")));     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7004")));     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7005")));     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7006")));     @SuppressWarnings("resource")  JedisCluster cluster = new JedisCluster(nodes, poolConfig);     for(int i=0;i<1000;i++){   try {   Thread.sleep(500);   System.out.println(i+"-------"+cluster.set("wc_"+i, "xinxin"+i));   }catch (Exception e) {    // TODO Auto-generated catch block    e.printStackTrace();    continue;   }  }


0