Redis - 介紹與使用場景

来源:https://www.cnblogs.com/fatedeity/archive/2023/01/31/17078356.html
-Advertisement-
Play Games

Redis 每秒可以處理超過 10 萬次讀寫操作,是已知性能最快的 key-value 資料庫,稱得上是必須要學會的知識。 ...


簡介

Redis 的全稱是 Remote Dictionary Server,是一個使用 C 語言編寫的、開源的(BSD 許可)高性能非關係型(NoSQL)的鍵值對資料庫。

Redis 的數據是存儲在記憶體中的,所以讀寫速度非常快,被廣泛應用於緩存方向,當然也有持久化資料庫的用法。

優缺點

優點

  • 讀寫性能優異, Redis 能讀的速度是 110000 次/s,寫的速度是 81000 次/s
  • 數據類型豐富,有 String、List、Hash、Set、SortedSet 等
  • 單線程原子性,Redis 所有的操作都是原子性的,也支持多個操作合併後的原子執行
  • 豐富的特性,Redis 支持發佈訂閱、通知、key 過期等功能
  • 支持持久化,Redis 支持 RDB、AOF 等持久化方式
  • 高可用性,Redis 支持主從複製、哨兵模式、Cluster 等高可用方式

缺點

  • 資料庫容量受物理記憶體的限制,不能用作海量數據的讀寫
  • Redis 難以支持線上擴容,修改配置文件之後重啟 Redis,恢復磁碟上的數據耗費時間較久

使用場景

數據緩存

Redis 是高性能的記憶體資料庫,因此,緩存是 Redis 最常用的場景。Redis 作為緩存使用的時候,一般是採用先更新資料庫,再刪除緩存的 Cache Aside Pattern 策略。

整體的邏輯是:業務從 Redis 中讀取數據,如果 Redis 中訪問不到數據,然後讀取資料庫中的數據,將資料庫中的數據緩存到 Redis 中;業務更新數據,直接修改資料庫中的數據,然後將 Redis 中的緩存刪除。

這種方案需要註意的就是:避免緩存擊穿,數據的實時性相對較低。

限時業務

Redis 支持給 key 設置過期時間,客戶端無法訪問到過期的 key,利用這一特性可以運用在限時的優惠活動、手機驗證碼等業務場景。

計數器

Redis 的 INCRBY 命令可以實現原子性的遞增,可以直接作為計數器存儲和遞增。尤其是,該命令在鍵不存在時會直接初始化值再執行 INCRBY 命令,執行成功後會直接返回計算增量之後的數值。

高併發的秒殺活動、分散式序列號的生成、限制手機發送簡訊次數、介面限制訪問次數等需要計數的功能,都涉及到計數器的概念,尤其是分散式系統會涉及到分散式計數器。

分散式鎖

先使用 SETNX 命令來爭搶鎖,結果返回 1 表示設置成功,搶到之後再用 EXPIRE 命令給鎖加一個過期時間防止忘記釋放鎖。

從 Redis 的 2.6.12 版本開始,可以通過 SET 命令的複雜參數,將 SETNX 命令和 EXPIRE 命令合併成一條命令來使用:

  • EX second: 設置鍵的過期時間為 second 秒,使用 EX 選項效果等同於 SETEX 命令。
  • PX millisecond: 設置鍵的過期時間為 millisecond 毫秒,使用 PX 選項效果等同於 PSETEX 命令。
  • NX: 只在鍵不存在時,才對鍵進行設置操作,使用 NX 選項效果等同於 SETNX 命令。
  • XX: 只在鍵已經存在時,才對鍵進行設置操作。

同樣的,使用 SET 命令操作成功之後會返回 OK,這樣才表示搶到了鎖。

為了避免分散式鎖被誤刪,加鎖時可以設置線程 ID 作為 value 值,刪除時需要線程的線程 ID 和 Redis 存儲的值一致才能夠刪除分散式鎖,否則只能等待鎖自動過期,整個刪除過程使用事務的方式保證原子性。

排行榜功能

通過 Redis 的 SortedSet 可以實現排行榜功能。

比如說需要展示點贊排行榜,可以將用戶 ID 作為 SortedSet 的 value 值,將用戶的點贊數作為 SortedSet 的 score 值,SortedSet 提供的 ZRANGEBYSCORE 命令可以快速返回已排序的點贊排行榜。

延時隊列

延時隊列其實就是一個帶有延遲功能的消息隊列,Redis 可以通過 SortedSet 實現延時隊列。

