Remote Dictionary Server

assets/Redis入门/image-20231017214847414.png

Redis 十大資料型別

Key

命令不區分大小寫 Key 區分大小寫

  • 查看所有 key keys *

  • exists key

  • type key

  • del key

  • unlink key 非阻塞刪除,僅僅將 keys 從 keyspace 中繼資料中刪除,真正的刪除會在後續非同步中操作。 del key 是原子的刪除,只有刪除成功了才會回傳刪除結果,如果是刪除大 key 用 del 會將後面的操作都阻塞,而 unlink key 不會阻塞,它會在背景非同步刪除資料

  • ttl key查看還有多少秒過期,-1 表示永不過期,-2 表示已過期

  • expire key 為給定的 key 設定過期時間

  • move key dbindex[0-15] 將目前資料庫的 key 移動到給定的資料庫 DB 當中

  • select dbindex 切換資料庫 (0-15),預設為 0

  • dbsize

  • flushdb [ASYNC/SYNC]

  • flushall

  • help @型別 , help @hash

keys pattern keys * keys set* exists key type key del key ../../../实战项目/assets/苍穹外卖/image-20231105225952599.png

字串 String

string 是 redis 最基本的型別,一個 key 對應 一個 value

string 型別是 二進位安全 的,意思是 redis 的 string 可以包含任何資料,比如 jpg 圖片或者序列化的物件。

string 型別是 Redis 最基本的資料型別,一個 redis 中字串 value 最多可以是 512M

  • SET key value
  • Get key
  • SETEX key seconds value
  • SETNX key value Set if not exists ../../../实战项目/assets/苍穹外卖/image-20231105202010994.png

列表 (list)

../../../实战项目/assets/苍穹外卖/image-20231105205301485.png assets/Redis入门/image-20231121205027427.png

Redis 列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部 (左邊) 或者尾部 (右邊)

它的底層實際是個雙端鏈結串列,最多可以包含 2^32-1 個元素 (4294967295,每個列表超過 40 億個元素)

簡單的字串列表,按照插入順序排序 assets/Redis入门/image-20231121205430305.png

  • lpush key value1 value2 value3
  • lrange key start stop 0 代表頭部,-1 代表尾部
  • rpop key
  • llen key
  • lindex key index
  • llen key
  • lrem key number value number=0 代表全部
  • ltrim key index1 index2 刪除從索引 index1 到索引 index2 的值
  • rpoplpush key1 key2 將 key1 最後一個資料彈到 key2 assets/Redis入门/image-20231121210221569.png
  • lset key index value 替換
  • linsert before value1 value2/aftervalue1 value2 before 在 value 1 前插入 value 2 assets/Redis入门/image-20231121210705633.png

assets/Redis入门/image-20231121205648659.png assets/Redis入门/image-20231121205704258.png

../../../实战项目/assets/苍穹外卖/image-20231105205257829.png

../../../../实战项目/assets/苍穹外卖/image-20231105204947520.png ../../../实战项目/assets/苍穹外卖/image-20231105205019432.png 最後插入的在第一位

雜湊 (hash)

../../../实战项目/assets/苍穹外卖/image-20231105205328325.png

一個 String 型別的 field 和 value 的映射表,hash 特別適合儲存 物件

Redis hash 是一個 string 型別 field (欄位) 和 value (值) 的映射表, hash 特別適合用於儲存物件。
Redis 中每個 hash 可以儲存 2^32-1 鍵值對 (40 多億) assets/Redis入门/image-20231121214424602.png

  • HSET key field value
  • HGET key field
  • HDEL key field
  • HKEYS key
  • HVALS key
  • hlen key
  • hexists key
  • hkeys/hvals
  • hincrby/hincrbyfloat
  • hsetnx

../../../../实战项目/assets/苍穹外卖/image-20231105205322936.png

assets/Redis入门/image-20231121215510513.png

集合 (set)

單值多 value,無重複,無序無重複, list 是有序有重複

../../../实战项目/assets/苍穹外卖/image-20231105210036482.png assets/Redis入门/image-20231121215858544.png

String 型別的無序集合,集合成員是唯一的,集合中 不能重複 的資料

Redis 的 Set 是 String 類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的資料,集合對象的編碼可以是 intset 或者 hashtable Redis 中 Set 集合是透過雜湊表實作的,所以新增,刪除,查找的複雜度都是 O(1) 集合中最大的成員數為 2^32-1 (4294967295,每個集合可儲存 40 多億個成員)

assets/Redis入门/image-20231121200638105.png assets/Redis入门/image-20231121200839424.png

  • kepptll 預設改後的 ttl 會變成-1, 需要指定不變

mset/mget 批次 getrange/setrange assets/Redis入门/image-20231121201854839.png assets/Redis入门/image-20231121201952299.png

INCR INCRBY DECR DECRBY

assets/Redis入门/image-20231121202052446.png STRLEN k1 xxx (String Length) APPEND key value assets/Redis入门/image-20231121202136946.png

  • sadd key nember1 number2 number3 新增的有重複時會自動去重

  • smembers key 走訪

  • scard key 個數

  • srem key member1 member2 member3 刪除

  • srandmember key [number] 從 key 中隨機展示[數字]個的元素,元素不刪除

  • spop key[number] 從集合中隨機彈出一個元素,彈一個刪除一個

  • smove key1 key2 value 將 key1 中的 value 遷移給 key2 assets/Redis入门/image-20231121220621472.png

  • sdiff key1 key2 : key 1-key 2的結果

  • sinter key1 key2 key3 交集

  • sintercard numkeys key [key...] [LIMIT limit] 也是交集,回傳個數 assets/Redis入门/image-20231121220933551.png

  • sunion key1 key2 key3 聯集

