Redis是基於記憶體的K-V鍵值對記憶體資料庫 淺談Redis7新特性 主要是自身底層性能和資源利用率上的提高和優化。 多AOF文件支持 config命令增強 限制客戶端記憶體使用 listpack緊湊列表調整 訪問安全性增強 Redis Functions(要搶Lua腳本的飯碗) RDB保存時間調整, ...
淺談Redis7新特性
-
主要是自身底層性能和資源利用率上的提高和優化。
-
多AOF文件支持
-
config命令增強
-
限制客戶端記憶體使用
-
listpack緊湊列表調整
-
訪問安全性增強
-
Redis Functions(要搶Lua腳本的飯碗)
-
RDB保存時間調整,保存規則發生變化。
-
命令新增和變動
Redis服務與客戶端日常操作
redis.conf配置文件,改完後確保生效,記得重啟
-
後臺啟動:預設daemonize no 改為
daemonize yes
-
關閉保護模式:預設protected-mode yes 改為
protected-mode no
-
註釋掉
bind 127.0.0.1
直接註釋掉這行(預設bind 127.0.0.1只能本機訪問)或改成本機IP地址,否則影響遠程IP連接 -
添加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的數據類型都是字元串!
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 的關係
0到-1表示全部
setrange
:設置指定偏移位置的值
數值增減(一定要是數字才能加減)
INCR key
遞增數值
INCRBY key increment
增加指定的整數
DECR key
遞減數值
DECRBY key decrement
減少指定的整數
獲得字元串長度和追加
STRLEN key
獲取字元串長度
APPEND key value
追加字元串
分散式鎖
set key value [EX seconds][PX milliseconds] [NX|XX]
getset(先get再set)
getset 將給定key的值設為value,並返回 key 的舊value
list
一個雙端鏈表的結構,容量是n的32次方減1,大概40多億,主要功能有push/pop等,一般用在棧、隊列、消息隊列等場景。
left、right都可以插入添加;
如果鍵不存在,創建新的鏈表;
如果鍵已存在,新增內容;
如果值全移除,對應的鍵也就消失了。
它的底層實際上是個雙向鏈表,對兩端的操作性能很高,通過索引下標的操作中間的節點性能會較差。
lpush、rpush、lrange()
lpush
:先進後出
rpush
:先進先出
lrange
:遍歷
lpop、rpop
lpop
:彈出第一個元素
rpop
:彈出最後一個元素
lindex
按照下標獲得元素
llen
獲取list中元素個數
Irem key count element
刪除count個element元素
ltrim key start stop
截取指定範圍的值後再賦給key
rpoplpush 源列表 目的列表
把源列表中的最後一個元素放到目的列表的第一個元素位置
lset key index value
給list中的指定索引設置一個新的value
linsert key before/after 已有值 新的值
在已有值前面/後面插入一個新的值
應用場景:
命令 | 場景 |
---|---|
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
設置/獲取
HMSET / HMGET
設置/批量獲取欄位(目前版本hset與hmset作用完全相同)
HGETALL
獲取指定hash的所有欄位
HDEL
刪除指定hash的指定欄位
HLEN
獲取某個key內的全部數量
HEXISTS key field
key中是否存在field欄位
HKEY /HVALS key
得到key中所有的鍵/值
HINCRBY key field increment(整數)
key中的field欄位增加一個整數
HINCRBYFLOAT key field increment(小數)
key中的field欄位增加一個小數
HSETNX
添加欄位,若未存在添加成功;已存在,添加失敗。
應用場景:購物車
set
無序、不可重覆的集合
SADD key member[member...]
添加元素
SMEMBERS key
遍歷集合中所有元素
SISMEMBER key member[member...]
判斷元素是否在集合中
SREM key member [member....]
刪除元素
SCARD key
獲取集合里的元素個數
srandmember key
SRANDMEMBER key [count]
從集合中隨機展現出count個元素(元素不刪除)
SPOP key [count]
從集合中隨機彈出count個元素,彈一個刪一個
SMOVE key1 key2 member
把key1中的member元素移動到key2
集合運算
SDIFF key1 key2
差集 ,屬於key1集合但不屬於key2集合的元素構成的集合(key1-key2)
SUNION key1 key2
並集,屬於key1集合或者屬於key2集合的元素合併後的集合(A ∪ B)
SINTER key1 key2
交集,屬於key1集合同時也屬於key2集合的共同擁有的元素構成的集合
SINTERCARD numkeys key [key...] [LIMIT limit]
返回結果集的基數。返回由所有給定集合的交集產生的集合的基數
應用場景:
微信抽獎小程式
命令 | 場景 |
---|---|
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]
添加元素
ZRANGE key start stop [WITHSCORES]
按照元素分數從小到大的順序,返回索引從start到stop之間的所有元素(0 ,-1 代表全部)
加上WITHSCORES 表示帶上分數
ZREVRANGE
按照元素分數從大到小的順序,返回索引從start到stop之間的所有元素(0 ,-1 代表全部)
加上WITHSCORES 表示帶上分數
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
獲取指定分數範圍的元素;
加上(
:不包含
LIMIT作用是限制返回 limit 開始下標步 多少步
ZSCORE key member
獲取元素的分數
ZCARD KEY
獲取集合中元素的數量
ZREM key member [member...]
刪除元素
ZINCRBY key increment member
增加某個元素的分數
ZCOUNT key min max
獲得指定分數範圍內的元素個數
ZMPOP numkeys key [key...] MIN/MAX [COUNT count]
從鍵名列表中的第一個非空排序集中彈出一個或多個元素,他們是成員分數對
ZRANK key member
獲得指定元素的下標值
ZREVRANK key member
逆序獲得下標值
應用場景:
思路:定義商品銷售排行榜(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數組
通過需求理解其作用:
-
用戶是否登錄過,比如京東每日簽到領京豆
-
電影、廣告是否被點擊過
-
釘釘打卡上下班、簽到統計
-
.......
SETBIT key offset value
setbit 鍵 值(只能0/1)
bitmap的偏移量是從0開始算的
GETBIT key offset
獲取點陣圖的值
STRLEN key
獲取點陣圖占用的位元組數,不是根據字元串長度計算的!凡是超過8位(0-7)後都是按照8位一組(1 byte)再擴容的!
BITCOUNT key
當前點陣圖中含有1的有多少
BITOP operation destkey key [key...]
operation:AND / OR / NOT / XOR
案例一:
某個網站的用戶有1000萬,做個用戶id和位置的映射
0號位對應用戶id:uid:055d-ddf
1號位對應用戶id:uid:dfd5-05d
......
簽到了代表1,沒簽到代表0
1號簽到人數:4
2號簽到人數:2
連續兩天都完成簽到的用戶有2個
案例二:
sign:u1:202401 表示u1用戶2024年1月簽到信息
查看該用戶3號和31號是否簽到:
查看該用戶2024年1月總計簽到的天數:
一年365天,全年天天簽到占用多少位元組?46 !
按年去存儲一個用戶的簽到情況,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
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.精準度的問題,我們知道地球不是平面坐標系,而是一個圓球,這種矩形計算在長距離計算時會有很大誤差
核心思想就是將球體轉換為平面,將平面中每一個區塊轉換為一點
主要分為三步:
-
將三維的地球變為二維的坐標
-
再將二維的坐標轉換為一維的點塊
-
最後將一維的點塊轉換為二進位再通過base32編碼
GEOADD key longitude latitude member [longitude latitude member ...]
geoadd用於存儲指定的地理空間位置,可以將一個或多個經緯度和該經緯度的位置名稱添加到指定key中
longitude :經度
latitude:緯度
member:位置名稱
GEOPOS key member [member ...]
用於從給定的key里返回所有指定名稱(member)的經緯度,不存在的返回null
解決中文亂碼
--raw
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
WITHDIST: 在返回位置元素的同時, 將位置元素與中心之間的距離也一併返回。 距離的單位和用戶給定的範圍單位保持一致。
WITHCOORD: 將位置元素的經度和維度也一併返回。
WITHHASH: 以 52 位有符號整數的形式, 返回位置元素經過原始 geohash 編碼的有序集合分值。 這個選項主要用於底層應用或者調試, 實際中的作用並不大
COUNT 限定返回的記錄數。
GEORADIUSBYMEMBER key member
根據位置名稱找出位於指定範圍內的元素,與GEORADIUS 類似
Stream
Redis5之前的痛點:
Redis消息隊列的2種方案:
-
List實現消息隊列
按照插入順序排序,你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
所以常用來做非同步隊列使用,將需要延後處理的任務結構體序列化成字元串塞進 Redis 的列