Redis7新特性簡介及十大資料型別

小陳_winwah發表於2023-10-31

Redis是基於記憶體的K-V鍵值對記憶體資料庫

image-20231022161340540

淺談Redis7新特性

  1. 主要是自身底層效能和資源利用率上的提高和最佳化。

  2. 多AOF檔案支援

  3. config命令增強

  4. 限制客戶端記憶體使用

  5. listpack緊湊列表調整

  6. 訪問安全性增強

  7. Redis Functions(要搶Lua指令碼的飯碗)

  8. RDB儲存時間調整,儲存規則發生變化。

  9. 命令新增和變動

Redis服務與客戶端日常操作

redis.conf配置檔案,改完後確保生效,記得重啟

  1. 後臺啟動:預設daemonize no 改為 daemonize yes

  2. 關閉保護模式:預設protected-mode yes 改為 protected-mode no

  3. 註釋掉bind 127.0.0.1 直接註釋掉這行(預設bind 127.0.0.1只能本機訪問)或改成本機IP地址,否則影響遠端IP連線

  4. 新增redis密碼:開啟註釋並把requirepass foobared 改為 requirepass + 你自己設定的密碼

指定配置檔案並啟動服務:redis-server /myredis/redis7.conf

檢視一下是否啟動成功:ps -ef |grep redis|grep -v grep

連線客戶端 redis-cli -a 111111 -p 6379

Linux中關閉redis服務

  • 單例項關閉

redis-cli -a 111111 shutdown

  • 多例項關閉指定埠

redis-cli -p 6379 shutdown

redis客戶端中關閉redis服務

直接 shutdown

Redis十大資料型別

這裡說的資料型別都是指value,key的資料型別都是字串!

image-20231022161309739

Redis鍵(key)的常用命令

  • keys * 檢視當前庫所有的key

  • exists key 判斷某個key是否存在

  • type key 檢視key是什麼資料型別

  • del key 刪除指定key的資料

  • unlink key 非阻塞刪除,僅將keys從keyspace後設資料中刪除,真正的刪除會在後續非同步中操作

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

  • expire key 為給定的key設定過期時間[EXPIRE-秒;PEXPIRE-毫秒;EXPIREAT-秒(時間戳)]

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

  • select dbindex 切換資料庫[0-15],預設為0

  • dbsize 檢視當前資料庫key的數量

  • flushdb 清空當前庫

  • flushall 通殺全部庫

各型別常用命令

  • Redis命令是不區分大小寫的,而key是區分大小寫的

  • 永遠的幫助命令help @型別 help@string help@list .....

String

最常用

GET key

 

SET key value [NX | XX] [GET] [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]

可選引數

  • NX:鍵不存在時設定

  • XX:鍵存在的時候設定

  • GET :返回指定鍵原本的值,若不存在時返回nil

  • EX:以秒為單位設定過期時間

  • PX:以毫秒為單位設定過期時間

  • EXAT:設定以秒為單位的UNIX時間戳所對應的時間為過期時間

  • PXAT:設定以毫秒為單位的UNIX時間戳所對應的時間為過期時間

  • KEEPTTL:保留設定前指定鍵的過期時間

    SET命令使用EX、PX、NX引數的效果等同於SETEX、PSETEX、SETNX命令(根據官方文件描述,未來版本中SETEX、PSETEX、SETNX命令可能會被淘汰)

返回值

OK:設定成功;

nil:未執行SET命令,如不滿足NX、XX條件等。

若使用GET引數,則返回該鍵原來的值,或在鍵不存在時返回nil。

如何獲得設定指定的Key過期的Unix時間,單位為秒

System.out.println(Long.toString(System.currentTimeMillis()/1000L));

 

同時設定/獲取多個鍵值

MSET key value [k1 v1 k2 v2 k3 v3 .....]

MGET key [k1 k2 k3 ......]

MSETNX key value [k1 v1 k2 v2 k3 v3 ......]

注意:msetnx中但凡有一個key是存在的,那麼整個msetnx將不會執行(返回0)

 