../../../../实战项目/assets/苍穹外卖/image-20231105210029219.png

assets/Redis入门/image-20231121201629268.png 全部成功才有效

有序集合 (ZSET)

../../../../实战项目/assets/苍穹外卖/image-20231105210503319.png

String 類型元素的集合,且不允許有重複成員,每個元素都會關聯一個 double 類型的分數,透過分數進行排序

  • zadd key minutes 1 name 1 minutes 2 name 2 minutes 3 name 3
  • zscore key member 取得元素分數
  • zCARD key 取得集合中元素的數量
  • zrangen key start stop [withscores]
  • zincrby key increment member
  • zrem key member [memeber ...] 刪除
  • zmpop number key min count 1
  • zrank key values/zrevrank key values 取得下標值或逆序下標值

../../../Project/assets/苍穹外卖/image-20231105210408970.png

assets/Redis入门/image-20231122192919337.png

地理空間 (GEO)

亂碼 : 使用中文連接 reids 時候要加 --raw

Redis GEO 主要用於儲存地理位置資訊,並對儲存的資訊進行操作 (longitude,dimension)

新增 地理位置的座標。 取得 地理位置的座標。 計算 兩個位置之間的距離。 根據 使用者給定的經緯度座標來取得指定範圍內的address location set

assets/Redis入门/image-20231122204143924.png

  • geoadd key longitude dimension name GEOADD city 116.403963 39.915119 "天安门" 116.403414 39.924091 "故宫" 116.024067 40.362639 "长城"

  • geopos 回傳經緯度 assets/Redis入门/image-20240228120420573.png

  • geohash 回傳座標的 geohash 表示 產生 base32 的編碼值,代表了座標 assets/Redis入门/image-20240228120448132.png

  • geodist key name1 name2 [m|km|ft|mi] 自動計算兩個地方相距 assets/Redis入门/image-20231122210330694.png

  • georadius 以給定的經緯度為中心,回傳鍵包含的位置元素中,與中心的距離不超過給定最大距離的所有位置元素 assets/Redis入门/image-20231122210524494.png

  • georadiusbymember assets/Redis入门/image-20231122205359002.png

redis 基數統計(HyperLogLog)

儲存資料個數,不儲存實際內容

HyperLogLog 是用來做 基數統計 的演算法,具有 去重複統計 功能,是 String 型別

優點 : 輸入元素的數量或者體積非常非常大時,計算基數所需要的空間總是固定且是很小的。

HyperLogLog是一種機率演算法,儲存的是資料的個數

在Redis裡面,每個HyperLogLog鍵只需要花費12KB記憶體,就可以計算接近2^64個不同元素的基數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。

但是,因為HyperLogLog只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以HyperLogLog不能像集合那樣,返回輸入的各個元素。

統計大致多少人訪問過一個頁面,IP 同一個只代表一個,去重複統計獨立訪客

assets/Redis入门/image-20231122202717716.png assets/Redis入门/image-20231122202857682.png

  • pfadd key value1 value2 value3
  • pfcount key
  • pfmerge key key1 key2 合併 key1 ,key 2 ,並不會儲存具體的值,只會告訴你數量

一句話:去重脫水後的真實資料 assets/Redis入门/image-20240227201541008.png

assets/Redis入门/image-20231122203556920.png

redis 位圖(bitmap)

由 0 和 1 狀態表現的二進位位的 bit 陣列,相當於 string 的子類,型別還是string

assets/Redis入门/image-20231121190255065.png 是否登陸過,是否點過,打卡上下班,簽到統計 使用 mysql 的資料量過大

  • setbit key 位置 值 值只能 0 或 1
  • getbit key 位置
  • strlen 統計位元組佔用多少, 8 位一個 bitmap setbit k1 1 1 setbit k1 7 1 佔用一個位元組 setbit k1 1 1 setbit k1 8 1 佔用兩個位元組
  • bitcount key 統計

assets/Redis入门/image-20231122200304768.png

assets/Redis入门/image-20231122200255908.png

assets/Redis入门/image-20231122200827153.png

redis 串流(Stream)

Redis Stream 是 Redis5.0版本新增加的資料結構。

Redis Stream主要用於訊息佇列(MQ,Message Queue),Redis本身就是一個Redis發布訂閱(pub/sub)來實現訊息佇列的功能,但它有個缺點就是訊息無法持久化,如果出現網路斷開、Redis宕機等,訊息就會被丟棄。

簡單來說發布訂閱(pub/sub)可以分發訊息,但無法記錄歷史訊息。

而Redis Stream提供了訊息的持久化和主備複製功能,可以讓任何客戶端訪問任何時刻的資料,並且能記住每一個客戶端的訪問位置,還能保證訊息不丟失。

5.0 之前 assets/Redis入门/image-20231123092240065.png assets/Redis入门/image-20231123092226220.png assets/Redis入门/image-20231123092353082.png

assets/Redis入门/image-20231123092836878.png assets/Redis入门/image-20231123093213705.png

