文章目錄
-
-
- 一. Redis
-
-
- 1.1 文法回顧
- 1.2 事務
- 1.3 持久化 (重點)
-
- 1.3.1 RDB 快照存儲
- 1.3.1 AOF 隻追加檔案
- 1.3.3 如何選擇
- 1.4 分布式設計
-
- 1.4.1 哨兵 (重點)
- 1.4.2 叢集
-
-
一. Redis
1.1 文法回顧
- String
- 記錄字元串/整數/浮點數
- 指令
- set 添加/修改資料
- get 擷取資料
- mset 添加多個資料
- mget 擷取多個資料
- incr 計數加1
- decr 計數減1
- incrby 計數加n
- 鍵指令
- 适用于所有的類型
- 指令
- del 删除資料
- exists 判斷資料是否存在
- expire 設定過期時間
- ttl 擷取剩餘時間
- keys 查詢滿足條件的鍵
- hash
- 類似
的結構字典
- 指令
- hset 添加字段
- hget 擷取字段
- hmset 添加多個字段
- hmget 擷取多個字段
- hdel 删除字段
- 類似
- list
- 是一個
雙向連結清單
- 指令
- lpush 從左側追加元素
- lrange 從左側周遊元素
- rpush 從右側追加元素
- lset 從左側修改元素
- lpop 從左側删除元素
- rpop 從右側删除元素
- ltrim 裁切清單
- 是一個
- zset
-
集合, 按照分數(score)進行排序有序
- 指令
- zadd 添加/修改元素
- zrange 周遊元素(按分數從小到大)
- zrevrange 反向周遊元素(從大到小)
- zrangebyscore 周遊指定分數範圍的元素
- zscore 查詢元素的分數
- zrem 删除元素
- zincrby 元素的分數計數加n
-
- set
-
集合 無序+去重無序
- 指令
- sadd 添加元素
- smembers 周遊元素
- sismember 判斷是否包含
- srem 删除元素
-
- redis-py
- python中獨立的redis包
- 安裝
pip install redis
1.2 事務
- 文法
- MULTI
- 開啟事務, 後續的指令會被加入到同一個事務中
- 事務中的操作會發給服務端, 但是不會立即執行, 而是放到了該事務的對應的一個隊列中, 服務端傳回QUEUED
- EXEC
- 執行EXEC後, 事務中的指令才會被執行
- 事務中的指令出現錯誤時,
, 而是繼續執行不會復原也不會停止事務
- DISCARD
- 取消事務, 事務隊列會清空, 用戶端退出事務狀态
- MULTI
- ACID
- 原子性
- 不支援
- 不會復原并且繼續執行
- 隔離性
- 支援
- 事務中指令順序執行, 并且不會被其他用戶端打斷 (先EXEC的先執行)
- 持久性
- 不支援, redis資料易丢失
- 一緻性
- 不支援
- 強一緻性要求 通過樂觀鎖(watch)來實作
- 原子性
- WATCH
- redis實作的樂觀鎖
- 機制
- 事務開啟前, 設定對資料的監聽, EXEC時, 如果發現資料發生過修改, 事務會自動取消(DISCARD)
- 事務EXEC後, 無論成敗, 監聽會被移除
# 解決更新丢失問題
WATCH mykey # 監視mykey的值
GET mykey # 讀取資料, 假設需要進行*2操作, 再将結果重新指派 (假設取出5)
MULTI # 開啟事務
SET mykey 10
EXEC # 如果mykey的值在執行exec之前發生過改變, 則該事務會取消(用戶端可以在發生碰撞後不斷重試)
如果隻是加減操作, 建議使用 incr類
的操作, 單一操作具有原子性
- 流水線
1.3 持久化 (重點)
1.3.1 RDB 快照存儲
- 将
完整的儲存到硬碟中記憶體中的所有資料
- 機制
- fork出一個
,專門進行資料持久化, 将記憶體中所有資料儲存到單個rdb檔案中(預設為dump.rdb)子程序
- redis重新開機後, 會加載rdb檔案中的資料到記憶體中
- fork出一個
- 觸發方式
- 配置中設定
自動持久化政策
-
|SAVE
|BGSAVE
(前提是設定了自動持久化政策)SHUTDOWN
- 配置中設定
- 相關配置
save 60 1000 # 多久執行一次自動快照操作 60秒内如果更新了1000次, 則持久化一次
stop-writes-on-bgsave-error no # 建立快照失敗後,是否繼續執行寫指令
rdbcompression yes # 是否對快照檔案進行壓縮
dbfilename dump.rdb # 如何命名快照檔案
dir ./ # 快照檔案儲存的位置
save # 關閉RDB機制
- 優缺點
- 優點
-
: 由于儲存到友善資料備份
中, 易于資料備份 (可以使用定時任務, 定時将檔案發送給資料備份中心)單獨的檔案
-
: 子程序單獨完成持久化操作, 父程序不參與IO操作, 最大化redis性能寫時複制
- 恢複大量資料時, 速度優于 AOF
-
- 缺點
-
, 如果redis意外停止工作(如電源斷電等), 則可能會丢失一段時間的資料不是實時儲存資料
- 資料量大時, fork程序會比較慢, 持久化時使redis響應速度變慢
-
- 優點
1.3.1 AOF 隻追加檔案
- Append-only file 隻追加檔案
-
而 不是全部重新寫入隻追加
-
, 而不是資料追加指令
-
- 機制
- 主線程将
追加到aof_buf(緩沖區)中, 根據使用的政策不同,寫指令
将緩存區的指令寫入到aof檔案中 (不使用子程序)子線程
- 當redis重新開機時, 會重新執行aof檔案中的指令來恢複資料
- 如果同時開啟了 RDB, 則優先使用 AOF
- 主線程将
- 檔案修複
- 如果AOF出錯 (磁盤滿了/寫入中途當機等), 則redis重新開機時會拒絕使用該AOF檔案
- 修複步驟
- 首先備份AOF檔案
- 使用redis-check-aof工具進行修複 (一般會删除末尾無法恢複的指令)
- 重新開機redis伺服器, 自動載入修複後的AOF檔案, 進行資料恢複
$ redis-check-aof –fix # 可選操作: 使用 diff -u 對比修複後的 AOF 檔案和原始 AOF 檔案的備份,檢視兩個檔案之間的不同之處。
- 檔案重寫/壓縮
- AOF 提供了重寫/壓縮機制(優化指令), 以避免AOF檔案過大
- fork子程序來完成 AOF 重寫
- 相關配置
appendonly no # 是否開啟AOF機制
appendfsync everysec # 多久将寫入的内容同步到硬碟 每秒一次
no-appendfsync-on-rewirete no # 重寫aof檔案時是否執行同步操作
auto-aof-rewrite-percentage 100 # 多久執行一次aof重寫, 當aof檔案的體積比上一次重寫後的aof檔案大了一倍時
auto-aof-rewrite-min-size 64mb # 多久執行一次aof重寫,當aof檔案體積大于64mb時
appendfilename appendonly.aof # aof檔案名
dir ./ # aof檔案儲存的位置(和rdb檔案共享該配置)
- 優缺點
-
優點
-
更可靠
預設每秒同步一次操作, 最多丢失一秒資料
- 提供了三種政策, 還可以不同步/每次寫同步
- 可以進行`檔案重寫`, 以避免AOF檔案過大
-
缺點
- 相同資料集, AOF檔案比RDB
,體積大
- 除非是不同步情況, 否則普遍要比RDB恢複速度慢
速度慢
-
1.3.3 如何選擇
- 對于
可以選擇使用redis進行持久化存儲更新頻繁, 一緻性要求不是非常高的資料
- RDB or AOF
- 資料安全性要求高, 都打開
- 可以接受短時間的資料丢失, 隻使用 RDB
- 即使使用 AOF, 最好也開啟 RDB, 因為便于備份并且回複速度快, bug更少
- 項目中的應用
- 使用redis進行一部分資料的持久化存儲
- 使用者的閱讀曆史
- 兩種持久化機制都開啟了
- 使用redis進行一部分資料的持久化存儲
1.4 分布式設計
1.4.1 哨兵 (重點)
- 作用
- 監控redis伺服器的運作狀态, 可以進行
(failover), 實作高可用自動故障轉移
- 與
配合使用的機制資料庫主從
- 監控redis伺服器的運作狀态, 可以進行
- 特點
- 獨立的程序, 每台redis伺服器應該至少配置一個哨兵程式
- 監控redis主伺服器的運作狀态
- 出現故障後可以向管理者/其他程式發出通知
- 針對故障,可以進行自動轉移, 并向用戶端提供新的通路位址
流言協定
- 當某個哨兵程式 發現監視的主伺服器下線後(心跳檢測), 會向監聽該伺服器的其他哨兵詢問, 是否确認主伺服器下線, 當 确認的哨兵數量 達到要求(配置檔案中設定)後, 會确認主伺服器下線(客觀下線), 然後進入投票環節
投票協定
- 當确認主伺服器客觀下線後, 哨兵會通過 投票的方式 來授權其中一個哨兵主導故障轉移處理
- 隻有在 大多數哨兵都參加投票 的前提下, 才會進行授權, 比如有5個哨兵, 則需要至少3個哨兵投票才可能授權
- 目的是避免出現錯誤的故障遷移
建議最低配置
- 至少在3台伺服器上分别啟動至少一個哨兵
- 如果隻有一台, 則伺服器當機後, 将無法進行故障遷移
- 如果隻有兩台, 一旦一個哨兵挂掉了, 則投票會失敗
- 相關配置 (sentinel.conf)
bind 127.0.0.1 # 哨兵綁定的ip
port 26381 # 哨兵監聽的端口号, redis用戶端需要通路哨兵的ip和端口号
sentinel monitor mymaster 127.0.0.1 6380 2 # 設定哨兵 (主資料庫别名 主資料庫ip 主資料庫端口 确認下線的最小哨兵數量)
sentinel down-after-milliseconds mymaster 60000 # 伺服器斷線逾時時長
sentinel failover-timeout mymaster 180000 # 故障轉移的逾時時間
sentinel parallel-syncs mymaster 1 # 執行故障轉移時,最多幾個從資料庫可以同步主資料庫資料(數量少會增加完成轉移的時長;數量多可能會影響主資料庫的資料查詢)
min-slaves-to-write 2 # 可執行故障轉移的從資料庫的最小數量(低于當數量時, 主資料庫将禁止寫入操作)
min-slaves-max-lag 10 # 從資料庫的最大響應時長
# 以上兩條連起來: 當至少有2個從資料庫可以進行複制并且響應延遲都在10秒之内時, 主資料庫才允許寫操作
- 啟動哨兵
redis-sentinel sentinel.conf
mysql官方沒有提供故障轉移方案, 需要用第三方的服務, 如 keepalive等
1.4.2 叢集
- 多個節點共同儲存資料
- 作用
- 拓展存儲空間
- 提高吞吐量, 提高寫能力
- 和單機的不同點
- 不再區分資料庫, 隻有0号庫, 單機預設0-15
- 不支援事務/管道/多值操作
- 叢集預設就內建了哨兵, 至少三主三從, 自動故障轉移
- 安裝
pip install redis-cluster
- 項目中的使用
- 主從配置了哨兵和持久化機制, 用于儲存使用者的閱讀曆史
- 叢集負責實作緩存設計