redis 中乙個字段 修改map redis原理

2021-10-13 23:59:11 字數 3546 閱讀 6697

redis單點吞吐量

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

redis的5中儲存型別

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

redis的string型別

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

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

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)、已準備好寫入資料

對來自客戶端的命令執行結束後,接下來處理定時任務(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實現分布式鎖

主要使用的命令:

實現思想:

mysql多表乙個字段

先執行這三個 show variables like group concat max len 查詢大小 set global group concat max len 10240000 設定大小滿足執行後能夠存放所有的插入語句 set session group concat max len 10...

oracle分組後合併其中乙個字段 (2)

1 select wmsys.wm concat t.org orgs,t.area name from select concat concat b.abbreviation,b.org name org,a.area name area name from t organization b le...

mysql乙個欄位為空時使用另乙個字段排序

表中有兩個日期欄位createdate,updatedate。其中updatedate可以為空,要求使用updatedate排序,如果updatedate為空則使用createdate排序,結果要順序排下來。按照常規方法 這樣的結果是為空的資料排在了最下面,不符合要求。這樣試試 這樣排的結果是先按u...