項目中要將單機版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節點執行命令
執行完畢後重新創建集羣
結果如上圖則爲成功創建集羣。