【redis相关】redis集群结合Spring配置的一些问题
项目中要将单机版redis服务器改为redis集群,配置的过程和配置过程中遇到的一些问题作如下记录。
首先修改redis的配置文件redis.conf
daemonize yes
port xxxx (每个节点一个端口)
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
因为要让redis集群正常运行至少需要三个主节点,所以这里我们创建6个节点,将配置好的redis复制一份到当前目录,再将这两个redis节点分别复制到其他两台虚拟机上。这样我们就在3台服务器上部署了6个redis节点来组成redis集群。
这里复制redis到其他虚拟机上采用scp命令
scp -r redis [email protected]:/
其中redis目录下包含两个redis节点
复制完成后,将六个redis节点的配置文件中的端口分别配置为7000~7005
分别启动六个redis节点,进入src目录下,执行
./redis-server ../redis.conf
问题1
访问集群中某个节点的时候可能会出现 JedisClusterException: CLUSTERDOWN Hash slot not served 的异常
这时进入相应的redis节点
redis-cli -h 10.211.55.9 -p 7000
检测节点是否可用
redis-trib.rb check 127.0.0.1:6379
结果: [ERR] Not all 16384 slots are covered by nodes
执行修复命令:redis-trib.rb fix 127.0.0.1:6379
等待修复完毕即可恢复节点。
继续配置集群,在spring配置文件中的配置如下
<bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
<property name="maxRedirects" value="6"></property>
<property name="clusterNodes">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.211.55.5"></constructor-arg>
<constructor-arg name="port" value="7000"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.211.55.5"></constructor-arg>
<constructor-arg name="port" value="7001"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.211.55.6"></constructor-arg>
<constructor-arg name="port" value="7002"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.211.55.6"></constructor-arg>
<constructor-arg name="port" value="7003"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.211.55.9"></constructor-arg>
<constructor-arg name="port" value="7004"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.211.55.9"></constructor-arg>
<constructor-arg name="port" value="7005"></constructor-arg>
</bean>
</set>
</property>
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大空闲数-->
<property name="maxIdle" value="300"/>
<!--连接池的最大数据库连接数 -->
<property name="maxTotal" value="1000"/>
<!--最大建立连接等待时间-->
<property name="maxWaitMillis" value="1000"/>
<!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->
<property name="numTestsPerEvictionRun" value="1024"/>
<!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
<property name="testOnBorrow" value="true"/>
<!--在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="true"/>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg name="clusterConfig" ref="redisClusterConfiguration"/>
<property name="timeout" value="10000"/>
<constructor-arg name="poolConfig" ref="jedisPoolConfig"/>
</bean>
<!--redis操作模版,使用该对象可以操作redis -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! -->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"></property>
</bean>
<!--自定义redis工具类,在需要缓存的地方注入此类 -->
<bean id="redisUtil" class="com.oceanier.util.RedisUtil">
<property name="redisTemplate" ref="redisTemplate"/>
</bean>
在终端执行命令,配置集群
./redis-trib.rb create —replicas 1 10.211.55.5:7000 10.211.55.5:7001 10.211.55.6:7002 10.211.55.6:7003 10.211.55.9:7004 10.211.55.9:7005
问题2
配置完成后启动项目,在查询缓存时出现如下错误
查看控制台没有报错,继续排查终端指令发现,在创建redis集群的时候并没有创建成功
我们需要对每个redis节点都执行 flushall 和 cluster reset 命令,然后再重新创建集群。
进入相应的redis节点执行命令
执行完毕后重新创建集群
结果如上图则为成功创建集群。