具體的實現如下:

  1. 將消息內容序列化成一個字元串作為 SortedSet 的 value 值,這個消息的到期處理時間作為 score,生產者調用 ZADD 命令生產消息,消費者可以使用 ZRANGEBYSCORE 命令獲取一段時間之前的數據輪詢處理;
  2. 通常使用多個線程輪詢 SortedSet 獲取到期的任務進行處理,多個線程是為了保障可用性,萬一掛了一個線程還有其他線程可以繼續處理;
  3. 因為有多個線程,所以需要考慮併發爭搶任務,確保任務不能被多次執行,Redis 的 ZREM 命令是多線程爭搶任務的關鍵,ZREM 命令會返回被成功移除的成員數量,可以通過 ZREM 命令來決定任務的唯一屬主;
  4. 同時也要註意一定要進行異常捕獲,避免因為個別任務處理問題導致迴圈異常退出,同一個任務可能會被多個進程取到之後再使用 ZREM 命令進行爭搶,那些沒搶到的進程都是白取了一次任務,這是浪費;
  5. 通常可以使用 Lua 腳本的方式,將 ZRANGEBYSCORE 命令和 ZREM 命令一同挪到伺服器端進行原子化操作,這樣多個進程之間爭搶任務時就不會出現這種浪費了。

非同步隊列

第一種方案 是使用 List 結構作為非同步隊列,RPUSH 命令生產消息,LPOP 命令消費消息。當使用 LPOP 命令沒有得到消息的時候,需要適當 sleep 一會再重試,在這裡 sleep 會導致消息的處理延遲增加。

如果不做 sleep 重試,改進的 第二種方案 是,使用 LPOP 命令的阻塞版本 BLPOP 命令,在 List 隊列中沒有消息的時候,它會阻塞直到消息到來,一旦數據到來,則立刻醒過來,消息的延遲幾乎為零。但是如果線程一直阻塞,Redis 的客戶端連接就成了閑置連接,閑置過久,伺服器一般會主動斷開連接,減少閑置資源占用。這個時候 BLPOP 命令會拋出異常來,代碼中需要處理這樣的異常。

除了 List 隊列之外,第三種方案 是使用 Pub/Sub 訂閱者模式實現一對多的消息隊列。但是 Redis 的發佈訂閱功能是無狀態的,對於發佈者來說,無法知道發佈的消息是否被訂閱者接收到,在消費者下線的情況下,生產的消息會丟失。

首發於「程式員翔仔」,點擊查看更多。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 集合框架體系Collection和Map常用API【彙總】 Collection公共的方法 Collection是單列結合的頂層介面,它的方法是所有單列集合都可以繼承使用的。 //把給定元素添加到集合中 public boolean add(E e) //把給定元素從集合中刪除 public boo ...
  • 本文介紹基於Python語言,按照一定命名規則批量修改多個文件的文件名的方法。 已知現有一個文件夾,其中包括班級所有同學上交的作業文件,每人一份;所有作業文件命名格式統一,都是地信1701_姓名_學習心得格式。 現需要對每一位同學的作業文件加以改名,有很多種需求。 第一種需求,將每一位同學作業文件名 ...
  • Python 是一種代表簡單思想的語言,其語法相對簡單,很容易上手。不過,如果就此小視 Python 語法的精妙和深邃,那就大錯特錯了。本文精心篩選了最能展現 Python 語法之精妙的十個知識點,並附上詳細的實例代碼。如能在實戰中融會貫通、靈活使用,必將使代碼更為精煉、高效,同時也會極大提升代碼B ...
  • 前言 相信大家看過不少講C# async await的文章,博客園就能搜到很多,但還是有很多C#程式員不明白。 如果搞不明白,其實也不影響使用。但有人就會疑惑,為什麼要用非同步?我感覺它更慢了,跟同步有啥區別? 有的人研究深入,比如去研究狀態機,可能會明白其中的原理。但深入研究的畢竟少數。有的人寫一些 ...
  • 由於一些客戶的內部系統需要提取一些記錄信息,如果手工錄入會變得比較麻煩,因此考慮使用百度雲的OCR進行圖片文字的提取處理,綜合比較了一下開源免費的Tesseract 類庫進行處理,不過識別效果不太理想,因此轉為了百度的OCR雲介面處理方式,測試的效果比較理想,基本上較少出現錯別字。本篇隨筆介紹如何利... ...
  • 1.背景知識 CRLF用來表示文本換行的方式 ,CR是回車的意思,對應 \r ;LF 是換行的意思,對應 \n Windows 換行符是 \r\n Unix 換行是 \n 如果一個將要在Linux伺服器上使用的文件,比如某個配置文件,在windows電腦打開,編輯過,那麼文件每一行末尾會多有\r 。 ...
  • MySQL中既存在redo log,又存在bin log,這是因為bin log是MySQL Server提供的一種歸檔日誌,其本身並不具備crash-safe能力。而redo log本身不具備歸檔能力,他是一種迴圈寫的日誌。 MySQL通過將這兩種日誌整合起來,並通過兩階段提交的機制,保證了數據... ...
  • 一:背景 1. 講故事 相信絕大部分用 SQLSERVER 作為底層存儲的程式員都知道 nolock 關鍵詞,即使當時不知道也會在踩過若幹阻塞坑之後果斷的加上 nolock,但這玩意有什麼註意事項呢?這就需要瞭解它的底層原理了。 二:nolock 的原理 1. sql 阻塞還原 為了方便講述,先創建 ...
