天天看點

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

項目開發視訊:

SpringCloud微服務開發入門

手把手開發基于SpringBoot的員工管理系統

億度雲盤~Java小白入門實戰

前言

本文我們将學習Redis的事務、分布式鎖以及持久化政策和淘汰政策。

事務

Redis提供的事務是将多個指令打包,然後一次性、按照先進先出的順序(FIFO)有序的執行。在執行過程中不會被打斷(在事務執行過程,其他用戶端送出的指令請求不會插入到事務執行指令序列中),當事務隊列中的是以指令都被執行(無論成功還是失敗)完畢之後,事務才會結束。

事務相關指令

  • multi 啟動事務
  • exec 送出事務
  • discard 放棄事務
  • watch 監視一個或多個鍵,如果有其他用戶端修改鍵的值,事務将失敗

事務操作

案例1:開啟事務,正常執行,送出事務

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

案例2:開啟事務,放棄事務,事務中的操作沒有執行

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

案例3:開始事務,出現了文法錯誤,送出事務後,操作都沒有執行

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

案例4:開始事務,出現數值錯誤(k1是字元串不能遞增),送出事務後,其它的操作可以執行

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

案例5:監視score鍵,沒有其它用戶端修改,事務正常執行

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

案例6:監視score鍵,送出前打開另一個用戶端修改score,送出事務後incrby score沒有執行

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

分布式鎖

我們的軟體系統經常會遇到并發問題,比如:網絡購票,N個使用者同時搶購100張票,隻能有100個使用者搶到,如果不進行處理,可能會出現:一張票賣給A又賣給B的情況。

悲觀鎖和樂觀鎖

并發問題一般采用鎖機制來解決,分為悲觀鎖和樂觀鎖。

  • 悲觀鎖

    認為目前的資源存在競争,是以每次獲得資源時都會上鎖,阻塞住其它線程。

    資料庫中的行鎖、表鎖、讀鎖、寫鎖以及Java的synchronized和Lock都屬于悲觀鎖。

    悲觀鎖會降低系統性能和吞吐量,提高資料的安全性,适用于多寫少讀的場景。

  • 樂觀鎖

    認為目前的資源不存在競争,是以每次獲得資源時都不上鎖,通過監視資料,送出修改前通過比較資料和原來的值,判斷是否有其他并發操作,最後決定修改的成功和失敗。

    樂觀鎖執行效率高,有利于提高系統吞吐量,适用于多讀少寫的場景。

Redis的watch指令采用的是樂觀鎖機制,性能很高,适合于作為分布式鎖來解決并發問題。

分布式鎖操作

模拟購票,核心代碼:

@Repository
public class TicketCache{

	Logger logger = Logger.getLogger(TicketCache.class);
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

	public String buyTicket(){
		//執行購票邏輯
	    Boolean execute = redisTemplate.execute(new SessionCallback<Boolean>() {
	        @Override
	        public Boolean execute(RedisOperations redisOperations) throws DataAccessException {
	            //監視票數
	            redisOperations.watch("ticket_num");
	            //讀取票數
	            int num = Integer.parseInt(redisOperations.opsForValue().get("ticket_num").toString());
	            if (num <= 0) {
	                logger.info("票已售完");
	                return false;
	            }
	            //開啟事務
	            redisOperations.multi();
	            //修改票數
	            redisOperations.opsForValue().increment("ticket_num", -1);
	            //送出事務
	            List list = redisOperations.exec();
	            //list為空,送出失敗
	            if (list == null || list.isEmpty()) {
	                logger.info("購票失敗");
	                return false;
	            }
	            logger.info("購票成功" + list.get(0));
	            return true;
	        }
	    });
	    return String.valueOf(execute);
	}
}
           

Redis持久化

Redis資料儲存在記憶體中,為避免關閉程式後資料的丢失,就需要将資料儲存到磁盤檔案上。

持久化政策

持久化政策包含

  • AOF:預設每秒對資料進行持久化
  • RDB:按條件觸發持久化操作,滿足任意一個條件
  1. 900 1 900秒中修改1次
  2. 300 10 300秒中修改10次
  3. 60 10000 60秒中修改10000次

配置方法

可以在redis.conf中配置持久化

如:RDB

Redis事務+分布式鎖+持久化政策+淘汰政策前言事務分布式鎖Redis持久化Redis淘汰政策結束

啟動AOF的配置

appendonly yes   開啟AOF  
appendfsync everysec  每秒儲存
           

選擇持久化政策

我們如何選擇RDB和AOF呢?視業務場景而定:

  • 允許少量資料丢失,性能要求高,選擇RDB
  • 隻允許很少資料丢失,選擇AOF
  • 幾乎不允許資料丢失,選擇RDB + AOF

Redis淘汰政策

Redis中的資料太多可能導緻記憶體溢出,Redis會根據情況淘汰一些資料。

Redis的記憶體上限:64位系統,上限就是記憶體上限;32位系統,最大是4G

配置最大記憶體:

max-memory  配置0就是無上限(預設)
           

淘汰政策

配置淘汰政策

maxmemory-policy
           

值:

  • noevication(預設)不淘汰
  • allkeys-lru (推薦)使用LRU算法淘汰比較少使用的鍵

    LRU算法:Least Recently Used 最近最少使用算法,淘汰長期不用的緩存

  • volatile-lru 在過期的鍵中淘汰較少使用的
  • allkeys-random 在所有鍵中随機淘汰
  • volatile-random 在過期鍵中随機淘汰
  • volatile-ttl 在過期鍵中淘汰存活時間短的鍵

結束

大家如果需要學習其他Java知識點,戳這裡 超詳細的Java知識點彙總

繼續閱讀