佇列相關指令

佇列: 即產生的一列 IDx

佇列相關指令

  • xadd 佇列名 * key1 value1 key2 value2 訊息 id 必須比上一個大, * 用於讓系統自動生成 id, 會生成訊息 ID assets/Redis入门/image-20231123100537117.png

assets/Redis入门/image-20231123094601208.png assets/Redis入门/image-20231123094610916.png

  • xrange mstream - +

assets/Redis入门/image-20231123100544429.png assets/Redis入门/image-20231123100556622.png

  • xdel key ID

  • xlen key - +

  • xtrim key maxlen number 最大的數量,前面的會被截掉 assets/Redis入门/image-20231123100609675.png

  • xread mstream - +

assets/Redis入门/image-20231123100707593.png assets/Redis入门/image-20231123100818606.png assets/Redis入门/image-20231123101137027.png assets/Redis入门/image-20231123101244474.png 阻塞有最大的而才會返回,會告訴你等了多久

消費相關指令

assets/Redis入门/image-20231123112957755.png

  • xgroup 佇列名 組名 assets/Redis入门/image-20231123113100326.png assets/Redis入门/image-20231123113033042.png

  • XREADGROUP GROUP 組名 消費名 STREAMS 佇列名 assets/Redis入门/image-20231123113313298.png 因為游標已經從頭走到尾了,即使同組也不能讀 但是不同組可以讀 assets/Redis入门/image-20231123113542833.png

assets/Redis入门/image-20231123114041008.png

  • xpending queue name group name 查詢每個消費群組內所有消費者

assets/Redis入门/image-20231123114405793.png

  • xpending queue name group name - + count consumer 查看某個消費者讀取了哪些資料 assets/Redis入门/image-20231123114926474.png 簽收後再查讀取過的資料會只剩沒有簽收的

xinfo stream queue name assets/Redis入门/image-20231123115317186.png

redis 位域(bitfield)(了解)

將 redis 字串看作一個由二進位組成的陣列,並能對變長位寬和任意沒有位元組對齊的指定整數位域進行定址和修改

透過 bitfield 指令可以一次性操作多個bit field(指的是連續的多個位元),它會執行一系列操作並回傳一個回應陣列,這個陣列中的元素對應參數列表中的相應執行結果。

說白了就是透過 bitfield 指令我們可以一次性對多個 bit field進行操作。

assets/Redis入门/image-20231123115707795.png assets/Redis入门/image-20231123115754768.png assets/Redis入门/image-20231123115826030.png ASCII 碼 | ASCII 碼對照表

位域修改,溢位控制

assets/Redis入门/image-20231123120056197.png

相當於可以改位元組碼

assets/Redis入门/image-20231123120325015.png assets/Redis入门/image-20231123121343466.png

assets/Redis入门/image-20231123120639247.png

assets/Redis入门/image-20231123120652968.png -128 到 127 超過則溢位

assets/Redis入门/image-20231123121237132.png

../../../../实战项目/assets/苍穹外卖/image-20231115200200782.png ../../../实战项目/assets/苍穹外卖/image-20231115200205004.png 兩個冒號就會有 empty ../../../Project/assets/苍穹外卖/image-20231115200324146.png ../../../Project/assets/苍穹外卖/image-20231115200336930.png

redis 持久化

Redis persistence | Redis

Persistence refers to the writing of data to durable storage

  1. 透過 RDB 快照檔案 (dump.rab) 還原,將磁碟的快照還原到記憶體
  2. 透過 AOF 記錄的指令進行還原

RDB

啟用: save time num 在 time 內觸發 num 次就生效 停用: save "" 或 redis-cli config set save ""(non persistent) 依舊可以手動 save/bgsave 產生 RDB

  • 路徑修改

  • 檔案名稱修改:設定檔搜尋 dump.

  • 設定檔搜尋 config get dir 取得目錄

  • 遇到的問題:需要 dumpfiles 資料夾權限更改

SAVE 阻塞,其他指令都會無法處理,線上禁止使用 BGSAVEfork 一個子行程進行複製持久化,主行程可以同時修改資料

assets/Redis入门/image-20231126151848905.png

fork()

fork() 函式會建立一個完全和父行程相同的子行程,包括程式碼、資料和開啟的檔案描述符等。 assets/Redis入门/image-20231126151647572.png assets/Redis入门/image-20240411183509864.png

lastsave date -d

lastsave用於取得最近一次成功執行持久化操作(快照或 AOF)的時間戳。它可以告訴你上次完成持久化的時間,對於監控和管理 Redis 實例非常有用 assets/Redis入门/image-20240411183910192.png assets/Redis入门/image-20231126152035426.png date -d @16695455399 assets/Redis入门/image-20231126152053891.png

RDB 優缺點
  1. 適合大規模資料還原
  2. 比 AOF 快
  3. 定時備份

assets/Redis入门/image-20231126153008277.png assets/Redis入门/image-20231126153045751.png

  • RDB 缺點
  1. 在沒有觸發達到儲存條件時發生意外的資料會遺失
  2. fork() 可能消耗效能大 assets/Redis入门/image-20231126153320689.png assets/Redis入门/image-20231126153352477.png assets/Redis入门/image-20231126162523850.png
修復

check -rdb /myredis/dumpfiles/dump6379.rdb