設定/獲取指定區間範圍內的值

setrange/getrange

getrange:類似 between...and 的關係

image-20231022181422065

0到-1表示全部

setrange:設定指定偏移位置的值

image-20231022181608981

數值增減(一定要是數字才能加減)

INCR key 遞增數值

INCRBY key increment 增加指定的整數

DECR key 遞減數值

DECRBY key decrement 減少指定的整數

 

獲得字串長度和追加

STRLEN key 獲取字串長度

APPEND key value 追加字串

 

分散式鎖

set key value [EX seconds][PX milliseconds] [NX|XX]

image-20231022182453425

 

getset(先get再set)

getset 將給定key的值設為value,並返回 key 的舊value

image-20231022182710438

 

list

一個雙端連結串列的結構,容量是n的32次方減1,大概40多億,主要功能有push/pop等,一般用在棧、佇列、訊息佇列等場景。

left、right都可以插入新增;

如果鍵不存在,建立新的連結串列;

如果鍵已存在,新增內容;

如果值全移除,對應的鍵也就消失了。

它的底層實際上是個雙向連結串列,對兩端的操作效能很高,透過索引下標的操作中間的節點效能會較差。

image-20231022191541264

lpush、rpush、lrange()

lpush:先進後出

rpush:先進先出

lrange:遍歷

image-20231022192200201

image-20231022192229308

image-20231022192250458

lpop、rpop

lpop:彈出第一個元素

rpop:彈出最後一個元素

image-20231022192521498

lindex

按照下標獲得元素

image-20231023230341033

llen

獲取list中元素個數

image-20231023230518663

Irem key count element

刪除count個element元素

image-20231025215739197

ltrim key start stop

擷取指定範圍的值後再賦給key

image-20231025220100282

rpoplpush 源列表 目的列表

把源列表中的最後一個元素放到目的列表的第一個元素位置

image-20231025221052244

lset key index value

給list中的指定索引設定一個新的value

image-20231025221622065

linsert key before/after 已有值 新的值

在已有值前面/後面插入一個新的值

image-20231025221941356

應用場景:

命令場景
lpush likearticle:userid 微信關注的公眾號只要釋出了新文章,就會放進我的list中
lrange likearticle:userid 0 9 檢視我訂閱的全部文章,類似分頁,下面0-9就是一次顯示10條

 

hash

類似於Map<String,Map<Object,Object>>,String是key;Map<Object,Object>是value

HSET / HGET

設定/獲取

image-20231025225218250

HMSET / HMGET

