91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用Redis緩存淘汰策略和事務實現樂觀鎖

發布時間:2022-07-22 10:04:31 來源:億速云 閱讀:116 作者:iii 欄目:開發技術

這篇文章主要介紹“怎么使用Redis緩存淘汰策略和事務實現樂觀鎖”,在日常操作中,相信很多人在怎么使用Redis緩存淘汰策略和事務實現樂觀鎖問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用Redis緩存淘汰策略和事務實現樂觀鎖”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    緩存淘汰策略

    標題LRU原理

    LRU(Least recently used,最近最少使用)算法根據數據的歷史訪問記錄來進行淘汰數據,其核心思想是“如果數據最近被訪問過,那么將來被訪問的幾率也更高”。

    最常見的實現是使用一個鏈表保存緩存數據,詳細算法實現如下:

    怎么使用Redis緩存淘汰策略和事務實現樂觀鎖

    • 新數據插入到鏈表頭部;

    • 每當緩存命中(即緩存數據被訪問),則將數據移到鏈表頭部;

    • 當鏈表滿的時候,將鏈表尾部的數據丟棄。

    在Java中可以使用LinkHashMap去實現LRU利用哈希鏈表實現:

    怎么使用Redis緩存淘汰策略和事務實現樂觀鎖

    標題Redis緩存淘汰策略

    設置最大緩存

    在 redis 中,允許用戶設置最大使用內存大小maxmemory,默認為0,沒有指定最大緩存,如果有新的數據添加,超過最大內存,則會使redis崩潰,所以一定要設置。

    redis 內存數據集大小上升到一定大小的時候,就會實行數據淘汰策略。

    淘汰策略

    redis淘汰策略配置:maxmemory-policy voltile-lru,支持熱配置

    redis 提供 6種數據淘汰策略:

    • volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰

    • volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰

    • volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰

    • allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰

    • allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰

    • no-enviction(驅逐):禁止驅逐數據

    Redis事務

    Redis事務介紹

    • Redis 的事務是通過 MULTI 、 EXEC 、 DISCARD 和 WATCH 、UNWATCH這五個命令來完成的。

    • Redis 的單個命令都是原子性的,所以這里需要確保事務性的對象是命令集合。

    • Redis 將命令集合序列化并確保處于同一事務的命令集合連續且不被打斷的執行

    • Redis 不支持回滾操作。 事務命令

    MULTI

    用于標記事務塊的開始。 Redis會將后續的命令逐個放入隊列中,然后使用EXEC命令原子化地執行這個命令序列。

    語法:

    multi

    EXEC

    在一個事務中執行所有先前放入隊列的命令,然后恢復正常的連接狀態

    語法:

    exec

    DISCARD

    清除所有先前在一個事務中放入隊列的命令,然后恢復正常的連接狀態。

    語法:

    discard

    WATCH

    當某個[事務需要按條件執行]時,就要使用這個命令將給定的[鍵設置為受監控]的狀態。

    語法:

    watch key [key…]

    注意事項:使用該命令可以實現 Redis 的樂觀鎖。

    UNWATCH

    清除所有先前為一個事務監控的鍵

    語法:

    unwatch

    命令圖解:

    怎么使用Redis緩存淘汰策略和事務實現樂觀鎖

    事務演示:

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s1 111
    QUEUED
    127.0.0.1:6379> hset set1 name zhangsan
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) (integer) 1
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s2 222
    QUEUED
    127.0.0.1:6379> hset set2 age 20
    QUEUED
    127.0.0.1:6379> discard
    OK
    127.0.0.1:6379> exec (error) ERR EXEC without MULTI 
    127.0.0.1:6379> watch s1
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s1 555
    QUEUED 127.0.0.1:6379> exec # 此時在沒有exec之前,通過另一個命令窗口對監控的s1字段進行修改 
    (nil)
    127.0.0.1:6379> get s1
    111

    Redis 不支持事務回滾(為什么呢)

    大多數事務失敗是因為語法錯誤或者類型錯誤,這兩種錯誤,在開發階段都是可以預見的Redis 為了性能方面就忽略了事務回滾。

    Redis樂觀鎖

    樂觀鎖基于CAS(Compare And Swap)思想(比較并替換),是不具有互斥性,不會產生鎖等待而消耗資源,但是需要反復的重試,但也是因為重試的機制,能比較快的響應。因此我們可以利用redis來

    實現樂觀鎖。具體思路如下:

    • 利用redis的watch功能,監控這個redisKey的狀態值

    • 獲取redisKey的值

    • 創建redis事務

    • 給這個key的值+1

    • 然后去執行這個事務,如果key的值被修改過則回滾,key不加1

    public void watch() {
    	try {
    		String watchKeys = "watchKeys";
    		//初始值 value=1
    		jedis.set(watchKeys, 1);
    		//監聽key為watchKeys的值
    		jedis.watch(watchkeys);
    		//開啟事務
    		Transaction tx = jedis.multi();
    		//watchKeys自增加一
    		tx.incr(watchKeys);
    		//執行事務,如果其他線程對watchKeys中的value進行修改,則該事務將不會執行
    		//通過redis事務以及watch命令實現樂觀鎖
    		List<Object> exec = tx.exec();
    		if (exec == null) {
    			System.out.println("事務未執行");
    		} else {
    			System.out.println("事務成功執行,watchKeys的value成功修改");
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	} finally {
    		jedis.close();
    	}
    }

    Redis樂觀鎖實現秒殺

    public class RedisLock {
        public static void main(String[] arg) {
            //庫存key 
            String redisKey = "stock";
            ExecutorService executorService = Executors.newFixedThreadPool(20);
            try {
                Jedis jedis = new RedisProperties.Jedis("127.0.0.1", 6378);
                // 可以被秒殺的庫存的初始值,庫存總共20個
                jedis.set(redisKey, "0");
                jedis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            for (int i = 0; i < 1000; i++) {
                executorService.execute(() -> {
                    Jedis jedis1 = new Jedis("127.0.0.1", 6378);
                    try {
                        jedis1.watch(redisKey);
                        String redisValue = jedis1.get(redisKey);
                        int valInteger = Integer.valueOf(redisValue);
                        String userInfo = UUID.randomUUID().toString();
                        // 沒有秒完
                        if (valInteger < 20) {
                            Transaction tx = jedis1.multi();
                            tx.incr(redisKey);
                            List list = tx.exec();
                            // 秒成功 失敗返回空list而不是空
                            if (list != null && list.size() > 0) {
                                System.out.println("用戶:" + userInfo + ",秒殺成 功!當前成功人數:" + (valInteger + 1));
                            }
                            // 版本變化,被別人搶了。
                            else {
                                System.out.println("用戶:" + userInfo + ",秒殺失 敗");
                            }
                        }
                        // 秒完了
                        else {
                            System.out.println("已經有20人秒殺成功,秒殺結束");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        jedis1.close();
                    }
                });
            }
            executorService.shutdown();
        }
    }

    到此,關于“怎么使用Redis緩存淘汰策略和事務實現樂觀鎖”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    旅游| 芦溪县| 临高县| 分宜县| 敦化市| 通榆县| 广宗县| 吉水县| 定西市| 利津县| 安塞县| 全椒县| 浦北县| 新营市| 台前县| 柞水县| 玉龙| 昌平区| 天台县| 浠水县| 青海省| 阿城市| 新源县| 肥乡县| 游戏| 苏尼特左旗| 台南县| 景洪市| 修文县| 汉川市| 上高县| 河间市| 宕昌县| 兴城市| 塔城市| 大悟县| 军事| 沂源县| 河池市| 乐清市| 达日县|