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
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...