assets/Redis入门/image-20231126160209266.png 寫到一半斷電導致破損了 assets/Redis入门/image-20231126160331485.png

assets/Redis入门/image-20231126160712998.png

最佳化設定

assets/Redis入门/image-20231126161731124.png

  • stop-writes-on-bgsave-error assets/Redis入门/image-20231126161858568.png

  • yes:如果在 bgsave 過程中,發生寫入錯誤, Redis 將停止接收任何請求,直到 bgsave 完成為止

  • no:即使在bgsave過程中發生寫入錯誤,Redis也會繼續接收請求並嘗試寫入

assets/Redis入门/image-20231126162149866.png

  • rdbcopression 壓縮變小,消耗一點 cpu assets/Redis入门/image-20231126162225061.png

rdbchecksum 安全與一致性 建議 yes assets/Redis入门/image-20231126162254828.png

rdb-del-sync-files 不用管

assets/Redis入门/image-20231126162436632.png

AOF

appendonly yes assets/Redis入门/image-20231126193414852.png

三種寫回策略

appendsync everysec

assets/Redis入门/image-20231126193529835.png 一般選 everysec, always 會導致 IO 太多,效能下降

assets/Redis入门/image-20231126193756484.png no 則取決於 linux 核心刷新資料的設定,通常 30 秒

儲存規則

assets/Redis入门/image-20231126195937792.png

incr 檔案內容 assets/Redis入门/image-20231126210856856.png

修復 redis-check-aof --fix 檔案名稱

如果只是資料被截斷 redis 不會被影響,redis 會自動捨棄錯誤的資料,但如果錯誤的資料發生在檔案中,後面的資料也會被捨棄,可能造成資料遺失

人為破壞 incr 檔案會連接不上 redis assets/Redis入门/image-20231129221629181.png

AOF 重寫機制

appendfsync every/always/no auto- aof- rewrite- percentage 100設定為 100 表示只要目前 AOF 檔案的大小是上一次 AOF 檔案大小的兩倍或更多 auto- aof- rewrite- min- size 1k incr 檔案達到 1k的兩倍就會重寫

assets/Redis入门/image-20231127115732684.png assets/Redis入门/image-20231127115842764.png

redis 交易

Transactions

交易的要求:希望一個命令或多條命令能夠合到一起成為一個不可分割、具備原子性、不被干擾打斷、統一執行的批次處理命令

assets/Redis入门/image-20231127155613382.png assets/Redis入门/image-20231127155650633.png

assets/Redis入门/image-20231127155803172.png assets/Redis入门/image-20231127155755041.png

正常執行

multi exec

放棄交易

multi discard

全體連坐

輸入過程中檢查出錯誤,redis 會直接傳回錯誤,任何命令都不會執行

assets/Redis入门/image-20231127161053009.png

冤頭債主

前期檢查不出的錯誤,執行時才知道,只有出錯的才不會執行 assets/Redis入门/image-20231127161546569.png assets/Redis入门/image-20231127161532114.png

watch 監控

無插隊情況 assets/Redis入门/image-20231127162554965.png

有插隊情況 assets/Redis入门/image-20231127162726154.png assets/Redis入门/image-20231127163027159.png

Redis 管道

Redis pipelining | Redis 如何最佳化頻繁命令往返造成的效能瓶頸

assets/Redis入门/image-20231127190117404.png assets/Redis入门/image-20231127190122911.png assets/Redis入门/image-20231127190249430.png 降低 RTT(Round Trip Time) 對效能的影響

assets/Redis入门/image-20231127190300529.png

assets/Redis入门/image-20231127190801826.png

assets/Redis入门/image-20231127191453890.png 需要 linux 用戶端和 伺服端共同完成 assets/Redis入门/image-20231127191824419.png

assets/Redis入门/image-20231127191846890.png

Redis 發布訂閱 (了解)

assets/Redis入门/image-20231127192118410.png assets/Redis入门/image-20231127192133520.png

assets/Redis入门/image-20231127192035674.png 就是 redis 訊息佇列的前身雛形 assets/Redis入门/image-20231127192244259.png assets/Redis入门/image-20231127192255279.png assets/Redis入门/image-20231127192312758.png

assets/Redis入门/image-20231127192329346.png

  • subscribe channel [channel ...]

assets/Redis入门/image-20231127192355858.png

  • publish channel message assets/Redis入门/image-20231127192454696.png

  • publish pattern [pattern ...] assets/Redis入门/image-20231127192503194.png

  • pubsub subcommand [argument [argument ...]] assets/Redis入门/image-20231127192606406.png

  • unsubscribe [channel [channel ...]] assets/Redis入门/image-20231127192722621.png

  • Punsubscribe [pattern [pattern ...]]

assets/Redis入门/image-20231127192732320.png

redis 複製(replica)

Redis replication | Redis

主從複製:master 以寫為主,slave 以讀為主 當 master 資料變化時,自動將新的資料非同步同步到其他 slave 資料庫

assets/Redis入门/image-20231127194141359.png 設定從庫不設定主庫

設定


