12、Spring技術棧-Redis Sentinel實現高可用緩衝叢集方案實戰__redis

來源:互聯網
上載者:User

Redis Sentinel的分布式特性介紹

Redis Sentinel是一個分布式系統,Sentinel運行在有許多Sentinel進程互相合作的環境下,它本身就是這樣被設計的。有許多Sentinel進程互相合作的優點如下: 當多個Sentinel同意一個master不再可用的時候,就執行故障檢測。這明顯降低了錯誤機率。 即使並非全部的Sentinel都在工作,Sentinel也可以正常工作,這種特性,讓系統非常的健康。

所有的Sentinels,Redis執行個體,串連到Sentinel和Redis的用戶端,本身就是一個有著特殊性質的大型分布式系統。在這篇文章中,我將通過執行個體的形式從部署Redis Sentinel叢集、使用Redis的Master Slave的模式部署Redis叢集來介紹在Spring項目中如何使用Redis Sentinel實現緩衝系統的高可用。

部署之前瞭解關於Sentinel的基本東西 一個健康的叢集部署,至少需要三個Sentinel執行個體 三個Sentinel執行個體應該被放在失敗獨立的電腦上或虛擬機器中,比如說不同的物理機或者在不同的可用性區域域上執行的虛擬機器。 Sentinel + Redis 分布式系統在失敗期間並不確保寫入請求被儲存,因為Redis使用非同步複製。可是有很多部署Sentinel的 方式來讓視窗把丟失寫入限制在特定的時刻,當然也有另外的不安全的方式來部署。 用戶端必須支援Sentinel。大多數用戶端庫都支援Sentinel,但並不是全部。 沒有高可用的設定是安全的,如果你在你的測試環境沒有經常去測試,或者甚至在生產環境中你也沒有經常去測試,如果Sentinel正常工作。 但是你或許有一個錯誤的配置而僅僅只是在很晚的時候才出現(淩晨3點你的主節點宕掉了)。 Sentinel,Docker ,其他的網路位址轉譯表,連接埠映射應該很小心的使用:Docker執行連接埠重新對應,破壞Sentinel自動探索另外的Sentinel進程和一個主節點的從節點列表。在文章的稍後部分查看更過關於Sentinel和Docker的資訊。

執行個體介紹 本執行個體通過部署3個Redis Sentinel實現Sentinel執行個體的高可用。 本執行個體通過部署1個Redis Master執行個體,3個Slave執行個體實現Redis緩衝的高可用。

Redis Master執行個體和Slave執行個體部署

下載並安裝Redis,此文不講解,具體可參考http://blog.csdn.net/zyhlwzy/article/details/78366265。

可參考Redis主從(Master-Slave)複製(Replication)設定一文第8節Redis主從複製實戰的部署方式部署Master-Slave,但是需要注意的是,本文需要的是一個Master執行個體,3個Slave執行個體。

Redis執行個體資訊如下:

IP Port 備忘
192.168.199.126 6379 Master
192.168.199.249 6382 Slave
192.168.199.249 6383 Slave
192.168.199.249 6384 Slave

配置Master
下載並安裝Redis,此文不講解,具體可參考http://blog.csdn.net/zyhlwzy/article/details/78366265。

Master的配置很簡單,我們開啟守護進程即可(示範執行個體不設定驗證資訊,如有需要自行設定)。

進入redis設定檔目錄(/data/redis/redis-4.0.1/redis.conf)編輯redis.conf進行如下配置。

daemonize yes

配置Slave

下載並安裝Redis,此文不講解,具體可參考http://blog.csdn.net/zyhlwzy/article/details/78366265。

建立Slave設定檔目錄,拷貝redis.conf到對應目錄並進行配置。

mkdir /data/redis/clustercd /data/redis/clustermkdir -p 6382cp /data/redis/redis-4.0.1/redis.conf /data/redis/cluster/6382/redis-6382.confmkdir -p 6383cp /data/redis/redis-4.0.1/redis.conf /data/redis/cluster/6383/redis-6383.confmkdir -p 6384cp /data/redis/redis-4.0.1/redis.conf /data/redis/cluster/6384/redis-6384.conf

3個Slave執行個體的設定檔內容,注意修改下面加粗字型部分的內容即可(注意注釋掉的要去掉注釋),其他都相同:

