redis原理總結

2021-08-15 10:11:09 字數 3718 閱讀 3311

redis單點吞吐量

單點tps達到8萬/秒,qps達到10萬/秒。

redis的5中儲存型別

string、list、set、map(hash)、stored-set

redis的string型別

能表達3中型別:字串、整數和浮點數。根據場景相互間自動轉型,並且根據需要選取底層的承載方式

value內部以int、sds作為結構儲存。int存放整型資料,sds存放位元組/字串和浮點型資料

擴容:當對字串的操作完成後預期的串長度小於1m時,擴容後的buf陣列大小=預期長度*2+1;若大於1m,則buf總是會預留出1m的free空間

value物件通常具有兩個記憶體部分:redisobject部分和redisobject的ptr指向的sds部分。建立value物件時,通常需要為redisobject和sds申請兩次記憶體。單對於短小的字串,可以把兩者連續存放,所以可以一次性把兩者的記憶體一起申請了

redis的list型別

list型別的value物件內部以linkedlist或ziplist承載。當list的元素個數和單個元素的長度較小時,redis會採用ziplist實現以減少記憶體占用,否則採用linkedlist結構

linkedlist內部實現是雙向鍊錶。在list中定義了頭尾元素指標和列表的長度,是的pop/push操作、llen操作的複雜度為o(1)。由於是鍊錶,lindex類的操作複雜度仍然是o(n)

ziplist的內部結構

redis的map型別

map又叫hash。map內部的key和value不能再巢狀map了,只能是string型別:整形、浮點型和字串

map主要由hashtable和ziplist兩種承載方式實現,對於資料量較小的map,採用ziplist實現

hashtable內部結構

ziplist內部結構

redis的set型別

set以intset或hashtable來儲存。hashtable中的value永遠為null,當set中只包含整數型的元素時,則採用intset

intset的內部結構

redis的sorted-set型別

類似map是乙個key-value對,但是有序的。value是乙個浮點數,稱為score,內部是按照score從小到大排序

內部結構以ziplist或skiplist+hashtable來實現

redis客戶端與伺服器的互動模式

序列的請求/響應模式

雙工的請求/相應模式(pipeline)

原子化的批量請求/響應模式(事務)

發布/訂閱模式

指令碼化的批量執行(指令碼模式)

redis通過watch機制實現樂觀鎖流程

將本次事務涉及的所有key註冊為觀察模式

執行唯讀操作

根據唯讀操作的結果組裝寫操作命令併發送到伺服器端入隊

傳送原子化的批量執行命令exec試圖執行連線的請求佇列中的命令

如果前面註冊為觀察模式的key中有乙個貨多個,在exec之前被修改過,則exec將直接失敗,拒絕執行;否則順序執行請求佇列中的所有請求

redis沒有原生的悲觀鎖或者快照實現,但可通過樂觀鎖繞過。一旦兩次讀到的操作不一樣,watch機制觸發,拒絕了後續的exec執行

redis的網路協議

redis協議位於tcp層之上,即客戶端和redis例項保持雙工的連線,互動的都是序列化後的協議資料

redis處理命令的主要邏輯

redis伺服器對命令的處理都是單執行緒的,但是i/o層面卻面向多個客戶端併發地提供服務,併發到內部單執行緒的轉化通過多路復用框架來實現

首先從多路服用框架(epoll、evport、kqueue)中select出已經ready的檔案描述符(filedescriptor)

ready的標準是已有資料到達核心(kernel)、已準備好寫入資料

對於上一步已經ready的fd,redis會分別對每個fd上已ready的事件進行處理,處理完相同fd上的所有事件後,再處理下乙個ready的fd。有3中事件型別

對來自客戶端的命令執行結束後,接下來處理定時任務(timeevent)

aeapipoll的等待時間取決於定時任務處理(timeevent)邏輯

本次主迴圈完畢,進入下一次主迴圈的beforesleep邏輯,後者負責處理資料過期、增量持久化的檔案寫入等任務

redis的持久化機制

redis主要提供了兩種持久化機制:rdb和aof;

rdb

aof

