最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis介紹與使用一文搞懂

 更新時間:2026年05月14日 09:53:34   作者:jjkkzzzz  
文章主要介紹了Redis的基本概念、應(yīng)用場景、數(shù)據(jù)模型、內(nèi)存存儲機(jī)制、高性能特點(diǎn)、安裝與配置、常用命令、持久化與備份、高級特性等內(nèi)容,感興趣的朋友跟隨小編一起看看吧

Redis簡介

1.1 什么是 Redis?

Redis 是一個開源的、高性能的內(nèi)存數(shù)據(jù)存儲系統(tǒng),可以作為數(shù)據(jù)庫、緩存以及消息中間件使用。它支持豐富的數(shù)據(jù)結(jié)構(gòu),如字符串、哈希、列表、集合和有序集合等,因此被廣泛用于需要高性能、高并發(fā)的應(yīng)用場景。Redis 采用單線程模型和基于內(nèi)存的存儲方式,保證了非常高的讀寫速度。

簡而言之,Redis 是一個鍵值數(shù)據(jù)庫,它通過將數(shù)據(jù)存儲在內(nèi)存中,以實(shí)現(xiàn)快速的數(shù)據(jù)訪問。Redis 支持豐富的功能,如持久化(將數(shù)據(jù)保存在硬盤上以防丟失)、事務(wù)處理、發(fā)布/訂閱模式、Lua 腳本執(zhí)行等。

Redis 的最大特點(diǎn)是它的速度極快,而這一點(diǎn)正是它在 Web 應(yīng)用、高并發(fā)系統(tǒng)以及分布式環(huán)境中大受歡迎的原因之一。

1.2 Redis 的應(yīng)用場景

Redis 因?yàn)槠涓咚俚淖x寫能力和多種數(shù)據(jù)結(jié)構(gòu)支持,應(yīng)用場景非常廣泛,常見的場景包括:

1.2.1 緩存系統(tǒng)

Redis 最常見的應(yīng)用場景就是作為緩存層。在應(yīng)用中,我們常常會緩存一些查詢頻繁且不經(jīng)常變動的數(shù)據(jù)。Redis 作為緩存系統(tǒng),可以極大提升數(shù)據(jù)讀取速度,減輕數(shù)據(jù)庫的負(fù)擔(dān)。例如,網(wǎng)站首頁的廣告推薦信息、商品詳情頁的緩存等。

1.2.2 實(shí)時數(shù)據(jù)處理

Redis 支持的數(shù)據(jù)結(jié)構(gòu)非常適合實(shí)時數(shù)據(jù)處理,例如排行榜、計(jì)數(shù)器、實(shí)時消息推送等。通過 Redis 的有序集合(ZSet),我們可以輕松實(shí)現(xiàn)排行榜等功能,并能實(shí)時更新排名數(shù)據(jù)。

1.2.3 消息隊(duì)列

Redis 提供的列表(List)和發(fā)布/訂閱(Pub/Sub)功能,非常適合用作消息隊(duì)列。在一個分布式系統(tǒng)中,生產(chǎn)者將消息推送到隊(duì)列中,消費(fèi)者異步處理這些消息。Redis 提供的高效操作能確保消息隊(duì)列處理的低延遲和高吞吐量。

1.2.4 會話管理

Redis 的高效性和內(nèi)存存儲使它非常適合用作 會話管理(Session Store)。比如,在 Web 應(yīng)用中,用戶登錄時,常將用戶會話信息存儲在 Redis 中,這樣可以快速訪問與更新會話信息。

1.2.5 分布式鎖

Redis 還可以用于實(shí)現(xiàn)分布式鎖,通過它的 SETNX 命令,可以實(shí)現(xiàn)保證分布式環(huán)境下任務(wù)的互斥訪問。

1.3 Redis 與傳統(tǒng)數(shù)據(jù)庫的區(qū)別

Redis 作為 NoSQL (對非關(guān)系型數(shù)據(jù)庫的統(tǒng)稱)數(shù)據(jù)庫,與傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(如 MySQL 和 SQLite3)相比,有許多顯著的區(qū)別。我們從幾個關(guān)鍵維度來對比 Redis 和傳統(tǒng)數(shù)據(jù)庫:

1.3.1 數(shù)據(jù)存儲方式

  • Redis:將數(shù)據(jù)存儲在內(nèi)存中,訪問速度極快。Redis 是一個內(nèi)存數(shù)據(jù)庫,支持內(nèi)存持久化(RDB 快照和 AOF 日志)以實(shí)現(xiàn)數(shù)據(jù)持久化。
  • MySQL/SQLite3:是磁盤數(shù)據(jù)庫,所有數(shù)據(jù)都存儲在磁盤中,雖然也有內(nèi)存緩存機(jī)制,但相較于 Redis,訪問速度較慢。SQLite3 通常用于嵌入式應(yīng)用和輕量級數(shù)據(jù)庫,而 MySQL 更適用于中大型應(yīng)用和多用戶環(huán)境。

1.3.2 數(shù)據(jù)結(jié)構(gòu)支持

  • Redis:支持豐富的內(nèi)存數(shù)據(jù)結(jié)構(gòu),除了基礎(chǔ)的鍵值對,還支持哈希表、列表、集合、有序集合等數(shù)據(jù)結(jié)構(gòu),適合多種應(yīng)用場景(如計(jì)數(shù)器、隊(duì)列、集合去重等)。
  • MySQL/SQLite3:主要支持表格結(jié)構(gòu),通過表格的行和列來組織數(shù)據(jù)。它們基于關(guān)系模型進(jìn)行數(shù)據(jù)存儲,所有操作都是基于 SQL 查詢的。

1.3.3 性能與可擴(kuò)展性

  • Redis:通過內(nèi)存存儲數(shù)據(jù),Redis 的讀寫速度非???,適合高并發(fā)訪問的場景。它采用單線程模型,避免了多線程的上下文切換和鎖的競爭,能夠在高并發(fā)場景中提供更高的性能。
  • MySQL/SQLite3:雖然 MySQL 在大規(guī)模數(shù)據(jù)操作時表現(xiàn)出色,但在性能上受限于磁盤 I/O。SQLite3 通常用于單機(jī)環(huán)境,適合小型應(yīng)用,不適合大規(guī)模的并發(fā)讀寫。

1.3.4 查詢能力

  • Redis:沒有復(fù)雜的查詢語言,如 SQL。所有操作都通過 Redis 的命令完成,功能較為簡單,適合簡單的鍵值對存儲以及對某些數(shù)據(jù)結(jié)構(gòu)的操作。
  • MySQL/SQLite3:支持 SQL 查詢,能夠進(jìn)行復(fù)雜的多表聯(lián)合查詢、聚合、過濾等操作。適用于關(guān)系型數(shù)據(jù),能夠進(jìn)行更復(fù)雜的數(shù)據(jù)分析和報(bào)表生成。

1.3.5 數(shù)據(jù)一致性

  • Redis:Redis 對 ACID 特性的支持是有限的。它支持命令級別的原子性,但不提供傳統(tǒng)意義上的事務(wù)隔離與強(qiáng)一致性保障。在分布式環(huán)境中,Redis 更加注重高性能和高可用性,允許在一定程度上犧牲數(shù)據(jù)一致性。
  • MySQL/SQLite3:MySQL 提供了完善的事務(wù)支持,遵循 ACID 原則,可以確保數(shù)據(jù)的一致性、可靠性和持久性,適合要求高一致性的場景。

補(bǔ)充:ACID特性

縮寫全稱中文名作用
AAtomicity原子性確保事務(wù)中的所有操作要么全部執(zhí)行成功,要么全部不執(zhí)行
CConsistency一致性確保事務(wù)前后,數(shù)據(jù)庫始終處于一致的狀態(tài)
IIsolation隔離性確保并發(fā)事務(wù)之間互不干擾
DDurability持久性一旦事務(wù)提交,其修改的數(shù)據(jù)應(yīng)永久保存在數(shù)據(jù)庫中

原子性(Atomicity):

一個事務(wù)中的所有操作要么全部成功,要么全部失敗,不可能只執(zhí)行部分操作。

舉例說明:
銀行轉(zhuǎn)賬中,從賬戶 A 扣錢、給賬戶 B 加錢,這兩個操作必須綁定執(zhí)行。如果只扣了 A 的錢,但沒給 B 加上,那事務(wù)就是不完整的 —— 原子性就被破壞了。

一致性(Consistency):

事務(wù)執(zhí)行前后,數(shù)據(jù)庫必須處于一致的狀態(tài),即遵守所有的約束條件(如唯一性、外鍵、業(yè)務(wù)規(guī)則等)。

舉例說明:
繼續(xù)銀行轉(zhuǎn)賬的例子,假設(shè)兩個賬戶總額是 10000 元,無論轉(zhuǎn)多少次,只要每次事務(wù)正確執(zhí)行,總額都不能改變 —— 這就體現(xiàn)了一致性。

隔離性(Isolation):

