1. 程式人生 > >Redis實現分散式環境下的分散式鎖機制

Redis實現分散式環境下的分散式鎖機制

redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value型別相對更多,包括string(字串)、list、set(集合)、zset(sorted set --有序集合)和hash(雜湊型別)。都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是快取在記憶體中。區別的是redis會週期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。 Redis 是一個高效能的key-value資料庫。 redis的出現,很大程度補償memcached這類key/value儲存的不足,在部 分場合可以對關係資料庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便. Redis支援主從同步。資料可以從主伺服器向任意數量的從伺服器上同步,從伺服器可以是關聯其他從伺服器的主伺服器。這使得Redis可執行單層樹複製。從盤可以有意無意的對資料進行寫操作。由於完全實現了釋出/訂閱機制,使得從資料庫在任何地方同步樹時,可訂閱一個頻道並接收主伺服器完整的訊息釋出記錄。同步對讀取操作的可擴充套件性和資料冗餘很有幫助。

分散式系統

       分散式系統(distributed system)是建立在網路之上的軟體系統。正是因為軟體的特性,所以分散式系統具有高度的內聚性和透明性。因此,網路和分散式系統之間的區別更多的在於高層軟體(特別是作業系統),而不是硬體。內聚性是指每一個資料庫分佈節點高度自治,有本地的資料庫管理系統。透明性是指每一個資料庫分佈節點對使用者的應用來說都是透明的,看不出是本地還是遠端。在分散式資料庫系統中,使用者感覺不到資料是分佈的,即使用者不須知道關係是否分割、有無副本、資料存於哪個站點以及事務在哪個站點上執行等。

Question

       由於分散式系統的特點,當我們的一個web專案跑在一個分散式的環境中。會實現類似於,當一個客戶端使用者向伺服器傳送一個請求時會會隨即的分配到一臺伺服器上進行執行並返回結果。像這類類似於查詢操作等有客戶端傳送請求在分散式環境下可以得到很快的響應對於整個系統也沒有影響。但是有些場景下我們需要執行一些類似與定時任務之類的操作。由於整個系統的服務可能在多個伺服器上都有配置所以可能會導致多個伺服器一起跑一個定時任務,這種場景是不被允許的。所以需要設定一個鎖來管理。

解決方法

        使用redis分散式鎖來管理-》情景當操作一個定時任務時只允許一個操作。可以在操作上加上鎖控制(在這個操作中,我嘗試了使用了Spring的AOP來封裝處理一個,實現在程式中加分散式鎖只需要通過註解的形式處理)

Redis的XML配置檔案

  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xmlns:util="http://www.springframework.org/schema/util"
  5.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd  
  7.        ">
  8.     <!-- 實現匯入properties配置檔案 -->
  9.     <util:propertiesid="app"location="classpath:app.properties"/>
  10.     <!-- jedisPoolConfig連線執行緒配置 -->
  11.     <beanid="jedisPoolConfig"class="redis.clients.jedis.JedisPoolConfig">
  12.         <propertyname="maxTotal"value="5"/>
  13.         <propertyname="maxIdle"value="2"/>
  14.         <propertyname="maxWaitMillis"value="10000"/>
  15.         <propertyname="testOnBorrow"value="true"/>
  16.     </bean>
  17.     <!-- jedisPool連線處理類 -->
  18.     <beanid="jedisPool"class="redis.clients.jedis.JedisPool">
  19.         <constructor-argindex="0"ref="jedisPoolConfig"/>
  20.         <constructor-argindex="1"value="127.0.0.1"/>
  21.         <constructor-argindex="2"value="6379"type="int"/>
  22.     </bean>
  23.     <!-- jedisTemplate是jedis的實現類 -->
  24.     <beanid="jedisTemplate"class="com.rabbit.util.RedisTemplate">
  25.         <constructor-argindex="0"ref="jedisPool"/>
  26.     </bean>
  27. </beans>