---通用部分---
bind 0.0.0.0 # 允許位址
protected-mode: yes #防止Redis實例在未進行任何安全配置(如requirepass/bind)的情況下被外界存取。
daemonize yes               # 允許後台啟動
logfile "/usr/local/redis/redis.log"                # 日誌路徑
dir /opt/software/redis-7.0.3/data                 # RDB檔案存放目錄
appenddirname "appendonlydir"  # AOF檔案會在dir的位置上的appenddirname資料夾保存
appendfilename "appendonly.aof" # AOF檔案名稱
appendonly yes                  # AOF 開啟

`redis` 主從: 讀寫分離,容災恢復,資料備份,水平擴容支撐高併發

主從:slave依舊可以作為其他slave的master(減少master的壓力)
只有最頂層master可以執行命令,slave會複製之前的也可以複製 
主機掛了從機會等待主機上線
中途變更:從機可以隨時修改主機,修改後會自動清除之間的資料,拷貝新master的

缺點: 
	掛了需要人工干預
	系統繁忙時,slave導致延遲高
	
--- Master.conf-----
requirepass xxx #master設定

--- 主從Slave.conf(只需要改從庫配置,無需更改主庫配置)------
# 指定主節點的 IP 和連接埠(推薦)
replicaof 主庫IP 主庫連接埠
# 或者使用舊的方式
slaveof 主庫IP 主庫連接埠
slaveof no one #停止當前資料庫和其他資料庫的同步

masterauth xxx #slave設定

---- 命令列 ----

info replication #查看資訊
slaveof 主庫IP 主庫連接埠  # 手動執行,當前工作階段有效

複製原理和工作流程

assets/Redis入门/image-20231128082838348.png

redis 哨兵sentinel

assets/Redis入门/image-20231128083837925.png 無人值守運維 : 將 slave 透過某種機制進行選取,進行主從替換

作用 主從監控: 監控主從 redis 運行 訊息通知: 故障轉移結果發送客戶端 故障轉移: 自動主從切換 配置中心: 透過連接哨兵來獲得當前 Redis 伺服器主節點位址

sentinel.conf 設定檔

在上一章複製配置好的情況下進行配置

sentinel.conf(配置好一个后直接拷贝改动)


設定檔

assets/Redis入门/image-20231202212105408.png assets/Redis入门/image-20231128162041506.png assets/Redis入门/image-20231128162104861.png assets/Redis入门/image-20231128162109484.png assets/Redis入门/image-20231128162114947.png assets/Redis入门/image-20231128162136182.png assets/Redis入门/image-20231128162129561.png

解釋

assets/Redis入门/image-20231128162400248.png assets/Redis入门/image-20231128161705724.png sentinel monitor <master-name> <ip> <redis-port> <quorum> assets/Redis入门/image-20231128162455437.png quorum :2,即 2 個哨兵同意即可 assets/Redis入门/image-20231128161803719.png assets/Redis入门/image-20231128161809890.png 網路壅塞、駭客攻擊、網路波動等等,哨兵之間互相溝通,來判斷是否真的故障了,有時只是某個哨兵自身的問題 sentinel auth-pass <master-name> <password> assets/Redis入门/image-20231128162738844.png

啟動叢集

assets/Redis入门/image-20231128163233329.png assets/Redis入门/image-20231128163700822.png

sentinel log

assets/Redis入门/image-20231128164037050.png assets/Redis入门/image-20231128164208041.png

conf 檔案被自動修改

assets/Redis入门/image-20231128164435226.png

關閉 master 接近 1s ,後台進行了選舉,同時 slave. conf 的檔案也會被修改

被選為主機的 conf 檔案內容被自動刪除

assets/Redis入门/image-20231128185117573.png

被選為 slave 的自動被修改 assets/Redis入门/image-20231128184954431.png

assets/Redis入门/image-20231128185229310.png

assets/Redis入门/image-20231128164551422.png assets/Redis入门/image-20231128164737006.png

第一次失敗是因為需要進行網路的重新讀取和規劃,告訴你原有的連線被斷開了,可能需要重發一次心跳包,重新續接上去

剩下的兩台slave其中一台會被選為master

assets/Redis入门/image-20231128165424672.png

即使之前的 master 回來,也不會成為現在的 master 了

assets/Redis入门/image-20231128174912268.png

小問題

assets/Redis入门/image-20231128174728658.png

assets/Redis入门/image-20231128174756181.png

assets/Redis入门/image-20231128174813772.png

哨兵的運行流程和選舉原理

assets/Redis入门/image-20231128190252964.png

  1. SDown 主觀下線 (Subjectively Down)

assets/Redis入门/image-20231128190530847.png assets/Redis入门/image-20231128191904890.png

  1. ODown 客觀下線 (Objectively Down) assets/Redis入门/image-20231128192001394.png assets/Redis入门/image-20231128192020926.png
    1. 選出哨兵

    assets/Redis入门/image-20231128192654194.png assets/Redis入门/image-20231128192617151.png assets/Redis入门/image-20231128192143544.png 三個中選出一個 leader,這個 leader 選出 master 4. 選舉日誌 assets/Redis入门/image-20231128192349190.png

  • 選舉 Raft 演算法 assets/Redis入门/image-20231128192506406.png
    1. 由哨兵開始推動 故障切換 流程並選出一個新的 master assets/Redis入门/image-20231128193708167.png
      1. 選出新 master

      assets/Redis入门/image-20231128193445312.png assets/Redis入门/image-20231128192952244.png assets/Redis入门/image-20231128193141643.png 複製偏移量 (replication offset):由於網路等原因,兩個 slave 不一定一樣大 2. 產生 master,別的變成 master 的 slave assets/Redis入门/image-20231128193431966.png 3. 將已下線的老的 master 設定為新選出的 master 的從節點 assets/Redis入门/image-20231128193459673.png assets/Redis入门/image-20231128193636342.png