配置選項 選項值 說明
daemonize yes 預設情況下 redis 不是作為守護進程啟動並執行,如果你想讓它在後台運行,你就把它改成 yes。
pidfile /data/redis/cluster/6382/redis-6382.pid 當redis作為守護進程啟動並執行時候,預設情況下它會寫一個 pid 到 /var/run/redis.pid 檔案裡面
port 6382 監聽連接埠號碼,預設為 6379,如果你設為 0 ,redis 將不在 socket 上監聽任何用戶端串連。
database 1 設定資料庫的數目。
cluster-enabled no 啟用或停用叢集
cluster-config-file /data/redis/cluster/6382/nodes-6382.conf 叢集設定檔,啟動時自動產生
cluster-node-timeout 15000 節點互聯逾時時間,單位毫秒
cluster-migration-barrier 1 這個參數表示的是,一個主節點在擁有多少個好的從節點的時候就要割讓一個從節點出來。
cluster-require-full-coverage yes 如果叢集中某些key space沒有被叢集中任何節點覆蓋,叢集將停止接受寫入
appendonly yes 啟用aof持久化方式
dir /data/redis/cluster/6382/ 節點資料持久化存放目錄
slaveof 192.168.199.126 6379 Master節點配置

如果配置成功並啟動,通過用戶端工具串連到Master時,輸入如下命令

info replication

將會得到如下結果

# Replicationrole:masterconnected_slaves:3slave0:ip=192.168.199.249,port=6384,state=online,offset=1127147,lag=1slave1:ip=192.168.199.249,port=6383,state=online,offset=1127292,lag=1slave2:ip=192.168.199.249,port=6382,state=online,offset=1127292,lag=1master_replid:beba8e13c44c5a4afcf8c82889b524b2f76faa22master_replid2:0000000000000000000000000000000000000000master_repl_offset:1127292second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:78717repl_backlog_histlen:1048576

Redis Sentinel部署

3個Redis Sentinel資訊如下

IP Port 備忘
192.168.199.126 26379 Sentinel
192.168.199.126 26479 Sentinel
192.168.199.126 26579 Sentinel

Redis安裝完成之後,在redis目錄(本執行個體是redis-4.0.1)下會有一個sentinel.conf檔案,建立sentinel目錄並將該設定檔拷貝進去重新命名為自訂的sentinel設定檔。

mkdir /data/redis/sentinelcp /data/redis/redis-4.0.1/sentinel.conf  /data/redis/sentinel/sentinel_26379.confcp /data/redis/redis-4.0.1/sentinel.conf  /data/redis/sentinel/sentinel_26479.confcp /data/redis/redis-4.0.1/sentinel.conf  /data/redis/sentinel/sentinel_26579.conf

sentinel_26379.conf配置內容:

protected-mode noport 26379sentinel monitor mymaster 192.168.199.249 6384 2sentinel failover-timeout mymaster 60000sentinel config-epoch mymaster 1sentinel leader-epoch mymaster 1sentinel known-slave mymaster 192.168.199.126 6379

sentinel_26479.conf配置內容:

protected-mode noport 26479sentinel monitor mymaster 192.168.199.249 6384 2sentinel failover-timeout mymaster 60000sentinel config-epoch mymaster 1sentinel leader-epoch mymaster 1sentinel known-slave mymaster 192.168.199.126 6379

sentinel_26579.conf配置內容:

protected-mode noport 26579sentinel monitor mymaster 192.168.199.249 6384 2sentinel failover-timeout mymaster 60000sentinel config-epoch mymaster 1sentinel leader-epoch mymaster 1sentinel known-slave mymaster 192.168.199.126 6379

啟動Redis Master執行個體

進入Redis Master伺服器Redis bin目錄,執行以下命令:

./redis-server /data/redis/redis-4.0.1/redis.conf

啟動Redis Slave執行個體

進入Redis Slave伺服器Redis bin目錄,執行以下命令:

./redis-server /data/redis/cluster/6382/redis-6382.conf./redis-server /data/redis/cluster/6383/redis-6383.conf./redis-server /data/redis/cluster/6384/redis-6384.conf

啟動Sentinel執行個體