封裝Jedis的實現類

  1. package com.rabbit.util;  
  2. import com.rabbit.ActionInterface.RedisAction;  
  3. import com.rabbit.ActionInterface.RedisNoResultAction;  
  4. import org.slf4j.Logger;  
  5. import org.slf4j.LoggerFactory;  
  6. import redis.clients.jedis.Jedis;  
  7. import redis.clients.jedis.exceptions.JedisConnectionException;  
  8. import redis.clients.jedis.exceptions.JedisException;  
  9. import redis.clients.util.Pool;  
  10. /** 
  11.  * 實現Jedis物件的封裝,實現操作 
  12.  */
  13. publicclass RedisTemplate {  
  14.     privatestatic Logger logger = LoggerFactory.getLogger(RedisTemplate.class);  
  15.     //封裝一個pool池用於jedis物件的管理
  16.     private Pool<Jedis> jedisPool;  
  17.     public RedisTemplate(Pool<Jedis> jedisPool) {  
  18.         this.jedisPool = jedisPool;  
  19.     }  
  20.     /** 
  21.      * 通過觀察者模式實現事件的回撥處理(使用範型) 
  22.      * 
  23.      * @param jedisAction   需要執行的方法介面 
  24.      * @param <T>           執行發放的返回型別 
  25.      * @return T 
  26.      * @throws JedisException 
  27.      * 返回執行好的物件資訊 
  28.      */
  29.     public <T> T execute(RedisAction<T> jedisAction){  
  30.         T result = null;  
  31.         Jedis jedis = null;  
  32.         boolean broken = false;  
  33.         try {  
  34.             jedis = jedisPool.getResource();  
  35.             result = jedisAction.action(jedis);  
  36.         } catch (JedisConnectionException e) {  
  37.             logger.error("Redis connection lost.", e);  
  38.             broken = true;  
  39.         } finally {  
  40.             //釋放jedis資源
  41.             closeResource(jedis, broken);  
  42.             return result;  
  43.         }  
  44.     }  
  45.     /** 
  46. 相關推薦

    Redis實現分散式環境分散式機制

    redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value型別相對更多,包括string(字串)、list、set(集合)、zset(sorted set --有序集合)和hash(雜湊型別)。都支援push/pop、add/

    Shiro許可權管理框架(二):Shiro結合Redis實現分散式環境的Session共享

    首發地址:https://www.guitu18.com/post/2019/07/28/44.html 本篇是Shiro系列第二篇,使用Shiro基於Redis實現分散式環境下的Session共享。在講Session共享之前先說一下為什麼要做Session共享。 為什麼要做Session共享 什麼是Ses

    分散式環境redis模擬session

    首先為什麼使用redis? 因為分散式有不同伺服器的緣故,如果你安照一般方式儲存session,那麼你的session會儲存在某一臺伺服器上,如果你的下一個請求並不是訪問這臺伺服器,那麼會發生讀取不到session的情況 redis儲存的實現方案: 第一種

    心跳機制tcp keepalive的討論、應用及“斷網”、"斷電"檢測的C代碼實現(Windows環境)

    astar har 心跳 存在 假設 clu ali clean struct 版權聲明:本文為博主原創文章,轉載時請務必註明本文地址, 禁止用於任何商業用途, 否則會用法律維權。 https://blog.csdn.net/stpeace/article/details/

    分散式環境 session 的跨域共享原理

    一、什麼是 session 共享 ? 如上圖,是一個簡單的分散式環境,以登入來說,當用戶發出請求,通過負載均衡,可能會走tomcat1伺服器,也可能會走tomcat2伺服器,此時就有可能,我們在tomcat1上實現了登入,儲存了session,但是tomcat2並沒有儲存,當有請求

    Spring Cloud (四): 分散式環境自動發現配置服務

    前一章, 我們的Hello world應用服務,通過配置伺服器Config Server獲取到了我們配置的hello資訊“hello world”. 但自己的配置檔案中必須配置config server的URL(http://localhost:8888), 如果把config server搬到另外一個獨立I

    Java叢集/分散式環境5種session處理策略

    前言 在搭建完叢集環境後,不得不考慮的一個問題就是使用者訪問產生的session如何處理。如果不做任何處理的話,使用者將出現頻繁登入的現象,比如叢集中存在A、B兩臺伺服器,使用者在第一次訪問網站時,Nginx通過其負載均衡機制將使用者請求轉發到A伺服器,這時A伺服器就會給使

    巧用分散式環境的優雅技術,只有頭髮少的人才研究過(轉載備忘)

    轉載自,向原作者致謝https://www.toutiao.com/a6633272364639470084/?iid=53593196063&app=news_article&group_id=6633272364639470084&timestamp=1544437809 什麼是

    【轉】【Linux運維-叢集技術進階】叢集/分散式環境5種session處理策略

    前言 在搭建完叢集環境後,不得不考慮的一個問題就是使用者訪問產生的session如何處理。如果不做任何處理的話,使用者將出現頻繁登入的現象,比如叢集中存在A、B兩臺伺服器,使用者在第一次訪問網站時,Nginx通過其負載均衡機制將使用者請求轉發到A伺服器,這時A伺服器

    單機環境分散式環境K-Means聚類演算法的執行例項

      單機環境下的K-Means聚類演算法執行例項 參考書籍《Mahout in Action》:要資源的可以找我~(中英文都有) 在eclipse平臺上實現K-Means例項 程式碼如下: package kmeans; import java.io.File; im

    Java B2B2C多使用者商城 springboot架構 (四): 分散式環境自動發現配置服務

    前一章, 我們的Hello world應用服務,通過配置伺服器Config Server獲取到了我們配置的hello資訊“hello world”. 但自己的配置檔案中必須配置config server的URL(http://localhost:8888), 如果把config server搬到另外一個獨立I

    分散式環境命令列正確執行hadoop示例wordcount

    首先確保hadoop已經正確安裝、配置以及執行。 1.     首先將wordcount原始碼從hadoop目錄中拷貝出來。 [[email protected] logs]# cp /usr/local/hadoop-1.1.2/src/examples/or

    hadoop版本3.1.0分散式環境執行mapreduce作業

    一、環境配置 1、hdfs-site.xml <configuration> <property> <name>dfs.replication</name> <value>1</

    分散式環境,怎麼保證執行緒安全

    避免併發 在分散式環境中,如果存在併發問題,那麼很難通過技術去解決,或者解決的代價很大,所以我們首先要想想是不是可以通過某些策略和業務設計來避免併發。比如通過合理的時間排程,避開共享資源的存取衝突。另外,在並行任務設計上可以通過適當的策略,保證任務與任務之間不存在共享資

    分散式環境資料一致性的設計總結

    相關理論: 在聊分散式環境下資料一致性問題之前我們先看一個理論(事務的ACID一定要知道的)CAP理論: CAP理論由加州大學伯克利分校的計算機教授Eric Brewer在2000年提出,其核心思想是任何基於網路的資料共享系統最多隻能滿足資料一致性(Consistency)、可用性(Availabilit

    Mybatis一級快取導致分散式環境的查詢髒資料

        Mybatis一級快取,也稱本地快取,預設是SqlSession級別的快取。在一次程式與資料庫的會話(Sqlsession)中,mybatis會維護一個以hashmap為儲存結構的一級快取,在這個會話中,只要在兩次相同條件的查詢中間,這個會話裡沒有出現增刪改的操作,那

    叢集/分散式環境5種共享session處理策略

    前言在搭建完叢集環境後,不得不考慮的一個問題就是使用者訪問產生的session如何處理。如果不做任何處理的話,使用者將出現頻繁登入的現象,比如叢集中存在A、B兩臺伺服器,使用者在第一次訪問網站時,Nginx通過其負載均衡機制將使用者請求轉發到A伺服器,這時A伺服器就會給使用者

    分散式環境定時任務如何做到只執行一次

    問題: 對於一個部署在多臺機器上的應用,程式執行時,如何保證多個機器上的定時任務只有一個機器上的任務被執行? 思路:對於每一個定時任務job都有一個唯一id,當發現改job處於執行狀態時,其他機器都不會去排程這個job quartz的分散式解決方案

    Hadoop分散式環境的資料抽樣

    1. 問題由來 Google曾經有一道非常經典的面試題: 給你一個長度為N的連結串列。N很大,但你不知道N有多大。你的任務是從這N個元素中隨機取出k個元素。你只能遍歷這個連結串列一次。你的演算法必須保證取出的元素恰好有k個,且它們是完全隨機的(出現概率均等)? 這道題的解

    叢集/分散式環境5種session處理策略

    前言 在搭建完叢集環境後,不得不考慮的一個問題就是使用者訪問產生的session如何處理。如果不做任何處理的話,使用者將出現頻繁登入的現象,比如叢集中存在A、B兩臺伺服器,使用者在第一次訪問網站時,Nginx通過其負載均衡機制將使用者請求轉發到A伺服器,這