導航:首頁 > 源碼編譯 > rediszset源碼解析

rediszset源碼解析

發布時間:2024-02-22 15:45:26

1. Redis中hash、set、zset的底層數據結構原理

Redis-哈希對象(hash)

Redis-集合對象(set)

其中hashtable的key為set中元素的值,而value為null

inset為可以理解為數組,使用inset數據結構需要滿足下述兩個條件:

intset的底層結構

查詢方式一般採用二分查找法,實際查詢復雜度也就在log(n)
Redis-有序集合對象(zset)
底層實現為 字典(dict) + 跳錶(skiplist),當數據比較少的時候用ziplist編碼結構存儲。

同時滿足以下兩個條件採用ziplist存儲:

ziplist存儲方式

總結

2. 三分鍾讀懂redis資料庫

redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字元串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁碟或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。

1. 使用Redis有哪些好處?

(1) 速度快,因為數據存在內存中,類似於HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1)

(2) 支持豐富數據類型,支持string,list,set,sorted set,hash

(3) 支持事務,操作都是原子性,所謂的原子性就是對數據的更改要麼全部執行,要麼全部不執行

(4) 豐富的特性:可用於緩存,消息,按key設置過期時間,過期後將會自動刪除

2. redis相比memcached有哪些優勢?

(1) memcached所有的值均是簡單的字元串,redis作為其替代者,支持更為豐富的數據類型

(2) redis的速度比memcached快很多

(3) redis可以持久化其數據

3. redis常見性能問題和解決方案:

(1) Master最好不要做任何持久化工作,如RDB內存快照和AOF日誌文件

(2) 如果數據比較重要,某個Slave開啟AOF備份數據,策略設置為每秒同步一次

(3) 為了主從復制的速度和連接的穩定性,Master和Slave最好在同一個區域網內

(4) 盡量避免在壓力很大的主庫上增加從庫

(5) 主從復制不要用圖狀結構,用單向鏈表結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3...

這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。

4. MySQL里有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據

相關知識:redis 內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。redis 提供 6種數據淘汰策略:

voltile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰

volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰

volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰

allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰

allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰

no-enviction(驅逐):禁止驅逐數據

相關推薦:《Python視頻教程》

5. Memcache與Redis的區別都有哪些?

1)、存儲方式

Memecache把數據全部存在內存之中,斷電後會掛掉,數據不能超過內存大小。

Redis有部份存在硬碟上,這樣能保證數據的持久性。

2)、數據支持類型

Memcache對數據類型支持相對簡單。

Redis有復雜的數據類型。

3),value大小

redis最大可以達到1GB,而memcache只有1MB

6. Redis 常見的性能問題都有哪些?如何解決?

1).Master寫內存快照,save命令調度rdbSave函數,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以Master最好不要寫內存快照。

2).Master AOF持久化,如果不重寫AOF文件,這個持久化方式對性能的影響是最小的,但是AOF文件會不斷增大,AOF文件過大會影響Master重啟的恢復速度。Master最好不要做任何持久化工作,包括內存快照和AOF日誌文件,特別是不要啟用內存快照做持久化,如果數據比較關鍵,某個Slave開啟AOF備份數據,策略為每秒同步一次。

3).Master調用BGREWRITEAOF重寫AOF文件,AOF在重寫的時候會佔大量的CPU和內存資源,導致服務load過高,出現短暫服務暫停現象。

4). Redis主從復制的性能問題,為了主從復制的速度和連接的穩定性,Slave和Master最好在同一個區域網內

7. redis 最適合的場景

Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用Memcached,何時使用Redis呢?

如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:

1.Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。

2.Redis支持數據的備份,即master-slave模式的數據備份。

3.Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。

(1)會話緩存(Session Cache)

