Redis內(nèi)存管理和持久化機(jī)制

內(nèi)存管理

Redis是一個(gè)基于內(nèi)存的key-value的數(shù)據(jù)庫(kù),其內(nèi)存管理是非常重要的;其針對(duì)不同操作系統(tǒng)的差異杖玲,同時(shí)方便自己實(shí)現(xiàn)相關(guān)的統(tǒng)計(jì)函數(shù),封裝了不同平臺(tái)的實(shí)現(xiàn)淘正,具體可參閱深入redis內(nèi)部--內(nèi)存管理摆马;

Redis支持多種不同的數(shù)據(jù)類型,如下:

  • String
  • List
  • Set
  • Hash
  • Sorted Set

下面就詳細(xì)來(lái)介紹下其數(shù)據(jù)結(jié)構(gòu)和編碼鸿吆。

數(shù)據(jù)結(jié)構(gòu)

所有的Redis對(duì)象都被封裝在RedisObject這個(gè)結(jié)構(gòu)體當(dāng)中囤采,如下:

typedef struct redisObject {
    unsigned type,           // 4字節(jié),數(shù)據(jù)類型(String,List,Set,Hash,Sorted Set)
    unsigned encoding,   // 4字節(jié)惩淳,編碼方式
    unsigned lru,              // 24字節(jié)
    int refcount,               // 對(duì)象引用計(jì)數(shù)
    void *ptr                    // 數(shù)據(jù)具體存儲(chǔ)的指向
} robj;

數(shù)據(jù)類型的常用編碼方式如下:

數(shù)據(jù)類型 常用 少量數(shù)據(jù) 特殊情況
String RAW EMBSTR INT O(1) O(1)
List LinkedList ZipList pop:O(1)
lset:O(N)
push:O(1)
lindex:O(N)
Set Hash Table INTSET(少量整數(shù)) O(1) O(1)
Hash Hash Table ZipList O(1) O(1)
Sorted Set SkipList ZipList zscore:O(1)
zrank:O(logN)
O(logN)

編碼方式介紹:

  • RAW:RedisObject的ptr指向名為sds的空間斑唬,包含Len和Free頭部和buf的實(shí)際數(shù)據(jù),F(xiàn)ree采用了某種預(yù)分配(若Len<1M黎泣,則Free分配與Len大小一致的空間恕刘;若大于Len>=1M,則Free分配1M空間抒倚;SDS的長(zhǎng)度為L(zhǎng)en+Free+buf+1(額外的1字節(jié)用于保存空字符))
  • EMBSTR:與RedisObject在連續(xù)的一塊內(nèi)存空間褐着,省去了多次內(nèi)存分配;條件是字符串長(zhǎng)度<=39
  • INT:字符串的特殊編碼方式托呕,若存儲(chǔ)的字符串是整數(shù)時(shí)含蓉,則ptr本身會(huì)等于該整數(shù),省去了sds的空間開銷项郊;實(shí)際上Redis在啟動(dòng)時(shí)會(huì)默認(rèn)創(chuàng)建10000個(gè)RedisObject馅扣,代表0-10000的整數(shù)
  • ZipList(壓縮列表):除了一些標(biāo)志性字段外用一塊類似數(shù)組的連續(xù)空間來(lái)進(jìn)行存儲(chǔ),缺點(diǎn)是讀寫時(shí)整個(gè)壓縮列表都需要更改着降,一般能達(dá)到10倍的壓縮比差油。Hash默認(rèn)值為512,List默認(rèn)是64
  • Hash Table:默認(rèn)初始大小為4,使用鏈地址法解決hash沖突蓄喇;rehash策略:將原來(lái)表中的數(shù)據(jù)rehash并放入新表发侵,之后替換;大量rehash可能會(huì)造成服務(wù)不可用妆偏,因此Redis使用漸進(jìn)式rehash策略刃鳄,分批進(jìn)行

過(guò)期機(jī)制

Redis為了不影響正常的讀寫操作,一般只會(huì)在必要或CPU空閑的時(shí)候做過(guò)期清理的動(dòng)作钱骂;

  1. 必要:一次事件循環(huán)結(jié)束叔锐,進(jìn)入事件偵聽前
  2. CPU空閑:系統(tǒng)空閑時(shí)做后臺(tái)定時(shí)清理任務(wù)(時(shí)間限制為25%的CPU時(shí)間);Redis后臺(tái)清理任務(wù)默認(rèn)100ms執(zhí)行1次见秽,25%限制是表示25ms用來(lái)執(zhí)行key清理

過(guò)期key清理算法:

  1. 依次遍歷所有db掌腰;
  2. 從db中隨機(jī)取得20個(gè)key,判斷是否過(guò)期张吉,若過(guò)期,則剔除催植;
  3. 若有5個(gè)以上的key的過(guò)期肮蛹,則重復(fù)步驟2,否則遍歷下一個(gè)db
  4. 清理過(guò)程中若達(dá)到了時(shí)間限制创南,則退出清理過(guò)程

持久化