多個事務(wù)并發(fā)執(zhí)行時,彼此之間互不干擾,各自的中間狀態(tài)對其他事務(wù)不可見。

舉例說明:
如果兩個事務(wù)同時修改同一個庫存,系統(tǒng)必須采取機(jī)制避免數(shù)據(jù)“被多次扣減”或出現(xiàn)“臟讀”等問題。傳統(tǒng)數(shù)據(jù)庫通過鎖機(jī)制或 MVCC(多版本并發(fā)控制)實(shí)現(xiàn)事務(wù)隔離,支持不同的隔離級別(如 Read Committed、Repeatable Read、Serializable 等)。

持久性(Durability):

一旦事務(wù)提交,其對數(shù)據(jù)庫的更改必須永久保存,即使系統(tǒng)崩潰也不會丟失數(shù)據(jù)。

舉例說明:
你轉(zhuǎn)賬后收到“轉(zhuǎn)賬成功”的提示,這筆交易即使服務(wù)器此時崩潰,系統(tǒng)重啟后也必須能恢復(fù)該記錄。數(shù)據(jù)庫通常通過寫 WAL(Write-Ahead Log)日志、刷盤等機(jī)制來保證持久性。

1.4 Redis 的優(yōu)勢與局限性

1.4.1 優(yōu)勢

  • 高性能:Redis 的內(nèi)存數(shù)據(jù)庫模型使其讀取和寫入速度非??欤m用于高并發(fā)、高訪問量的場景。
  • 豐富的數(shù)據(jù)結(jié)構(gòu)支持:除了基本的鍵值對,Redis 還支持哈希、列表、集合、有序集合等多種數(shù)據(jù)結(jié)構(gòu),使得 Redis 在解決特定問題時比傳統(tǒng)數(shù)據(jù)庫更具優(yōu)勢。
  • 簡單易用:Redis 提供的命令簡潔且直觀,容易上手,適合快速開發(fā)。
  • 高可用性與分布式支持:Redis 提供了主從復(fù)制、Redis Sentinel 和 Redis Cluster 等功能,可以構(gòu)建高可用、可擴(kuò)展的分布式系統(tǒng)。
  • 支持持久化:Redis 可以將內(nèi)存數(shù)據(jù)持久化到磁盤,通過 RDB 快照或 AOF 日志來保證數(shù)據(jù)持久性,適應(yīng)了大多數(shù)高性能應(yīng)用場景。

1.4.2 局限性

  • 內(nèi)存限制:作為內(nèi)存數(shù)據(jù)庫,Redis 的存儲受限于服務(wù)器的內(nèi)存大小。如果存儲大量數(shù)據(jù),可能會遇到內(nèi)存不足的情況。
  • 不支持復(fù)雜查詢:Redis 主要提供簡單的 CRUD 操作,對于復(fù)雜的 SQL 查詢(如多表關(guān)聯(lián)、聚合查詢等)不支持,需要結(jié)合其他工具進(jìn)行實(shí)現(xiàn)。
  • 數(shù)據(jù)一致性問題:Redis 犧牲了部分?jǐn)?shù)據(jù)一致性和事務(wù)性,適用于非事務(wù)性和高可用性場景,但對于一些要求強(qiáng)一致性的應(yīng)用,可能不合適。

Redis 基礎(chǔ)概念

2.1 Redis 數(shù)據(jù)模型

2.1.1 鍵(Key)

在 Redis 中,每條數(shù)據(jù)都是一個鍵值對(Key-Value)。
Key 就是數(shù)據(jù)的唯一標(biāo)識符,相當(dāng)于傳統(tǒng)數(shù)據(jù)庫中的主鍵(Primary Key)。它的特性如下:

  • 類型:字符串(string),但內(nèi)容可以是任何字節(jié)數(shù)組。
  • 最大長度:512 MB。
  • 通常作為查詢的入口,不支持模糊檢索(除了 KEYS 命令)。
  • 最佳實(shí)踐:采用命名空間方式命名,如:user:1001:name

2.1.2 值(Value)

值的類型可以是多種結(jié)構(gòu),不僅僅是字符串。這是 Redis 最有特色的設(shè)計(jì)。

2.1.3 數(shù)據(jù)類型

Redis 支持五大基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)(以及一些高級結(jié)構(gòu),如 HyperLogLog、Bitmap、Geo):

類型簡介使用場景示例命令
字符串(String)最基本的數(shù)據(jù)類型,可存儲文本或二進(jìn)制緩存、計(jì)數(shù)器、token 存儲SET key value, INCR key
哈希(Hash)鍵值對集合,適用于對象表示存儲用戶信息、配置項(xiàng)HSET user:1001 name zhang
列表(List)有序鏈表,支持左右兩端插入彈出消息隊(duì)列、時間線LPUSH, RPOP
集合(Set)無序不重復(fù)元素集合標(biāo)簽、好友推薦、去重SADD, SINTER
有序集合(ZSet)每個元素有一個分?jǐn)?shù),用于排序排行榜、帶權(quán)集合ZADD, ZRANGE

Redis 的強(qiáng)大正是因?yàn)橹担╒alue)不僅是數(shù)據(jù),也可以是結(jié)構(gòu)化的數(shù)據(jù)集合。

2.2 Redis 內(nèi)存存儲機(jī)制

Redis 是內(nèi)存數(shù)據(jù)庫,數(shù)據(jù)讀寫全部在內(nèi)存中完成,這也是其高性能的核心原因。

2.2.1 內(nèi)存持久化(RDB 和 AOF)

【RDB】(快照)

  • 以時間間隔為單位,周期性生成數(shù)據(jù)快照并寫入磁盤(.rdb 文件)。
  • 優(yōu)點(diǎn):恢復(fù)速度快,占用空間小。
  • 缺點(diǎn):一旦崩潰,可能丟失上次快照之后的數(shù)據(jù)。

【AOF】(Append Only File)

  • 每次寫操作都會以命令形式寫入日志文件(.aof)。
  • 優(yōu)點(diǎn):數(shù)據(jù)幾乎不丟失,恢復(fù)最完整。
  • 缺點(diǎn):文件大,恢復(fù)慢。

Redis 支持 RDB 和 AOF 混合持久化,也可以配置成只使用其中一種。

2.2.2 數(shù)據(jù)備份與恢復(fù)

  • 備份方式:
    • 復(fù)制 RDB 或 AOF 文件。
    • 使用 SAVEBGSAVE 手動觸發(fā)。
  • 恢復(fù)方式:
    • 直接將 RDB/AOF 文件放置到數(shù)據(jù)目錄,重啟 Redis。
[Redis 內(nèi)存數(shù)據(jù)]
       |
       |(定期快照)
       v
     RDB 文件 (或 AOF 日志)
       |
       |
       v
   磁盤持久化文件

2.3 Redis 的高性能特點(diǎn)

Redis 在高性能方面的設(shè)計(jì)非常值得稱道,以下三點(diǎn)是核心:

2.3.1 單線程模型

Redis 的命令處理采用單線程模型,不加鎖、不阻塞,避免了線程切換開銷。

  • 所有命令串行執(zhí)行,天然避免并發(fā)競爭問題。
  • 主要瓶頸是 CPU,而不是鎖。
客戶端請求
     |
     v
+-----------+
| Redis 主線程 |
+-----------+
     |
     v
處理命令(串行執(zhí)行)

2.3.2 異步 IO(非阻塞網(wǎng)絡(luò)模型)

  • Redis 使用 epoll(Linux)/kqueue(BSD) 等多路復(fù)用技術(shù)進(jìn)行 異步 IO 處理。
  • 雖然命令執(zhí)行是單線程,但網(wǎng)絡(luò)收發(fā)是非阻塞的,連接處理效率極高。
  • 底層采用 ae_event_loop 實(shí)現(xiàn)事件驅(qū)動模型。
+-------------+
| 客戶端連接池 |
+-------------+
     |
     v
[ epoll 監(jiān)聽 socket 事件 ]
     |
     v
[ 有請求來了 ]
     |
     v
[ 主線程按序處理請求 ]

2.3.3 內(nèi)存數(shù)據(jù)庫

Redis 完全基于內(nèi)存工作,數(shù)據(jù)訪問無需磁盤 I/O:

  • 所有數(shù)據(jù)保存在內(nèi)存中,讀寫速度為納秒級(ns)。
  • 后臺定期將內(nèi)存數(shù)據(jù)異步持久化到磁盤(非阻塞)。

這就是 Redis 快如閃電的根本原因。

redis核心模型簡化示意圖

+----------------+        +----------------------+
|   客戶端請求    | -----> |   網(wǎng)絡(luò)層(非阻塞 IO)  |
+----------------+        +----------------------+
                                |
                                v
                      +------------------+
                      |   單線程命令處理   | <- Redis 主線程(串行)
                      +------------------+
                                |
              +----------------+----------------+
              |                                 |
     +----------------+              +--------------------+
     | 內(nèi)存數(shù)據(jù)結(jié)構(gòu)區(qū)  |              | 持久化(RDB / AOF) |
     +----------------+              +--------------------+

