spring data redis 叢集(sentinel實現)和simple spring memcached分布式初使用__spring

來源:互聯網
上載者:User

本人菜鳥一名,剛畢業出來沒多久,在上海一家公司工作,公司有算上我有3個java程式員,其他兩個有兩到三年的工作經驗,他們負責APP的介面開發,我一個人負責後台管理介面開發,公司項目架構是用Spring搭建的,開發工具也是Spring的,持久層整合了Spring data jap和Mybatis,控制層用的是Spring MVC ,對於剛出校園的我來說覺得這架構塔的特別牛。由於項目的許可權做的有點複雜,而且查詢的地方特別多,網頁載入速度特別慢,老大說把那些許可權判斷放我緩衝裡,讓我去做,我當時就楞住了,我剛從學校出來,只知道hibernate二級緩衝,老大讓我在memcached和redis中選一個,還要做叢集模式的,我那時還是試用期,為了突顯自己的能力,就硬著頭皮答應下來了。現在就寫下我學習這兩個緩衝的路程。


redis sentinel 介紹:(此處copy)

Redis 的 Sentinel 系統用於管理多個 Redis 伺服器(instance),該系統執行以下三個任務: 監控(Monitoring):Sentinel 會不斷地檢查你的主伺服器和從伺服器是否運作正常。 提醒(Notification):當被監控的某個 Redis 伺服器出現問題時,Sentinel 可以通過 API 向管理員或者其他應用程式發送通知。 自動故障遷移(Automatic failover):當一個主伺服器不能正常工作時,Sentinel 會開始一次自動故障遷移操作,它會將失效主伺服器的其中一個從伺服器升級為新的主伺服器,並讓失效主伺服器的其他從伺服器改為複製新的主伺服器;當用戶端試圖串連失效的主伺服器時,叢集也會向用戶端返回新主伺服器的地址,使得叢集可以使用新主伺服器代替失效伺服器。

首先介紹redis sentinel服務端配置

這是連接埠號碼為6479的redis主伺服器

##redis.conf
##redis-0,預設為def_master 
port 6479
##授權密碼,請各個配置保持一致
requirepass 123456
masterauth 123456
##暫且禁用指令重新命名
##rename-command
##開啟AOF,禁用snapshot
appendonly yes
save 900 1
save 300 10
save 60 10000
##slaveof no one
slave-read-only yes




這是連接埠號碼為6480的從伺服器

##redis.conf
##redis-0,預設為def_master 
port 6480
slaveof 127.0.0.1 6479
##授權密碼,請各個配置保持一致
requirepass 123456
masterauth 123456
##暫且禁用指令重新命名
##rename-command
##開啟AOF,禁用snapshot
appendonly yes
save 900 1
save 300 10
save 60 10000
##slaveof no one
slave-read-only yes



這是sentinel 叢集管理器sentinel.conf配置

##redis-0  
##sentinel執行個體之間的通訊連接埠  
port 26379  
##指定sentinel使用的連接埠,不能與redis-server運行執行個體的連接埠衝突,1表示至少一台從伺服器發現主伺服器故障就會自動主從切換
sentinel monitor def_master 127.0.0.1 6479 1  
##串連redis服務密碼
sentinel auth-pass def_master 123456 
##表示如果5s內mymaster沒響應,就認為主伺服器發生故障
sentinel down-after-milliseconds def_master 50000   
##表示如果master重新選出來後,其它slave節點能同時並行從新master同步緩衝的台數有多少個,顯然該值越大,所有slave節點完成同步切換的整體速度越快,但如果此時正好有人在訪問這些slave,可能造成讀取失敗,影響面會更廣。最保定的設定為1,只同一時間,只能有一台幹這件事,這樣其它slave還能繼續服務,但是所有slave全部完成緩衝更新同步的進程將變慢。
sentinel parallel-syncs def_master 1  
表示如果90秒後,mysater仍沒活過來,則啟動failover(容錯移轉),從剩下的slave中選一個升級為master
sentinel failover-timeout def_master 900000  


配置寫好後就開始啟動reids服務,我這是在Windows環境下測試的,在linux下命令有所不同。


輸入cmd命令進入控制台,

開啟redis檔案位置,輸入redis-server.exe redis6479.conf啟動reids主伺服器。

然後開啟從伺服器位置,輸入redis-server.exe redis6480.conf啟動reids從伺服器。

然後啟動sentinel,開啟檔案位置輸入redis-server sentinel.conf  --sentinel啟動管理器。

完了之後服務端就開啟成功。


一下是用戶端串連服務端代碼編寫:

Spring提供了Spring data redis這個子項目,本人用的就是Spring data redis

spring的設定檔:

spring-data-redis.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:p="http://www.springframework.org/schema/p" 
 xmlns:c="http://www.springframework.org/schema/c" 
 xmlns:cache="http://www.springframework.org/schema/cache"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
                    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context-3.2.xsd
                    http://www.springframework.org/schema/aop
                    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 
                   http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
                   
    <context:component-scan base-package="org.tht.service"/>
 
  <cache:annotation-driven></cache:annotation-driven>
 
     <bean id="redisSentinelConfiguration"

        class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<!--這裡的def_master就是叢集管理器的名字,我們在用戶端只需串連sentinel,sentinel會幫我們去管理redis伺服器 -->
        <property name="def_master ">

            <bean class="org.springframework.data.redis.connection.RedisNode">

                <property name="name" value="mymaster"></property>

            </bean>

        </property>

        <property name="sentinels">

            <set>
                  <bean class="org.springframework.data.redis.connection.RedisNode">


                    <constructor-arg name="host" value="127.0.0.1"/>


                    <constructor-arg name="port" value="26379"/>               

                </bean>

            </set>

        </property>

   </bean>


   <bean id="jeidsConnectionFactory"


   class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="password" value="123456"></property>
      <constructor-arg ref="redisSentinelConfiguration"/>

   </bean>


 


   <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"


      p:connection-factory-ref="jeidsConnectionFactory"/>
      
      <bean
        id="cacheManager"
        class="org.springframework.data.redis.cache.RedisCacheManager"
        c:template-ref="redisTemplate"/>
      
    </beans>
  

