詳解Redis核心資料結構和高效能原理分析(一)
一、Redis介紹
1、Redis是什麼
Remote Dictionary Server(Redis)是一個開源的使用 ANSI C 語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value 資料庫,並提供多種語言的 API。
它通常被稱為資料結構伺服器,因為值(value)可以是 字串(String), 雜湊(Map),列表(list), 集合(sets) 和 有序集合(sorted sets)等型別。
2、Redis的優缺點
- 支援多種資料結構,如 string(字串)、 list(雙向連結串列)、dict(hash 表)、set(集合)、
zset(排序 set)、hyperloglog(基數估算)- 支援持久化操作,可以進行 aof 及 rdb 資料持久化到磁碟,從而進行資料備份或數
據恢復等操作,較好的防止資料丟失的手段。- 支援通過 Replication 進行資料複製,通過 master-slave 機制,可以實時進行資料的
同步複製,支援多級複製和增量複製,master-slave 機制是 Redis 進行 HA 的重要手段。- 單程式請求,所有命令序列執行,併發情況下不需要考慮資料一致性問題。
二、Redis的安裝(若需要docker版,請看我其他文章)
三、Redis 資料型別
總圖:
1、string(字串)
1.1、定義
Redis 字串是位元組序列。Redis 字串是二進位制安全的,這意味著他們有一個已知的
長度沒有任何特殊字元終止,所以你可以儲存任何東西,512 兆為上限
1.2、常用命令
字串常用操作
SET key value //存入字串鍵值對
MSET key value [key value ...] //批量儲存字串鍵值對
SETNX key value //存入一個不存在的字串鍵值對
GET key //獲取一個字串鍵值
MGET key [key ...] //批量獲取字串鍵值
DEL key [key ...] //刪除一個鍵
EXPIRE key seconds //設定一個鍵的過期時間(秒)
原子加減
INCR key //將key中儲存的數字值加1
DECR key //將key中儲存的數字值減1
INCRBY key increment //將key所儲存的值加上increment
DECRBY key decrement //將key所儲存的值減去decrement
1.3、應用場景
1、單值快取
SET key value
GET key
2、分散式鎖
SETNX product:10001 true //返回1代表獲取鎖成功
SETNX product:10001 true //返回0代表獲取鎖失敗
。。。執行業務操作
DEL product:10001 //執行完業務釋放鎖
SET product:10001 true ex 10 nx //防止程式意外終止導致死鎖
3、計數器
INCR article:readcount:{文章id}
GET article:readcount:{文章id}
4、Web叢集session共享
spring session + redis實現session共享
5、分散式系統全域性序列號
INCRBY orderId 1000 //redis批量生成序列號提升效能
6、物件快取
1) SET user:1 value(json格式資料)
2) MSET user:1:name zhz user:1:balance 1888
MGET user:1:name user:1:balance
2、list(連結串列)
2.1、定義
Redis 的連結串列是簡單的字串列表,排序插入順序。您可以新增元素到 Redis 的列表的
頭部或尾部。
2.2、常用命令
1、List常用操作
LPUSH key value [value ...] //將一個或多個值value插入到key列表的表頭(最左邊)
RPUSH key value [value ...] //將一個或多個值value插入到key列表的表尾(最右邊)
LPOP key //移除並返回key列表的頭元素
RPOP key //移除並返回key列表的尾元素
LRANGE key start stop //返回列表key中指定區間內的元素,區間以偏移量start和stop指定
BLPOP key [key ...] timeout //從key列表表頭彈出一個元素,若列表中沒有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
BRPOP key [key ...] timeout //從key列表表尾彈出一個元素,若列表中沒有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
2.1、應用場景
1、常用資料結構
Stack(棧) = LPUSH + LPOP
Queue(佇列)= LPUSH + RPOP
Blocking MQ(阻塞佇列)= LPUSH + BRPOP
2、微博和微信公號訊息流
3、微博訊息和微信公號訊息
/**
* 事例
**/
A關注了MacTalk,備胎說車等大V
1)MacTalk發微博,訊息ID為10018
LPUSH msg:{A-ID} 10018
2)備胎說車發微博,訊息ID為10086
LPUSH msg:{A-ID} 10086
3)檢視最新微博訊息
LRANGE msg:{A-ID} 0 4
3、 Hash(hash表)
3.1、定義
Redis 的雜湊是鍵值對的集合。 Redis 的雜湊值是字串欄位和字串值之間的對映,
因此它們被用來表示物件。
3.2、常用命令
Hash常用操作
HSET key field value //儲存一個雜湊表key的鍵值
HSETNX key field value //儲存一個不存在的雜湊表key的鍵值
HMSET key field value [field value ...] //在一個雜湊表key中儲存多個鍵值對
HGET key field //獲取雜湊表key對應的field鍵值
HMGET key field [field ...] //批量獲取雜湊表key中多個field鍵值
HDEL key field [field ...] //刪除雜湊表key中的field鍵值
HLEN key //返回雜湊表key中field的數量
HGETALL key //返回雜湊表key中所有的鍵值
HINCRBY key field increment //為雜湊表key中field鍵的值加上增量increment
3.3、應用場景
物件快取
HMSET user {userId}:name zhz {userId}:balance 1888
HMSET user 1:name zhz1:balance 1888
HMGET user 1:name 1:balance
電商購物車
1)以使用者id為key
2)商品id為field
3)商品數量為value
購物車操作
新增商品->hset cart:1001 10088 1
增加數量->hincrby cart:1001 10088 1
商品總數->hlen cart:1001
刪除商品->hdel cart:1001 10088
獲取購物車所有商品->hgetall cart:1001
3.4、優缺點
- 優點
1)同類資料歸類整合儲存,方便資料管理
2)相比string操作消耗記憶體與cpu更小
3)相比string儲存更節省空間- 缺點
過期功能不能使用在field上,只能用在key上
Redis叢集架構下不適合大規模使用
4、set(集合)
4.1、定義
Redis 的集合是字串的無序集合。
4.2、常用命令
1、Set常用操作
SADD key member [member ...] //往集合key中存入元素,元素存在則忽略,若key不存在則新建
SREM key member [member ...] //從集合key中刪除元素
SMEMBERS key //獲取集合key中所有元素
SCARD key //獲取集合key的元素個數
SISMEMBER key member //判斷member元素是否存在於集合key中
SRANDMEMBER key [count] //從集合key中選出count個元素,元素不從key中刪除
SPOP key [count] //從集合key中選出count個元素,元素從key中刪除
2、Set運算操作
SINTER key [key ...] //交集運算
SINTERSTORE destination key [key ..] //將交集結果存入新集合destination中
SUNION key [key ..] //並集運算
SUNIONSTORE destination key [key ...] //將並集結果存入新集合destination中
SDIFF key [key ...] //差集運算
SDIFFSTORE destination key [key ...] //將差集結果存入新集合destination中
4.3、應用場景
1、微信抽獎小程式
1)點選參與抽獎加入集合
SADD key {userlD}
2)檢視參與抽獎所有使用者
SMEMBERS key
3)抽取count名中獎者
SRANDMEMBER key [count] / SPOP key [count]
2、微信微博點贊,收藏,標籤
1) 點贊
SADD like:{訊息ID} {使用者ID}
2) 取消點贊
SREM like:{訊息ID} {使用者ID}
3) 檢查使用者是否點過贊
SISMEMBER like:{訊息ID} {使用者ID}
4) 獲取點讚的使用者列表
SMEMBERS like:{訊息ID}
5) 獲取點贊使用者數
SCARD like:{訊息ID}
3、集合操作
SINTER set1 set2 set3 -> { c }
SUNION set1 set2 set3 -> { a,b,c,d,e }
SDIFF set1 set2 set3 -> { a }
4、集合操作實現微博微信關注模型
1) A關注的人:
ASet-> {B, C}
2) D老師關注的人:
DSet--> {A, E, B, C}
3) B老師關注的人:
BSet-> {A, D, E, C, F)
4) 我A和D老師共同關注:
SINTER ASet DSet--> {B, C}
5) 我A關注的人也關注他(D老師):
SISMEMBER BSet D
SISMEMBER CSet D
6) 我可能認識的人:
SDIFF DSet ASet->(A, E}
5、集合操作實現電商商品篩選
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}
5、zset(sorted set->有序集合)
5.1、定義
Redis 的有序集合類似於 Redis 的集合,字串不重複的集合。
5.2、常用命令
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中元素個數
ZRANGE key start stop [WITHSCORES] //正序獲取有序集合key從start下標到stop下標的元素
ZREVRANGE key start stop [WITHSCORES] //倒序獲取有序集合key從start下標到stop下標的元素
Zset集合操作
ZUNIONSTORE destkey numkeys key [key ...] //並集計算
ZINTERSTORE destkey numkeys key [key …] //交集計算
5.3、應用場景
Zset集合操作實現排行榜
1)點選新聞
ZINCRBY hotNews:20190819 1 守護香港
2)展示當日排行前十
ZREVRANGE hotNews:20190819 0 9 WITHSCORES
3)七日搜尋榜單計算
ZUNIONSTORE hotNews:20190813-20190819 7
hotNews:20190813 hotNews:20190814... hotNews:20190819
4)展示七日排行前十
ZREVRANGE hotNews:20190813-20190819 0 9 WITHSCORES
6、其他高階命令
1、keys:
全量遍歷鍵, 用來列出所有滿足特定正則字串規則的key,當redis資料量比較大時,效能比較差,要避免使用
2、SCAN cursor [MATCH pattern] [COUNT count]
scan 引數提供了三個引數,第一個是 cursor 整數值(hash桶的索引值),第二個是 key 的正則模式,
第三個是一次遍歷的key的數量(參考值,底層遍歷的數量不一定),並不是符合條件的結果數量。第
一次遍歷時,cursor 值為 0,然後將返回結果中第一個整數值作為下一次遍歷的 cursor。一直遍歷
到返回的 cursor 值為 0 時結束。
注意:但是scan並非完美無瑕, 如果在scan的過程中如果有鍵的變化(增加、 刪除、 修改) ,那
麼遍歷效果可能會碰到如下問題: 新增的鍵可能沒有遍歷到, 遍歷出了重複的鍵等情況, 也就是說
scan並不能保證完整的遍歷出來所有的鍵,開發市需要考慮
3、Info:
檢視redis服務執行資訊,分為 9 大塊,每個塊都有非常多的引數,這 9 個塊分別是:
4、Server
伺服器執行的環境引數
5、Clients
客戶端相關資訊
6、Memory
伺服器執行記憶體統計資料
7、Persistence
持久化資訊
8、Stats
通用統計資料
9、Replication
主從複製相關資訊
10、CPU CPU
使用情況
11、Cluster
叢集資訊
12、KeySpace
鍵值對統計數量資訊
四、基本資料結構總結
五、Redis的單執行緒和高效能
1、Redis是單執行緒嗎?
Redis 的單執行緒主要是指 Redis 的網路 IO 和鍵值對讀寫是由一個執行緒來完成的,這也是 Redis 對外提供鍵值儲存服務的主要流程。但 Redis 的其他功能,比如持久化、非同步刪除、叢集資料同步等,其實是由額外的執行緒執行的。
2、Redis 單執行緒為什麼還能這麼快?
- 它所有的資料都在記憶體中,所有的運算都是記憶體級別的運算,而且單執行緒避免了多執行緒的切換效能損耗問題。因為 Redis 是單執行緒,所以要小心使用 Redis 指令,對於那些耗時的指令(比如
keys),一定要謹慎使用,一不小心就可能會導致 Redis 卡頓。- Redis完全基於記憶體,絕大部分請求是純粹的記憶體操作,非常迅速,資料存在記憶體中。
- 資料結構簡單,對資料操作也簡單。
- 採用單執行緒,避免了不必要的上下文切換和競爭條件,不存在多執行緒導致的CPU切換,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有死鎖問題導致的效能消耗。
- 使用多路複用IO模型,非阻塞IO。
3、Redis 單執行緒如何處理那麼多的併發客戶端連線?
Redis的IO多路複用:redis利用epoll來實現IO多路複用,將連線資訊和事件放到佇列中,依次放到
檔案事件分派器,事件分派器將事件分發給事件處理器。
相關文章
- Redis資料結構SortedSet底層原理詳解Redis資料結構
- Redis資料結構詳解(2)-redis中的字典dictRedis資料結構
- Redis內部資料結構詳解(4)——ziplistRedis資料結構
- 【Redis 系列】redis 學習十五,redis sds資料結構和底層設計原理Redis資料結構
- Tomcat結構原理詳解Tomcat
- 深入瞭解Redis資料結構Redis資料結構
- 資料結構:棧詳解資料結構
- JAVA常用資料結構及原理分析Java資料結構
- redis資料結構實現(一)Redis資料結構
- Redis資料結構概覽(原始碼分析)Redis資料結構原始碼
- Redis sds資料結構實現分析ZFRedis資料結構
- Redis核心原理與實踐--列表實現原理之quicklist結構RedisUI
- 探索Redis設計與實現2:Redis內部資料結構詳解——dictRedis資料結構
- 探索Redis設計與實現3:Redis內部資料結構詳解——sdsRedis資料結構
- 探索Redis設計與實現4:Redis內部資料結構詳解——ziplistRedis資料結構
- 探索Redis設計與實現5:Redis內部資料結構詳解——quicklistRedis資料結構UI
- 探索Redis設計與實現6:Redis內部資料結構詳解——skiplistRedis資料結構
- 探索Redis設計與實現7:Redis內部資料結構詳解——intsetRedis資料結構
- 3.10 solidity資料結構詳解Solid資料結構
- 高階資料結構詳解資料結構
- Redis資料結構Redis資料結構
- Redis 資料結構Redis資料結構
- Redis List 底層三種資料結構原理剖析Redis資料結構
- 高效能的Redis之物件底層實現原理詳解Redis物件
- 深入瞭解Redis底層資料結構Redis資料結構
- redis 資料結構和內部編碼Redis資料結構
- Redis叢集模式和常用資料結構Redis模式資料結構
- redis的資料結構Redis資料結構
- Redis(二十):Redis資料過期和淘汰策略詳解(轉)Redis
- Redis 5種資料結構 及使用場景分析Redis資料結構
- Redis原始碼分析-底層資料結構盤點Redis原始碼資料結構
- Redis基礎(一)資料結構與資料型別Redis資料結構資料型別
- Redis設計與實現閱讀總結(一)資料結構和物件Redis資料結構物件
- Linux 4.x MTD原始碼分析-核心資料結構Linux原始碼資料結構
- 【Redis破障之路】二:Redis安裝和基本資料結構Redis資料結構
- 達夢資料庫索引結構詳解資料庫索引
- 圖解:Java 中的資料結構及原理圖解Java資料結構
- 競拍系統設計和核心資料結構資料結構