引言
在日常開發中我們有很多場景需要提供高并發的服務,那如果寫出高并發的服務呢,目前最常用的方式就是使用緩存對數據訪問進行加速。以提高接口的響應速度,提升并發量。
接下來我們來探索下如果更高效的使用緩存。我們以最常被使用的緩存redis為例分別分析下redis的5種數據結構的使用場景;
字符串(strings)
數據緩存
業務場景
使用緩存就是為了加速程序處理的效率,所以一般是對數據庫數據的緩存,因為redis的讀寫效率高于數據庫,還有一種是對于接口數據的緩存,一方面是保護下游服務避免流量直接打到下游服務,領一方面有些數據沒有必要完全實時性。比如影城的座位圖。
技術方案
key:業務前綴:業務唯一id
過期時間:隨業務而定,有設置X時間(超時消失,然后訪問時惰性加載)還有設置業務完全失效的,比如影城的座位圖,當排期徹底過期后該緩存就沒有意義。
初始值:一般該類型的緩存使用的都是惰性加載,不需要初始值;即緩存沒有從遠程資源獲取存入緩存下次備用;
邏輯處理:先獲取緩存,有緩存使用緩存,沒有就調用遠程資源,寫入緩存。
在使用的時候也要根據相應的業務場景進行調整,比如上述的影城座位圖緩存,為了客戶體驗即就算影城的這次接口沒有返回數據,也不應該給用戶看到的是空的信息,所以在做業務處理時,存入redis 的值不止是接口的返回數據,還有數據的請求時間,每次緩存獲取完數據看下請求數據是否在規定的有效時間內,如果不在,調用接口刷新返回結果,如果有數據返回存入緩存返回數據,如果接口返回超時等錯誤,返回上次緩存的數據,盡量給客戶提供最新的數據
限流 (INCR 命令)
業務場景
集群限流。有些服務是有最大訪問限制的,即整個集群每分鐘只能處理X個請求,有兩種情況會有這2種需求,一種是對集群的保護。一種是營造業務繁忙的場景。只放少量的人進入后面的流程。
技術方案
key:業務前綴:yyyyMMddHHmm (后面的時間就是限流的單位,該事例是分鐘)
過期時間:限流最小單位+X (x一般幾秒就夠,怕業務服務器和redis機器的時間有誤差導致控制精度不足)
初始值:不需要設置 如果key 不存在 INCR 命令自動設置初始值為0
邏輯處理:進入方法第一件事就是進行自增處理,如果返回值大于限流值直接返回服務正忙。否則放行。
限流變種 如果資源同一時間只需要訪問一次,比如影城特定場次座位圖,在同一時間你只需去影城獲取一次,所以在請求之前先獲取值,如果等于1獲取影城座位圖,然后更新座位圖緩存。 如果值大于1就不調用影城的座位圖,而是稍作等待,使用緩存中的數據。
活動總量控制 (INCRBY 命令)
業務場景
發紅包,在營銷活動中經常有需求是對總量要進行控制的。因為成本問題不能進行超發。
技術方案
key:業務前綴:活動唯一標識;
過期時間:活動的解釋時間+24小時;
初始值:活動的最大領取數;
邏輯處理:每次請求進來,判斷完硬性條件,如活動狀態,活動時間等,即確認完領取資格,調用INCRBY key -1 命令進行原子性減一。只要返回值>=0認為還有庫存進行領取操作。如果活動的并發量太大,領取操作可以使用隊列來進行異步處理。
增加庫存:如果活動火爆需要增加庫存,直接使用 set key 增加庫存數來進行庫存的增加。
利用set命令中nx參數做分布式鎖
業務場景
需要并發控制的地方。舉個具體的顯示場景,比如1個停車位只能停1個車,如果2個車同時進入就是事故;但是這種1個資源只能被一個請求占用的情況使用 INCR 也能完成相同的功能。還有一種場景就是幾個車道并入單車道,這種場景就沒法用INCR ,因為INCR只能