最常用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其他存儲(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,如果用戶的購物車信息全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎?

幸運的是,隨著 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來緩存會話的文檔。甚至廣為人知的商業平台Magento也提供Redis的插件。

(2)全頁緩存(FPC)

除基本的會話token之外,Redis還提供很簡便的FPC平台。回到一致性問題,即使重啟了Redis實例,因為有磁碟的持久化,用戶也不會看到頁面載入速度的下降,這是一個極大改進,類似php本地FPC。

再次以Magento為例,Magento提供一個插件來使用Redis作為全頁緩存後端。

此外,對WordPress的用戶來說,Pantheon有一個非常好的插件 wp-redis,這個插件能幫助你以最快速度載入你曾瀏覽過的頁面。

(3)隊列

Reids在內存存儲引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作為一個很好的消息隊列平台來使用。Redis作為隊列使用的操作,就類似於本地程序語言(如Python)對 list 的 push/pop 操作。

如果你快速的在Google中搜索「Redis queues」,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis創建非常好的後端工具,以滿足各種隊列需求。例如,Celery有一個後台就是使用Redis作為broker,你可以從這里去查看。

(4)排行榜/計數器

Redis在內存中對數字進行遞增或遞減的操作實現的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis只是正好提供了這兩種數據結構。所以,我們要從排序集合中獲取到排名最靠前的10個用戶–我們稱之為「user_scores」,我們只需要像下面一樣執行即可:

當然,這是假定你是根據你用戶的分數做遞增的排序。如果你想返回用戶及用戶的分數,你需要這樣執行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一個很好的例子,用Ruby實現的,它的排行榜就是使用Redis來存儲數據的,你可以在這里看到。

(5)發布/訂閱

最後(但肯定不是最不重要的)是Redis的發布/訂閱功能。發布/訂閱的使用場景確實非常多。我已看見人們在社交網路連接中使用,還可作為基於發布/訂閱的腳本觸發器,甚至用Redis的發布/訂閱功能來建立聊天系統!(不,這是真的,你可以去核實)。

3. 通過redis的有序集合[zset] 實現延遲隊列

php使用redis的有序集合zset實現延遲隊列

我們通過redis的有序集合zset來實現簡單的延遲隊列,將消息數據序列化,作為zset的基本元素,把 消息生產時間戳 + 消息處理延遲時間戳 作為score,每次通過zRangeByScore獲取一條消息進行處理,後通過zRem刪除集合元激滑碰素:相當於移除需要消費的 Job。

優點:

缺點:
1.不適合延遲時間高的業務場景。延遲時間可能有幾秒鍾的誤差。
2.不適合明談大型項目 ,大型項目建議使用讓褲rabbitmq的延遲i消息隊列

下面是簡單的實現demo

4. Redis底層數據結構解密

一:摘要概述
很多 redis 的使用者都可以清晰明白的道出Redis中常用的對象如string、list、hash、set、zset,一些場景比較豐富的使用者可能會說布隆過濾器、geo、Hash等。但是對於這些對象底層實現的數據結構卻是知之甚少,將會詳細闡述redis中的底層數據結構。為了彌補大家的創傷,今天分享Redis底層數據結構內容。
二:SDS
string作為redis中常用對象之一,普遍用於用戶信息緩存等場景。當string對象中encoding編碼為embstr或raw時都是採用sds作為其底層實現
2.1 SDS結構
源碼文件位於redis安裝目錄src下的sds.h,sds聲明了五種頭部類型,分別為sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64。根據字元串長度創建不同頭部的sds實例
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len;
uint8_t alloc;
unsigned char flags;
char buf[];
};
屬性名稱作用含義
len字元串長度
alloc預分配空間大小
flags低三位用於表示sds類型,可以查看sds.h文件76-82行定義
buf[]存儲字元串用數組
2.2 SDS與C字元串區別
區別描述
長度計算 c中的字元串長度計算需要數組遍歷,但是redis中的sds自身維護了len屬性。所以O(1)時間復雜度即可
緩沖區溢出c中字元串更改如果未提前做好內存分配則會內存溢出,但是sds則會根據alloc與len計算預留內存是否足夠分配重新申請內存
動態擴展 緩沖區溢出已經闡述這個概念,sds的內存空間會在字元串內容變更時自動擴展計算。策略為當字元換小於1M時*2翻倍,大於1M時每次擴容1M
惰性釋放 與空間預分配相似操作的還有內存惰性釋放,即字元串刪除某些內容後所佔用的內存空間並不會立即釋放,後續字元串變更擴展就無需再申請內存
二:ZipList
ziplist可以說把redis對於內存的極致操作體現的淋漓盡致,鏈表除了節點值之外還需要維護前後節點兩個指針,並且還會造成內存碎片。壓縮列表緊湊的內存布局,所有節點都維護在整塊內存中處理
2.1 ZipList結構
屬性名稱作用含義
zlbytes列表健佔用內存的總位元組數,在對列表健內存重分配或者是計算zlend的時候使用
zltail 指向壓縮列表起始地址的指針
zllen 壓縮列表的節點數量
entry壓縮列表保存的節點數據
zlend壓縮列表的尾節點
2.2 Entry節點結構
屬性名稱作用含義
previous_entry_length 位元組為單位記錄上一個節點的長度,如果上一個位元組長度小於254佔用1位元組。大於254佔用5位元組,第一個位元組設置為OxFE(十進制254),後面四個位元組儲存長度
encoding 記錄content記錄的數據類型以及長度。長度一、二、五位元組,值的最高位為00、01、10表示類型為位元組數組,長度使用除去最高位的其它位記錄。11開頭表示儲存整數,除去最高位其他位置表示content數據長度
content 記錄壓縮列表記錄的數據

閱讀全文

與rediszset源碼解析相關的資料

熱點內容
外國免費手機vr資源網站 瀏覽:830
魔獸游戲伺服器怎麼弄 瀏覽:422
成人性教育的片在哪裡能看? 瀏覽:993
pdf壓縮破解版 瀏覽:180
簽字版pdf 瀏覽:309
主角姓庄穿越到香港當探長 瀏覽:271
百度網盤視頻是雙語的怎麼改為單語的 瀏覽:334
伺服器關閉玩家充的錢怎麼辦 瀏覽:251
日本男男影片 瀏覽:860
matlab實用教程pdf 瀏覽:769
伺服器加密方式哪種好 瀏覽:121
顯示加密服務超時 瀏覽:611
日語口譯pdf 瀏覽:433
外人如何評價身邊的程序員 瀏覽:105
霍夫曼編碼壓縮演算法 瀏覽:122
我想學習單片機 瀏覽:644
陳寶蓮拍過 瀏覽:336
遙調命令的設定命令實現過程 瀏覽:76
演算法中最壞情況都為多少 瀏覽:995
排序演算法圖形化展示 瀏覽:782