使用建議

assets/Redis入门/image-20231128193847788.png

雖然能夠無人值守的故障遷移:但是選舉哨兵 leader 和產生新的 master,少說需要 5-10s,這期間的資料就會遺失

-

redis 叢集 (cluster)

redis-cli -a password -p 6385 -c -c 進行路由傳遞

assets/Redis入门/image-20231202212649536.png assets/Redis入门/image-20231202212834197.png assets/Redis入门/image-20231202213448232.png assets/Redis入门/image-20231202213554725.png 不再需要之前的哨兵

作用

assets/Redis入门/image-20231202213834193.png

叢集演算法-分片-槽位 slot

assets/Redis入门/image-20231203131219819.png assets/Redis入门/image-20231203131116284.png

優勢 assets/Redis入门/image-20231203131040071.png

assets/Redis入门/image-20231203131230997.png 讀寫都是同一個槽位 assets/Redis入门/image-20231203131554439.png

鍵值會用 CRC16 演算法進行校驗和,然後對 16384 取模,得到一個槽位的編號(如 1234 號)

assets/Redis入门/image-20231203132043842.png

雜湊槽位映射

雜湊取餘分區

assets/Redis入门/image-20231203144348748.png assets/Redis入门/image-20231203144408975.png

一致性雜湊演算法分區

一致性雜湊演算法分區 :所有的 hash 值構成一個全量集,邏輯控制使其首尾相連形成一個閉合空間,所有雜湊值都落到環上,伺服器節點也根據雜湊落到環上,然後值會順時針找到最近的伺服器節點進行儲存

優點 : 容錯性,拓展性

缺點: 伺服器太少時會出現資料傾斜問題

assets/Redis入门/image-20231203235042370.png 提出一致性 Hash 解決方案,目的是當伺服器個數發生變化時,盡量減少影響客戶端到伺服器的映射關係

演算法構建一致性雜湊環

assets/Redis入门/image-20231203235403225.png assets/Redis入门/image-20231203235412330.png assets/Redis入门/image-20231203235419050.png assets/Redis入门/image-20231204194821114.png

redis 伺服器 IP 節點映射 assets/Redis入门/image-20231204193546139.png assets/Redis入门/image-20231204193557277.png

key 落到伺服器的落鍵規則

assets/Redis入门/image-20231204194356866.png assets/Redis入门/image-20231204194413583.png

優點

  • 容錯性 assets/Redis入门/image-20231204195936881.png assets/Redis入门/image-20231204195941607.png

  • 拓展性

assets/Redis入门/image-20231204195956302.png assets/Redis入门/image-20231204200040523.png

缺點

assets/Redis入门/image-20231204200101720.png assets/Redis入门/image-20231204200111578.png

雜湊槽分區 assets/Redis入门/image-20231204200408320.png assets/Redis入门/image-20231204200413940.png

雜湊槽分區

雜湊槽分區 : 在 資料 和 節點 中加了一層 雜湊槽 (16384),來管理 資料和節點間的關係, 槽 解決了粒度問題,雜湊 解決了映射問題,

redis 會將大致相等的雜湊槽分別映射到不同節點上

雜湊值對 16384 取模,餘數是幾落到對應的槽裡

assets/Redis入门/image-20231204200722768.png assets/Redis入门/image-20231204200821099.png assets/Redis入门/image-20231204200826047.png HASH_SLOT= CRC16(key) mod 16384

  • 雜湊值計算 assets/Redis入门/image-20231205083811562.png assets/Redis入门/image-20231205083818441.png assets/Redis入门/image-20231205083827192.png

為何 redis 叢集最大槽數是 16384 個

  1. assets/Redis入门/image-20231205084534724.png assets/Redis入门/image-20231205084554208.png assets/Redis入门/image-20231205084713411.png assets/Redis入门/image-20231205085258694.png assets/Redis入门/image-20231205085304306.png assets/Redis入门/image-20231205085318451.png

redis 叢集不保證強一致性,在特定條件下,redis 叢集可能會丟掉一些被系統收到的寫入請求命令 assets/Redis入门/image-20231205085505374.png

叢集環境搭建步驟

三主三從 redis 叢集配置

assets/Redis入门/image-20231205230852024.png

1. 新建6個配置目錄 mkdis -p /myredis/cluster
2. 配置6個設定檔
3. 構建主從關係

assets/Redis入门/image-20231205153658678.png assets/Redis入门/image-20231205153741767.png assets/Redis入门/image-20231205154742443.png 不一定按照寫的分配, 以實際分配為準

assets/Redis入门/image-20231205153138122.png 主,從的設定檔完全一樣,如下(影片 6 台設定檔全部都是下面內容) assets/Redis入门/image-20231205152529952.png 5000ms = 5s

3.構建主從關係

不一定按照寫的分配, 以實際分配為準

redis-cli -a password --cluster create --cluster-replicas x 
ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6

assets/Redis入门/image-20231205154211128.png assets/Redis入门/image-20231205154225253.png assets/Redis入门/image-20231205154317053.png assets/Redis入门/image-20231205154328501.png