進入Redis Slave伺服器Redis bin目錄,執行以下命令:

./redis-sentinel /data/redis/sentinel/sentinel_26379.conf ./redis-sentinel /data/redis/sentinel/sentinel_26479.conf ./redis-sentinel /data/redis/sentinel/sentinel_26579.conf 

如果啟動時出現如下資訊,表示啟動成功

Maven配置

<dependency>        <groupId>redis.clients</groupId>        <artifactId>jedis</artifactId>        <version>2.9.0</version>    </dependency>           <dependency>         <groupId>org.springframework.data</groupId>         <artifactId>spring-data-redis</artifactId>          <version>1.7.5.RELEASE</version></dependency>

在config.properties中增加如下配置

#Redis sentinel使用redis.sentinel1.host=192.168.199.126redis.sentinel1.port=26379redis.sentinel2.host=192.168.199.126redis.sentinel2.port=26479redis.sentinel3.host=192.168.199.126redis.sentinel3.port=26579redis.sentinel.masterName=mymaster

建立spring-redis-sentinel.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:context="http://www.springframework.org/schema/context"    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"    xmlns:task="http://www.springframework.org/schema/task" xmlns:cache="http://www.springframework.org/schema/cache"    xmlns:c='http://www.springframework.org/schema/c' xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd"    default-lazy-init="true">    <!-- 開啟spring cache註解功能 -->    <cache:annotation-driven cache-manager="redisCacheManager" />    <context:annotation-config />    <context:property-placeholder        ignore-unresolvable="true" location="classpath:config.properties" />    <!-- Redis -->    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">        <property name="maxTotal" value="${redis.maxTotal}" />        <property name="maxIdle" value="${redis.maxIdle}" />        <property name="maxWaitMillis" value="${redis.maxWait}" />        <property name="testOnBorrow" value="${redis.testOnBorrow}" />    </bean>    <bean id="sentinelConfiguration"        class="org.springframework.data.redis.connection.RedisSentinelConfiguration">        <property name="master">            <bean class="org.springframework.data.redis.connection.RedisNode">                <property name="name" value="${redis.sentinel.masterName}"></property>            </bean>        </property>        <property name="sentinels">            <set>                <bean class="org.springframework.data.redis.connection.RedisNode">                    <constructor-arg name="host" value="${redis.sentinel1.host}"></constructor-arg>                    <constructor-arg name="port" value="${redis.sentinel1.port}"></constructor-arg>                </bean>                <bean class="org.springframework.data.redis.connection.RedisNode">                    <constructor-arg name="host" value="${redis.sentinel2.host}"></constructor-arg>                    <constructor-arg name="port" value="${redis.sentinel2.port}"></constructor-arg>                </bean>                <bean class="org.springframework.data.redis.connection.RedisNode">                    <constructor-arg name="host" value="${redis.sentinel3.host}"></constructor-arg>                    <constructor-arg name="port" value="${redis.sentinel3.port}"></constructor-arg>                </bean>            </set>        </property>    </bean>    <!-- redis伺服器中心 -->    <bean id="jedisConnectionFactory"        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">        <constructor-arg name="sentinelConfig" ref="sentinelConfiguration"></constructor-arg>        <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>    </bean>    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">        <property name="connectionFactory" ref="jedisConnectionFactory" />        <property name="keySerializer">            <bean                class="org.springframework.data.redis.serializer.StringRedisSerializer" />        </property>        <property name="valueSerializer">            <bean                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />        </property>    </bean>    <!-- redis緩衝管理器 -->    <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">        <constructor-arg name="redisOperations" ref="redisTemplate" />    </bean>    <bean id="redisUtils" class="ron.blog.blog_service.utils.RedisUtils" /></beans>

在spring-context.xml引入spring-redis-sentinel.xml

<import resource="classpath:spring-redis-sentinel.xml" />

編寫Redis協助類RedisUtils

public class RedisUtils {    /**      * RedisTemplate是一個簡化Redis資料訪問的一個協助類,      * 此類對Redis命令進行進階封裝,通過此類可以調用ValueOperations和ListOperations等等方法。      */      @Autowired      private RedisTemplate<Serializable, Object> redisTemplate;      /**      * 大量刪除對應的value      *       * @param keys      */      
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.