現在我們寫方法:


   @Cacheable(value="messageCache",key="#name")
    public String getMessage(String name) {
       
        return userService.findByName(name);
    }

這是查詢方法,@Cacheable(value="messageCache",key="#name")

這個註解是查詢redis緩衝,value:命名空間,key:返回資料對應的鍵。如果緩衝中沒有這個key就會去查詢資料庫,並將返回的值存入redis,有則直接從緩衝中讀取資料。



//更新緩衝

@CachePut(value="messageCache",key="#name")
public String updateMessage(String name) {
       
      return userService.findByName(name);
    }

這個註解是修改redis緩衝@CachePut(value="messageCache",key="#name")



//清空命名空間為messageCache下的所有緩衝
@CacheEvict(value="messageCache",allEntries=true)
public void deleteOperationAuthByPageUrlCache() {


}


//清空命名空間為messageCache下key為name的緩衝
@CacheEvict(value="messageCache",allEntries=true,key="#name")
public void deleteOperationAuthByPageUrlCache() {


}


以上代碼經過本人測試過,沒問題,當主伺服器發生故障時從伺服器會自動升為主伺服器,兩台redis伺服器的資料會同步,這種叢集模式無需擔心伺服器掛掉之後資料的丟失。


在學校redis之前本人也學習了memcached,之說以選擇redis下面會說明原因。


以下是memcached基於用戶端分布式代碼:

Google提供了memcached與Spring整合的組件simple spring memcached,一下是spring-memcache.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:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
                    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context-3.2.xsd
                    http://www.springframework.org/schema/aop
                    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 
                   ">
  
  <context:component-scan base-package="org.tht.service"/>
  
  <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  
  <import resource="simplesm-context.xml" />
  <!-- 預設一個client -->
  <bean name="defaultMemcachedClient" class="com.google.code.ssm.CacheFactory">
    <property name="cacheClientFactory">
      <bean name="cacheClientFactory" class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" />
    </property>
    <property name="addressProvider">
      <bean class="com.google.code.ssm.config.DefaultAddressProvider">

<!--伺服器位址,在這裡實現分布式 -->
        <property name="address" value="127.0.0.1:11211,192.168.1.227:12677" />
      </bean>
    </property>
    <!-- 一致性hash ~。~ -->
    <property name="configuration">
      <bean class="com.google.code.ssm.providers.CacheConfiguration">
        <property name="consistentHashing" value="true" />
      </bean>
    </property>
  </bean>
  <bean class="com.google.code.ssm.Settings">
<property name="order" value="500" />
  </bean>
</beans>  


一下是方法:

 /** 
     * 當執行getUserById查詢方法時,系統首先會從緩衝中擷取id對應的實體 
     * 如果實體還沒有被緩衝,則執行查詢方法並將查詢結果放入緩衝中 
     */  
@ReadThroughSingleCache(namespace = "test")
 public CacheBean getUserById(@ParameterValueKeyProvider String userId) throws Exception{
   System.out.println("沒有快取命中");
   CacheBean cacheBean=new CacheBean();
cacheBean.setUserId(userId);
cacheBean.setUserName("趙六");
   return cacheBean;
 }


/** 
     * 當執行delete方法時,系統會刪除緩衝中id對應的實體 
     */ 
@InvalidateSingleCache(namespace="test")
public void delete(@ParameterValueKeyProvider Integer userId){
System.out.println(userId);
}


 /** 
     * 當執行update方法時,系統會更新緩衝中id對應的實體 
     * 將實體內容更新成@*DataUpdateContent標籤所描述的實體 
     */  
@UpdateSingleCache(namespace="test")
public void update(@ParameterValueKeyProvider @ParameterDataUpdateContent CacheBean cacheBean){
System.out.println(cacheBean.getUserName());
}


現在就開始說說redis和memcached的區別:

在此之前你可能在網上查看了很多關於兩者的區別,在此我只說我在用這兩個緩衝的心得與體會。

區別1:memcached的分布式是基於用戶端的(下面會介紹),而redis的分布式是基於服務端的(上面已經寫的很清楚了)

區別2:redis可以根據命名空間刪除該命名空間下的所有key,而memcached必須得指定key(想刪除命名空間下的所有key,只能先將該命名空間下的所有key查出來再進行刪除)

區別3:Redis支援資料的持久化,可以將記憶體中的資料保持在磁碟中,重啟的時候可以再次載入進行使用,而memcached伺服器重啟後所有快取資料都會清空。

以上3個區別是我的切身體會,還有很多區別在這裡就不一一說明了,在網上都可以查到。


本人菜鳥一枚,大神勿噴,以上只是本人學習的一點小體會,也只是懂了點皮毛,也有很多不懂得地方,希望可以和你們一起交流,共同進步。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.