redis安裝與配置

3.1 linux安裝 Redis

3.1.1 使用包管理器安裝

sudo apt update
sudo apt install redis-server

安裝完成后,可以使用以下命令啟動和查看 Redis 服務(wù):

sudo systemctl start redis
sudo systemctl enable redis   # 開機(jī)啟動
sudo systemctl status redis

默認(rèn)配置文件路徑為 /etc/redis/redis.conf,默認(rèn)端口是 6379。

3.1.2 源碼編譯安裝

# 1. 下載源碼
wget https://download.redis.io/releases/redis-7.2.4.tar.gz
tar -xzf redis-7.2.4.tar.gz
cd redis-7.2.4
# 2. 編譯
make -j4
# 3. 可選:執(zhí)行測試(需要 tcl)
make test
# 4. 安裝
sudo make install

安裝后,會將 redis-serverredis-cli 等可執(zhí)行文件放到 /usr/local/bin/

你可以直接運(yùn)行:

redis-server      # 啟動服務(wù)
redis-cli         # 客戶端命令行

配置文件可在源碼目錄中找到:redis.conf,你可以復(fù)制到合適位置如 /etc/redis/。

3.2 配置 Redis

Redis 的核心配置文件是:redis.conf,默認(rèn)位置因安裝方式而異。

你可以使用:

redis-server /redis.conf的path

來自定義啟動 Redis。

3.2.1 常見配置項(xiàng)(redis.conf)

配置項(xiàng)作用示例
port監(jiān)聽端口port 6379
bind限制綁定的 IPbind 127.0.0.1
requirepass設(shè)置訪問密碼requirepass yourpassword
dir持久化文件保存目錄dir /var/lib/redis/
dbfilenameRDB 文件名dbfilename dump.rdb
appendonly是否開啟 AOFappendonly yes
appendfilenameAOF 文件名appendfilename "appendonly.aof"
maxmemory限制最大內(nèi)存maxmemory 256mb
maxmemory-policy內(nèi)存淘汰策略allkeys-lru、volatile-ttl

3.2.2 安全配置(密碼、IP 限制)

綁定指定 IP:

bind 127.0.0.1  # 限制本地訪問

設(shè)置訪問密碼:要求所有客戶端在執(zhí)行任何命令前必須提供這個密碼

requirepass mystrongpassword
客戶端連接時輸入上述步驟設(shè)置的密碼:
redis-cli -a mystrongpassword

關(guān)閉危險(xiǎn)命令(如 FLUSHALL):

rename-command FLUSHALL ""
rename-command FLUSHDB ""

3.2.3 性能優(yōu)化配置(內(nèi)存、持久化等)

內(nèi)存限制(適用于緩存場景):

# 設(shè)置 Redis 使用的最大內(nèi)存為 512MB,超出后會觸發(fā)內(nèi)存淘汰策略
maxmemory 512mb
# 設(shè)置內(nèi)存淘汰策略為 allkeys-lru(從所有鍵中挑選最近最少使用的鍵淘汰)
maxmemory-policy allkeys-lru

持久化控制(視業(yè)務(wù)需求選擇):

        關(guān)閉持久化(僅做緩存):

save ""
appendonly no

        開啟 AOF 且設(shè)置為每秒同步:

appendonly yes
appendfsync everysec

Redis 常用命令

4.1 字符串(String)

Redis 中最基本的數(shù)據(jù)類型,類似于傳統(tǒng)數(shù)據(jù)庫中的單個字段值。

Redis 的字符串結(jié)構(gòu)是:

Key -> "value"

常用命令:

  • SET key value:設(shè)置鍵值。
  • GET key:獲取鍵值。
  • DEL key:刪除鍵。
  • INCR key / DECR key:對數(shù)值型字符串進(jìn)行自增/自減操作。
  • INCRBY key amount / DECRBY key amount:按指定步長增減。
  • APPEND key value:向原字符串追加內(nèi)容。
  • STRLEN key:返回字符串長度。
  • MSET key1 val1 key2 val2 ...:批量設(shè)置多個鍵值對。
  • MGET key1 key2 ...:批量獲取多個鍵值。
  • SETNX key value:僅當(dāng) key 不存在時設(shè)置。
  • SETEX key seconds value:設(shè)置值并指定過期時間。

示例:

## 設(shè)置與獲取
SET name "Alice"
# 返回: OK
# 當(dāng)前鍵值對為:
# name -> "Alice"
GET name
# 返回: "Alice"
# 說明: "name" 鍵的值為 "Alice"
## 批量操作
MSET age 25 city "Shanghai"
# 返回: OK
# 當(dāng)前鍵值對為:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
MGET name age city
# 返回:
# 1) "Alice"
# 2) "25"
# 3) "Shanghai"
# 說明: 返回 "name", "age", "city" 鍵的值
## 自增自減
SET counter 10
# 返回: OK
# 當(dāng)前鍵值對為:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "10"
INCR counter
# 返回: 11
# 當(dāng)前鍵值對為:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "11"
INCRBY counter 5
# 返回: 16
# 當(dāng)前鍵值對為:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "16"
DECR counter
# 返回: 15
# 當(dāng)前鍵值對為:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "15"
DECRBY counter 2
# 返回: 13
# 當(dāng)前鍵值對為:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"
## 字符串追加與長度
APPEND name " Smith"
# 返回: 11      # 新字符串長度
# 當(dāng)前鍵值對為:
# name -> "Alice Smith"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"
GET name
# 返回: "Alice Smith"
# 說明: "name" 鍵的值已更新為 "Alice Smith"
STRLEN name
# 返回: 11
# 說明: "name" 字段的長度為 11("Alice Smith")
## 設(shè)置過期鍵值對
SETEX token 60 "abc123"
# 返回: OK
# 當(dāng)前鍵值對為:
# name -> "Alice Smith"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"
# token -> "abc123"(將在60秒后自動過期)
GET token
# 返回: "abc123"
# 說明: "token" 鍵的值為 "abc123",且將在60秒后過期
## 條件設(shè)置(鍵不存在時才設(shè)置)
SETNX city "Beijing"
# 返回: 0      # 因?yàn)?city 已存在,未設(shè)置成功
# 當(dāng)前鍵值對為:
# name -> "Alice Smith"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"
# token -> "abc123"(將在60秒后過期)
GET city
# 返回: "Shanghai"
# 說明: "city" 鍵的值仍為 "Shanghai"
## 最終鍵值狀態(tài)(執(zhí)行完上述命令后)
name      -> "Alice Smith"
age       -> "25"
city      -> "Shanghai"
counter   -> "13"
token     -> "abc123"  (將于60秒后自動失效)

4.2 哈希(Hash)

哈希表用于存儲對象,常用于表示用戶信息、商品信息等。

Redis 的哈希結(jié)構(gòu)是:

Key -> {
    field1: value1,
    field2: value2,
    ...
}

常用命令:

  • HSET key field value:設(shè)置字段。
  • HGET key field:獲取字段值。
  • HGETALL key:獲取所有字段和值。
  • HMSET key field1 val1 field2 val2 ...:一次設(shè)置多個字段(Redis 4.0 后不推薦)。
  • HMGET key field1 field2 ...:一次獲取多個字段。
  • HDEL key field [field ...]:刪除字段。
  • HEXISTS key field:判斷字段是否存在。
  • HLEN key:返回字段數(shù)量。
  • HINCRBY key field increment:字段數(shù)值加減。
  • HSTRLEN key field:字段值長度。

示例:

## 設(shè)置與獲取
HSET user:1001 name "Bob" age "30" gender "male"
# 返回: 3    # 表示新增了3個字段
# 當(dāng)前哈希表 user:1001 內(nèi)容為:
# user:1001 -> {
#     "name": "Bob",
#     "age": "30",
#     "gender": "male"
# }
HGET user:1001 name
# 返回: "Bob"
# 說明: "name" 字段值為 "Bob"
## 批量設(shè)置與獲取
HMSET user:1001 email "bob@example.com" phone "123456789"
# 返回: OK
# 當(dāng)前哈希表 user:1001 內(nèi)容為:
# user:1001 -> {
#     "name": "Bob",
#     "age": "30",
#     "gender": "male",
#     "email": "bob@example.com",
#     "phone": "123456789"
# }
HMGET user:1001 name email phone
# 返回:
# 1) "Bob"
# 2) "bob@example.com"
# 3) "123456789"
# 說明: 分別返回 "name", "email", "phone" 字段的值
## 刪除字段與判斷字段是否存在
HDEL user:1001 gender
# 返回: 1    # 成功刪除1個字段
# 當(dāng)前哈希表 user:1001 內(nèi)容為:
# user:1001 -> {
#     "name": "Bob",
#     "age": "30",
#     "email": "bob@example.com",
#     "phone": "123456789"
# }
HEXISTS user:1001 age
# 返回: 1    # 字段 age 存在
# 說明: "age" 字段仍然存在
## 哈希結(jié)構(gòu)長度信息
HLEN user:1001
# 返回: 4    # 當(dāng)前哈希表中還有 4 個字段
# 當(dāng)前哈希表 user:1001 內(nèi)容為:
# user:1001 -> {
#     "name": "Bob",
#     "age": "30",
#     "email": "bob@example.com",
#     "phone": "123456789"
# }
HSTRLEN user:1001 name
# 返回: 3    # name 字段的字符串長度為 3("Bob")
# 說明: "name" 字段的值長度為 3
## 自增字段(用于數(shù)值字段)
HINCRBY user:1001 age 2
# 返回: 32   # 將 age 從 30 增加到 32
# 當(dāng)前哈希表 user:1001 內(nèi)容為:
# user:1001 -> {
#     "name": "Bob",
#     "age": "32",
#     "email": "bob@example.com",
#     "phone": "123456789"
# }
## 獲取全部字段和值
HGETALL user:1001
# 返回:
# 1) "name"
# 2) "Bob"
# 3) "age"
# 4) "32"
# 5) "email"
# 6) "bob@example.com"
# 7) "phone"
# 8) "123456789"
# 說明: 返回所有字段和值
## 最終哈希表 user:1001 的結(jié)構(gòu)如下:
{
  "name":  "Bob",
  "age":   "32",
  "email": "bob@example.com",
  "phone": "123456789"
}