以 6381 為切入點,查看並檢驗叢集關係

info replication assets/Redis入门/image-20231205155031182.png assets/Redis入门/image-20231205155430747.png

cluster nodes

assets/Redis入门/image-20231205155115235.png assets/Redis入门/image-20231205155143405.png

三主三從 redis 叢集讀寫

assets/Redis入门/image-20231205230916809.png assets/Redis入门/image-20231205161316784.png assets/Redis入门/image-20231205161350237.png 由於槽位的限制,不再是想怎麼存就怎麼存,需要路由到位 assets/Redis入门/image-20231205161521080.png assets/Redis入门/image-20231205161717414.png 內部由於有 CRC16 和重定向演算法 k1 被重定向到另一個槽位

連接叢集需要加 c, 這樣連接的是大redis redis-cli -a password -p 6385 -c assets/Redis入门/image-20231205162004326.png

  • cluster keyslot 鍵

查看某個 key 的槽位值 assets/Redis入门/image-20231205162205983.png

主從容錯切換遷移案例

assets/Redis入门/image-20231205230907949.png

master 掛後 slave 會自動上位,即使之前 master 重新回歸,也會變成slave assets/Redis入门/image-20231205165234327.png assets/Redis入门/image-20231205170302315.png 恢復後變成slave assets/Redis入门/image-20231205170323087.png assets/Redis入门/image-20231205170339639.png

手動故障轉移 or 節點從屬調整

assets/Redis入门/image-20231205230829552.png

CLUSTER NODES

assets/Redis入门/image-20231205170556028.png 將之前的 master 恢復後還變成 master

主從擴容案例

assets/Redis入门/image-20231205230817239.png

assets/Redis入门/image-20231205170824165.png

新增 redis-cli -a password --cluster add-node ip1:port1 ip:port ip1:port1 是新加的位址 ip:port 是已有的位址 加入後不會被分配槽號 assets/Redis入门/image-20231205173021176.png assets/Redis入门/image-20231205173035025.png assets/Redis入门/image-20231205173042672.png

檢查

assets/Redis入门/image-20231205173056997.png 加入後不會被分配槽號 assets/Redis入门/image-20231205173102117.png

重新分配槽號 (reshard)

redis-cli -a psw --cluster reshard ip:port

assets/Redis入门/image-20231205174241978.png 填 16384/4=4096 assets/Redis入门/image-20231205174344627.png 填新的 assets/Redis入门/image-20231205174353465.png assets/Redis入门/image-20231205174409229.png assets/Redis入门/image-20231205174420847.png

分配好了槽位,目前還沒有掛 slave assets/Redis入门/image-20231205174526896.png assets/Redis入门/image-20231205175038245.png assets/Redis入门/image-20231205175226091.png

assets/Redis入门/image-20231205175404224.png assets/Redis入门/image-20231205175418201.png assets/Redis入门/image-20231205175431590.png

assets/Redis入门/image-20231205175548040.png

主從縮容案例

assets/Redis入门/image-20231205230804953.png

assets/Redis入门/image-20231205230308788.png

redis-cli -a psw --cluster del-node ip:port ID assets/Redis入门/image-20231205231045083.png assets/Redis入门/image-20231205231253566.png slave 被成功刪除,接下來將 6387 的槽號清空,重新分配 (本例群不還給了 6381)

redis-cli -a psw --cluster reshard ip:6381 然後輸入 4096

assets/Redis入门/image-20231205231545653.png assets/Redis入门/image-20231205231614693.png assets/Redis入门/image-20231205231816259.png 不需要兩個 slave , 之後將 6387 刪除

redis-cli -a psw --cluster del-node ip:port ID

assets/Redis入门/image-20231205232000366.png

叢集常用操作命令和 CRC16 演算法分析

assets/Redis入门/image-20231205232531447.png

assets/Redis入门/image-20231205232249543.png assets/Redis入门/image-20231205232547770.png

assets/Redis入门/image-20231205232600766.png assets/Redis入门/image-20231205232616885.png assets/Redis入门/image-20231205232645850.png cluster keyslot key cluster countkeysinslot 12707 assets/Redis入门/image-20231205233046866.png

Spring 使用 Redis

Redis 的 Java 客戶端很多,常用的幾種: Jedis Lettuce Spring Data Redis

Spring Data Redis 是 Spring 的一部分, 對 Redis 底層開發套件進行了高度封裝。 在 Spring 專案中, 可以使用 Spring Data Redis 來簡化操作

RedisTemplate

連線時注意 :

auth 是客戶端的後續認證命令 password 是伺服器端的連線認證設定

yaml
server.port=7777

spring.application.name=redis7_study

# ========================logging=====================
logging.level.root=info
logging.level.com.atguigu.redis7=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n 

logging.file.name=D:/Users/XCJY/Desktop/qianduan
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n

# ========================swagger=====================
spring.swagger2.enabled=true
#在springboot2.6.X結合swagger2.9.X會提示documentationPluginsBootstrapper空指標異常,
#原因是在springboot2.6.X中將SpringMVC預設路徑比對策略從AntPathMatcher更改為PathPatternParser,
# 導致出錯,解決辦法是matching-strategy切換回之前ant_path_matcher
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

