點(diǎn)贊再看彤委,養(yǎng)成習(xí)慣柳爽,搜一搜【一角錢技術(shù)】關(guān)注更多原創(chuàng)技術(shù)文章。本文 GitHub org_hejianhui/JavaStudy 已收錄,有我的系列文章闪萄。
五種常用數(shù)據(jù)結(jié)構(gòu)
String 結(jié)構(gòu)
字符串常用操作
SET key value //存入字符串鍵值對(duì)
MSET key value [key value ...] //批量存儲(chǔ)字符串鍵值對(duì)
SETNX key value //存入一個(gè)不存在的字符串鍵值對(duì)
GET key //獲取一個(gè)字符串鍵值
MGET key [key ...] //批量獲取字符串鍵值
DEL key [key ...] //刪除一個(gè)鍵
EXPIRE key seconds //設(shè)置一個(gè)鍵的過期時(shí)間(秒)
原子加減
INCR key //將key中儲(chǔ)存的數(shù)字值加1
DECR key //將key中儲(chǔ)存的數(shù)字值減1
INCRBY key increment //將key所儲(chǔ)存的值加上increment
DECRBY key decrement //將key所儲(chǔ)存的值減去decrement
String 應(yīng)用場(chǎng)景
- 單值緩存
- 對(duì)象緩存
- 分布式鎖
- 計(jì)數(shù)器
- Web集群Session共享
- 分布式系統(tǒng)全局序列號(hào)
- 單值緩存
SET key value
Get key
- 對(duì)象緩存
SET user:1 value(json格式數(shù)據(jù))
MSET user:1:name yijiaoqian user:1:balance 1888
MGET user:1:name user:1:balance
- 分布式鎖
SETNX product:10001 true //返回1代表獲取鎖成功
SETNX product:10001 true //返回0代表獲取鎖失敗
...執(zhí)行業(yè)務(wù)操作...
DEL product:10001 //執(zhí)行完業(yè)務(wù)釋放鎖
SET product:10001 true ex 10 nx //防止程序意外終止導(dǎo)致死鎖
- 計(jì)數(shù)器
INCR article:readcount:{文章id}
GET article:readcount:{文章id}
- Web集群Session共享
Spring session + redis 實(shí)現(xiàn)sessio共享
- 分布式系統(tǒng)全局序列號(hào)
INCRBY orderId 1000 //redis批量生成序列號(hào)提升性能
Hash 結(jié)構(gòu)
Hash常用操作
HSET key field value //存儲(chǔ)一個(gè)哈希表key的鍵值
HSETNX key field value //存儲(chǔ)一個(gè)不存在的哈希表key的鍵值
HMSET key field value [field value ...] //在一個(gè)哈希表key中存儲(chǔ)多個(gè)鍵值對(duì)
HGET key field //獲取哈希表key對(duì)應(yīng)的field鍵值
HMGET key field [field ...] //批量獲取哈希表key中多個(gè)field鍵值
HDEL key field [field ...] //刪除哈希表key中的field鍵值
HLEN key //返回哈希表key中field的數(shù)量
HGETALL key //返回哈希表key中所有的鍵值
HINCRBY key field increment //為哈希表key中field鍵的值加上增量increment
Hash應(yīng)用場(chǎng)景
- 對(duì)象存儲(chǔ)
HMSET user {userId}:name yijiaoqian {userId}:balance 1888
HMSET user 1:name yijiaoqian 1:balance 1888
HMGET user 1:name 1:balance
- 電商購(gòu)物車
- 以用戶id為key
- 商品id為field
- 商品數(shù)量為value
購(gòu)物車操作:
- 添加商品:hset cart:1001 10088 1
- 增加數(shù)量:hincrby cart:1001 10088 1
- 商品總數(shù):hlen cart:1001
- 刪除商品:hdel cart:1001 10088
- 獲取購(gòu)物車所有商品:hgetall cart:1001
Hash結(jié)構(gòu)優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 同類數(shù)據(jù)歸類整合儲(chǔ)存泞当,方便數(shù)據(jù)管理
- 相比string操作消耗內(nèi)存與cpu更小
- 相比string儲(chǔ)存更節(jié)省空間
缺點(diǎn):
- 過期功能不能使用在field上迹蛤,只能用在key上
- Redis集群架構(gòu)下不適合大規(guī)模使用
List 結(jié)構(gòu)
List常用操作
LPUSH key value [value ...] //將一個(gè)或多個(gè)值value插入到key列表的表頭(最左邊)
RPUSH key value [value ...] //將一個(gè)或多個(gè)值value插入到key列表的表尾(最右邊)
LPOP key //移除并返回key列表的頭元素
RPOP key //移除并返回key列表的尾元素
LRANGE key start stop //返回列表key中指定區(qū)間內(nèi)的元素,區(qū)間以偏移量start和stop指定
BLPOP key [key ...] timeout //從key列表表頭彈出一個(gè)元素襟士,若列表中沒有元素盗飒,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
BRPOP key [key ...] timeout //從key列表表尾彈出一個(gè)元素,若列表中沒有元素陋桂,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
List應(yīng)用場(chǎng)景
- 常用數(shù)據(jù)結(jié)構(gòu):
- Stack(棧) = LPUSH + LPOP (FILO)
- Queue(隊(duì)列)= LPUSH + RPOP (FIFO)
- Blocking MQ(阻塞隊(duì)列)= LPUSH + BRPOP
- 微博和微信公號(hào)消息流
一角錢關(guān)注了雷軍逆趣、馬云等大V
1)雷布斯發(fā)微博,消息ID為10018
LPUSH msg:{一角錢-ID} 10018
2)馬云發(fā)微博嗜历,消息ID為10086
LPUSH msg:{一角錢-ID} 10086
3)查看最新微博消息
LRANGE msg:{一角錢-ID} 0 4
Set 結(jié)構(gòu)
Set常用操作
SADD key member [member ...] //往集合key中存入元素宣渗,元素存在則忽略,若key不存在則新建
SREM key member [member ...] //從集合key中刪除元素
SMEMBERS key //獲取集合key中所有元素
SCARD key //獲取集合key的元素個(gè)數(shù)
SISMEMBER key member //判斷member元素是否存在于集合key中
SRANDMEMBER key [count] //從集合key中選出count個(gè)元素梨州,元素不從key中刪除
SPOP key [count] //從集合key中選出count個(gè)元素痕囱,元素從key中刪除
Set運(yùn)算操作
SINTER key [key ...] //交集運(yùn)算
SINTERSTORE destination key [key ..] //將交集結(jié)果存入新集合destination中
SUNION key [key ..] //并集運(yùn)算
SUNIONSTORE destination key [key ...] //將并集結(jié)果存入新集合destination中
SDIFF key [key ...] //差集運(yùn)算
SDIFFSTORE destination key [key ...] //將差集結(jié)果存入新集合destination中
Set應(yīng)用場(chǎng)景
- 微信抽獎(jiǎng)小程序
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-4MXrY6h4-1608565742118)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bcbd972138c54f229f249954a4634578~tplv-k3u1fbpfcp-zoom-1.image)]
1.點(diǎn)擊參與抽獎(jiǎng)加入集合: SADD key {userID}
2.查看參與抽獎(jiǎng)所有用戶:SMEMBERS key
3.抽取count名中獎(jiǎng)?wù)撸篠RANDMEMBER key [count]/ SPOP key [count]
- 微信微博點(diǎn)贊、收藏暴匠、標(biāo)簽
1.點(diǎn)贊: SADD like:{消息ID} {用戶ID}
2.取消點(diǎn)贊: SREM like:{消息ID} {用戶ID}
3.檢查用戶是否點(diǎn)過贊: SISMEMBER like:{消息ID} {用戶ID}
4.獲取點(diǎn)贊的用戶列表: SMEMBERS like:{消息ID}
5.獲取點(diǎn)贊用戶數(shù): SCARD like:{消息ID}
- 集合操作
SINTER set1 set2 set3 -> { c } // 交集
SUNION set1 set2 set3 -> { a,b,c,d,e } // 并集
SDIFF set1 set2 set3 -> { a } // 差集
- 集合操作實(shí)現(xiàn)微博微信關(guān)注模型
1) 張三關(guān)注的人:
zhangsanSet-> {lisi, wangwu}
2) 一角錢關(guān)注的人:
yijiaoqianSet--> {zhangsan, zhaoliu, lisi, wangwu}
3) 李四關(guān)注的人:
lisiSet-> {zhangsan, yijiaoqian, zhaoliu, wangwu, xunyu)
4) 我和一角錢共同關(guān)注:
SINTER zhangsanSet yijiaoqianSet--> {lisi, wangwu}
5) 我關(guān)注的人也關(guān)注他(一角錢):
SISMEMBER lisiSet yijiaoqian
SISMEMBER wangwuSet yijiaoqian
6) 我可能認(rèn)識(shí)的人:
SDIFF yijiaoqianSet zhangsanSet->(zhangsan, zhaoliu}
- 集合操作實(shí)現(xiàn)電商商品篩選
SADD brand:huawei P40
SADD brand:xiaomi mi-10
SADD brand:iPhone iphone12
SADD os:android P40 mi-10
SADD cpu:brand:intel P40 mi-10
SADD ram:8G P40 mi-10 iphone12
SINTER os:android cpu:brand:intel ram:8G > {P40鞍恢,mi-10}
ZSet 有序集合結(jié)構(gòu)
ZSet常用操作
ZADD key score member [[score member]…] //往有序集合key中加入帶分值元素
ZREM key member [member …] //從有序集合key中刪除元素
ZSCORE key member //返回有序集合key中元素member的分值
ZINCRBY key increment member //為有序集合key中元素member的分值加上increment
ZCARD key //返回有序集合key中元素個(gè)數(shù)
ZRANGE key start stop [WITHSCORES] //正序獲取有序集合key從start下標(biāo)到stop下標(biāo)的元素
ZREVRANGE key start stop [WITHSCORES]//倒序獲取有序集合key從start下標(biāo)到stop下標(biāo)的元素
ZSet集合操作
ZUNIONSTORE destkey numkeys key [key ...] //并集計(jì)算
ZINTERSTORE destkey numkeys key [key …] //交集計(jì)算
ZSet應(yīng)用場(chǎng)景
- ZSet集合操作實(shí)現(xiàn)排行榜
1. 點(diǎn)擊新聞:
ZINCRBY hotNews:20201221 1 完善低齡未成年人犯罪規(guī)定
2. 展示當(dāng)日排行前十:
ZREVRANGE hotNews:20201221 0 9 WITHSCORES
3. 七日搜索榜單計(jì)算:
ZUNIONSTORE hotNews:20201215-20201221 7
hotNews:20201215 hotNews:20201216... hotNews:20201221
4. 展示七日排行前十:
ZREVRANGE hotNews:20201215-20201221 0 9 WITHSCORES
Redis的單線程和高性能
Redis是單線程嗎?
Redis的單線程主要是指 Redis 的網(wǎng)絡(luò)IO和鍵值對(duì)讀寫是由一個(gè)線程來完成的,這也是Redis對(duì)外提供鍵值存儲(chǔ)服務(wù)的主要流程帮掉。但是Redis的其他功能弦悉,比如持久化、異步刪除蟆炊、集群數(shù)據(jù)同步等稽莉,其實(shí)由額外的線程執(zhí)行的。
Redis 單線程為什么還能這么快涩搓?
因?yàn)樗械臄?shù)據(jù)都在內(nèi)存中污秆,所有的運(yùn)算都是內(nèi)存級(jí)別的運(yùn)算,而且單線程避免來多線程的切換性能損耗問題缩膝,正因?yàn)镽edis是單線程混狠,所以要小心使用Redis 指令,對(duì)于那些耗時(shí)的指令(比如keys)疾层,一定要謹(jǐn)慎使用将饺,一不小心就可能會(huì)導(dǎo)致 Redis 卡頓。
Redis 單線程如何處理那么多的并發(fā)客戶端連接痛黎?
Redis 的IO多路服用:redis利用epoll實(shí)現(xiàn)IO多路復(fù)用予弧,將連接信息和事件放到隊(duì)列中,依次放到文件事件分派器湖饱,事件分派器將事件分發(fā)給事件處理器掖蛤。
# 查看redis支持的最大連接數(shù),在redis.conf文件中可修改井厌,# maxclients 10000
127.0.0.1:6379> CONFIG GET maxclients
##1) "maxclients"
##2) "10000"
其他高級(jí)命令
keys:全量遍歷鍵
用來列出所有滿足特定正則字符串規(guī)則的key蚓庭,當(dāng)redis數(shù)據(jù)量比較大時(shí),性能比較差仅仆,要避免使用器赞。
127.0.0.1:6379> set codehole1 a
OK
127.0.0.1:6379> set codehole2 b
OK
127.0.0.1:6379> set codehole3 c
OK
127.0.0.1:6379> set code1hole a
OK
127.0.0.1:6379> set code2hole b
OK
127.0.0.1:6379> set code3hole c
OK
127.0.0.1:6379> keys *
1) "codehole1"
2) "codehole3"
3) "codehole2"
4) "code3hole"
5) "code1hole"
6) "code2hole"
127.0.0.1:6379> keys codehole*
1) "codehole1"
2) "codehole3"
3) "codehole2"
127.0.0.1:6379> keys code*hole
1) "code3hole"
2) "code1hole"
3) "code2hole"
scan:漸進(jìn)式遍歷鍵
SCAN cursor [MATCH pattern] [COUNT count]
scan 參數(shù)提供了三個(gè)參數(shù):
- 第一個(gè)參數(shù) cursor 整數(shù)值(hash桶的索引值)
- 第二個(gè)是 key 的正則模式
- 第三個(gè)是一次遍歷的key的數(shù)量(參考值,底層遍歷的數(shù)量不一定)墓拜,并不少符合條件的結(jié)果數(shù)量港柜。
第一次遍歷時(shí),cursor 值為0咳榜,然后將返回結(jié)果中的第一個(gè)整數(shù)值作為下一次遍歷的 cursor夏醉。一直遍歷到返回的 cursor 值為0時(shí)結(jié)束。
注意:但是scan并非完美無暇涌韩,如果在scan的過程中如果有鍵的變化(增加畔柔、刪除、修改)贸辈,那么遍歷效果可能會(huì)碰到如下問題:新增的鍵可能沒有遍歷到释树,遍歷出了重復(fù)的鍵等情況肠槽,也就是說scan并不能保證完整的遍歷出來所有的鍵擎淤,這些是我們?cè)陂_發(fā)時(shí)需要考慮的奢啥。
info:查看redis服務(wù)運(yùn)行信息
分為 9 大塊,每個(gè)塊都有非常多的參數(shù):
- Server 服務(wù)器運(yùn)行的環(huán)境參數(shù)
- Clients 客戶端相關(guān)信息
- Memory 服務(wù)器運(yùn)行內(nèi)存的統(tǒng)計(jì)數(shù)據(jù)
- Persistence 持久化信息
- Stats 通用統(tǒng)計(jì)數(shù)據(jù)
- Replication 主從復(fù)制相關(guān)信息
- CPU CPU使用情況
- Cluster 集群信息
- KeySpace 鍵值對(duì)統(tǒng)計(jì)數(shù)量信息
核心屬性說明:
connected_clients:2 # 正在連接的客戶端數(shù)量
instantaneous_ops_per_sec:789 # 每秒執(zhí)行多少次指令
used_memory:929864 # Redis分配的內(nèi)存總量(byte)嘴拢,包含redis進(jìn)程內(nèi)部的開銷和數(shù)據(jù)占用的內(nèi)存
used_memory_human:908.07K # Redis分配的內(nèi)存總量(Kb桩盲,human會(huì)展示出單位)
used_memory_rss_human:2.28M # 向操作系統(tǒng)申請(qǐng)的內(nèi)存大小(Mb)(這個(gè)值一般是大于used_memory的,因?yàn)镽edis的內(nèi)存分配策略會(huì)產(chǎn)生內(nèi)存碎片)
used_memory_peak:929864 # redis的內(nèi)存消耗峰值(byte)
used_memory_peak_human:908.07K # redis的內(nèi)存消耗峰值(KB)
maxmemory:0 # 配置中設(shè)置的最大可使用內(nèi)存值(byte),默認(rèn)0,不限制
maxmemory_human:0B # 配置中設(shè)置的最大可使用內(nèi)存值
maxmemory_policy:noeviction # 當(dāng)達(dá)到maxmemory時(shí)的淘汰策略
文章持續(xù)更新席吴,可以公眾號(hào)搜一搜「 一角錢技術(shù) 」第一時(shí)間閱讀赌结, 本文 GitHub org_hejianhui/JavaStudy 已經(jīng)收錄,歡迎 Star孝冒。