4.3 列表(List)

列表是一種雙向鏈表結(jié)構(gòu),支持從兩端插入和彈出元素。

Redis 的列表結(jié)構(gòu)是:

Key -> [ value1, value2, value3, ... ]

常用命令:

  • LPUSH key value [value ...] / RPUSH key value [value ...]:從左/右插入。
  • LPOP key / RPOP key:從左/右彈出。
  • LRANGE key start stop:獲取指定范圍元素。
  • LLEN key:獲取列表長度。
  • LREM key count value:移除指定值。
  • LSET key index value:設(shè)置指定索引的值。
  • LINDEX key index:獲取指定索引值。
  • LTRIM key start stop:保留指定區(qū)間,刪除其余元素。
  • BLPOP key [key ...] timeout / BRPOP key [key ...] timeout:阻塞式彈出。

示例:

# 插入元素
LPUSH tasks "task3" "task2"
RPUSH tasks "task4"
head <--> "task2" <--> "task3" <--> "task4" <--> tail
# 查詢
LLEN tasks    #LLEN tasks 返回列表的長度,結(jié)果是 3。
LRANGE tasks 0 -1  
#LRANGE tasks 0 -1 返回從索引 0 到 -1(即整個列表),結(jié)果是 ["task2", "task3", "task4"]。
LINDEX tasks 1
LINDEX tasks 1 返回索引 1 的元素,結(jié)果是 "task3"。
# 設(shè)置與移除
LSET tasks 1 "task2_updated"
head <--> "task2" <--> "task2_updated" <--> "task4" <--> tail
LREM tasks 0 "task3"
head <--> "task2" <--> "task2_updated" <--> "task4" <--> tail
# 截取與彈出
LTRIM tasks 0 1
head <--> "task2" <--> "task2_updated" <--> tail
LPOP tasks
head <--> "task2_updated" <--> tail
RPOP tasks
head <--> tail

4.4 集合(Set)

集合用于存儲不重復(fù)元素,支持集合運(yùn)算。

Redis 的集合結(jié)構(gòu)是:

Key -> {value1,value2,value3,...}

常用命令:

  • SADD key member [member ...]:添加元素。
  • SMEMBERS key:獲取所有元素。
  • SREM key member [member ...]:刪除元素。
  • SISMEMBER key member:判斷是否存在。
  • SCARD key:集合元素?cái)?shù)量。
  • SRANDMEMBER key [count]:隨機(jī)返回一個或多個元素。
  • SPOP key [count]:隨機(jī)彈出元素。
  • SUNION key1 key2 ...:求并集。
  • SINTER key1 key2 ...:求交集。
  • SDIFF key1 key2 ...:求差集。

示例:

## 添加元素
SADD tags "redis" "database" "nosql"
# 返回: 3     # 成功添加了3個新元素
# 當(dāng)前集合內(nèi)容(順序可能不同):
# tags -> {
#     "redis",
#     "database",
#     "nosql"
# }
## 再次添加重復(fù)元素
SADD tags "redis" "backend"
# 返回: 1     # 只有 "backend" 是新元素
# 當(dāng)前集合內(nèi)容(順序可能不同):
# tags -> {
#     "redis",
#     "database",
#     "nosql",
#     "backend"
# }
## 查看所有成員
SMEMBERS tags
# 返回:
# 1) "redis"
# 2) "nosql"
# 3) "database"
# 4) "backend"
# (集合是無序的,順序可能不同)
## 判斷元素是否存在
SISMEMBER tags "redis"
# 返回: 1     # 表示存在
SISMEMBER tags "mysql"
# 返回: 0     # 表示不存在
## 移除元素
SREM tags "nosql"
# 返回: 1     # 成功移除1個元素
# 當(dāng)前集合內(nèi)容(順序可能不同):
# tags -> {
#     "redis",
#     "database",
#     "backend"
# }
## 集合大小
SCARD tags
# 返回: 3
## 隨機(jī)彈出一個元素
SPOP tags
# 返回: (例如)"backend"   # 每次隨機(jī),結(jié)果可能不同
# 當(dāng)前集合內(nèi)容(順序可能不同):
# tags -> {
#     "redis",
#     "database"
# }
## 最終集合內(nèi)容
SMEMBERS tags
# 返回:
# 1) "redis"
# 2) "database"
# (假設(shè)彈出了 "backend")

4.5 有序集合(Sorted Set)

每個元素有一個 score,成員按照 score 自動從小到大排序。與集合(Set)相比,多了一個“分?jǐn)?shù)”維度,且結(jié)果是有序的。

Redis 的有序集合結(jié)構(gòu)是:

Key -> {
    member1: score1,
    member2: score2,
    ...
}

常用命令:

  • ZADD key score member [score member ...]:添加元素。
  • ZRANGE key start stop [WITHSCORES] / ZREVRANGE:按分?jǐn)?shù)排序查詢。
  • ZREM key member [member ...]:刪除成員。
  • ZSCORE key member:獲取某成員的分?jǐn)?shù)。
  • ZRANK key member / ZREVRANK:獲取排名。
  • ZINCRBY key increment member:對成員分?jǐn)?shù)自增。
  • ZCOUNT key min max:統(tǒng)計(jì)分?jǐn)?shù)在范圍內(nèi)的元素?cái)?shù)量。
  • ZRANGEBYSCORE key min max:按分?jǐn)?shù)范圍查詢。

示例:

# Redis 有序集合操作演示(scoreboard)
# 1. 添加與查詢
ZADD scoreboard 100 "Alice" 150 "Bob" 130 "Carol"
# 返回結(jié)果:
# (integer) 3    # 成功添加 3 個成員
# Redis 中有序集合 scoreboard 內(nèi)容為(按 score 排序):
# scoreboard -> {
#     "Alice": 100,
#     "Carol": 130,
#     "Bob":   150
# }
ZRANGE scoreboard 0 -1 WITHSCORES
# 返回結(jié)果(按 score 從小到大):
# 1) "Alice"
# 2) "100"
# 3) "Carol"
# 4) "130"
# 5) "Bob"
# 6) "150"
ZREVRANGE scoreboard 0 1
# 返回結(jié)果(按 score 從大到小,前兩個成員):
# 1) "Bob"
# 2) "Carol"
# 2. 分?jǐn)?shù)與排名查詢
ZSCORE scoreboard Alice
# 返回結(jié)果:
# "100"
# 說明: "Alice" 的分?jǐn)?shù)為 100
ZRANK scoreboard Carol
# 返回結(jié)果:
# 1
# 說明: "Carol" 排名第 2(從 0 開始)
ZREVRANK scoreboard Bob
# 返回結(jié)果:
# 0
# 說明: "Bob" 在倒序中排名第 1(最高分)
# 3. 分?jǐn)?shù)修改與范圍查詢
ZINCRBY scoreboard 10 Alice
# 返回結(jié)果:
# "110"
# 說明: "Alice" 的分?jǐn)?shù)已增加 10,變?yōu)?110
ZRANGE scoreboard 0 -1 WITHSCORES
# 返回結(jié)果(按 score 從小到大):
# 1) "Alice"
# 2) "110"
# 3) "Carol"
# 4) "130"
# 5) "Bob"
# 6) "150"
ZCOUNT scoreboard 120 160
# 返回結(jié)果:
# (integer) 2
# 說明: "scoreboard" 中分?jǐn)?shù)在 120 到 160 之間的成員有 2 個("Carol" 和 "Bob")
ZRANGEBYSCORE scoreboard 120 200
# 返回結(jié)果:
# 1) "Carol"
# 2) "Bob"

4.6 鍵操作(Key Operations)

用于管理所有鍵的通用命令。

