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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...