Redis支持四種持久化方式伦忠;如下:

  • 定時(shí)快照方式(snapshot)[RDB方式]
  • 基于語(yǔ)句追加文件的方式(aof)
  • 虛擬內(nèi)存(vm) <font color="red">已被放棄</font>
  • Diskstore方式<font color="red">實(shí)驗(yàn)階段</font>

前兩種方式為小數(shù)據(jù)量追加落地方式;后兩種為嘗試存儲(chǔ)數(shù)據(jù)超過(guò)物理內(nèi)存時(shí)稿辙,一次性落地方式昆码;

定時(shí)快照方式(snapshot)

該方式實(shí)際是在Redis內(nèi)部執(zhí)行一個(gè)定時(shí)任務(wù),根據(jù)redis.conf中配置的save的時(shí)間間隔去檢查當(dāng)前數(shù)據(jù)改變次數(shù)和時(shí)間是否滿足配置邻储,如果滿足則從父進(jìn)程fork(copy-on-write機(jī)制)出一個(gè)子進(jìn)程赋咽,通過(guò)該子進(jìn)程遍歷內(nèi)存來(lái)轉(zhuǎn)換成rdb文件;

# Save the DB on disk:
# 設(shè)置sedis進(jìn)行數(shù)據(jù)庫(kù)鏡像的頻率吨娜。
# 900秒(15分鐘)內(nèi)至少1個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化)脓匿。
# 300秒(5分鐘)內(nèi)至少10個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化)。
# 60秒(1分鐘)內(nèi)至少10000個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化)宦赠。
save 900 1
save 300 10
save 60 10000
 
stop-writes-on-bgsave-error yes

# 在進(jìn)行鏡像備份時(shí),是否進(jìn)行壓縮陪毡。yes:壓縮,但是需要一些cpu的消耗勾扭。no:不壓縮毡琉,需要更多的磁盤空間。
rdbcompression yes
# 一個(gè)CRC64的校驗(yàn)就被放在了文件末尾妙色,當(dāng)存儲(chǔ)或者加載rbd文件的時(shí)候會(huì)有一個(gè)10%左右的性能下降桅滋,為了達(dá)到性能的最大化,你可以關(guān)掉這個(gè)配置項(xiàng)身辨。
rdbchecksum yes
# 快照的文件名
dbfilename dump.rdb
# 存放快照的目錄
dir /var/lib/redis 

缺陷:快照只是一段時(shí)間的數(shù)據(jù)的體現(xiàn)虱歪,若發(fā)生宕機(jī)蜂绎,數(shù)據(jù)會(huì)丟失

基于語(yǔ)句追加文件的方式(aof)

類似mysql的binlog方式,每個(gè)數(shù)據(jù)發(fā)生改變都會(huì)追加至一個(gè)log文件中笋鄙;

# 是否開啟AOF师枣,默認(rèn)關(guān)閉(no)
appendonly yes
# 指定 AOF 文件名
appendfilename appendonly.aof
# Redis支持三種不同的刷寫模式:
# appendfsync always #每次收到寫命令就立即強(qiáng)制寫入磁盤,是最有保證的完全的持久化萧落,但速度也是最慢的践美,一般不推薦使用。
appendfsync everysec #每秒鐘強(qiáng)制寫入磁盤一次找岖,在性能和持久化方面做了很好的折中陨倡,是受推薦的方式。
# appendfsync no #完全依賴OS的寫入许布,一般為30秒左右一次兴革,性能最好但是持久化最沒(méi)有保證,不被推薦蜜唾。

缺陷:追加log文件可能過(guò)大杂曲,恢復(fù)慢;實(shí)時(shí)寫log會(huì)影響redis本身性能

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末袁余,一起剝皮案震驚了整個(gè)濱河市擎勘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颖榜,老刑警劉巖棚饵,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異掩完,居然都是意外死亡噪漾,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門且蓬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)怪与,“玉大人,你說(shuō)我怎么就攤上這事缅疟》直穑” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵存淫,是天一觀的道長(zhǎng)耘斩。 經(jīng)常有香客問(wèn)我,道長(zhǎng)桅咆,這世上最難降的妖魔是什么括授? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上荚虚,老公的妹妹穿的比我還像新娘薛夜。我一直安慰自己,他們只是感情好版述,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布梯澜。 她就那樣靜靜地躺著,像睡著了一般渴析。 火紅的嫁衣襯著肌膚如雪晚伙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天俭茧,我揣著相機(jī)與錄音咆疗,去河邊找鬼。 笑死母债,一個(gè)胖子當(dāng)著我的面吹牛午磁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毡们,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼迅皇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了漏隐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤奴迅,失蹤者是張志新(化名)和其女友劉穎青责,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體取具,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脖隶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了暇检。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片产阱。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖块仆,靈堂內(nèi)的尸體忽然破棺而出构蹬,到底是詐尸還是另有隱情,我是刑警寧澤悔据,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布庄敛,位于F島的核電站,受9級(jí)特大地震影響科汗,放射性物質(zhì)發(fā)生泄漏藻烤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怖亭。 院中可真熱鬧涎显,春花似錦、人聲如沸兴猩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)峭跳。三九已至膘婶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛀醉,已是汗流浹背悬襟。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拯刁,地道東北人脊岳。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像垛玻,于是被迫代替她去往敵國(guó)和親割捅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容