常用命令:

  • EXPIRE key seconds:設(shè)置鍵過期時間。
  • TTL key:查看剩余時間。
  • PERSIST key:取消過期時間。
  • DEL key [key ...]:刪除鍵。
  • RENAME key newkey:重命名鍵。
  • TYPE key:查看鍵類型。
  • KEYS pattern:通配符查詢。
  • EXISTS key:判斷鍵是否存在。
  • MOVE key db:將指定的鍵遷移到指定的數(shù)據(jù)庫
  • DOUBLE OBJECT key:查看給定鍵的內(nèi)部信息(包括內(nèi)存占用等)
# 1. EXPIRE key seconds:設(shè)置鍵的過期時間
SET mykey "Hello"
# 返回: OK
EXPIRE mykey 60
# 返回: 1    # 設(shè)置成功,鍵 mykey 將在60秒后過期
TTL mykey
# 返回: 60   # 返回剩余過期時間為 60 秒
# 2. TTL key:查看剩余時間
TTL mykey
# 返回: 60   # mykey 剩余過期時間 60 秒
# 3. PERSIST key:取消過期時間
PERSIST mykey
# 返回: 1    # 表示取消了過期時間
TTL mykey
# 返回: -1   # 不再有過期時間
# 4. DEL key [key ...]:刪除一個或多個鍵
DEL mykey
# 返回: 1    # 刪除成功
TTL mykey
# 返回: (error) No such key   # 鍵已刪除,不存在
# 5. RENAME key newkey:重命名鍵
SET mykey "Hello"
# 返回: OK
RENAME mykey newkey
# 返回: OK    # 重命名成功
GET newkey
# 返回: "Hello"   # 可以通過新鍵名獲取相同的值
# 6. TYPE key:查看鍵的類型
SET mykey "Hello"
# 返回: OK
TYPE mykey
# 返回: string   # 表示 mykey 的類型是 string
# 7. KEYS pattern:通配符查詢
SET user1 "Alice"
SET user2 "Bob"
SET admin "Charlie"
# 返回: OK
KEYS user*
# 返回:
# 1) "user1"
# 2) "user2"
# 8. EXISTS key:判斷鍵是否存在
EXISTS mykey
# 返回: 0    # 表示 mykey 不存在
EXISTS newkey
# 返回: 1    # 表示 newkey 存在
# 9. MOVE key db:將鍵遷移到指定的數(shù)據(jù)庫
SET mykey "Hello"
# 返回: OK
MOVE mykey 1
# 返回: 1    # 表示成功將 mykey 從當(dāng)前數(shù)據(jù)庫遷移到數(shù)據(jù)庫 1
SELECT 1
# 返回: OK
GET mykey
# 返回: "Hello"   # 在數(shù)據(jù)庫 1 中可以找到 `mykey`
# 10. OBJECT key:查看給定鍵的內(nèi)部信息
SET mykey "Hello"
# 返回: OK
OBJECT ENCODING mykey
# 返回: "raw"    # 返回鍵的編碼方式
OBJECT IDLETIME mykey
# 返回: 0       # 返回 mykey 的空閑時間(單位:秒)

4.7 redis常用數(shù)據(jù)庫管理命令

SELECT index

切換 Redis 數(shù)據(jù)庫。Redis 默認(rèn)有 16 個數(shù)據(jù)庫,使用索引來切換。

SELECT 2
# 返回: OK    # 選擇數(shù)據(jù)庫 2

FLUSHDB

刪除當(dāng)前數(shù)據(jù)庫中的所有鍵。清空當(dāng)前數(shù)據(jù)庫,但不會影響其他數(shù)據(jù)庫中的數(shù)據(jù)。

PFLUSHDB

異步刪除當(dāng)前數(shù)據(jù)庫中的所有鍵,Redis 5.0+ 引入,減少阻塞。

FLUSHALL

刪除所有數(shù)據(jù)庫中的所有鍵。執(zhí)行后會清空 Redis 實(shí)例中的所有數(shù)據(jù)。此命令操作不可逆。

PFLUSHALL

異步刪除所有數(shù)據(jù)庫中的所有鍵,類似于 FLUSHALL,但執(zhí)行時不會阻塞其他客戶端請求。

DBSIZE

返回當(dāng)前數(shù)據(jù)庫中鍵的數(shù)量。用于獲取當(dāng)前數(shù)據(jù)庫中的鍵數(shù)量。

INFO [section]

獲取 Redis 實(shí)例的各種信息,可以指定某一部分的詳細(xì)信息(如服務(wù)器、內(nèi)存、客戶端、持久化等)。

INFO
# 返回:
# # Server
# redis_version:6.2.1
# # Clients
# connected_clients:10
# # Memory
# used_memory:100000

LATENCY LATEST

查看 Redis 實(shí)例的最新延遲信息。

CLIENT LIST

返回當(dāng)前所有客戶端的連接信息。包括客戶端的 ID、連接地址、空閑時間等。

CLIENT LIST
# 返回:
# 1) id=1 addr=127.0.0.1:6379 fd=8 name= age=10 idle=5 flags=N db=0
# 2) id=2 addr=127.0.0.1:6380 fd=9 name= age=20 idle=15 flags=N db=1

CLIENT KILL id

關(guān)閉指定的客戶端連接。

CONFIG GET parameter

獲取 Redis 配置參數(shù)的當(dāng)前值。

CONFIG GET maxmemory
# 返回: 
# 1) "maxmemory"
# 2) "0"

CONFIG SET parameter value

設(shè)置 Redis 配置參數(shù)的值。注意某些配置只能在啟動時設(shè)置。

CONFIG SET maxmemory 1024mb
# 返回: OK    # 將最大內(nèi)存限制設(shè)置為 1024MB

CONFIG REWRITE

重寫 Redis 配置文件,將當(dāng)前的配置更新到 Redis 配置文件中。適用于持久化配置更改。

CONFIG REWRITE
# 返回: OK    # 配置文件重寫成功

SHUTDOWN

關(guān)閉 Redis 實(shí)例。

LASTSAVE

返回 Redis 上次成功保存數(shù)據(jù)的時間戳

Redis 持久化與備份

Redis 提供了兩種主要的持久化機(jī)制:RDB(快照)持久化AOF(追加文件)持久化。此外,Redis 還支持 混合持久化,即同時啟用 RDB 和 AOF 持久化。

6.1 RDB 快照持久化

RDB 是 Redis 的一種持久化方式,能夠在指定時間間隔內(nèi)創(chuàng)建 Redis 數(shù)據(jù)庫的快照,保存在磁盤上。RDB 文件存儲了 Redis 數(shù)據(jù)的完整快照,能夠在 Redis 重啟時用于數(shù)據(jù)恢復(fù)。

6.1.1 配置與觸發(fā)機(jī)制

Redis 的 RDB 快照持久化通過配置文件中的 save 指令來控制觸發(fā)條件。每當(dāng) Redis 發(fā)生某些變化時,它會在滿足特定條件后自動保存數(shù)據(jù)。

save 配置參數(shù)示例:

save 900 1      # 在 900 秒(15分鐘)內(nèi),如果有至少 1 個鍵被修改,則觸發(fā) RDB 快照保存
save 300 10     # 在 300 秒(5分鐘)內(nèi),如果至少有 10 個鍵被修改,則觸發(fā) RDB 快照保存
save 60 10000   # 在 60 秒內(nèi),如果至少有 10000 個鍵被修改,則觸發(fā) RDB 快照保存

配置說明:

  • 每條 save 規(guī)則由兩個數(shù)字組成,<seconds><changes>,即在 <seconds> 秒內(nèi),如果發(fā)生了至少 <changes> 次寫操作,Redis 會觸發(fā) RDB 快照持久化。
  • 例如,save 900 1 表示在 900 秒(15分鐘)內(nèi),如果有至少 1 個鍵被修改,則觸發(fā)快照保存。

手動觸發(fā) RDB 快照:

你也可以手動觸發(fā) RDB 快照:

BGSAVE

該命令會在后臺創(chuàng)建 RDB 快照,并保存到磁盤中,允許 Redis 繼續(xù)響應(yīng)客戶端請求。

RDB 快照觸發(fā)的場景:

  • 定期自動保存:按照 save 配置的規(guī)則觸發(fā)。
  • 手動保存:通過 BGSAVESAVE 命令手動觸發(fā)。
  • 主從同步:當(dāng) Redis 實(shí)例作為主服務(wù)器時,RDB 快照也會用于從服務(wù)器同步數(shù)據(jù)。

6.1.2 恢復(fù)與恢復(fù)時的注意事項(xiàng)