# ========================redis單機=====================
spring.redis.database=0
# 修改為自己真實IP
spring.redis.host=192.168.111.185
spring.redis.port=6379
spring.redis.auth=111111
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

lettuceConnectionFactory 適合高併發

RedisConfig

@Configuration  
public class RedisConfig  
{  
    /**  
     * redis序列化的工具設定類,下面這個請一定開啟設定  
     * 127.0.0.1:6379> keys *  
     * 1) "ord:102"  序列化過  
     * 2) "\xac\xed\x00\x05t\x00\aord:102"   野生,沒有序列化過  
     * this.redisTemplate.opsForValue(); //提供了操作string類型的所有方法  
     * this.redisTemplate.opsForList(); // 提供了操作list類型的所有方法  
     * this.redisTemplate.opsForSet(); //提供了操作set的所有方法  
     * this.redisTemplate.opsForHash(); //提供了操作hash表的所有方法  
     * this.redisTemplate.opsForZSet(); //提供了操作zset的所有方法  
     * @param lettuceConnectionFactory  
     * @return  
     */  
    @Bean  
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory)  
    {  
        //開始建立redis範本物件...  
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();  
        //設定redis的連線工廠物件  
       redisTemplate.setConnectionFactory(lettuceConnectionFactory);  
        //設置key序列化方式string  
        redisTemplate.setKeySerializer(new StringRedisSerializer());  
        //設置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替換預設序列化  
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());  
        //設定雜湊序列化方式  
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());  
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());  
		//RedisTemplate 的所有屬性設定完成後,進行一些初始化操作
        redisTemplate.afterPropertiesSet();  
  
        return redisTemplate;  
    }  
}
SwaggerConfig
@Configuration  
@EnableSwagger2  
public class SwaggerConfig  
{  
    @Value("${spring.swagger2.enabled}")  
    private Boolean enabled;  
  
    @Bean  
    public Docket createRestApi() {  
        return new Docket(DocumentationType.SWAGGER_2)  
                .apiInfo(apiInfo())  
                .enable(enabled)  
                .select()  
                .apis(RequestHandlerSelectors.basePackage("com.atguigu.redis7")) //你自己的package  
                .paths(PathSelectors.any())  
                .build();  
    }  
    public ApiInfo apiInfo() {  
        return new ApiInfoBuilder()  
                .title("springboot利用swagger2构建api接口文档 "+"\t"+ DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()))  
                .description("springboot+redis整合,有问题给管理员阳哥邮件:zzyybs@126.com")  
                .version("1.0")  
                .termsOfServiceUrl("https://www.atguigu.com/")  
                .build();  
    }  
}

RedisTemplate 操作類

Spring 提供的 Redis 資料結構的操作類

  • ValueOperations 類,提供 Redis String API 操作
  • ListOperations 類,提供 Redis List API 操作
  • SetOperations 類,提供 Redis Set API 操作
  • ZSetOperations 類,提供 Redis ZSet(Sorted Set) API 操作
  • GeoOperations 類,提供 Redis Geo API 操作

序列化問題

assets/Redis入门/image-20231206170034684.png

//ThreadLocalRandom.current(): 取得與目前執行緒綁定的執行緒本地隨機數產生器  
//.nextInt(1000): 產生一個0到999之間的隨機整數  
//+1: 將產生的隨機整數加1,使範圍變為1到1000  
int keyId= ThreadLocalRandom.current().nextInt(1000)+1;  
String serialNO= UUID.randomUUID().toString();

將 redisTemplate 預設使用的``

想讓 linux 客戶端檢視中文 --raw 否則會是亂碼 assets/Redis入门/image-20231206174534541.png assets/Redis入门/image-20231206171032961.png

原因

assets/Redis入门/image-20231206171347835.png assets/Redis入门/image-20231206171358790.png 預設是 JDK 序列化方式,會導致亂碼,透過手動指定來取代預設的

assets/Redis入门/image-20231206171523544.png

連線叢集

連線叢集設定
spring.redis.password=111111
# 取得失敗 最大重定向次數
spring.redis.cluster.max-redirects=3
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

#支援叢集拓撲動態感應重新整理,自適應拓撲重新整理是否使用所有可用的更新,預設false關閉,不新增master掛後spring不知道
spring.redis.lettuce.cluster.refresh.adaptive=true

#定時重新整理
spring.redis.lettuce.cluster.refresh.period=2000
spring.redis.cluster.nodes=192.168.111.175:6381,192.168.111.175:6382,192.168.111.172:6383,192.168.111.172:6384,192.168.111.174:6385,192.168.111.174:6386

assets/Redis入门/image-20231207091438992.png assets/Redis入门/image-20231207091457707.png

解決方案 assets/Redis入门/image-20231207091744697.png

https://github.com/lettuce-io/lettuce-core/wiki/Redis-Cluster#user-content-refreshing-the-cluster-topology-view

assets/Redis入门/image-20231207091636337.png assets/Redis入门/image-20231207091646755.png

#支援叢集拓撲動態感應重新整理,自適應拓撲重新整理是否使用所有可用的更新,預設false關閉,不新增master掛後spring不知道
spring.redis.lettuce.cluster.refresh.adaptive=true

#定時重新整理
spring.redis.lettuce.cluster.refresh.period=2000

資料

  1. 起步思維: 官網
  2. 排除故障思維 : 日誌

Redis脑图(基础篇+高级篇) ↗