【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節點執行命令

執行完畢後重新創建集羣

結果如上圖則爲成功創建集羣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章