在阿里云上搭建redis高可用集群,并写一个简单的springboot小demo测试
搭建Redis-Cluster
搭建需求
搭建6 台 redis 服务器(搭建伪集群),实现6 个 redis 实例,并运行在不同的端口 7001-7006
1.准备工作
(1.1)安装gcc 【此步省略】
Redis 是 c 语言开发的。安装 redis 需要 c 语言的编译环境。如果没有 gcc 需要在线安装。
yum install gcc-c++
(1.2)使用yum命令安装 ruby (我们需要使用ruby脚本来实现集群搭建)【此步省略】
yum install ruby
yum install rubygems
(1.3)将redis源码包上传到 linux 系统 ,解压redis源码包
tar -zxvf redis(安装的redis的压缩包)
(1.4)编译redis源码 ,进入redis源码文件夹
make
看到以下输出结果,表示编译成功
(1.5)创建目录/usr/local/redis-cluster目录, 安装6个redis实例,分别安装在以下目录
/usr/local/redis-cluster/redis-1
/usr/local/redis-cluster/redis-2
/usr/local/redis-cluster/redis-3
/usr/local/redis-cluster/redis-4
/usr/local/redis-cluster/redis-5
/usr/local/redis-cluster/redis-6
以第一个redis实例为例,命令如下
make install PREFIX=/usr/local/redis-cluster/redis-1
出现此提示表示成功,按此方法安装其余5个redis实例
(1.6)复制配置文件 将 /redis-3.0.0/redis.conf 复制到redis下的bin目录下
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-1/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-2/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-3/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-4/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-5/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-6/bin
2.配置集群
(2.1)修改每个redis节点的配置文件redis.conf
修改运行端口为7001 (7002 7003 …)
将cluster-enabled yes 前的注释去掉(632行)
(2.2)启动每个redis实例
以第一个实例为例,命令如下
cd /usr/local/redis-cluster/redis-1/bin/
./redis-server redis.conf
把其余的5个也启动起来,然后查看一下是不是都启动起来了
[root@localhost ~]# ps -ef | grep redis
root 15776 15775 0 08:19 pts/1 00:00:00 ./redis-server *:7001 [cluster]
root 15810 15784 0 08:22 pts/2 00:00:00 ./redis-server *:7002 [cluster]
root 15831 15813 0 08:23 pts/3 00:00:00 ./redis-server *:7003 [cluster]
root 15852 15834 0 08:23 pts/4 00:00:00 ./redis-server *:7004 [cluster]
root 15872 15856 0 08:24 pts/5 00:00:00 ./redis-server *:7005 [cluster]
root 15891 15875 0 08:24 pts/6 00:00:00 ./redis-server *:7006 [cluster]
root 15926 15895 0 08:24 pts/7 00:00:00 grep redis
(2.3)上传redis-3.0.0.gem ,安装 ruby用于搭建redis集群的脚本。
[root@localhost ~]# gem install redis-3.0.0.gem
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation for redis-3.0.0...
Installing RDoc documentation for redis-3.0.0...
(2.4)使用 ruby 脚本搭建集群。
进入redis源码目录中的src目录 执行下面的命令
./redis-trib.rb create --replicas 1 192.168.25.140:7001 192.168.25.140:7002 192.168.25.140:7003
192.168.25.140:7004 192.168.25.140:7005 192.168.25.140:7006
出现下列提示信息
>>> Creating cluster
Connecting to node 192.168.25.140:7001: OK
Connecting to node 192.168.25.140:7002: OK
Connecting to node 192.168.25.140:7003: OK
Connecting to node 192.168.25.140:7004: OK
Connecting to node 192.168.25.140:7005: OK
Connecting to node 192.168.25.140:7006: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.25.140:7001
192.168.25.140:7002
192.168.25.140:7003
Adding replica 192.168.25.140:7004 to 192.168.25.140:7001
Adding replica 192.168.25.140:7005 to 192.168.25.140:7002
Adding replica 192.168.25.140:7006 to 192.168.25.140:7003
M: 1800237a743c2aa918ade045a28128448c6ce689 192.168.25.140:7001
slots:0-5460 (5461 slots) master
M: 7cb3f7d5c60bfbd3ab28800f8fd3bf6de005bf0d 192.168.25.140:7002
slots:5461-10922 (5462 slots) master
M: 436e88ec323a2f8bb08bf09f7df07cc7909fcf81 192.168.25.140:7003
slots:10923-16383 (5461 slots) master
S: c2a39a94b5f41532cd83bf6643e98fc277c2f441 192.168.25.140:7004
replicates 1800237a743c2aa918ade045a28128448c6ce689
S: b0e38d80273515c84b1a01820d8ecee04547d776 192.168.25.140:7005
replicates 7cb3f7d5c60bfbd3ab28800f8fd3bf6de005bf0d
S: 03bf6bd7e3e6eece5a02043224497c2c8e185132 192.168.25.140:7006
replicates 436e88ec323a2f8bb08bf09f7df07cc7909fcf81
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.25.140:7001)
M: 1800237a743c2aa918ade045a28128448c6ce689 192.168.25.140:7001
slots:0-5460 (5461 slots) master
M: 7cb3f7d5c60bfbd3ab28800f8fd3bf6de005bf0d 192.168.25.140:7002
slots:5461-10922 (5462 slots) master
M: 436e88ec323a2f8bb08bf09f7df07cc7909fcf81 192.168.25.140:7003
slots:10923-16383 (5461 slots) master
M: c2a39a94b5f41532cd83bf6643e98fc277c2f441 192.168.25.140:7004
slots: (0 slots) master
replicates 1800237a743c2aa918ade045a28128448c6ce689
M: b0e38d80273515c84b1a01820d8ecee04547d776 192.168.25.140:7005
slots: (0 slots) master
replicates 7cb3f7d5c60bfbd3ab28800f8fd3bf6de005bf0d
M: 03bf6bd7e3e6eece5a02043224497c2c8e185132 192.168.25.140:7006
slots: (0 slots) master
replicates 436e88ec323a2f8bb08bf09f7df07cc7909fcf81
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
3.连接Redis-Cluster
(3.1)客户端工具连接
Redis-cli 连接集群:
redis-cli -p 主机ip -p 端口(集群中任意端口) -c
-c:代表连接的是 redis 集群
测试值的存取:
(1)从本地连接到集群redis 使用7001端口 加 -c 参数
(2)存入name值为abc ,系统提示此值被存入到了7002端口所在的redis (槽是5798)
(3)提取name的值,可以提取。
(4)退出(quit)
(5)再次以7001端口进入 ,不带-c
(6)查询name值,无法获取,因为值在7002端口的redis上
(7)我们以7002端口进入,获取name值发现是可以获取的,而以其它端口进入均不能获取
./redis-cli -c -p 7000 -h 127.0.0.1
查看redis集群状态
./redis-trib.rb check 127.0.0.1:7001
在网上很多都是在虚拟机上搭建redis伪分布式的,很少在阿里云服务器搭建的。在这次搭建中我遇到了很多坑,分享出来希望能帮到你。整个步骤就不说了,说一下在这个过程中遇到的问题:
redis.conf中属性bind:
1.(1)默认的是127.0.0.1不能使用这个否则只能内部访问,在连接时使用的搭建的命令:./redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1.171:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006(7001-7006是我使用的端口)
(2)私网就是使用ifconfig命令出来的那个,搭建是命令:./redis-trib.rb create --replicas 1 私网ip:7001 私网ip:7002 127.0.0.1:7003 私网ip:7004 私网ip:7005 私网ip:7006。如果使用这个用RedisDesktManager(windows下的一个图形界面客户端)能够访问和连接,但用JedisCluster连接连接时会报异常(redis.clients.jedis.exceptions.JedisConnectionException:Could not get a resource from the pool)。
(3)公网ip(就是你访问的服务器的地址)emmm就会发现连服务都启动不起来。
(4)正确版本,注释掉用#bind XXXXXXX并且在redis.conf中需要将改为:protected-mode no。然而执行:./redis-trib.rb create --replicas 1 公网ip:7001 公网ip:7002 公网ip:7003 公网ip:7004 公网ip:7005 公网ip:7006执行到一半的时候会卡住(waiting for the cluster to join…),这时需要将你的端口+10000开放我的是把17001,17002等开放了(本机包括阿里云的的安全规则)。之后再从新搭建就可以成功了,使用JedisCluster2.9.0访问也能访问了。
(3.2)SpringDataRedis连接Redis集群
修改品优购工程 在pinyougou-common工程添加spring 配置文件
applicationContext-redis-cluster.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:properties/redis-cluster-config.properties" />
<bean id="redis-clusterConfiguration" class="org.springframework.data.redis.connection.redis-clusterConfiguration">
<property name="maxRedirects" value="${redis.maxRedirects}"></property>
<property name="clusterNodes">
<set>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host1}"></constructor-arg>
<constructor-arg name="port" value="${redis.port1}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host2}"></constructor-arg>
<constructor-arg name="port" value="${redis.port2}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host3}"></constructor-arg>
<constructor-arg name="port" value="${redis.port3}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host4}"></constructor-arg>
<constructor-arg name="port" value="${redis.port4}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host5}"></constructor-arg>
<constructor-arg name="port" value="${redis.port5}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.redis-clusterNode">
<constructor-arg name="host" value="${redis.host6}"></constructor-arg>
<constructor-arg name="port" value="${redis.port6}"></constructor-arg>
</bean>
</set>
</property>
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxTotal" value="${redis.maxTotal}" />
</bean>
<bean id="jeidsConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
<constructor-arg ref="redis-clusterConfiguration" />
<constructor-arg ref="jedisPoolConfig" />
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jeidsConnectionFactory" />
</bean>
</beans>
添加属性文件redis-cluster-config.properties
#cluster configuration
redis.host1=192.168.25.140
redis.port1=7001
redis.host2=192.168.25.140
redis.port2=7002
redis.host3=192.168.25.140
redis.port3=7003
redis.host4=192.168.25.140
redis.port4=7004
redis.host5=192.168.25.140
redis.port5=7005
redis.host6=192.168.25.140
redis.port6=7006
redis.maxRedirects=3
redis.maxIdle=100
redis.maxTotal=600
4.demo测试
创建项目
(4.1)在pom.xml添加redis的jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
(4.2)配置application.yml
spring:
redis:
cluster:
nodes: 公网ip:7001,公网ip:7002,公网ip:7003,公网ip:7004,公网ip:7005公网ip:7006
max-redirects: 6
(4.3)在test中进行测试
System.out.println(redisTemplate.hasKey("name"));
redisTemplate.opsForValue().set("name", "123214");
String name = (String) redisTemplate.opsForValue().get("name");
System.out.println(name);
redisTemplate.opsForValue().set("name2", "123214");
String name2 = (String) redisTemplate.opsForValue().get("name");
System.out.println(name2);
redisTemplate.opsForValue().set("name3", "123214");
String name3 = (String) redisTemplate.opsForValue().get("name");
System.out.println(name3);
redisTemplate.opsForValue().set("name4", "123214");
String name4 = (String) redisTemplate.opsForValue().get("name");
System.out.println(name4);
HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
hashOperations.put("user", "test", "测试");
System.out.println(hashOperations.get("user", "test"));
5.模拟集群异常测试
关闭节点命令
./redis-cli -p 端口 shutdown