㈠ 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 記錄壓縮列表記錄的數據
㈡ Redis哨兵機制原理淺析
上一篇文章Redis主從復制原理中簡要地說明了主從復制的一個基本原理,包含全量復制、復制積壓緩沖區與增量復制等內容,有興趣的同學可以先看下。
利用主從復制,可以實現讀寫分離、數據備份等功能。但如果主庫宕機後,需要運維人員手動地將一個從庫提升為新主庫,並將其他從庫slaveof新主庫,以此來實現故障恢復。
因此, 主從模式的一個缺點,就在於無法實現自動化地故障恢復 。Redis後來引入了哨兵機制,哨兵機制大大提升了系統的高可用性。
哨兵,就是站崗放哨的,時刻監控周圍的一舉一動,在第一時間發現敵情並發出及時的警報。
Redis中的哨兵(Sentinel), 則是一個特殊的Redis實例 ,不過它並不存儲數據。也就是說,哨兵在啟動時,不會去載入RDB文件。
關於Redis的持久化,可以參考我的另外一篇文章 談談Redis的持久化——AOF日誌與RDB快照
上圖就是一個典型的哨兵架構,由數據節點與哨兵節點構成,通常會部署多個哨兵節點。
哨兵主要具有三個作用, 監控、選主與通知 。
監控:哨兵會利用心跳機制,周期性不斷地檢測主庫與從庫的存活性
選主:哨兵檢測到主庫宕機後,選擇一個從庫將之切換為新主庫
通知:哨兵會將新主庫的地址通知到所有從庫,使得所有從庫與舊主庫slaveof新主庫,也會將新主庫的地址通知到客戶端上
我會在下文詳細講一下監控與選主的過程
哨兵系統是通過3個定時任務,來完成對主庫、從庫與哨兵之間的探活。
首先我們會在配置文件中配置主庫地址,這樣哨兵在啟動後,會以 每隔10秒 的頻率向主庫發送info命令,從而獲得當前的主從拓撲關系,這樣就拿到了所有從庫的地址。
接著 每隔2秒 ,會使用pub/sub(發布訂閱)機制,在主庫上的 sentinel :hello的頻道上發布消息,消息內容包括哨兵自己的ip、port、runid與主庫的配置。
每個哨兵都會訂閱該頻道,在該頻道上發布與消費消息,從而實現哨兵之間的互相感知。
利用啟動配置與info命令可以獲取到主從庫地址,利用發布訂閱可以感知到其餘的哨兵節點。
在此基礎上,哨兵會 每隔1秒 向主庫、從庫與其他哨兵節點發送PING命令,因此來進行互相探活。
當某個哨兵在 **down-after-milliseconds(默認是30秒) **配置的連續時間內,仍然沒有收到主庫的正確響應,則當前哨兵會認為主庫 主觀下線 ,並將其標記為sdown(subjective down)
為了避免當前哨兵對主庫的誤判,因此這個時候還需要參考其他哨兵的意見。
接著當前哨兵會向其他哨兵發送 sentinel is-master-down-by-addr 命令, 如果有半數以上(由quorum參數決定)的哨兵認為主庫確實處於主觀下線狀態,則當前哨兵認為主庫客觀下線 ,標記為odown(objective down)
一旦某個主庫被認定為客觀下線時,這個時候需要進行哨兵選舉,選舉出一個領導者哨兵,來完成主從切換的過程。
哨兵A在向其他哨兵發送 sentinel is-master-down-by-addr 命令時,同時要求其他哨兵同意將其設置為Leader,也就是想獲得其他哨兵的投票。
在每一輪選舉中,每個哨兵僅有一票。投票遵循先來先到的原則,如果某個哨兵沒有投給別人,就會投給哨兵A。
首先獲得半數以上投票的哨兵,將被選舉稱為Leader。
這里的哨兵選舉,採用的是Raft演算法。這里不對Raft做詳細的探討,有興趣的同學,可以參考我的另外一篇文章 22張圖,帶你入門分布式一致性演算法Raft
該文章採用大量的圖例,相信你可以從中學習到全新的知識,從而打開分布式一致性演算法的大門,大夥們記得等我搞完Paxos與Zab。
過半投票機制也常用於很多演算法中,例如RedLock,在半數以上的節點上加鎖成功,才代表申請到了分布式鎖,具體可參考這篇文章的最後 我用了上萬字,走了一遍Redis實現分布式鎖的坎坷之路,從單機到主從再到多實例,原來會發生這么多的問題
在Zookeeper選舉中,同樣也用到了過半投票機制,在這篇文章中 面試官:能給我畫個Zookeeper選舉的圖嗎? 我從源碼角度分析了Zookeeper選舉的過程。
在選舉到領導者哨兵後,將由該哨兵完成故障恢復工作。
故障恢復分為以下兩步:
詳細說一下第一步,挑選是有條件的。首先要過濾出不健康的節點,再按某種規則排序,最後取第一個從庫,我們直接從源碼入手:
因此,以下從庫會被過濾出:
剩下的節點,就是健康的節點,此時再執行一次快速排序,排序的規則如下:
本文算是Redis哨兵的一個入門文章,主要講了哨兵的作用,例如監控、選主和通知。
在Redis讀寫分離的情況下,使用哨兵可以很輕松地做到故障恢復,提升了整體的可用性。
但哨兵無法解決Redis單機寫的瓶頸,這就需要引入集群模式,相應的文章也被列為明年的寫作計劃中。
</article>
㈢ redis源碼好在哪裡之命令處理
接收請求:讀入客戶端發送過來的請求(query_string),解析請求獲取命令
查找命令:在hash表中查找命令,判斷用戶輸入的命令是否正確、是否存在
預檢查:檢查命令的參數個數是否滿足要求,客戶端是否已經認證等
執行命令:執行命令
執行完成:發送結果到客戶端,記錄慢日誌等
㈣ 《Redis設計與實現》epub下載在線閱讀,求百度網盤雲資源
《Redis設計與實現》(黃健宏)電子書網盤下載免費在線閱讀
資源鏈接:
鏈接:https://pan..com/s/1_lHh14OiOgGfcHYYigtQEA
書名:Redis設計與實現
作者:黃健宏
豆瓣評分:8.6
出版社:機械工業出版社
出版年份:2014-6
頁數:388
內容簡介:
【編輯推薦】
系統而全面地描述了 Redis 內部運行機制
圖示豐富,描述清晰,並給出大量參考信息,是NoSQL資料庫開發人員案頭必備
包括大部分Redis單機特徵,以及所有多機特性
【讀者評價】
這本書描述的知識點很豐富,覆蓋很全,裡面提到特性較多,有不少我們也沒用過 :) 每個命令內部的機制的介紹很不錯,很多估計也是首次有詳細文檔介紹。——楊衛華(@TimYang)新浪微博技術總監
近幾年Redis以其高性能、高靈活性的優點,變得越來越流行。但很多人在使用Redis時,僅僅還是停留在比較表層的功能性認識,缺乏對內部機制原理的深入理解。本書是huangz同學長期對Redis源碼的閱讀心得結晶,書中對Redis的各個方面都進行了詳細且深入的講解,將復雜的原理用最簡單的方式為大家解構和講解,強烈推薦給每一位Redis的使用者閱讀。—— iammutex,NoSQLFan站長,樂視網技術經理
Redis 是近些年來特別火爆的 NoSQL 之一。縱觀中外各種書籍還沒有一本能對 Redis 內部進行深入剖析,《Redis 設計與實現》可謂開此先河。常和作者在網上交流,知道作者為這本書付出了大量的心血。這本書行文流暢,思路清晰,詳細地介紹了 Redis 源碼的方方面面。無論是想學習 NoSQL、網路編程的初學者,還是源碼控的進階者,本書都會有很大的幫助。—— 阮若夷,支付寶高級專家
【內容簡介】
本書全面而完整地講解了Redis的內部機制與實現方式,對Redis的大多數單機功能以及所有多機功能的實現原理進行了介紹,展示了這些功能的核心數據結構以及關鍵的演算法思想,圖示豐富,描述清晰,並給出大量參考信息。通過閱讀本書,讀者可以快速、有效地了解Redis的內部構造以及運作機制,更好、更高效地使用Redis。
本書主要分為四大部分。第一部分「數據結構與對象」介紹了Redis中的各種對象及其數據結構,並說明這些數據結構如何影響對象的功能和性能。第二部分「單機資料庫的實現」對Redis實現單機資料庫的方法進行了介紹,包括資料庫、RDB持久化、AOF持久化、事件等。第三部分「多機資料庫的實現」對Redis的Sentinel、復制、集群三個多機功能進行了介紹。第四部分「獨立功能的實現」對Redis中各個相對獨立的功能模塊進行了介紹,涉及發布與訂閱、事務、Lua腳本、排序、二進制位數組、慢查詢日誌、監視器等。
作者簡介:
黃健宏 軟體開發者,他喜歡函數式編程,熱愛開源軟體。出於對資料庫的強烈興趣,他開始閱讀和分析 Redis 源代碼,並對 Redis 2.6 和 Redis 3.0 的源代碼進行了詳細注釋。
㈤ redis什麼時候用哈希
假定我們有一個hashmap的邏輯結構,用戶編號的為15的人,name是dlf,school是x
當我們在redic-cli命令行下敲下 hset id:15 name dlf時
redis裡面都發生了什麼事情呢?
任何一個使用過redis的用戶,即使沒有看過redis的源碼,想一下這個過程,那麼肯定都包含下面這幾步
1 socket連接
2 redis-server收到命令信息
3 redis-server解析命令信息(找到對應的命令,及附帶的參數)
4 調用對應的命令
5 返回結果
當然在redis-cli發送命令之前,redis-server首先啟動,然後載入各種配置,初始化伺服器等等。
在這篇博客里,我們只介紹第四點,就是找到redis內部的命令後,並且也已經分析出了參數,如何調用的過程。
首先我們看一個時序圖(那個,我得聲明,我並沒有學習過時序圖的精確概念,下面的圖大概只能說明調用過程,如果繪制的某些部分不符合時序圖的規定,大家見諒哦)換句話說,如果第一次執行hset user:id name zhangsan
dictadd會返回ok,然後跳出dictreplace
至於第一次調用hset userid:14 school x
與hset userid:14 name lisi
會怎麼樣,大家自己想吧
[java]view plain
[java]view plain
閱讀全文
㈥ Redis源碼分析之事件循環
本篇我們來講Redis的事件循環,Redis的事件循環會根據系統選擇evport、epoll、kqueue或select來進行IO多路復用,我們這里只分析epoll。
首先我們來看一下Redis的IO多路復用對事件循環(aeEventLoop)提供的介面。
以epoll(ae_epoll.c)為例,先來看一下Redis的IO多路復用的使用過程:
首先需要創建,即調用aeApiCreate:
aeApiState結構體有兩個成員,events和epfd。events用於存儲就緒的epoll事件,epfd存儲epoll的文件描述符。aeApiCreate的主要邏輯是為aeApiState分配存儲空間,調用epoll_create系統調用創建epoll並獲取描述符,最後將aeApiState賦值給aeEventLoop的apidata。
然後在有新的文件描述符(比如接受了一個新連接)需要加入到epoll中時,調用aeApiAddEvent:
參數fd是需要監視的文件描述符,mask標明是需要監視可讀還是可寫事件。aeApiAddEvent的主要邏輯是調用系統調用epoll_ctl注冊或修改添加事件的監聽類型到epoll。
然後在有文件描述符失效或者需要修改監聽類型時,調用aeApiDelEvent:
參數fd是需要刪除的文件描述符,mask標明是需要刪除可讀還是可寫事件。aeApiDelEvent主要邏輯是調用系統調用epoll_ctl刪除或修改刪除事件的監聽類型到epoll。
然後需要檢查是否有就緒的事件,調用aeApiPoll:
tvp是等待時間,一般而言,這個值是0(不是NULL)代表沒有就緒事件立即返回。主要邏輯是調用系統調用epoll_wait拿到就緒事件保存到events中,然後將events中的就緒事件復制到事件循環aeEventLoop的fired中,最後返回就緒事件的數量。
我們來分析一下Redis的事件循環(ae.c)。
先看主要介面:
創建過程:
初始化aeEventLoop和aeApiState並返回aeEventLoop。
注冊文件事件:
存儲到events中並調用aeApiAddEvent注冊到epoll中。
注冊定時事件:
創建aeTimeEvent並將其插入到定時事件鏈表的頭部。
主循環:
不停的調用aeProcessEvents拉取並處理事件。
接下來看aeProcessEvents的邏輯:
再看一下定時事件的觸發,也就是processTimeEvents的邏輯:
遍歷注冊的定時事件,找出到期的事件並調用處理函數,如果處理函數返回了下次執行的時間,則更新下次觸發的時間,否則刪除該事件。
㈦ php面試題 memcache和redis的區別
Redis與Memcached的區別傳統MySQL+ Memcached架構遇到的問題實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。2.Memcached與MySQL資料庫數據一致性問題。3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。4.跨機房cache同步問題。眾多NoSQL百花齊放,如何選擇最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解決以下幾種問題1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。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支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。Redis只會緩存所有的 key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計 算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以 保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存 中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個 操作,直到子線程完成swap操作後才可以進行修改。使用Redis特有內存模型前後的情況對比:VM off: 300k keys, 4096 bytes values: 1.3G usedVM on: 300k keys, 4096 bytes values: 73M usedVM off: 1 million keys, 256 bytes values: 430.12M usedVM on: 1 million keys, 256 bytes values: 160.09M usedVM on: 1 million keys, values as large as you want, still: 160.09M used當 從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。 這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行 批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程 池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。補充的知識點:memcached和redis的比較1 網路IO模型Memcached是多線程,非阻塞IO復用的網路模型,分為監聽主線程和worker子線程,監聽線程監聽網路連接,接受請求後,將連接描述字pipe 傳遞給worker線程,進行讀寫IO, 網路層使用libevent封裝的事件庫,多線程模型可以發揮多核作用,但是引入了cache coherency和鎖的問題,比如,Memcached最常用的stats 命令,實際Memcached所有操作都要對這個全局變數加鎖,進行計數等工作,帶來了性能損耗。(Memcached網路IO模型)Redis使用單線程的IO復用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操作來說,單線程可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單線程模型實際會嚴重影響整體吞吐量,CPU計算過程中,整個IO調度都是被阻塞住的。2.內存管理方面Memcached使用預分配的內存池的方式,使用slab和大小不同的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內存池的方式可以省去申請/釋放內存的開銷,並且能減小內存碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在內存仍然有很大空間時,新的數據也可能會被剔除,原因可以參考Timyang的文章:/memcached/)。Memcached的客戶端軟體實現非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang, Lua等。當前Memcached使用廣泛,除了LiveJournal以外還有Wikipedia、Flickr、Twitter、Youtube和WordPress等。在Window系統下,Memcached的安裝非常方便,只需從以上給出的地址下載可執行軟體然後運行memcached.exe –d install即可完成安裝。在Linux等系統下,我們首先需要安裝libevent,然後從獲取源碼,make && make install即可。默認情況下,Memcached的伺服器啟動程序會安裝到/usr/local/bin目錄下。在啟動Memcached時,我們可以為其配置不同的啟動參數。1.1 Memcache配置Memcached伺服器在啟動時需要對關鍵的參數進行配置,下面我們就看一看Memcached在啟動時需要設定哪些關鍵參數以及這些參數的作用。1)-p Memcached的TCP監聽埠,預設配置為11211;2)-U Memcached的UDP監聽埠,預設配置為11211,為0時表示關閉UDP監聽;3)-s Memcached監聽的UNIX套接字路徑;4)-a 訪問UNIX套接字的八進制掩碼,預設配置為0700;5)-l 監聽的伺服器IP地址,默認為所有網卡;6)-d 為Memcached伺服器啟動守護進程;7)-r 最大core文件大小;8)-u 運行Memcached的用戶,如果當前為root的話需要使用此參數指定用戶;9)-m 分配給Memcached使用的內存數量,單位是MB;10)-M 指示Memcached在內存用光的時候返回錯誤而不是使用LRU演算法移除數據記錄;11)-c 最大並發連數,預設配置為1024;12)-v –vv –vvv 設定伺服器端列印的消息的詳細程度,其中-v僅列印錯誤和警告信息,-vv在-v的基礎上還會列印客戶端的命令和相應,-vvv在-vv的基礎上還會列印內存狀態轉換信息;13)-f 用於設置chunk大小的遞增因子;14)-n 最小的chunk大小,預設配置為48個位元組;15)-t Memcached伺服器使用的線程數,預設配置為4個;16)-L 嘗試使用大內存頁;17)-R 每個事件的最大請求數,預設配置為20個;18)-C 禁用CAS,CAS模式會帶來8個位元組的冗餘;2. Redis簡介Redis是一個開源的key-value存儲系統。與Memcached類似,Redis將大部分數據存儲在內存中,支持的數據類型包括:字元串、哈希表、鏈表、集合、有序集合以及基於這些數據類型的相關操作。Redis使用C語言開發,在大多數像Linux、BSD和Solaris等POSIX系統上無需任何外部依賴就可以使用。Redis支持的客戶端語言也非常豐富,常用的計算機語言如C、C#、C++、Object-C、PHP、Python、Java、Perl、Lua、Erlang等均有可用的客戶端來訪問Redis伺服器。當前Redis的應用已經非常廣泛,國內像新浪、淘寶,國外像Flickr、Github等均在使用Redis的緩存服務。Redis的安裝非常方便,只需從bin目錄下。在啟動Redis伺服器時,我們需要為其指定一個配置文件,預設情況下配置文件在Redis的源碼目錄下,文件名為redis.conf。php面試題 memcache和redis的區別
㈧ RedisTokenStore 源碼解析 以及內存泄漏問題
前端時間,正好在做公司許可權相關的架構問題,然後選擇了Spring OAuth2來作為公司許可權框架,先記錄下目前遇到原生問題吧,後續有時間再來整理這個框架的整體脈絡;
RedisTokenStore 主要是來做token持久化到redis的工具類
我們先來看下緩存到redis中有哪些key
ACCESS :用來存放 AccessToken 對象(登錄的token值,還有登錄過期時間,token刷新值)
AUTH_TO_ACCESS :緩存的也是AccessToken 對象,是可以根據用戶名和client_id來查找當前用戶的AccessToken
AUTH :用來存放用戶信息(OAuth2Authentication),有許可權信息,用戶信息等
ACCESS_TO_REFRESH :可以根據該值,通過AccessToken找到refreshToken
REFRESH :用來存放refreshToken
REFRESH_TO_ACCESS :根據refreshToken來找到AccessToken
CLIENT_ID_TO_ACCESS :存放當前client_id有多少AccessToken
UNAME_TO_ACCESS :當沒有做單點登錄的話,可以使用該key,根據用戶名查找當前用戶有多少AccessToken可以使用
根據client_id和用戶名,來獲取當前用戶的accessToken,如果緩存中的OAuth2Authentication已經過期,或者雷勇有變化,則會重新更新緩存;
緩存OAuth2AccessToken 和 OAuth2Authentication 對象,該方法主要在登錄時調用,會把上面說的所有key值都緩存起來;
再看下,移除accessToken時
目前主要是看這幾個方法,其他方法也挺簡單的,主要是一些redis緩存操作的;
client_id_to_access 和 uname_to_access 使用的是set集合,眾所周知redis的set集合的過期時間是按照整個key來設置的;
每次登陸時,會先根據client_id和用戶名去緩存中查找是否有可使用的AccessToken,如果有則返回緩存中的值,沒有則生成新的;
所以每次登陸都會往這兩個集合中放入新的accessToken,如果當某個用戶在AccessToken有效期內沒有操作,則當前用戶的登陸信息會被動下線,access 和 auth 中緩存的值都會過期,再次登陸時就查找不到了;
但是如果當前平台用戶量不小,那麼一直都會有人操作,client_id_to_access 這個集合就會一直續期,那麼過期了的accessToken就會一直存在該集合中,且不會減少,造成內存泄漏;
1.自己實現TokenStore,修改client_id_to_access 數據結構
2.寫個定時任務,定期掃描client_id_to_access ,清除掉已經過期的token
3.如果不需要知道當前有哪些用戶登錄,或者該功能已經用了其他方式實現的,可以直接去掉這兩個redis key
㈨ redis源碼解讀:單線程的redis是如何實現高速緩存的
redis可能是最近幾年最火的緩存資料庫方案了,在各個高並發領域都有應用。
這篇文章,我們將從源代碼的角度來分析一下,為何如此一個高性能,高應用的緩存,會是單線程的方案,當然一個方案的高性能,高並發是多方面的綜合因素,其它的因素我們將在後續解讀。後續分析主要以LINUX操作系統為基礎,這也是redis應用最廣的平台。
單線程最大的受限是什麼?就是CPU,現在伺服器一般已經是多CPU,而單線程只能使用到其中的一個核。
redis作為一個網路內存緩存資料庫,在實現高性能時,主要有4個點。
1.網路高並發,高流量的數據處理。
一個非同步,高效,且對CPU要求不高的網路模型,這個模型主要是由OS來提供的,目前在LINUX最主流使用的是EPOLL,這個網上介紹很多,主要是基於事件驅動的一個非同步模型。
2.程序內部的合理構架,調用邏輯,內存管理。
redis在採用純C實現時,整體調用邏輯很短,但在內存方面,適當的合並了一些對象和對齊,比如sds等,在底層使用了內存池,在不同情況下使用的不太一樣。
但整體處理上沒有NGINX的內池設計巧妙,當然二者不太一樣,NGINX是基於請求釋放的邏輯來設計的,因此針對請求,可以一次申請大塊,分量使用,再最後統一釋放。
3.數據復制的代價,不管是讀取數據或是寫入數據,一般都是需要有數據復制的過程。
數據復制其實就是一次內存,真正的代價是在於存在大VALUE,當value值長度超過16KB時,性能會開始下降。因為單線程的原因,如果存在一個超大VALUE,比如20MB,則會因為這個請求卡住整個線程,導致後續的請求進不來,雖然後面的請求是能快速處理的小請求。
4.redis中數據結構中演算法的代價,有些結構在大數據量時,代價是很高的。
很多時間,大家忽略了演算法的運算代碼,因為像memcached等這類是完全的KV緩存,不存在什麼演算法,除了一個KEY的查找定位HASH演算法。
而redis不一樣,提供了不少高階的數據對象,這些對象具有上層的一些演算法能力,而這些能力是需要比如GEO模塊。
㈩ 學習redis 源代碼,使用哪個版本好
Redis支持數據的持久化,可以將內存中的數據保存在磁碟中,重啟的時候可以再次載入進行使用。Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。Redis支持數據的備份,即master-slave模式的數據備份。