當兩種方式同時開啟時,資料恢復redis會優先選擇aof恢復。一般情況下,只要使用預設開啟的rdb即可,因為相對於aof,rdb便於進行資料庫備份,並且恢復資料集的速度也要快很多。

開啟持久化快取機制,對效能會有一定的影響,特別是當設定的記憶體滿了的時候,更是下降到幾百reqs/s。所以如果只是用來做快取的話,可以關掉持久化。

redis記憶體分析的設計思路

主要有3種方式可以實現

設計思路:

開源框架:

redis記憶體估算

基礎的資料型別:sds、dict、intset、zipmap、adlist、quicklist、skiplist

舉例:以key為hello,value為world,型別是string,它的記憶體使用:

redis集群(redis cluster)

redis3以後,節點之間提供了完整的sharding(分片)、replication(主備感知能力)、failover(故障轉移)的特性

配置一致性:每個節點(node)內部都儲存了集群的配置資訊,儲存在clusterstate中,通過引入自增的epoch變數來使得集群配置在各個節點間保持一致

sharding資料分片

failover故障轉移

集群不可用的情況:

普通雜湊演算法和一致性雜湊演算法對比

普通雜湊:也稱硬雜湊,採用簡單取模的方式,將機器進行雜湊,這在cache環境不變的情況下能取得讓人滿意的結果,但是當cache環境動態變化時,這種靜態取模的方式顯然就不滿足單調性的要求(當增加或減少一台機子時,幾乎所有的儲存內容都要被重新雜湊到別的緩衝區中)。

一致性雜湊:將機器節點和key值都按照一樣的hash演算法對映到乙個0~2^32的圓環上。當有乙個寫入快取的請求到來時,計算key值k對應的雜湊值hash(k),如果該值正好對應之前某個機器節點的hash值,則直接寫入該機器節點,如果沒有對應的機器節點,則順時針查詢下乙個節點,進行寫入,如果超過2^32還沒找到對應節點,則從0開始查詢(因為是環狀結構)。為了更可能的滿足平衡性,可以引入虛擬節點,即乙個實體節點對映到多個虛擬節點。

參考:快取雪崩,快取穿透,快取併發,快取預熱,快取演算法

快取雪崩:可能是因為資料未載入到快取中,或者快取同一時間大面積的失效,從而導致所有請求都去查資料庫,導致資料庫cpu和記憶體負載過高,甚至宕機。解決思路:

快取穿透:指使用者查詢資料,在資料庫沒有,自然在快取中也不會有。這樣就導致使用者查詢的時候,在快取中找不到,每次都要去資料庫中查詢。解決思路:

快取併發:如果**併發訪問高,乙個快取如果失效,可能出現多個程序同時查詢db,同時設定快取的情況,如果併發確實很大,這也可能造成db壓力過大,還有快取頻繁更新的問題。解決思路:

快取預熱:目的就是在系統上線前,將資料載入到快取中。解決思路:

快取演算法:

用redis實現分布式鎖

主要使用的命令:

實現思想:

redis集群配置檔案和集群狀態

redis cluster配置檔案和集群狀態詳解

redis的bigkey

如何提取redis中的大key

redis原理總結 很全面

redis單點吞吐量 單點tps達到8萬 秒,qps達到10萬 秒。redis的5中儲存型別 string list set map hash stored set redis的string型別 能表達3中型別 字串 整數和浮點數。根據場景相互間自動轉型,並且根據需要選取底層的承載方式 value內...

redis原理總結 很全面

redis單點吞吐量 單點tps達到8萬 秒,qps達到10萬 秒。redis的5中儲存型別 string list set map hash stored set redis的string型別 能表達3中型別 字串 整數和浮點數。根據場景相互間自動轉型,並且根據需要選取底層的承載方式 value內...

Redis原理介紹

redis是乙個基於key value的快取記憶體系統,類似於memcached,但是支援更複雜的資料結構list set sortedset,並且有持久化的功能。由於近期工作很多地方都用到了它,所以花了不少時間來閱讀文章 編碼實驗,了解一下 redis 都能做些什麼,能有什麼樣的效能表現。首先遇到...