Redis 零基礎入門到實戰教程
- Redis(Remote Dictionary Server)是一款開源、高性能、基於內存的鍵值對數據庫,支持多種數據結構,廣泛用於緩存、消息隊列、分佈式鎖等場景。本教程從基礎到實戰,幫你快速掌握 Redis 核心用法。
- 視頻教程:
https://pan.quark.cn/s/10e98d308913
一、Redis 安裝與環境準備
1. 安裝方式(推薦 3 種)
(1)Windows 安裝(適合新手)
- 下載地址:Redis 官方 Windows 版本(選擇最新穩定版,如 3.2.100)
- 安裝步驟:
- 雙擊安裝包,勾選“Add Redis to PATH”(自動配置環境變量)
- 默認端口 6379,無需修改,直接下一步完成安裝
- 驗證:打開 CMD,輸入
redis-cli,出現127.0.0.1:6379>表示成功
(2)Linux 安裝(CentOS/Ubuntu)
- CentOS:
# 安裝 EPEL 源
yum install epel-release -y
# 安裝 Redis
yum install redis -y
# 啓動 Redis 並設置開機自啓
systemctl start redis
systemctl enable redis
- Ubuntu:
apt update
apt install redis-server -y
# 啓動服務
systemctl start redis-server
- 驗證:輸入
redis-cli ping,返回PONG表示正常
(3)Docker 安裝(推薦開發/測試環境)
# 拉取 Redis 鏡像(默認最新穩定版)
docker pull redis
# 啓動容器(映射端口 6379,設置密碼 123456)
docker run -d -p 6379:6379 --name redis-demo redis --requirepass "123456"
# 進入容器操作 Redis
docker exec -it redis-demo redis-cli -a 123456
2. 核心配置文件(redis.conf)
關鍵配置項(修改後需重啓 Redis):
bind 127.0.0.1:默認只允許本地訪問,生產環境需改為服務器 IP 或0.0.0.0(允許所有地址訪問)port 6379:默認端口,可自定義(如 6380)requirepass 123456:設置密碼(生產環境必須配置)daemonize yes:Linux 下後台運行(默認 no,前台運行)maxmemory 1gb:設置最大內存(避免內存溢出,需配合淘汰策略)maxmemory-policy allkeys-lru:內存滿時淘汰策略(優先刪除最近最少使用的鍵)
二、Redis 核心數據結構(重點)
Redis 支持 5 種基礎數據結構,以及 HyperLogLog、Geo 等高級結構,核心是鍵(key)- 值(value) 映射,鍵都是字符串類型,值支持多種結構。
1. 字符串(String):最基礎的鍵值對
用途:
存儲字符串、數字(計數器)、二進制數據(如圖片 Base64),是最常用的結構。
核心命令:
|
命令
|
功能
|
示例
|
|
|
設置鍵值(覆蓋已有鍵)
|
|
|
|
獲取鍵值
|
|
|
|
僅當鍵不存在時設置(分佈式鎖核心)
|
|
|
|
批量設置
|
|
|
|
批量獲取
|
|
|
|
數字自增 1
|
|
|
|
數字自減 1
|
|
|
|
設置過期時間(秒)
|
|
|
|
原子性設置值 + 過期時間
|
|
實戰場景:
- 緩存用户信息(
set user:1001 '{"id":1001,"name":"張三"}') - 計數器(文章閲讀量、接口訪問次數)
- 驗證碼存儲(設置短期過期)
2. 哈希(Hash):適合存儲對象
用途:
存儲結構化數據(如用户、商品信息),相當於“鍵值對中的鍵值對”,支持單獨修改某個字段,無需整體更新。
核心命令:
|
命令
|
功能
|
示例
|
|
|
設置哈希字段值
|
|
|
|
獲取哈希字段值
|
|
|
|
獲取所有字段和值
|
|
|
|
批量設置字段
|
|
|
|
批量獲取字段
|
|
|
|
刪除字段
|
|
|
|
判斷字段是否存在
|
|
實戰場景:
- 存儲用户信息(避免字符串 JSON 解析的開銷)
- 商品詳情緩存(
hset product:2001 name 手機 price 2999 stock 100)
3. 列表(List):有序可重複的字符串集合
用途:
實現隊列、棧、消息列表(如朋友圈動態),底層是雙向鏈表,首尾操作效率極高(O(1)),中間操作效率低(O(n))。
核心命令:
|
命令
|
功能
|
示例
|
|
|
從列表左側插入元素
|
|
|
|
從列表右側插入元素
|
|
|
|
從左側彈出元素(刪除並返回)
|
|
|
|
從右側彈出元素
|
|
|
|
獲取指定範圍元素(0 開始,-1 表示末尾)
|
|
|
|
獲取列表長度
|
|
實戰場景:
- 消息隊列(
rpush生產消息,lpop消費消息,簡單場景) - 最新消息列表(如“最近評論”,
lpush新增,lrange分頁查詢) - 棧(
lpush + lpop)/ 隊列(lpush + rpop)
4. 集合(Set):無序不可重複的字符串集合
用途:
去重、交集/並集/差集計算(如共同好友、標籤篩選),底層是哈希表,查詢、添加、刪除效率均為 O(1)。
核心命令:
|
命令
|
功能
|
示例
|
|
|
添加元素(重複元素自動去重)
|
|
|
|
獲取所有元素
|
|
|
|
判斷元素是否存在
|
|
|
|
獲取集合大小
|
|
|
|
求兩個集合的交集(共同元素)
|
|
|
|
求並集(所有元素去重)
|
|
|
|
求差集(set1 有但 set2 沒有)
|
|
實戰場景:
- 用户標籤(去重存儲)
- 共同好友推薦(交集計算)
- 抽獎活動(
srandmember set-key隨機取元素,spop隨機刪除元素)
5. 有序集合(Sorted Set/ZSet):有序不可重複的集合
用途:
排序場景(如排行榜、熱搜榜),每個元素關聯一個分數(score),按分數自動排序,底層是“跳錶”,兼顧排序和查詢效率。
核心命令:
|
命令
|
功能
|
示例
|
|
|
添加元素(分數決定順序)
|
|
|
|
按分數升序取元素(withscores 顯示分數)
|
|
|
|
按分數降序取元素(排行榜常用)
|
|
|
|
獲取元素的分數
|
|
|
|
增加元素分數(計數器+排序)
|
|
|
|
獲取元素個數
|
|
實戰場景:
- 文章閲讀量排行榜(分數=閲讀量,
zrevrange取Top N) - 熱搜榜(分數=搜索次數,定時更新)
- 積分排名(用户積分作為分數)
三、Redis 高級特性
1. 過期鍵刪除策略
Redis 採用“惰性刪除 + 定期刪除”結合的策略:
- 惰性刪除:訪問過期鍵時才刪除(節省 CPU,可能浪費內存)
- 定期刪除:每隔一段時間掃描部分過期鍵(平衡 CPU 和內存)
- 配合內存淘汰策略(
maxmemory-policy):內存滿時自動刪除鍵,常用策略:
allkeys-lru:刪除所有鍵中最近最少使用的volatile-lru:只刪除帶過期時間的鍵中最近最少使用的noeviction:默認策略,內存滿時拒絕寫操作(推薦生產環境用allkeys-lru)
2. 持久化(避免數據丟失)
Redis 是內存數據庫,默認數據僅存於內存,重啓後丟失,需開啓持久化將數據寫入磁盤。
(1)RDB 持久化(默認開啓)
- 原理:在指定時間間隔內,將內存中的數據快照寫入磁盤(生成 .rdb 文件)
- 觸發方式:
- 自動觸發:配置文件中
save 900 1(900 秒內至少 1 個鍵修改)、save 300 10等 - 手動觸發:
save(阻塞 Redis,不推薦)、bgsave(後台異步執行,推薦)
- 優點:恢復速度快,適合備份
- 缺點:可能丟失最近一次快照後的更新數據
(2)AOF 持久化(推薦生產環境開啓)
- 原理:記錄每一條寫命令(如 set、hset),重啓時重新執行命令恢復數據
- 開啓方式:修改
redis.conf→appendonly yes,生成 .aof 文件 - 同步策略(
appendfsync):
always:每寫一條命令同步到磁盤(最安全,性能略低)everysec:每秒同步一次(推薦,平衡安全和性能)no:由操作系統決定同步時機(性能高,風險高)
- 優點:數據丟失少(最多丟失 1 秒數據)
- 缺點:AOF 文件體積大,恢復速度比 RDB 慢
(3)最佳實踐:
- 生產環境開啓 AOF + RDB 雙持久化:AOF 保證數據安全性,RDB 用於快速恢復
- 定期備份 .rdb 和 .aof 文件,防止磁盤損壞
3. 緩存常見問題與解決方案
(1)緩存穿透
- 問題:請求不存在的鍵(如惡意查詢
user:9999,而該用户不存在),導致請求直接穿透到數據庫,壓垮數據庫 - 解決方案:
- 緩存空值:對不存在的鍵,緩存
null並設置短期過期時間(如 5 分鐘) - 布隆過濾器:提前過濾不存在的鍵(適合數據量大的場景)
(2)緩存擊穿
- 問題:某個熱點鍵過期時,大量請求同時訪問該鍵,穿透到數據庫
- 解決方案:
- 互斥鎖:第一個請求獲取鎖,查詢數據庫並更新緩存,其他請求等待鎖釋放後查詢緩存
- 熱點鍵永不過期:定期後台更新緩存,不設置過期時間
(3)緩存雪崩
- 問題:大量緩存鍵同時過期,或 Redis 服務宕機,導致所有請求穿透到數據庫
- 解決方案:
- 過期時間隨機化:給每個鍵的過期時間加隨機值(如
expire key 3600 + rand(0, 600)),避免同時過期 - 服務熔斷/限流:數據庫壓力過大時,拒絕部分請求
- Redis 集羣:避免單點故障(後續講解)
四、Redis 集羣(高可用與擴容)
單節點 Redis 存在單點故障和內存上限問題,生產環境需部署集羣。
1. 主從複製(主從架構)
- 原理:1 個主節點(Master)+ 多個從節點(Slave),主節點負責寫操作,從節點負責讀操作,主節點數據自動同步到從節點
- 核心作用:
- 讀寫分離:減輕主節點壓力(讀請求分發到從節點)
- 容災備份:主節點故障時,從節點可切換為主節點
- 配置步驟(以 1 主 2 從為例):
- 準備 3 個 Redis 實例(端口 6379、6380、6381)
- 從節點配置文件添加:
slaveof 主節點IP 主節點端口(如slaveof 127.0.0.1 6379) - 主節點設置密碼後,從節點需添加:
masterauth 主節點密碼 - 驗證:主節點執行
info replication,查看從節點信息
2. 哨兵模式(Sentinel)
- 問題:主從複製中,主節點故障後需手動切換從節點為主節點,不滿足高可用
- 原理:部署多個哨兵進程(Sentinel),監控主從節點,主節點故障時自動選舉新主節點,實現故障自動切換
- 核心功能:
- 監控:檢查主從節點是否正常運行
- 自動故障轉移:主節點宕機後,選舉從節點為新主,其他從節點切換到新主
- 通知:故障時通過腳本通知管理員
3. Redis Cluster(分片集羣)
- 問題:主從複製和哨兵模式無法解決“內存擴容”問題(單主節點內存有限)
- 原理:將數據分片存儲到多個主節點(默認 16384 個哈希槽),每個主節點負責一部分槽,配合從節點實現高可用
- 核心特點:
- 分片存儲:突破單節點內存限制(如 3 主 3 從,總內存是 3 個主節點內存之和)
- 自動路由:客户端請求根據鍵的哈希值自動路由到對應主節點
- 容錯性:單個主節點故障,其從節點自動切換為主節點
五、Redis 實戰案例:實現分佈式鎖
分佈式鎖是 Redis 最常用的實戰場景之一,用於解決分佈式系統中併發競爭問題(如秒殺、庫存扣減)。
核心思路:
- 利用
setnx key value原子性:多個進程同時搶鎖,只有一個能成功(setnx返回 1) - 給鎖設置過期時間:防止持有鎖的進程宕機導致鎖無法釋放
- 釋放鎖時驗證 value:避免誤釋放其他進程的鎖(value 用唯一標識,如 UUID)
實現步驟(Python 示例):
- 安裝 Redis 客户端:
pip install redis - 代碼實現:
import redis
import uuid
import time
# 連接 Redis
redis_client = redis.Redis(
host="127.0.0.1",
port=6379,
password="123456",
decode_responses=True # 自動解碼為字符串
)
def acquire_lock(lock_key, expire_seconds=30):
"""獲取分佈式鎖"""
lock_value = str(uuid.uuid4()) # 唯一標識,用於釋放鎖時驗證
# setnx + expire 原子操作(避免設置鎖後未設置過期時間進程宕機)
success = redis_client.set(
name=lock_key,
value=lock_value,
nx=True, # 僅當鍵不存在時設置(等價於 setnx)
ex=expire_seconds # 過期時間(秒)
)
return success, lock_value
def release_lock(lock_key, lock_value):
"""釋放分佈式鎖(驗證 value,避免誤釋放)"""
# 用 Lua 腳本保證原子性(查詢 + 刪除必須原子執行)
lua_script = """
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
"""
result = redis_client.eval(lua_script, 1, lock_key, lock_value)
return result == 1
# 測試:模擬 10 個進程搶鎖
def task(thread_id):
lock_key = "distributed_lock"
success, lock_value = acquire_lock(lock_key)
if success:
print(f"線程 {thread_id} 成功獲取鎖,開始執行任務...")
time.sleep(2) # 模擬任務執行
release_lock(lock_key, lock_value)
print(f"線程 {thread_id} 釋放鎖")
else:
print(f"線程 {thread_id} 搶鎖失敗,稍後重試")
# 模擬併發
if __name__ == "__main__":
import threading
for i in range(10):
t = threading.Thread(target=task, args=(i,))
t.start()
關鍵注意點:
- 鎖的過期時間:需大於任務執行時間,避免任務未完成鎖已過期
- 原子性:
set nx ex是原子操作,釋放鎖必須用 Lua 腳本保證原子性 - 容錯性:如果進程持有鎖期間宕機,鎖會因過期時間自動釋放,不會死鎖
六、總結與學習資源
1. 核心要點回顧
- Redis 是基於內存的高性能鍵值數據庫,支持 5 種核心數據結構
- 重點掌握:String(緩存/計數)、Hash(對象存儲)、ZSet(排序)
- 生產環境必須配置:密碼、持久化(AOF+RDB)、內存淘汰策略、集羣(高可用)
- 避坑點:緩存穿透/擊穿/雪崩、分佈式鎖的原子性