RDB 恢復(fù)過程非常簡單,Redis 啟動時會自動加載最新的 RDB 快照文件?;謴?fù)時需要注意以下幾點(diǎn):

  • 文件路徑:RDB 快照文件默認(rèn)保存為 dump.rdb,位于 Redis 配置文件中指定的 dir 目錄。
  • 啟動時恢復(fù):當(dāng) Redis 啟動時,它會自動檢查當(dāng)前目錄中的 dump.rdb 文件并加載它。如果找到了該文件,Redis 會根據(jù)快照中的數(shù)據(jù)來恢復(fù)數(shù)據(jù)庫。
  • 數(shù)據(jù)丟失問題:RDB 快照的恢復(fù)時間受保存的時間間隔影響。如果發(fā)生 Redis 重啟,且上次保存快照時已有變化,恢復(fù)時會丟失在快照保存和重啟期間的數(shù)據(jù)。

6.2 AOF 日志持久化

AOF(Append Only File)是 Redis 的另一種持久化方式,它通過記錄每個寫命令到一個日志文件中,以此來實(shí)現(xiàn)持久化。

6.2.1 配置與觸發(fā)機(jī)制

Redis 默認(rèn)情況下不啟用 AOF 持久化,若啟用 AOF,Redis 會將所有寫命令追加到 AOF 文件中。你可以在 Redis 配置文件中通過設(shè)置 appendonly 參數(shù)來啟用 AOF。

AOF 配置參數(shù)示例:

appendonly yes      # 啟用 AOF 持久化
appendfsync everysec    # 每秒同步一次 AOF 文件

AOF 文件的三種同步策略:

  • always:每次執(zhí)行寫命令后立即同步 AOF 文件(會導(dǎo)致性能下降)。
  • everysec:每秒同步一次 AOF 文件(這是默認(rèn)設(shè)置,性能與安全平衡)。
  • no:不自動同步(只有通過后臺線程在某個間隔內(nèi)同步)。

6.2.2 數(shù)據(jù)恢復(fù)

AOF 恢復(fù)過程如下:

  • Redis 啟動時會讀取 AOF 文件,并按照文件中記錄的寫操作依次執(zhí)行,從而恢復(fù)數(shù)據(jù)。
  • AOF 文件通常比 RDB 文件要大,因?yàn)樗涗浟嗣總€寫操作,因此恢復(fù)過程可能會比 RDB 恢復(fù)慢。

AOF 恢復(fù)時的注意事項(xiàng):

  • AOF 文件的位置與 RDB 文件類似,默認(rèn)保存在 Redis 的工作目錄中,文件名為 appendonly.aof
  • 如果 AOF 文件損壞,Redis 會嘗試修復(fù)(啟用 aof-load-truncated 配置項(xiàng))。
  • 為了避免 AOF 文件膨脹過大,Redis 提供了 AOF 重寫(AOF Rewrite)功能,它會根據(jù)當(dāng)前數(shù)據(jù)庫狀態(tài)生成一個新的 AOF 文件,去除重復(fù)操作。

6.3 混合持久化(RDB + AOF)

Redis 5.0 引入了混合持久化模式,它結(jié)合了 RDB 和 AOF 的優(yōu)勢,既能提供數(shù)據(jù)的持久化,又能保證數(shù)據(jù)恢復(fù)時的快速性和完整性。

混合持久化工作原理

混合持久化在 RDB 快照的基礎(chǔ)上,將 AOF 文件和 RDB 文件結(jié)合。在持久化時,Redis 會將數(shù)據(jù)庫的快照存儲在 RDB 文件中,同時將增量的寫操作記錄到 AOF 文件中。這樣做的好處是:

  • RDB 提供了快速的恢復(fù):通過 RDB 快照快速恢復(fù)數(shù)據(jù)。
  • AOF 提供了精確的恢復(fù):AOF 文件記錄所有的寫操作,可以精確地恢復(fù)數(shù)據(jù)。

混合持久化啟用方式:

在配置文件中,可以通過設(shè)置 appendonlyappendfsync 參數(shù)來啟用混合持久化。Redis 默認(rèn)啟用了這種模式:

appendonly yes      # 啟用 AOF 持久化
appendfsync everysec    # 每秒同步一次 AOF 文件

混合持久化的優(yōu)勢

  • 恢復(fù)速度快:使用 RDB 文件作為基礎(chǔ)快照,并通過 AOF 增量更新數(shù)據(jù),可以提高數(shù)據(jù)恢復(fù)速度。
  • 數(shù)據(jù)完整性:AOF 文件記錄了所有寫命令,確保數(shù)據(jù)不會丟失。
  • 高效的空間使用:混合持久化減少了 AOF 文件的寫入操作,減少了 AOF 文件的大小。

混合持久化恢復(fù)

結(jié)合了兩者的優(yōu)勢,在每次生成 RDB 快照時,它不僅會寫入 RDB 文件,還會嵌入到 AOF 文件的開頭,作為基準(zhǔn)狀態(tài)。隨后,AOF 文件會繼續(xù)追加快照生成之后的寫操作增量,以保證最新的數(shù)據(jù)不會丟失。再生成下一次快照時會將AOF文件覆蓋,并將新生成的快照繼續(xù)嵌入到AOF文件的開頭,循環(huán)往復(fù)。這樣,恢復(fù)數(shù)據(jù)時,Redis 先加載嵌入的快照快速恢復(fù)大部分?jǐn)?shù)據(jù),再順序執(zhí)行快照之后的增量操作,就能完整恢復(fù)到最新狀態(tài),這樣就同時兼顧恢復(fù)速度和數(shù)據(jù)安全性。

Redis 高級特性

7.1 發(fā)布/訂閱(Pub/Sub)

Redis 提供了內(nèi)建的發(fā)布/訂閱消息系統(tǒng)(Pub/Sub),允許消息從發(fā)送者(發(fā)布者)廣播給一個或多個接收者(訂閱者),而無需兩者之間直接通信。

它是一種典型的消息廣播模型,適用于聊天室、實(shí)時通知、系統(tǒng)廣播等場景。

核心命令:

命令說明
SUBSCRIBE channel [channel ...]訂閱一個或多個頻道
PUBLISH channel message向指定頻道發(fā)布消息
UNSUBSCRIBE [channel ...]取消訂閱
PSUBSCRIBE pattern [pattern ...]使用通配符訂閱多個頻道
PUNSUBSCRIBE [pattern ...]取消模式訂閱

示例:

開啟終端 A(作為訂閱者):

SUBSCRIBE news

        此時 Redis 會將該客戶端狀態(tài)切換為“訂閱模式”,并阻塞式監(jiān)聽名為 news 的頻道。Redis 會自動推送任何發(fā)布到該頻道的消息到這個客戶端。

注意:客戶端一旦 SUBSCRIBEPSUBSCRIBE,進(jìn)入阻塞狀態(tài),就不能再發(fā)送普通命令(比如 SET、GET),只能接收消息,直到:UNSUBSCRIBE或連接斷開。

開啟終端 B(作為發(fā)布者):

PUBLISH news "Redis 7.0 Released!"

注意: Redis 不會緩存消息,消息是實(shí)時廣播的,若發(fā)布時沒有任何訂閱者,消息直接被丟棄,消息傳遞是同步推送到所有訂閱者,大量訂閱者可能拖慢發(fā)布速度。

終端 A 將自動接收到消息:

1) "message"    表示這條數(shù)據(jù)是一個消息類型的推送。
2) "news"       這是消息來自的頻道名稱。
3) "Redis 7.0 Released!"  這是發(fā)布者發(fā)送的具體消息內(nèi)容。

Redis 協(xié)議會把推送過來的內(nèi)容打包成一個“數(shù)組”,所以你看到的是 1)、2)3),這其實(shí)就是 Redis 的 RESP 協(xié)議(Redis Serialization Protocol)中的數(shù)組結(jié)構(gòu)形式。

+-------------------+       +-------------------+
|     Publisher     |       |    Subscriber A   |
|-------------------|       |-------------------|
| PUBLISH news "..."|-----> | SUBSCRIBE news    |
+-------------------+       +-------------------+
                            +-------------------+
                            |    Subscriber B   |
                            |-------------------|
                            | SUBSCRIBE news    |
                            +-------------------+
     -- 任何 PUBLISH news 的消息將同時被 A 和 B 接收到 --

7.2 事務(wù)(MULTI / EXEC / WATCH)

Redis 支持簡單形式的事務(wù)機(jī)制,允許將多個命令打包為一個事務(wù)塊執(zhí)行,從而實(shí)現(xiàn)操作的原子性。

Redis 事務(wù)主要由以下指令組成:

  • MULTI:標(biāo)記事務(wù)開始。
  • EXEC:執(zhí)行所有事務(wù)命令。
  • DISCARD:放棄事務(wù)。
  • WATCH:對一個或多個鍵設(shè)置監(jiān)視,當(dāng)其中任意鍵在事務(wù)執(zhí)行前被修改,事務(wù)將被中斷。

Redis 事務(wù)的執(zhí)行流程

  • WATCH(可選)對關(guān)鍵 key 進(jìn)行樂觀鎖監(jiān)控。
  • MULTI 開啟事務(wù)隊(duì)列。
  • 后續(xù)所有命令將被入隊(duì)緩存。
  • EXEC 觸發(fā)事務(wù),Redis 依次執(zhí)行隊(duì)列中的命令。
  • 如果期間被監(jiān)視的 key 被外部修改,事務(wù)失敗,EXEC 返回 null。

