連結redis
方式一:
redis-cli -h 192.168.88.129 -p 6379 -a root
方式二:
redis-cli -h 192.168.88.129 -p 6379
AUTH root
redis通用命令
help @string 檢視幫助
keys * 查詢所有key
MSET k v k1 v1 批次插入
exists 確定一個鍵是否存在
常見
常見命令 | 資訊 |
---|---|
help @string | 檢視幫助 |
keys * | 查詢所有key(*所有 ) |
MSET k v k1 v1 | 批次插入 |
exists name | 確定一個鍵是否存在Determine if a key exists |
EXPIRE | 給一個值設定一個有效期 |
TTL name | 檢視key剩餘有效期 |
1string
string型別常見命令 | 資訊 |
---|---|
set name zhangsan | 設定鍵值(name為鍵,zhangsan為值) |
get name | 透過鍵獲取值 |
MSET k v k1 v1 | 批次插入 |
MSET k1 k2 name | 批次獲取 |
INCR | 讓一個整形的key自增1 |
INCRBY | 讓一個整形的key自增並指定步長 |
INCRBYFLOAT | 讓一個浮點型的數字自增並指定步長 |
SETNX | 新增一個String型別的鍵值對,前提是這個key不存在,否則不執行 |
SETEX | 新增一個String型別的鍵值對,並指定有效期 |
2hash
Hash通用命令 | 資訊 |
---|---|
HSET key field value | 新增或者修改hash型別key的field的值 |
HGET key field | 獲取一個hash型別key的field的值 |
HMSET | 批次新增多個hash型別key的field的值 |
HMGET | 批次獲取多個hash型別key的field的值 |
HGETALL | 獲取一個hash型別的key中的所有的field和value |
HKEYS | 獲取一個hash型別的key中的所有的field |
HINCRBY | 讓一個hash型別key的欄位值自增並指定步長 |
HSETNX | 新增一個hash型別的key的field值,前提是這個field不存在,否則不執行 |
3list
list通用命令 | 資訊 |
---|---|
LPUSH key element ... | 向列表左側插入一個或多個元素 |
LPOP key | 移除並返回列表左側的第一個元素,沒有則返回nil |
RPUSH key element ... | 向列表右側插入一個或多個元素 |
RPOP key | 移除並返回列表右側的第一個元素 |
LRANGE key star end | 返回一段角標範圍內的所有元素 |
BLPOP和BRPOP | 與LPOP和RPOP類似,只不過在沒有元素時等待指定時間,而不是直接返回nil |
4set
set通用命令 | 資訊 |
---|---|
SADD key member ... | 向set中新增一個或多個元素 |
SREM key member ... | 移除set中的指定元素 |
SCARD key | 返回set中元素的個數 |
SISMEMBER key member | 判斷一個元素是否存在於set中 |
SMEMBERS | 獲取set中的所有元素 |
SINTER key1 key2 ... | 求key1與key2的交集 |
SDIFF key1 key2 ... | 求key1與key2的差集 |
SUNION key1 key2 .. | 求key1和key2的並集 |
5SortedSet
SortedSet通用命令 | 資訊 |
---|---|
ZADD key score member | 新增一個或多個元素到sorted set ,如果已經存在則更新其score值 |
ZREM key member | 刪除sorted set中的一個指定元素 |
ZSCORE key member | 獲取sorted set中的指定元素的score值 |
ZRANK key member | 獲取sorted set 中的指定元素的排名 |
ZCARD key | 獲取sorted set中的元素個數 |
ZCOUNT key min max | 統計score值在給定範圍內的所有元素的個數 |
ZINCRBY key increment member | 讓sorted set中的指定元素自增,步長為指定的increment值 |
ZRANGE key min max | 按照score排序後,獲取指定排名範圍內的元素 |
ZRANGEBYSCORE key min max | 按照score排序後,獲取指定score範圍內的元素 |
ZDIFF.ZINTER.ZUNION | 求差集.交集.並集 |
- 升序獲取sorted set 中的指定元素的排名:ZRANK key member
- 降序獲取sorted set 中的指定元素的排名:ZREVRANK key memeber
stream
6stream
7.4 Redis訊息佇列-基於Stream的訊息佇列
Stream 是 Redis 5.0 引入的一種新資料型別,可以實現一個功能非常完善的訊息佇列。
傳送訊息的命令:
例如:
讀取訊息的方式之一:XREAD
例如,使用XREAD讀取第一個訊息:
XREAD阻塞方式,讀取最新的訊息:
在業務開發中,我們可以迴圈的呼叫XREAD阻塞方式來查詢最新訊息,從而實現持續監聽佇列的效果,虛擬碼如下
注意:當我們指定起始ID為$時,代表讀取最新的訊息,如果我們處理一條訊息的過程中,又有超過1條以上的訊息到達佇列,則下次獲取時也只能獲取到最新的一條,會出現漏讀訊息的問題
STREAM型別訊息佇列的XREAD命令特點:
- 訊息可回溯
- 一個訊息可以被多個消費者讀取
- 可以阻塞讀取
- 有訊息漏讀的風險
7.5 Redis訊息佇列-基於Stream的訊息佇列-消費者組
消費者組(Consumer Group):將多個消費者劃分到一個組中,監聽同一個佇列。具備下列特點:
建立消費者組:
key:佇列名稱
groupName:消費者組名稱
ID:起始ID標示,$代表佇列中最後一個訊息,0則代表佇列中第一個訊息
MKSTREAM:佇列不存在時自動建立佇列
其它常見命令:
刪除指定的消費者組
XGROUP DESTORY key groupName
給指定的消費者組新增消費者
XGROUP CREATECONSUMER key groupname consumername
刪除消費者組中的指定消費者
XGROUP DELCONSUMER key groupname consumername
從消費者組讀取訊息:
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
- group:消費組名稱
- consumer:消費者名稱,如果消費者不存在,會自動建立一個消費者
- count:本次查詢的最大數量
- BLOCK milliseconds:當沒有訊息時最長等待時間
- NOACK:無需手動ACK,獲取到訊息後自動確認
- STREAMS key:指定佇列名稱
- ID:獲取訊息的起始ID:
">":從下一個未消費的訊息開始
其它:根據指定id從pending-list中獲取已消費但未確認的訊息,例如0,是從pending-list中的第一個訊息開始
消費者監聽訊息的基本思路:
STREAM型別訊息佇列的XREADGROUP命令特點:
- 訊息可回溯
- 可以多消費者爭搶訊息,加快消費速度
- 可以阻塞讀取
- 沒有訊息漏讀的風險
- 有訊息確認機制,保證訊息至少被消費一次
最後我們來個小對比
7.1 Redis訊息佇列-認識訊息佇列
什麼是訊息佇列:字面意思就是存放訊息的佇列。最簡單的訊息佇列模型包括3個角色:
- 訊息佇列:儲存和管理訊息,也被稱為訊息代理(Message Broker)
- 生產者:傳送訊息到訊息佇列
- 消費者:從訊息佇列獲取訊息並處理訊息
使用佇列的好處在於 解耦:所謂解耦,舉一個生活中的例子就是:快遞員(生產者)把快遞放到快遞櫃裡邊(Message Queue)去,我們(消費者)從快遞櫃裡邊去拿東西,這就是一個非同步,如果耦合,那麼這個快遞員相當於直接把快遞交給你,這事固然好,但是萬一你不在家,那麼快遞員就會一直等你,這就浪費了快遞員的時間,所以這種思想在我們日常開發中,是非常有必要的。
這種場景在我們秒殺中就變成了:我們下單之後,利用redis去進行校驗下單條件,再透過佇列把訊息傳送出去,然後再啟動一個執行緒去消費這個訊息,完成解耦,同時也加快我們的響應速度。
這裡我們可以使用一些現成的mq,比如kafka,rabbitmq等等,但是呢,如果沒有安裝mq,我們也可以直接使用redis提供的mq方案,降低我們的部署和學習成本。
7.2 Redis訊息佇列-基於List實現訊息佇列
基於List結構模擬訊息佇列
訊息佇列(Message Queue),字面意思就是存放訊息的佇列。而Redis的list資料結構是一個雙向連結串列,很容易模擬出佇列效果。
佇列是入口和出口不在一邊,因此我們可以利用:LPUSH 結合 RPOP、或者 RPUSH 結合 LPOP來實現。
不過要注意的是,當佇列中沒有訊息時RPOP或LPOP操作會返回null,並不像JVM的阻塞佇列那樣會阻塞並等待訊息。因此這裡應該使用BRPOP或者BLPOP來實現阻塞效果。
基於List的訊息佇列有哪些優缺點?
優點:
- 利用Redis儲存,不受限於JVM記憶體上限
- 基於Redis的持久化機制,資料安全性有保證
- 可以滿足訊息有序性
缺點:
- 無法避免訊息丟失
- 只支援單消費者
7.3 Redis訊息佇列-基於PubSub的訊息佇列
PubSub(釋出訂閱)是Redis2.0版本引入的訊息傳遞模型。顧名思義,消費者可以訂閱一個或多個channel,生產者向對應channel傳送訊息後,所有訂閱者都能收到相關訊息。
SUBSCRIBE channel [channel] :訂閱一個或多個頻道
PUBLISH channel msg :向一個頻道傳送訊息
PSUBSCRIBE pattern[pattern] :訂閱與pattern格式匹配的所有頻道
基於PubSub的訊息佇列有哪些優缺點?
優點:
- 採用釋出訂閱模型,支援多生產、多消費
缺點:
- 不支援資料持久化
- 無法避免訊息丟失
- 訊息堆積有上限,超出時資料丟失
7geo
GEO就是Geolocation的簡寫形式,代表地理座標。Redis在3.2版本中加入了對GEO的支援,允許儲存地理座標資訊,幫助我們根據經緯度來檢索資料。常見的命令有:
- GEOADD:新增一個地理空間資訊,包含:經度(longitude)、緯度(latitude)、值(member)
- GEODIST:計算指定的兩個點之間的距離並返回
- GEOHASH:將指定member的座標轉為hash字串形式並返回
- GEOPOS:返回指定member的座標
- GEORADIUS:指定圓心、半徑,找到該圓內包含的所有member,並按照與圓心之間的距離排序後返回。6.以後已廢棄
- GEOSEARCH:在指定範圍內搜尋member,並按照與指定點之間的距離排序後返回。範圍可以是圓形或矩形。6.2.新功能
- GEOSEARCHSTORE:與GEOSEARCH功能一致,不過可以把結果儲存到一個指定的key。 6.2.新功能
8BitMap
使用者一次簽到,就是一條記錄,假如有1000萬使用者,平均每人每年簽到次數為10次,則這張表一年的資料量為 1億條
每簽到一次需要使用(8 + 8 + 1 + 1 + 3 + 1)共22 位元組的記憶體,一個月則最多需要600多位元組
我們如何能夠簡化一點呢?其實可以考慮小時候一個挺常見的方案,就是小時候,咱們準備一張小小的卡片,你只要簽到就打上一個勾,我最後判斷你是否簽到,其實只需要到小卡片上看一看就知道了
我們可以採用類似這樣的方案來實現我們的簽到需求。
我們按月來統計使用者簽到資訊,簽到記錄為1,未簽到則記錄為0.
把每一個bit位對應當月的每一天,形成了對映關係。用0和1標示業務狀態,這種思路就稱為點陣圖(BitMap)。這樣我們就用極小的空間,來實現了大量資料的表示
Redis中是利用string型別資料結構實現BitMap,因此最大上限是512M,轉換為bit則是 2^32個bit位。
BitMap的操作命令有:
- SETBIT:向指定位置(offset)存入一個0或1
- GETBIT :獲取指定位置(offset)的bit值
- BITCOUNT :統計BitMap中值為1的bit位的數量
- BITFIELD :操作(查詢、修改、自增)BitMap中bit陣列中的指定位置(offset)的值
- BITFIELD_RO :獲取BitMap中bit陣列,並以十進位制形式返回
- BITOP :將多個BitMap的結果做位運算(與 、或、異或)
- BITPOS :查詢bit陣列中指定範圍內第一個0或1出現的位置