一周排行
    -Advertisement-
    Play Games
  • @ 先看一下導出的整體效果(如下圖),其中標註的區域都是通過後臺動態生成的: 一、先在Word中建立好表格模板 1.1、參數創建方法(Word和WPS) 1.1.1、Office中Word域的創建 1.1.1.1、選中指定的單元格 -> 點擊頭部工具欄中的”插入“ -> 選擇 ”文檔部件“ -> 選 ...
  • 在實際工作中,經常會有一些需要定時操作的業務,如:定時發郵件,定時統計信息等內容,那麼如何實現才能使得我們的項目整齊劃一呢?本文通過一些簡單的小例子,簡述在.Net6+Quartz實現定時任務的一些基本操作,及相關知識介紹,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 紙殼CMS支持將評論、留言、表單提交、訂閱等通知,通過WebHook發送到第三方平臺,比如釘釘。 創建釘釘WebHook 需要在釘釘群中創建自定義機器人,具體方法可以參考釘釘的官方文檔: 自定義機器人接入 需要註意的是,在安全設置中不要使用加簽,使用自定義關鍵字即可。在發送的消息中,只要包含這個關鍵 ...
  • 向下轉型的使用 Java的多態性: 父類指向子類的聲明 Animal animal = new Dog()//Dog()重寫了父類Animal 有了對象的多態性以後,記憶體實際上載入的是==子類==的屬性和方法,但是由於變數聲明為==父類類型==,導致編譯時只能調用父類的屬性和方法,子類特有的屬性方法 ...
  • spring源碼環境搭建 組件 版本 jdk 1.8.0_192 spring-framework 5.3.x gradle 7.5.1 idea 2022.3.3 aspectJ 1.9 可根據spring-framwork項目說明靈活選擇 一、拉取spring-framework項目 1、spr ...
  • 首先任何的商業邏輯,光流量增長,沒法變現是沒用的。 就像博客群發提效工具,得有對應的用戶,更得有對應付費用戶群體的畫像。剩下的就是靠增長,被動讓他們找到你的產品,用產品解決他們痛點,他們自然而然會付費。 下麵大致分享下從三個方向分享下: 用戶痛點 -> 真正的付費用戶群體 產品價值 PLG 增長 一 ...
  • Object類的使用 Object類 Object類中的方法可以在網上搜索得到 Object類是所有java類的父類 如果類在聲明中未使用extends關鍵字指明其父類,則預設父類為java.lang.Object類 Object類中的功能(屬性、方法)具有通用性。 屬性:無 方法:equals() ...
  • Qt 源碼分析之moveToThread 這一次,我們來看Qt中關於將一個QObject對象移動至一個線程的函數moveToThread Qt使用線程的基本方法 首先,我們簡單的介紹一下在Qt中使用多線程的幾種方法: 重寫QThread的run函數,將要在多線程執行的任務放到run函數里 /*myt ...
  • 包裝類的使用 包裝類的使用 java提供8種基本數據類型對應的包裝類,使得基本數據類型變數具有類的特征 掌握:==基本數據類型、包裝類、String==三者之間的互相轉換 自動裝箱與自動拆箱==[基本數據類型和包裝類的轉換]== JDK5.0新特性,自動裝箱與自動拆箱。 class Test{ pu ...
  • 本文已經收錄到Github倉庫,該倉庫包含電腦基礎、Java基礎、多線程、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~ Github地址 大家好,我是大彬~ 今天來聊聊接 ...