示例操作 1:普通事務(wù)

MULTI
SET user:score 100
INCRBY user:score 50
GET user:score
EXEC

返回:

1) OK
2) (integer) 150
3) "150"

示例操作 2:使用 WATCH 實(shí)現(xiàn)樂觀鎖(模擬余額扣款)

客戶端 A:

SET balance 100
WATCH balance
GET balance       # → "100"
MULTI
DECRBY balance 20
EXEC

如果此時客戶端 B 修改了 balance

客戶端 B:

SET balance 50

那么客戶端 A 的 EXEC 將返回 nil,表示事務(wù)失?。?/p>

(nil)

這是因?yàn)楸O(jiān)視的鍵 balance 在事務(wù)期間被其他客戶端改動,Redis 終止執(zhí)行,以保證數(shù)據(jù)一致性。

注意:

特性說明
? 原子性EXEC 中的命令會順序執(zhí)行,不會被打斷
? 回滾能力Redis 事務(wù)不支持回滾(沒有 ROLLBACK)
? 隔離級別沒有真正的隔離性,其他客戶端仍可讀寫
? 并發(fā)控制可使用 WATCH 模擬樂觀鎖

7.3 腳本與 Lua 支持

為什么需要腳本支持?

Redis 本身只支持原子執(zhí)行的命令,但不支持復(fù)雜邏輯控制(如條件、循環(huán))。Lua 腳本支持帶來了以下優(yōu)勢:

  • 原子性執(zhí)行:腳本中的所有命令作為一個整體執(zhí)行,中間不會被其他命令打斷。
  • 減少網(wǎng)絡(luò)開銷:多個操作通過一次請求提交,節(jié)省 RT。
  • 支持復(fù)雜邏輯:如 if/else、for 循環(huán)、函數(shù)等。

基本命令

EVAL script numkeys key [key ...] arg [arg ...]

  • script:Lua 腳本代碼字符串
  • numkeys:表示接下來有幾個 key 參數(shù)
  • key1...keyN:傳遞給腳本的 Redis 鍵名
  • arg1...argN:額外的參數(shù),不作為鍵

示例 :只有在鍵不存在時才設(shè)置

EVAL "if redis.call('exists', KEYS[1]) == 0 then 
         redis.call('set', KEYS[1], ARGV[1]) 
         return 'OK' 
      else 
         return 'EXISTS' 
      end" 1 mykey myvalue

解釋:

  • KEYS[1]"mykey",ARGV[1]"myvalue"
  • 如果 mykey 不存在,則設(shè)置為 "myvalue" 并返回 "OK"
  • 否則返回 "EXISTS"

示例 :批量刪除匹配前綴的 key

EVAL "local keys = redis.call('keys', ARGV[1])
      for i,k in ipairs(keys) do 
        redis.call('del', k) 
      end 
      return #keys" 0 "temp:*"

說明:

  • 刪除所有匹配 "temp:*" 的 key
  • #keys 返回刪除的數(shù)量

Lua腳本常用命令:

函數(shù)參數(shù)說明使用示例
redis.call(command, ...)command: Redis 命令字符串;...args: 參數(shù)列表用于執(zhí)行 Redis 命令,并返回結(jié)果lua<br>local result = redis.call('get', KEYS[1])<br>return result
redis.pcall(command, ...)command: Redis 命令字符串;...args: 參數(shù)列表類似 redis.call,但在錯誤時返回 nillua<br>local result = redis.pcall('get', KEYS[1])<br>if result then<br>return result<br>else<br>return "Key not found"<br>end
redis.sha1hex(string)string: 需要計(jì)算 SHA1 校驗(yàn)和的字符串計(jì)算字符串的 SHA1 校驗(yàn)和lua<br>local sha1 = redis.sha1hex('this is a test string')<br>return sha1
redis.evalsha(sha1, numkeys, ...)sha1: 腳本的 SHA1 校驗(yàn)和;numkeys: 鍵的數(shù)量;...: 鍵和參數(shù)列表執(zhí)行已加載的 Lua 腳本(使用 SHA1)lua<br>local sha1 = redis.sha1hex('return redis.call("get", KEYS[1])')<br>redis.evalsha(sha1, 1, 'my_key')
redis.log(level, message)level: 日志級別("debug", "verbose", "notice", "warning" 等);message: 日志內(nèi)容記錄日志消息lua<br>redis.log("notice", "This is a log message")
redis.sleep(seconds)seconds: 暫停的秒數(shù)(可以是小數(shù))暫停腳本執(zhí)行指定的時間lua<br>redis.sleep(2)<br>return "Finished Sleeping"
redis.setex(key, seconds, value)key: 鍵名;seconds: 過期時間(秒);value: 設(shè)置的值設(shè)置一個帶有過期時間的鍵lua<br>redis.setex("my_key", 300, "value")<br>return "Key set with expiration"
redis.bitcount(key)key: 鍵名計(jì)算指定鍵的位計(jì)數(shù)lua<br>redis.bitcount("my_bit_key")
redis.getrange(key, start, end)key: 鍵名;start: 起始位置;end: 結(jié)束位置獲取指定鍵的子字符串lua<br>redis.getrange("my_key", 0, 5)

7.4 Redis 集群與分片

為了突破單機(jī) Redis 在容量與并發(fā)性能上的限制,Redis 官方提供了原生的 Redis Cluster 機(jī)制,它通過數(shù)據(jù)的分片(sharding)與節(jié)點(diǎn)間的協(xié)作,實(shí)現(xiàn)了高可用、可擴(kuò)展的分布式部署方式。

7.4.1 分片(Sharding)與哈希槽機(jī)制

 分片(Sharding) 是將數(shù)據(jù)水平切分為多個部分,每個部分存儲在不同 Redis 節(jié)點(diǎn)上,從而分擔(dān)負(fù)載、提升容量。Redis Cluster 采用的是哈希槽分片策略。

注意:Redis Cluster 使用多個主節(jié)點(diǎn)(master nodes)來實(shí)現(xiàn)分片,每個主節(jié)點(diǎn)負(fù)責(zé)一部分哈希槽(0 ~ 16383 之間的一段)。

哈希槽(Hash Slot) 是 Redis Cluster 的核心分片單位。Redis 將整個 key 空間劃分為 16384 個槽(編號 0 到 16383),每個鍵通過哈希函數(shù)映射到某個槽位,再由特定節(jié)點(diǎn)負(fù)責(zé)這個槽。

哈希槽計(jì)算方法:

HASH_SLOT = CRC16(key) mod 16384

也就是說,Redis 使用 CRC16 哈希算法對 key 計(jì)算哈希值,并將其對 16384 取模,結(jié)果即為槽編號。

示例:計(jì)算某個鍵屬于哪個哈希槽

> CLUSTER KEYSLOT mykey  
(integer) 10285

7.4.2 Redis Cluster 架構(gòu)與節(jié)點(diǎn)角色

節(jié)點(diǎn)類型

Redis Cluster 中的節(jié)點(diǎn)分為兩類:

  • 主節(jié)點(diǎn)(Master):負(fù)責(zé)持有實(shí)際的數(shù)據(jù)和哈希槽。
  • 從節(jié)點(diǎn)(Slave):用于主節(jié)點(diǎn)的備份,當(dāng)主節(jié)點(diǎn)故障時進(jìn)行故障轉(zhuǎn)移。

高可用機(jī)制

當(dāng)某個主節(jié)點(diǎn)宕機(jī)且多數(shù)節(jié)點(diǎn)(>半數(shù))發(fā)現(xiàn)異常后,會自動觸發(fā) 故障轉(zhuǎn)移(failover),其從節(jié)點(diǎn)會被提升為主節(jié)點(diǎn)。

假設(shè)有 6 個主節(jié)點(diǎn)(M1 ~ M6),如果 M1 宕機(jī),要至少有一半以上的其他主節(jié)點(diǎn)(也就是至少 ceil(6/2) = 4 個)同時認(rèn)為 M1 不可達(dá)(PFAIL 或 FAIL),才會觸發(fā) failover 流程。這些判斷是在 Redis Cluster 的 Gossip 協(xié)議中完成的,主節(jié)點(diǎn)之間會周期性地互相 PING/ACK 探測是否“可達(dá)”。

典型拓?fù)浣Y(jié)構(gòu)

  • 至少 3 個主節(jié)點(diǎn) + 3 個從節(jié)點(diǎn)
  • 每個主節(jié)點(diǎn)管理若干個哈希槽
  • 從節(jié)點(diǎn)分別跟隨某個主節(jié)點(diǎn)做備份
Node A (Master) --> Node A1 (Slave)
Node B (Master) --> Node B1 (Slave)
Node C (Master) --> Node C1 (Slave)

7.4.3 Redis 集群搭建流程(以 6 個節(jié)點(diǎn)為例)

Step 1:準(zhǔn)備配置文件

