寫在前面
今天來繼續學習 Redis。
Redis 持久化機制
快照 (Snapshot)
特點
快照持久化可以將某一時刻的所有資料寫入硬碟,預設開啟,儲存為 .rdb
檔案,也稱為 RDB 持久化。
快照生成方式
客戶端方式
-
BGSAVE
- 使用 BGSAVE 命令建立快照,Redis 會建立一個子程序進行寫入,父程序繼續處理命令請求。
- 名詞解釋:
fork
是建立子程序的操作,初期父子程序共享記憶體,直到寫操作發生才會分開。
-
SAVE
- 使用 SAVE 命令建立快照,Redis 在快照建立期間會阻塞,不響應其他命令。
- 注意: SAVE 命令會使 Redis 處於阻塞狀態。
伺服器配置自動觸發
-
滿足配置自動觸發
- 在
redis.conf
中設定save
配置選項,Redis 會在滿足條件時自動觸發 BGSAVE。 - 設定多個
save
選項時,任意條件滿足均會觸發 BGSAVE。
- 在
-
接收客戶端 shutdown 指令
- 執行 shutdown 指令時,Redis 會執行 SAVE 命令,然後關閉伺服器。
配置生成快照名稱和位置
-
修改生成快照名稱
dbfilename dump.rdb
-
修改生成位置
dir ./
問題
快照可能導致資料丟失,尤其是在快照後有寫操作而斷電的情況下。
AOF 只追加日誌檔案
特點
將所有寫命令記錄到日誌檔案中,透過執行日誌檔案中的命令來恢復資料。
開啟 AOF 持久化
在 redis.conf
中開啟:
appendonly yes
appendfilename "appendonly.aof"
日誌追加頻率
-
always 【謹慎使用】
- 每個寫命令都同步寫入硬碟,降低 Redis 效能,SSD 使用者應慎用。
-
everysec 【推薦預設】
- 每秒同步一次 AOF 檔案,效能與無持久化時接近,最多丟失一秒資料。
-
no 【不推薦】
- 由作業系統決定同步時間,不會影響 Redis 效能,但可能丟失不定數量的資料。
修改同步頻率
- 修改
appendfsync
為everysec
、always
或no
。
AOF 檔案的重寫
AOF 檔案會變大,Redis 提供 AOF 重寫機制來壓縮檔案。
觸發重寫方式
-
客戶端方式觸發
- 執行
BGREWRITEAOF
命令,不會阻塞 Redis 服務。
- 執行
-
伺服器配置自動觸發
- 配置
auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
選項。
- 配置
重寫原理
7.0.0之前
從 Redis 7.0.0 開始,使用多部分 AOF 機制,將 AOF 檔案拆分為基礎檔案和增量檔案,透過清單檔案跟蹤。
重寫流程
- Redis 呼叫
fork
,子程序重寫 AOF 檔案。 - 父程序繼續處理客戶端請求,將寫命令快取。
- 子程序完成重寫後,父程序將快取的寫命令寫入新檔案。
- 用新檔案替換舊檔案。
總結
可以同時使用 AOF 和快照持久化,也可以單獨使用,具體選擇取決於資料和應用的需求。持久化檔案應定期備份。
常見問題
-
Redis 中持久化方案有幾種?
- 兩種方案:RDB 快照持久化和 AOF 檔案持久化。
-
如何觸發 RDB 持久化?幾種方式?有什麼區別?
- BGSAVE: 建立子程序進行快照。
- SAVE: 阻塞當前 Redis 例項,建立快照。
- shutdown: 伺服器關閉時自動執行 SAVE。
- ctrl+c 或 kill -9: 直接停止程序,觸發 SAVE。
-
AOF 持久化與 RDB 持久化的優缺點?
- RDB: 啟動快,可能丟失資料。
- AOF: 資料永續性好,啟動時效能差,檔案變大。推薦結合使用。
-
Redis 7.0 之前和之後的重寫機制?
- 之前: 父程序將操作放到記憶體,子程序生成新 AOF 檔案。
- 之後: 使用多部分 AOF 檔案,父程序寫入新檔案,子程序生成基礎 AOF 檔案和增量檔案,原子替換。
-
如何不讓啟動介面佔用視窗?
- 在
redis.conf
中設定daemonize
為yes
。
- 在
點陣圖 (Bitmap)
介紹
點陣圖不是一種真正的資料型別,而是定義在字串型別中的。一個字串最多可以儲存 512MB 的內容。
- 位上限:
2^(9(512) + 10(1024) + 10(1024) + 3(8b=1B)) = 2^32b
位操作命令
-
SETBIT
- 說明: 設定某一位上的值。
- 語法:
SETBIT key offset value
(offset
為位偏移量,從 0 開始)
-
GETBIT
- 說明: 獲取某一位上的值。
- 語法:
GETBIT key offset
-
BITPOS
- 說明: 返回指定值 (0 或 1) 在指定區間上首次出現的下標。
- 語法:
BITPOS key bit [start] [end]
- 查詢範圍:
- 不指定範圍:
BITPOS key bit
- 指定開始位置:
BITPOS key bit start
- 指定開始和結束位置:
BITPOS key bit start end
- 不指定範圍:
-
BITOP
- 說明: 對一個或多個儲存二進位制位的字串進行位操作,並將結果儲存到
destkey
。 - 操作型別:
-
AND:
BITOP AND destkey key [key ...]
-
OR:
BITOP OR destkey key [key ...]
-
XOR:
BITOP XOR destkey key [key ...]
-
NOT:
BITOP NOT destkey key
-
- 說明: 對一個或多個儲存二進位制位的字串進行位操作,並將結果儲存到
-
BITCOUNT
- 說明: 統計指定區間內值為 1 的個數。
- 語法:
BITCOUNT key [start] [end]
- 區間:
- 正方向:
BITCOUNT key start end
(從左向右) - 負方向:
BITCOUNT key start end
(從右向左)
- 正方向:
點陣圖應用場景
-
網站使用者簽到的天數統計
- 使用者 ID 為 key,天作為 offset,簽到置為 1。
- 例如,第 366 天簽到,資料儲存為
000000000000000
。
-
按天統計網站活躍使用者
- 天作為 key,使用者 ID 為 offset,活躍使用者置為 1。
- 統計活躍使用者數量:例如,50000000 使用者分佈在 366 天的資料大約為 2GB。
-
使用者線上狀態和人數統計
- 使用點陣圖記錄使用者線上狀態,可以有效統計當前線上人數和活動情況。
Java 操作 Redis
引入依賴
在 pom.xml
檔案中新增 Jedis 連線依賴:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.2</version>
</dependency>
建立 Jedis 物件
public static void main(String[] args) {
// 1. 建立 Jedis 物件
Jedis jedis = new Jedis("192.168.xxx.xxx", 7000);
// 2. 選擇操作的資料庫,預設為 0 號庫
jedis.select(0);
// 3. 執行相關操作
// ...
// 4. 釋放資源
jedis.close();
}
操作 Key 相關 API
-
DEL
- 說明: 刪除指定的 key。
- 返回值: 被刪除 key 的數量。
-
EXISTS
- 說明: 檢查 key 是否存在。
- 返回值: 存在返回 1,不存在返回 0。
-
EXPIRE
- 說明: 為已經存在的 key 設定過期時間。
- 返回值: 設定成功返回 1,失敗返回 0。
- 擴充套件:
PEXPIRE
: 毫秒級別。PEXPIREAT
: 指定時間戳。
-
KEYS
- 說明: 返回符合模式的 key 列表。
- 返回值: 符合模式的 key 列表。
-
MOVE
- 說明: 將 key 移動到另一個資料庫。
- 返回值: 移動成功返回 1,失敗返回 0。
-
TTL
- 說明: 獲取 key 的剩餘生存時間。
- 返回值:
- 當 key 不存在時返回 -2。
- 當 key 存在但沒有設定剩餘生存時間時返回 -1。
- 否則,返回剩餘生存時間(秒)。
-
PTTL
- 說明: 獲取 key 的剩餘生存時間(毫秒級)。
-
RANDOMKEY
- 說明: 返回一個隨機的 key。
- 返回值: 資料庫不為空時返回一個 key,空時返回
null
。
-
RENAME
- 說明: 重新命名 key。
- 返回值: 成功返回 OK,失敗返回錯誤資訊。
-
TYPE
- 說明: 獲取 key 的資料型別。
- 返回值:
none
(key 不存在)、string
、list
、set
、zset
、hash
。
操作 String 相關 API
-
SET
- 說明: 設定 key 的值。
-
GET
- 說明: 獲取 key 的值。
-
MSET
- 說明: 批次設定多個 key 的值。
-
MGET
- 說明: 批次獲取多個 key 的值。
- 返回值: 字串列表。
-
GETSET
- 說明: 獲取 key 的值並設定新值。
- 示例:
GETSET age 24
返回原值,設定新值為 24。
-
STRLEN
- 說明: 獲取 key 對應字串的長度。
-
APPEND
- 說明: 追加字串到 key 的值末尾。
- 返回值: 修改後的長度。
-
GETRANGE
- 說明: 獲取 key 對應字串的子串。
- 示例:
GETRANGE key 0 4
返回子串。
-
SETEX
- 說明: 設定 key 的值並設定過期時間(秒)。
- 示例: 10 秒後自動銷燬。
-
PSETEX
- 說明: 設定 key 的值並設定過期時間(毫秒)。
-
SETNX
- 說明: 僅當 key 不存在時設定 key 的值。
- 返回值: 已存在返回 0,不存在返回 1。
-
MSETNX
- 說明: 批次設定多個 key 的值,僅當所有 key 都不存在時成功。
- 返回值: 僅當所有 key 都不存在時成功。
-
DECR
- 說明: 將 key 對應的值減 1。
- 示例:
DECR key
返回減少後的值。
-
DECRBY
- 說明: 將 key 對應的值減指定的值。
- 示例:
DECRBY key 2
返回減少後的值。
-
INCR
- 說明: 將 key 對應的值加 1。
- 示例:
INCR key
返回增加後的值。
-
INCRBY
- 說明: 將 key 對應的值加指定的值。
- 示例:
INCRBY key 2
返回增加後的值。
-
INCRBYFLOAT
- 說明: 將 key 對應的值按浮點數增加。
- 示例:
INCRBYFLOAT key 2.5
返回增加後的值。