設定/批次獲取欄位(目前版本hset與hmset作用完全相同

image-20231025225258734

HGETALL

獲取指定hash的所有欄位

HDEL

刪除指定hash的指定欄位

HLEN

獲取某個key內的全部數量

image-20231025225607613

HEXISTS key field

key中是否存在field欄位

HKEY /HVALS key

得到key中所有的鍵/值

HINCRBY key field increment(整數)

key中的field欄位增加一個整數

HINCRBYFLOAT key field increment(小數)

key中的field欄位增加一個小數

HSETNX

新增欄位,若未存在新增成功;已存在,新增失敗。

image-20231026233546996

應用場景:購物車

 

set

無序、不可重複的集合

SADD key member[member...]

新增元素

image-20231026234642508

SMEMBERS key

遍歷集合中所有元素

SISMEMBER key member[member...]

判斷元素是否在集合中

image-20231026234804318

SREM key member [member....]

刪除元素

image-20231026234923545

SCARD key

獲取集合裡的元素個數

srandmember key

 

SRANDMEMBER key [count]

從集合中隨機展現出count個元素(元素不刪除)

image-20231026235230165

 

SPOP key [count]

從集合中隨機彈出count個元素,彈一個刪一個

 

SMOVE key1 key2 member

把key1中的member元素移動到key2

image-20231026235830989

集合運算

SDIFF key1 key2

差集 ,屬於key1集合但不屬於key2集合的元素構成的集合(key1-key2)

image-20231028114032952

SUNION key1 key2

並集,屬於key1集合或者屬於key2集合的元素合併後的集合(A ∪ B)

image-20231028114237862

SINTER key1 key2

交集,屬於key1集合同時也屬於key2集合的共同擁有的元素構成的集合

image-20231028114348913

SINTERCARD numkeys key [key...] [LIMIT limit]

返回結果集的基數。返回由所有給定集合的交集產生的集合的基數

image-20231028115708899

應用場景:

微信抽獎小程式

image-20231028120348081

命令場景
SADD key userid 使用者ID,立即參與按鈕
SCARD key 顯示已經有多少人參與了,上圖23208人參加
SRANDMEMBER key2 隨機抽獎2個人,元素不刪除
SPOP key 3 隨機抽獎3個人,元素會刪除

微信朋友圈點贊檢視同贊朋友

命令場景
sadd pub:msgID 點贊使用者ID1 點贊使用者ID2 新增點贊
srem pub:msgID 點贊使用者ID 取消點贊
SMEMBERS pub:msgID 展現所有點贊過的使用者
scard pub:msgID 點贊使用者數統計,就是常見的點贊紅色數字
SISMEMBER pub:msgID 使用者ID 判斷某個朋友是否對樓主點贊過

QQ推送可能認識的人

SDIFF user1 user2

zset

在set基礎上,每個val值前加一個score分數值;

set是 key v1 v2 v3...

zset是 key score1 v1 score2 v2 score3 v3

 

ZADD key score member[score member]

新增元素

image-20231028130311472

ZRANGE key start stop [WITHSCORES]

按照元素分數從小到大的順序,返回索引從start到stop之間的所有元素(0 ,-1 代表全部)

加上WITHSCORES 表示帶上分數

image-20231028130534413

image-20231028130647075

ZREVRANGE

按照元素分數從大到小的順序,返回索引從start到stop之間的所有元素(0 ,-1 代表全部)

加上WITHSCORES 表示帶上分數

image-20231028131014790

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

獲取指定分數範圍的元素;

加上(:不包含

LIMIT作用是限制返回 limit 開始下標步 多少步

image-20231028131740415

image-20231028132108155

ZSCORE key member

獲取元素的分數

 

ZCARD KEY

獲取集合中元素的數量

 

ZREM key member [member...]

刪除元素

image-20231028135104336

ZINCRBY key increment member

增加某個元素的分數

image-20231028220506251

ZCOUNT key min max

獲得指定分數範圍內的元素個數

image-20231028220859328

ZMPOP numkeys key [key...] MIN/MAX [COUNT count]

從鍵名列表中的第一個非空排序集中彈出一個或多個元素,他們是成員分數對

image-20231028222306510

image-20231028222556412

ZRANK key member

獲得指定元素的下標值

image-20231028222955575

ZREVRANK key member

逆序獲得下標值

image-20231028223407093

應用場景:

思路:定義商品銷售排行榜(soreted set集合),key 為 goods:sellsort,分數為商品銷售數量

商品編號1001的銷量是9,商品編號1002的銷量是15, zadd goods:sellsort 9 1001 15 1002

有一個客戶又買了2件商品1001,商品編號1001銷量加2 zindrby goods:sellsort 2 1001

求商品銷量前10名 zrange goods:sellsort 0 9 withscores

 

bitmap(點陣圖)

說明:用String型別作為底層資料結構實現的一種統計二值狀態的資料型別

點陣圖本質是陣列,它是基於String資料型別的按位的操作。該陣列由多個二進位制位組成,每個二進位制位都對應一個偏移量(我們稱之為一個索引)。

Bitmap支援的最大位數是23位,它可以極大的節約儲存空間,使用512M記憶體就可以儲存多達42.9億的位元組資訊(232 = 4294967296)

概述:由0和1狀態表現的二進位制位的bit陣列

透過需求理解其作用:

  • 使用者是否登入過,比如京東每日簽到領京豆

  • 電影、廣告是否被點選過

  • 釘釘打卡上下班、簽到統計

  • .......

image-20231029150133981

 

SETBIT key offset value

setbit 鍵 值(只能0/1)

bitmap的偏移量是從0開始算的

 

GETBIT key offset

獲取點陣圖的值

image-20231029150723937

 

STRLEN key

獲取點陣圖佔用的位元組數,不是根據字串長度計算的!凡是超過8位(0-7)後都是按照8位一組(1 byte)再擴容的!

image-20231029151437751

 

BITCOUNT key

當前點陣圖中含有1的有多少

image-20231029151731397

BITOP operation destkey key [key...]

operation:AND / OR / NOT / XOR

案例一:

某個網站的使用者有1000萬,做個使用者id和位置的對映

0號位對應使用者id:uid:055d-ddf

1號位對應使用者id:uid:dfd5-05d

......

簽到了代表1,沒簽到代表0

image-20231029154526554

 

1號簽到人數:4

2號簽到人數:2

image-20231029154612059

 

連續兩天都完成簽到的使用者有2個

image-20231029154425288

 

案例二:

sign:u1:202401 表示u1使用者2024年1月簽到資訊

image-20231029160053494

檢視該使用者3號和31號是否簽到:

image-20231029160246877

檢視該使用者2024年1月總計簽到的天數:

image-20231029160334901

 

一年365天,全年天天簽到佔用多少位元組?46

image-20231029160546616

按年去儲存一個使用者的簽到情況,365 天只需要 365 / 8 ≈ 46 Byte,1000W 使用者量一年也只需要 44 MB 就足夠了。

假如是億級的系統,

每天使用1個1億位的Bitmap約佔12MB的記憶體(108/8/1024/1024),10天的Bitmap的記憶體開銷約為120MB,記憶體壓力不算太高。

此外,在實際使用時,最好對Bitmap設定過期時間,讓Redis自動刪除不再需要的簽到記錄以節省記憶體開銷。

 

HyperLogLog(基數統計)

看需求:

統計某個網站、文章的的UV(Unique Visitor)、一般理解為客戶端IP,需要去重的。

使用者搜尋網站關鍵詞的數量;統計使用者每天搜尋不同詞條的個數

HyperLogLog是用來做基數統計的演算法,HyperLogLog的優點是在輸入元素的數量或者體積非常非常大時,計算基數所需空間總是固定的、很小的。

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

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

案例Case:

全集 I = {2,4,6,8,11,22,44,4,8,10} 去掉重複的內容後: 基數 = {2,4,6,8,11,22,44,10} = 8

基數統計:用於統計一個集合中不重複的元素個數,就是對集合去重複後剩餘元素的計算

總結:去重脫水後的真實資料

PFADD key element [element...]

新增指定元素到 HyperLogLog 中

PFCOUNT key [key...]

返回給定HyperLogLog 的基數估算值。

PFMERGE destkey sourcekey [sourcekey...]

將多個HyperLogLog合併為一個HyperLogLog

image-20231029163803081

 

GEO(地理空間)

移動網際網路時代LBS(Location Based Service)應用越來越多,交友軟體中附近的人、外賣軟體中附近的美食店鋪、高德地圖附近的核酸檢查點等等,那這種附近各種形形色色的XXX地址位置選擇是如何實現的?

 

地球上的地理位置是使用二維的經緯度表示,經度範圍 (-180, 180],緯度範圍 (-90, 90],只要我們確定一個點的經緯度就可以名取得他在地球的位置。

例如滴滴叫車,最直觀的操作就是實時記錄更新各個車的位置,然後當我們要找車時,在資料庫中查詢距離我們(座標x0,y0)附近r公里範圍內部的車輛

 

使用如下偽SQL即可:

select taxi from position where x0-r < x < x0+r and y0-r < y < y0+r

但是這樣會有什麼問題呢?

1.查詢效能問題,如果併發高,資料量大這種查詢是要搞垮資料庫的

2.這個查詢的是一個矩形訪問,而不是以我為中心r公里為半徑的圓形訪問。

3.精準度的問題,我們知道地球不是平面座標系,而是一個圓球,這種矩形計算在長距離計算時會有很大誤差

核心思想就是將球體轉換為平面,將平面中每一個區塊轉換為一點

image-20231029171405926

主要分為三步:

  1. 將三維的地球變為二維的座標

  2. 再將二維的座標轉換為一維的點塊

  3. 最後將一維的點塊轉換為二進位制再透過base32編碼

 

image-20231029173735244

GEOADD key longitude latitude member [longitude latitude member ...]

geoadd用於儲存指定的地理空間位置,可以將一個或多個經緯度和該經緯度的位置名稱新增到指定key中

longitude :經度

latitude:緯度

member:位置名稱

 

GEOPOS key member [member ...]

用於從給定的key裡返回所有指定名稱(member)的經緯度,不存在的返回null

 

解決中文亂碼

--raw

image-20231029174352653

 

GEOHASH key member [member ...]

返回座標的geohash表示

 

GEODIST key member1 member2 [M|KM|FT|MI]

兩個位置之間的距離;m 米 km 千米 ft 英尺 mi 英里

 

GEORADIUS key longitude latitude radius M|KM|FT|MI [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC|DESC] [STORE key] [STOREDIST key]

以給定的經緯度為中心,返回鍵包含的位置元素當中,與中心的距離不超過給定最大距離的所有位置元素

當前位置:116.418017 39.914402

image-20231029174419780

WITHDIST: 在返回位置元素的同時, 將位置元素與中心之間的距離也一併返回。 距離的單位和使用者給定的範圍單位保持一致。

WITHCOORD: 將位置元素的經度和維度也一併返回。

WITHHASH: 以 52 位有符號整數的形式, 返回位置元素經過原始 geohash 編碼的有序集合分值。 這個選項主要用於底層應用或者除錯, 實際中的作用並不大

COUNT 限定返回的記錄數。

 

GEORADIUSBYMEMBER key member

根據位置名稱找出位於指定範圍內的元素,與GEORADIUS 類似

image-20231029175201419

 

 

Stream

Redis5之前的痛點:

Redis訊息佇列的2種方案:

  1. List實現訊息佇列

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

所以常用來做非同步佇列使用,將需要延後處理的任務結構體序列化成字串塞進 Redis 的列表,另一個執行緒從這個列表中輪詢資料進行處理。

List實現方式其實就是點對點的方式,它對於一對多的情況力不從心。

image-20231029180351772

LPUSH、RPOP 左進右出 RPUSH、LPOP 右進左出

image-20231029180517267

  1. 釋出訂閱(Pub/Sub)

Redis釋出訂閱有個缺點就是訊息無法持久化,如果出現網路斷開、Redis 當機等,訊息就會被丟棄。而且也沒有 Ack 機制來保證資料的可靠性,假設一個消費者都沒有,那訊息就直接被丟棄了。

image-20231029180933945

Redis 5.0版本新增了一個更強大的資料結構-----Stream -> 一句話:Redis版的MQ訊息中介軟體+阻塞佇列

Stream 能幹嘛

實現訊息佇列,它支援訊息持久化、支援自動生成全域性唯一ID、支援ack確認訊息的模式、支援消費組模式等,讓訊息佇列更加穩定和可靠

Stream的結構

image-20231029181711012

一個訊息連結串列,將所有加入的訊息都串起來,每個訊息都有一個唯一的ID和對應的內容。

名詞解釋
Message Content 訊息內容
Consumer group 消費組,透過XGROUP CREATE 命令建立,同一個消費組可以有多個消費者
Last_delivered_id 遊標,每個消費組會有個遊標 last_delivered_id,任意一個消費者讀取了訊息都會使遊標 last_delivered_id 往前移動。
Consumer 消費者,消費組中的消費者
Pending_ids 消費者會有一個狀態變數,用於記錄被當前消費已讀取但未ack的訊息Id,如果客戶端沒有ack,這個變數裡面的訊息ID會越來越多,一旦某個訊息被ack它就開始減少。這個pending_ids變數在Redis官方被稱之為 PEL(Pending Entries List),記錄了當前已經被客戶端讀取的訊息,但是還沒有 ack (Acknowledge character:確認字元),它用來確保客戶端至少消費了訊息一次,而不會在網路傳輸的中途丟失了沒處理

特殊符號:

符號解釋
- + 最小和最大可能出現的id
$ $表示只消費新的訊息,當前流中最大的id,可用於將要到來的訊息
> 用於XREADGROUP命令,表示迄今為止還沒有傳送給組中使用者的訊息,會更新消費者組的最後ID
* 用於XADD命令中,讓系統自動生成id

佇列相關指令:

XADD

XADD 用於向Stream 佇列中新增訊息,如果指定的Stream 佇列不存在,則該命令執行時會新建一個Stream 佇列

* 號表示伺服器自動生成 MessageID(類似mysql裡面主鍵auto_increment),後面順序跟著一堆 業務key/value

image-20231029184128275

image-20231029183819187

  1. 資訊條目指的是序列號,在相同的毫秒下序列號從0開始遞增,序列號是64位長度,理論上在同一毫秒內生成的資料量無法到達這個級別,因此不用擔心序列號會不夠用。millisecondsTime指的是Redis節點伺服器的本地時間,如果存在當前的毫秒時間戳比以前已經存在的資料的時間戳小的話(本地時間鍾後跳),那麼系統將會採用以前相同的毫秒建立新的ID,也即redis 在增加資訊條目時會檢查當前 id 與上一條目的 id, 自動糾正錯誤的情況,一定要保證後面的 id 比前面大,一個流中資訊條目的ID必須是單調增的,這是流的基礎。

  2. 客戶端顯示傳入規則:Redis對於ID有強制要求,格式必須是時間戳-自增Id這樣的方式,且後續ID不能小於前一個ID

  3. Stream的訊息內容,也就是圖中的Message Content它的結構類似Hash結構,以key-value的形式存在。

 

XRANGE

遍歷

image-20231029184355740

 

XREVRANGE

反轉遍歷

image-20231029184804484

 

XDEL

刪除

image-20231029185237918

XLEN

獲取Stream佇列的訊息的長度

image-20231029192046918

 

XTRIM key MAXLEN| MINID [LIMIT count]

用於對Stream的長度進行擷取

MAXLEN:允許的最大長度,對流進行修剪限制長度

MINID:允許的最小id,從某個id值開始比該id值小的將會被拋棄

MAXLEN

image-20231029192650891

擷取後:

image-20231029192707800

 

MINID

image-20231029193103660

XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key...] id [id...]

用於獲取訊息(阻塞/非阻塞),只會返回大於指定id的訊息

COUNT 最多讀取多少條訊息

BLOCK 是否以阻塞的方式讀取訊息,預設不阻塞,如果 milliseconds設定為0,表示永遠阻塞。

  • $代表特殊ID,表示以當前Stream已經儲存的最大的ID作為最後一個ID,當前Stream中不存在大於當前最大ID的訊息,因此此時返回nil

  • 0-0代表從最小的ID開始獲取Stream中的訊息,當不指定count,將會返回Stream中的所有訊息,注意也可以使用0(00/000也都是可以的……)

非阻塞式:

image-20231029203115867

阻塞式:

案例需要兩個Redis客戶端

第一個客戶端輸入阻塞獲取訊息的指令,此時客戶端進入阻塞狀態

image-20231029204856530

直到第二個客戶端執行完成新增訊息指令,第一個客戶端才可獲取到訊息從而退出阻塞狀態

image-20231029205234891

image-20231029205417497

Stream的基礎方法,使用xadd存入訊息和xread迴圈阻塞讀取訊息的方式可以實現簡易版的訊息佇列,互動流程如下

image-20231029205500753

對比List結構

image-20231029205534231

 

 

消費組相關指令:

XGROUP CREATE key groupname

建立消費組

$表示從Stream尾部開始消費

0表示從Stream頭部開始消費

建立消費者組的時候必須指定 ID, ID 為 0 表示從頭開始消費,為 $ 表示只消費新的訊息,隊尾新來

image-20231029213729977

XREADGROUP GROUP

讀取訊息

“>” 表示從第一條尚未被消費的訊息開始讀取

消費組groupA內的消費者

stream中的訊息一旦被消費組裡的一個消費者讀取了,就不能再被同組的其他消費者讀取了,即同一個消費組裡的消費者不能消費同一條訊息:

image-20231029215207248

但是,不同消費組的消費者可以消費同一條訊息:

image-20231029215455282

but,please thinking why we need 消費組?

讓組內的多個消費者共同分擔讀取訊息,所以,我們通常會讓每個消費者讀取部分訊息,從而實現訊息讀取負載在多個消費者間是均衡分佈的

 

image-20231029220222370

image-20231029220244090

 

基於Stream實現的訊息佇列,如何保證消費者在發生故障或當機再次重啟後,仍然可以讀取未處理完的訊息?

  1. Streams 會自動使用內部佇列(也稱為 PENDING List)留存消費組裡每個消費者讀取的訊息保底措施,直到消費者使用 XACK 命令通知 Streams“訊息已經處理完成”。

  2. 消費確認增加了訊息的可靠性,一般在業務處理完成之後,需要執行 XACK 命令確認訊息已經被消費完成

image-20231029221158831

 

XPENDING

查詢每個消費組內所有消費者【已讀取、但尚未確認】的訊息

image-20231029222010789

一旦某條訊息被某個消費者處理了該消費者就可以使用 XACK 命令通知 Streams,然後這條訊息就會被刪除

XACK key group id

向訊息佇列確認訊息處理完成

image-20231029222755716

XINFO STREAM key

用於列印Stream/Consumer/Group的詳細資訊

image-20231029223223064

 

Stream 使用建議:

Stream還是不能100%等價於Kafka、RabbitMQ來使用的,生產案例少,慎用

僅代表本人愚見,非權威!

 

bitfield 位域(瞭解)

bitfield命令可以將一個Redis字串看作是一個由二進位制位組成的陣列,並對這個陣列中任意偏移進行訪問。可以使用命令對一個有符號的5位整型數的第1234位設定指定值,也可以對一個31位無符號整型數的第4567位進行取值。類似地,本命令可以對指定的整數進行自增和自減操作,可配置的上溢和下溢處理操作。

bitfield命令可以在一次呼叫中同時對多個位範圍進行操作:它接受一系列待執行的操作作為引數,並返回一個陣列,陣列中的每個元素就是對應操作的執行結果。

用途:

BITFIELD命令的作用在於它能夠將很多小的整數儲存到一個長度較大的點陣圖中,又或者將一個非常龐大的鍵分割為多個較小的鍵來進行儲存,從而非常高效地使用記憶體,使得Redis能夠得到更多不同的應用——特別是在實時分析領域:BITFIELD能夠以指定的方式對計算溢位進行控制的能力,使得它可以被應用於這一領域。

當需要一個整型時,有符號整型需在位數前加 i,無符號在位數前加 u。例如,u8是一個8位的無符號整型,i16是一個16位的有符號整型。

GET type offset

返回指定的位域

 

image-20231031211942593

image-20231031212014009

hello 等價於 0110100001100101011011000110110001101111;

SET type offset value

設定指定位域的值並返回它的原值

image-20231031213019131

 

溢位控制:

  • WRAP(預設):使用迴繞(wrap around)方法處理有符號整數和無符號整數的溢位情況

  • SAT:使用飽和計算(saturation arithmetic)方法處理溢位,下溢計算的結果為最小的整數值,而上溢計算的結果為最大的整數值。

  • FAIL:命令將拒絕執行那些會導致上溢或者下溢情況出現的計算,並向使用者返回空值表示計算未被執行。

 

INCRBY type offset increment

WRAP

image-20231031231119197

SAT

image-20231031231318584

FAIL

image-20231031231527607

 

十大資料型別結束啦!

 

相關文章