創(chuàng)建 6 個 Redis 實(shí)例配置文件,以下為示例配置重點(diǎn):

redis.conf
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

其他端口(7001 - 7005)依次修改端口號。

Step 2:啟動所有 Redis 實(shí)例

redis-server ./7000/redis.conf
redis-server ./7001/redis.conf
...
redis-server ./7005/redis.conf

Step 3:創(chuàng)建集群

使用 redis-cli--cluster create 命令:

redis-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1
--cluster-replicas 1,意味著:每個主節(jié)點(diǎn)都配一個從節(jié)點(diǎn)
16384 個哈希槽均勻分配給3個主節(jié)點(diǎn)
這些節(jié)點(diǎn)的主從角色是 redis-cli 在執(zhí)行時自動決定的,而不是你手動指定誰是主誰是從。
如果你想手動決定哪些是主哪些是從,**就不能使用這個命令,而是得用更底層的命令逐個 CLUSTER MEET、CLUSTER ADDSLOTS 等來構(gòu)建集群。

此命令會自動分配槽位,并為每個主節(jié)點(diǎn)分配一個從節(jié)點(diǎn)。

Step 4:驗(yàn)證集群狀態(tài)

redis-cli -c -p 7000 cluster info
redis-cli -c -p 7000 cluster nodes

7.4.4 集群管理相關(guān)命令

命令說明
CLUSTER INFO查看當(dāng)前節(jié)點(diǎn)的集群信息
CLUSTER NODES查看整個集群的所有節(jié)點(diǎn)
CLUSTER SLOTS查看槽分布情況
CLUSTER KEYSLOT <key>查詢 key 屬于哪個哈希槽
CLUSTER FORGET <node-id>移除某個節(jié)點(diǎn)(強(qiáng)制)
CLUSTER MEET <ip> <port>添加新節(jié)點(diǎn)到集群
CLUSTER REPLICATE <node-id>將當(dāng)前節(jié)點(diǎn)設(shè)置為某主節(jié)點(diǎn)的從節(jié)點(diǎn)
CLUSTER RESET重置節(jié)點(diǎn)并清除其集群配置

示例:

查看集群信息
127.0.0.1:7000> CLUSTER INFO
輸出:
cluster_state:ok 表示集群正常。
cluster_slots_assigned:16384 表示總共分配了 16384 個槽位。
cluster_size:3 表示集群有 3 個主節(jié)點(diǎn)。
....
查看集群節(jié)點(diǎn)信息
127.0.0.1:7000> CLUSTER NODES
07c37dfeb2352e56c38e8c801c0bb4a6b5fd64a6 127.0.0.1:7000 master - 0 1624567890 1 connected 0-5460
3c3f3f5c6b44c1a1beec77c57d56b983f56cb0a1 127.0.0.1:7003 slave 07c37dfeb2352e56c38e8c801c0bb4a6b5fd64a6 0 1624567891 2 connected
......
列出了集群中的所有節(jié)點(diǎn)。
每行展示一個節(jié)點(diǎn)的狀態(tài),包括節(jié)點(diǎn) ID、IP 地址、角色(master/slave)以及其負(fù)責(zé)的槽位范圍。
查看哈希槽分配情況
127.0.0.1:7000> CLUSTER SLOTS
1) 1) (integer) 0
   2) (integer) 5460
   3) 1) "127.0.0.1"
      2) (integer) 7000
      3) "my-cluster-1"
2) 1) (integer) 5461
   2) (integer) 10922
   3) 1) "127.0.0.1"
      2) (integer) 7001
      3) "my-cluster-2"
3) 1) (integer) 10923
   2) (integer) 16383
   3) 1) "127.0.0.1"
      2) (integer) 7002
      3) "my-cluster-3"
顯示了哈希槽(0-16383)的分配情況,列出了每個主節(jié)點(diǎn)及其負(fù)責(zé)的槽區(qū)間。
每個主節(jié)點(diǎn)對應(yīng)的從節(jié)點(diǎn)會在后續(xù)的操作中自動關(guān)聯(lián)。
查看某個鍵屬于哪個哈希槽
127.0.0.1:7000> CLUSTER KEYSLOT mykey
(integer) 10285
mykey被分配到哈希槽10285中。
......

到此這篇關(guān)于Redis介紹與使用一文搞懂的文章就介紹到這了,更多相關(guān)Redis介紹與使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis去重的3種不同方法匯總

    Redis去重的3種不同方法匯總

    Redis是完全開源免費(fèi)的,遵守BSD協(xié)議,是一個高性能的key-value數(shù)據(jù)庫,下面這篇文章主要給大家介紹了關(guān)于Redis去重的3種不同方法,需要的朋友可以參考下
    2021-11-11
  • Redis緩存更新策略詳解

    Redis緩存更新策略詳解

    本文介紹了4種核心緩存更新策略(Cache-Aside、Write-Through、Write-Behind、Refresh-Ahead),并討論了3種補(bǔ)充策略(Read-Through、最終一致性、過期淘汰),感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • 關(guān)于Redis的內(nèi)存淘汰策略詳解

    關(guān)于Redis的內(nèi)存淘汰策略詳解

    當(dāng)內(nèi)存空間使用達(dá)到限制時,Redis 會根據(jù)配置策略來選擇不同處理方式,要么返回 errors,要么按照不同的策略算法來清除一些舊數(shù)據(jù),達(dá)到回收內(nèi)存的目的,這就是 Redis 的內(nèi)存淘汰,有些文章中,內(nèi)存淘汰也叫緩存回收,需要的朋友可以參考下
    2023-05-05
  • Redis中List實(shí)現(xiàn)雙鏈表

    Redis中List實(shí)現(xiàn)雙鏈表

    本文主要介紹了Redis中List實(shí)現(xiàn)雙鏈表,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Redis偶發(fā)連接失敗案例實(shí)戰(zhàn)記錄

    Redis偶發(fā)連接失敗案例實(shí)戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于Redis偶發(fā)連接失敗的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使Redis具有一定的參考學(xué)習(xí)價值,用需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10
  • Redis分布式鎖之紅鎖的實(shí)現(xiàn)

    Redis分布式鎖之紅鎖的實(shí)現(xiàn)

    在Redis中,紅鎖是一種分布式鎖的實(shí)現(xiàn)機(jī)制,旨在解決多個客戶端在分布式環(huán)境中對共享資源進(jìn)行并發(fā)訪問的問題,本文主要介紹了Redis分布式鎖之紅鎖的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 詳解Redis瘦身指南

    詳解Redis瘦身指南

    Redis應(yīng)該是開發(fā)者最常用的緩存服務(wù)器了,它豐富的數(shù)據(jù)結(jié)構(gòu),快速高效的內(nèi)存操作能幫助開發(fā)者迅速完成復(fù)雜功能的設(shè)計(jì),作為一個內(nèi)存型數(shù)據(jù)庫,Redis經(jīng)常會遇到內(nèi)存問題,今天我們來談一下Redis常見的內(nèi)存滿的問題,介紹一下給 Redis “瘦身”的通用方式。
    2021-05-05
  • Redis禁用命令、危險(xiǎn)命令及規(guī)避方法

    Redis禁用命令、危險(xiǎn)命令及規(guī)避方法

    這篇文章主要介紹了Redis禁用命令、危險(xiǎn)命令及規(guī)避方法,本文介紹了個非常致命的兩個命令以及用配置文件禁用這些命令的方法,需要的朋友可以參考下
    2015-06-06
  • redis服務(wù)啟動與停止方式

    redis服務(wù)啟動與停止方式

    這篇文章主要介紹了redis服務(wù)啟動與停止方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Redis中AOF與RDB持久化策略深入分析

    Redis中AOF與RDB持久化策略深入分析

    Redis作為一款內(nèi)存數(shù)據(jù)庫,因?yàn)槭莾?nèi)存讀寫,所以性能很強(qiáng),但內(nèi)存存儲是易失性的,斷電或系統(tǒng)奔潰都會導(dǎo)致數(shù)據(jù)丟失,因此Redis也需要將其數(shù)據(jù)持久化到磁盤上面,當(dāng)Redis服務(wù)重啟時,會把磁盤上的數(shù)據(jù)再加載進(jìn)內(nèi)存,Redis提供了兩種持久化機(jī)制-RDB快照和AOF日志
    2022-11-11

最新評論

鄂伦春自治旗| 元阳县| 恩施市| 台东县| 永修县| 凤山县| 永丰县| 揭东县| 寿阳县| 宜丰县| 万宁市| 鲁山县| 孙吴县| 枝江市| 昌宁县| 嘉祥县| 虞城县| 永善县| 当涂县| 静安区| 新宁县| 康乐县| 西乡县| 宾阳县| 宜兰市| 丘北县| 固阳县| 平和县| 丹江口市| 久治县| 齐齐哈尔市| 松原市| 河源市| 宜宾市| 英吉沙县| 宜都市| 上林县| 凤城市| 大荔县| 丁青县| 聊城市|