国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從零單排學(xué)Redis【白銀】

denson / 2568人閱讀

摘要:對(duì)于數(shù)據(jù)結(jié)構(gòu)哈希表我們?cè)谏弦黄惨呀?jīng)詳細(xì)說(shuō)了。鍵空間示意圖的數(shù)據(jù)庫(kù)就是使用字典哈希表來(lái)作為底層實(shí)現(xiàn)的,對(duì)數(shù)據(jù)庫(kù)的增刪改查都是構(gòu)建在字典哈希表的操作之上的。

前言
只有光頭才能變強(qiáng)

今天繼續(xù)來(lái)學(xué)習(xí)Redis,上一篇從零單排學(xué)Redis【青銅】已經(jīng)將Redis常用的數(shù)據(jù)結(jié)構(gòu)過(guò)了一遍了。如果還沒(méi)看的同學(xué)可以先去看一遍再回來(lái)~

這篇主要講的內(nèi)容有:

Redis服務(wù)器的數(shù)據(jù)庫(kù)

Redis對(duì)過(guò)期鍵的處理

Redis持久化策略(RDB和AOF)

本文力求簡(jiǎn)單講清每個(gè)知識(shí)點(diǎn),希望大家看完能有所收獲

一、Redis服務(wù)器中的數(shù)據(jù)庫(kù)

我們應(yīng)該都用過(guò)MySQL,MySQL我們可以在里邊創(chuàng)建好幾個(gè)庫(kù):

同樣地,Redis服務(wù)器中也有數(shù)據(jù)庫(kù)這么一個(gè)概念。如果不指定具體的數(shù)量,默認(rèn)會(huì)有16個(gè)數(shù)據(jù)庫(kù)。

上面的命令我們也可以發(fā)現(xiàn):當(dāng)切換到15號(hào)數(shù)據(jù)庫(kù),存進(jìn)15號(hào)庫(kù)的數(shù)據(jù),再切換到0號(hào)數(shù)據(jù)庫(kù)時(shí),是獲取不到的!

這說(shuō)明,數(shù)據(jù)庫(kù)與數(shù)據(jù)庫(kù)之間的數(shù)據(jù)是隔離的。

1.1Redis數(shù)據(jù)庫(kù)的原理

Redis服務(wù)器用redisServer結(jié)構(gòu)體來(lái)表示,其中redisDb是一個(gè)數(shù)組,用來(lái)保存所有的數(shù)據(jù)庫(kù),dbnum代表數(shù)據(jù)庫(kù)的數(shù)量(這個(gè)可以配置,默認(rèn)是16)

struct redisServer{  

    //redisDb數(shù)組,表示服務(wù)器中所有的數(shù)據(jù)庫(kù)
    redisDb *db;  
    
    //服務(wù)器中數(shù)據(jù)庫(kù)的數(shù)量
    int dbnum;  
  
}; 

我們知道Redis是C/S結(jié)構(gòu),Redis客戶端通過(guò)redisClient結(jié)構(gòu)體來(lái)表示:

typedef struct redisClient{  
   
    //客戶端當(dāng)前所選數(shù)據(jù)庫(kù)
    redisDb *db;  
     
}redisClient;

Redis客戶端連接Redis服務(wù)端時(shí)的示例圖:

Redis中對(duì)每個(gè)數(shù)據(jù)庫(kù)用redisDb結(jié)構(gòu)體來(lái)表示:

typedef struct redisDb { 
    int id;         // 數(shù)據(jù)庫(kù)ID標(biāo)識(shí)
    dict *dict;     // 鍵空間,存放著所有的鍵值對(duì)              
    dict *expires;  // 過(guò)期哈希表,保存著鍵的過(guò)期時(shí)間                          
    dict *watched_keys; // 被watch命令監(jiān)控的key和相應(yīng)client    
    long long avg_ttl;  // 數(shù)據(jù)庫(kù)內(nèi)所有鍵的平均TTL(生存時(shí)間)     
} redisDb;

從代碼上我們可以發(fā)現(xiàn)最重要的應(yīng)該是dict *dict,它用來(lái)存放著所有的鍵值對(duì)。對(duì)于dict數(shù)據(jù)結(jié)構(gòu)(哈希表)我們?cè)谏弦黄惨呀?jīng)詳細(xì)說(shuō)了。一般我們將存儲(chǔ)所有鍵值對(duì)的dict稱為鍵空間

鍵空間示意圖:

Redis的數(shù)據(jù)庫(kù)就是使用字典(哈希表)來(lái)作為底層實(shí)現(xiàn)的,對(duì)數(shù)據(jù)庫(kù)的增刪改查都是構(gòu)建在字典(哈希表)的操作之上的

例如:

redis > GET message

"hello world"

1.2鍵的過(guò)期時(shí)間

Redis是基于內(nèi)存,內(nèi)存是比較昂貴的,容量肯定比不上硬盤(pán)的。就我們現(xiàn)在一臺(tái)普通的機(jī)子,可能就8G內(nèi)存,但硬盤(pán)隨隨便便都1T了。

因?yàn)槲覀兊膬?nèi)存是有限的。所以我們會(huì)干掉不常用的數(shù)據(jù),保留常用的數(shù)據(jù)。這就需要我們?cè)O(shè)置一下鍵的過(guò)期(生存)時(shí)間了。

設(shè)置鍵的生存時(shí)間可以通過(guò)EXPIRE或者PEXPIRE命令。

設(shè)置鍵的過(guò)期時(shí)間可以通過(guò)EXPIREAT或者PEXPIREAT命令。

其實(shí)EXPIREPEXPIREEXPIREAT這三個(gè)命令都是通過(guò)PEXPIREAT命令來(lái)實(shí)現(xiàn)的。

我們?cè)趓edisDb結(jié)構(gòu)體中還發(fā)現(xiàn)了dict *expires;屬性,存放所有鍵過(guò)期的時(shí)間。

舉個(gè)例子基本就可以理解了:

redis > PEXPIREAT message 1391234400000
(integer) 1

設(shè)置了message鍵的過(guò)期時(shí)間為1391234400000

既然有設(shè)置過(guò)期(生存)時(shí)間的命令,那肯定也有移除過(guò)期時(shí)間,查看剩余生存時(shí)間的命令了:

PERSIST(移除過(guò)期時(shí)間)

TTL(Time To Live)返回剩余生存時(shí)間,以秒為單位

PTTL以毫秒為單位返回鍵的剩余生存時(shí)間

1.2.1過(guò)期策略

上面我們已經(jīng)能夠了解到:過(guò)期鍵是保存在哈希表中了。那這些過(guò)期鍵到了過(guò)期的時(shí)間,就會(huì)立馬被刪除掉嗎??

要回答上面的問(wèn)題,需要我們了解一下刪除策略的知識(shí),刪除策略可分為三種

定時(shí)刪除(對(duì)內(nèi)存友好,對(duì)CPU不友好)

到時(shí)間點(diǎn)上就把所有過(guò)期的鍵刪除了。

惰性刪除(對(duì)CPU極度友好,對(duì)內(nèi)存極度不友好)

每次從鍵空間取鍵的時(shí)候,判斷一下該鍵是否過(guò)期了,如果過(guò)期了就刪除。

定期刪除(折中)

每隔一段時(shí)間去刪除過(guò)期鍵,限制刪除的執(zhí)行時(shí)長(zhǎng)和頻率。

Redis采用的是惰性刪除+定期刪除兩種策略,所以說(shuō),在Redis里邊如果過(guò)期鍵到了過(guò)期的時(shí)間了,未必被立馬刪除的!

1.2.2內(nèi)存淘汰機(jī)制

如果定期刪除漏掉了很多過(guò)期key,也沒(méi)及時(shí)去查(沒(méi)走惰性刪除),大量過(guò)期key堆積在內(nèi)存里,導(dǎo)致redis內(nèi)存塊耗盡了,咋整?

我們可以設(shè)置內(nèi)存最大使用量,當(dāng)內(nèi)存使用量超出時(shí),會(huì)施行數(shù)據(jù)淘汰策略

Redis的內(nèi)存淘汰機(jī)制有以下幾種:

一般場(chǎng)景:

使用 Redis 緩存數(shù)據(jù)時(shí),為了提高緩存命中率,需要保證緩存數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)。可以將內(nèi)存最大使用量設(shè)置為熱點(diǎn)數(shù)據(jù)占用的內(nèi)存量,然后啟用allkeys-lru淘汰策略,將最近最少使用的數(shù)據(jù)淘汰
二、Redis持久化

Redis是基于內(nèi)存的,如果不想辦法將數(shù)據(jù)保存在硬盤(pán)上,一旦Redis重啟(退出/故障),內(nèi)存的數(shù)據(jù)將會(huì)全部丟失。

我們肯定不想Redis里頭的數(shù)據(jù)由于某些故障全部丟失(導(dǎo)致所有請(qǐng)求都走M(jìn)ySQL),即便發(fā)生了故障也希望可以將Redis原有的數(shù)據(jù)恢復(fù)過(guò)來(lái),這就是持久化的作用。

Redis提供了兩種不同的持久化方法來(lái)講數(shù)據(jù)存儲(chǔ)到硬盤(pán)里邊:

RDB(基于快照),將某一時(shí)刻的所有數(shù)據(jù)保存到一個(gè)RDB文件中。

AOF(append-only-file),當(dāng)Redis服務(wù)器執(zhí)行寫(xiě)命令的時(shí)候,將執(zhí)行的寫(xiě)命令保存到AOF文件中。

2.1RDB(快照持久化)

RDB持久化可以手動(dòng)執(zhí)行,也可以根據(jù)服務(wù)器配置定期執(zhí)行。RDB持久化所生成的RDB文件是一個(gè)經(jīng)過(guò)壓縮的二進(jìn)制文件,Redis可以通過(guò)這個(gè)文件還原數(shù)據(jù)庫(kù)的數(shù)據(jù)。

有兩個(gè)命令可以生成RDB文件:

SAVE會(huì)阻塞Redis服務(wù)器進(jìn)程,服務(wù)器不能接收任何請(qǐng)求,直到RDB文件創(chuàng)建完畢為止。

BGSAVE創(chuàng)建出一個(gè)子進(jìn)程,由子進(jìn)程來(lái)負(fù)責(zé)創(chuàng)建RDB文件,服務(wù)器進(jìn)程可以繼續(xù)接收請(qǐng)求。

Redis服務(wù)器在啟動(dòng)的時(shí)候,如果發(fā)現(xiàn)有RDB文件,就會(huì)自動(dòng)載入RDB文件(不需要人工干預(yù))

服務(wù)器在載入RDB文件期間,會(huì)處于阻塞狀態(tài),直到載入工作完成。

除了手動(dòng)調(diào)用SAVE或者BGSAVE命令生成RDB文件之外,我們可以使用配置的方式來(lái)定期執(zhí)行:

在默認(rèn)的配置下,如果以下的條件被觸發(fā),就會(huì)執(zhí)行BGSAVE命令

    save 900 1              #在900秒(15分鐘)之后,至少有1個(gè)key發(fā)生變化,
    save 300 10            #在300秒(5分鐘)之后,至少有10個(gè)key發(fā)生變化
    save 60 10000        #在60秒(1分鐘)之后,至少有10000個(gè)key發(fā)生變化

原理大概就是這樣子的(結(jié)合上面的配置來(lái)看):

struct redisServer{
    // 修改計(jì)數(shù)器
    long long dirty;

    // 上一次執(zhí)行保存的時(shí)間
    time_t lastsave;

    // 參數(shù)的配置
    struct saveparam *saveparams;
};

遍歷參數(shù)數(shù)組,判斷修改次數(shù)和時(shí)間是否符合,如果符合則調(diào)用besave()來(lái)生成RDB文件

總結(jié):通過(guò)手動(dòng)調(diào)用SAVE或者BGSAVE命令或者配置條件觸發(fā),將數(shù)據(jù)庫(kù)某一時(shí)刻的數(shù)據(jù)快照,生成RDB文件實(shí)現(xiàn)持久化。

2.2AOF(文件追加)

上面已經(jīng)介紹了RDB持久化是通過(guò)將某一時(shí)刻數(shù)據(jù)庫(kù)的數(shù)據(jù)“快照”來(lái)實(shí)現(xiàn)的,下面我們來(lái)看看AOF是怎么實(shí)現(xiàn)的。

AOF是通過(guò)保存Redis服務(wù)器所執(zhí)行的寫(xiě)命令來(lái)記錄數(shù)據(jù)庫(kù)的數(shù)據(jù)的。

比如說(shuō)我們對(duì)空白的數(shù)據(jù)庫(kù)執(zhí)行以下寫(xiě)命令:

redis> SET meg "hello"
OK

redis> SADD fruits "apple" "banana" "cherry"
(integer) 3

redis> RPUSH numbers 128 256 512
(integer) 3 

Redis會(huì)產(chǎn)生以下內(nèi)容的AOF文件:

這些都是以Redis的命令請(qǐng)求協(xié)議格式保存的。Redis協(xié)議規(guī)范(RESP)參考資料:

https://www.cnblogs.com/tommy-huang/p/6051577.html

AOF持久化功能的實(shí)現(xiàn)可以分為3個(gè)步驟:

命令追加:命令寫(xiě)入aof_buf緩沖區(qū)

文件寫(xiě)入:調(diào)用flushAppendOnlyFile函數(shù),考慮是否要將aof_buf緩沖區(qū)寫(xiě)入AOF文件中

文件同步:考慮是否將內(nèi)存緩沖區(qū)的數(shù)據(jù)真正寫(xiě)入到硬盤(pán)

flushAppendOnlyFile函數(shù)的行為由服務(wù)器配置的appendfsyn選項(xiàng)來(lái)決定的:

    appendfsync always     # 每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫(xiě)入AOF文件。
    appendfsync everysec   # 每秒鐘同步一次,該策略為AOF的默認(rèn)策略。
    appendfsync no         # 從不同步。高效但是數(shù)據(jù)不會(huì)被持久化。

從字面上應(yīng)該就更好理解了,這里我就不細(xì)說(shuō)了...

下面來(lái)看一下AOF是如何載入與數(shù)據(jù)還原的:

創(chuàng)建一個(gè)偽客戶端(本地)來(lái)執(zhí)行AOF的命令,直到AOF命令被全部執(zhí)行完畢。

2.2.1AOF重寫(xiě)

從前面的示例看出,我們寫(xiě)了三條命令,AOF文件就保存了三條命令。如果我們的命令是這樣子的:

redis > RPUSH list "Java" "3y"
(integer)2

redis > RPUSH list "Java3y"
integer(3)

redis > RPUSH list "yyy"
integer(4)

同樣地,AOF也會(huì)保存3條命令。我們會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題:上面的命令是可以合并起來(lái)成為1條命令的,并不需要3條。這樣就可以讓AOF文件的體積變得更小

AOF重寫(xiě)由Redis自行觸發(fā)(參數(shù)配置),也可以用BGREWRITEAOF命令手動(dòng)觸發(fā)重寫(xiě)操作。

要值得說(shuō)明的是:AOF重寫(xiě)不需要對(duì)現(xiàn)有的AOF文件進(jìn)行任何的讀取、分析。AOF重寫(xiě)是通過(guò)讀取服務(wù)器當(dāng)前數(shù)據(jù)庫(kù)的數(shù)據(jù)來(lái)實(shí)現(xiàn)的

比如說(shuō)現(xiàn)在有一個(gè)Redis數(shù)據(jù)庫(kù)的數(shù)據(jù)如下:

新的AOF文件的命令如下,沒(méi)有一條是多余的

2.2.2AOF后臺(tái)重寫(xiě)

Redis將AOF重寫(xiě)程序放到子進(jìn)程里執(zhí)行(BGREWRITEAOF命令),像BGSAVE命令一樣fork出一個(gè)子進(jìn)程來(lái)完成重寫(xiě)AOF的操作,從而不會(huì)影響到主進(jìn)程。

AOF后臺(tái)重寫(xiě)是不會(huì)阻塞主進(jìn)程接收請(qǐng)求的,新的寫(xiě)命令請(qǐng)求可能會(huì)導(dǎo)致當(dāng)前數(shù)據(jù)庫(kù)和重寫(xiě)后的AOF文件的數(shù)據(jù)不一致

為了解決數(shù)據(jù)不一致的問(wèn)題,Redis服務(wù)器設(shè)置了一個(gè)AOF重寫(xiě)緩沖區(qū),這個(gè)緩存區(qū)會(huì)在服務(wù)器創(chuàng)建出子進(jìn)程之后使用

2.3RDB和AOF對(duì)過(guò)期鍵的策略

RDB持久化對(duì)過(guò)期鍵的策略:

執(zhí)行SAVE或者BGSAVE命令創(chuàng)建出的RDB文件,程序會(huì)對(duì)數(shù)據(jù)庫(kù)中的過(guò)期鍵檢查,已過(guò)期的鍵不會(huì)保存在RDB文件中

載入RDB文件時(shí),程序同樣會(huì)對(duì)RDB文件中的鍵進(jìn)行檢查,過(guò)期的鍵會(huì)被忽略

AOF持久化對(duì)過(guò)期鍵的策略:

如果數(shù)據(jù)庫(kù)的鍵已過(guò)期,但還沒(méi)被惰性/定期刪除,AOF文件不會(huì)因?yàn)檫@個(gè)過(guò)期鍵產(chǎn)生任何影響(也就說(shuō)會(huì)保留),當(dāng)過(guò)期的鍵被刪除了以后,會(huì)追加一條DEL命令來(lái)顯示記錄該鍵被刪除了

重寫(xiě)AOF文件時(shí),程序會(huì)對(duì)RDB文件中的鍵進(jìn)行檢查,過(guò)期的鍵會(huì)被忽略

復(fù)制模式:

主服務(wù)器來(lái)控制從服務(wù)器統(tǒng)一刪除過(guò)期鍵(保證主從服務(wù)器數(shù)據(jù)的一致性)

2.4RDB和AOF用哪個(gè)?

RDB和AOF并不互斥,它倆可以同時(shí)使用

RDB的優(yōu)點(diǎn):載入時(shí)恢復(fù)數(shù)據(jù)快、文件體積小。

RDB的缺點(diǎn):會(huì)一定程度上丟失數(shù)據(jù)(因?yàn)橄到y(tǒng)一旦在定時(shí)持久化之前出現(xiàn)宕機(jī)現(xiàn)象,此前沒(méi)有來(lái)得及寫(xiě)入磁盤(pán)的數(shù)據(jù)都將丟失。)

AOF的優(yōu)點(diǎn):丟失數(shù)據(jù)少(默認(rèn)配置只丟失一秒的數(shù)據(jù))。

AOF的缺點(diǎn):恢復(fù)數(shù)據(jù)相對(duì)較慢,文件體積大

如果Redis服務(wù)器同時(shí)開(kāi)啟了RDB和AOF持久化,服務(wù)器會(huì)優(yōu)先使用AOF文件來(lái)還原數(shù)據(jù)(因?yàn)锳OF更新頻率比RDB更新頻率要高,還原的數(shù)據(jù)更完善)

可能涉及到RDB和AOF的配置:

redis持久化,兩種方式
1、rdb快照方式
2、aof日志方式

----------rdb快照------------
save 900 1
save 300 10
save 60 10000

stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/rdb/

-----------Aof的配置-----------
appendonly no # 是否打開(kāi) aof日志功能

appendfsync always #每一個(gè)命令都立即同步到aof,安全速度慢
appendfsync everysec
appendfsync no 寫(xiě)入工作交給操作系統(tǒng),由操作系統(tǒng)判斷緩沖區(qū)大小,統(tǒng)一寫(xiě)入到aof  同步頻率低,速度快


no-appendfsync-on-rewrite yes 正在導(dǎo)出rdb快照的時(shí)候不要寫(xiě)aof
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb 


./bin/redis-benchmark -n 20000

官網(wǎng)文檔:

https://redis.io/topics/persistence#rdb-advantages

三、最后

現(xiàn)在臨近雙十一買阿里云服務(wù)器就特別省錢!之前我買學(xué)生機(jī)也要9.8塊錢一個(gè)月,現(xiàn)在最低價(jià)只需要8.3一個(gè)月!

無(wú)論是Nginx/Elasticsearch/Redis這些技術(shù)都是在Linux下完美運(yùn)行的,如果還是程序員新手,買一個(gè)學(xué)習(xí)Linux基礎(chǔ)命令,學(xué)習(xí)搭建環(huán)境也是不錯(cuò)的選擇。

如果有要買服務(wù)器的同學(xué)可通過(guò)我的鏈接直接享受最低價(jià):https://m.aliyun.com/act/team1111/#/share?params=N.FF7yxCciiM.pfn5xpli

如果大家有更好的理解方式或者文章有錯(cuò)誤的地方還請(qǐng)大家不吝在評(píng)論區(qū)留言,大家互相學(xué)習(xí)交流~~~

參考資料:

《Redis設(shè)計(jì)與實(shí)現(xiàn)》

《Redis實(shí)戰(zhàn)》

一個(gè)堅(jiān)持原創(chuàng)的Java技術(shù)公眾號(hào):Java3y,歡迎大家關(guān)注

3y所有的原創(chuàng)文章:

文章的目錄導(dǎo)航(腦圖+海量視頻資源):https://github.com/ZhongFuCheng3y/3y

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/72093.html

相關(guān)文章

  • 從零單排學(xué)Redis【鉑金一】

    摘要:前言只有光頭才能變強(qiáng)好的,今天我們要上鉑金段位了,如果還沒(méi)經(jīng)歷過(guò)青銅和白銀和黃金階段的,可以先去蹭蹭經(jīng)驗(yàn)再回來(lái)從零單排學(xué)青銅從零單排學(xué)白銀從零單排學(xué)黃金這篇文章主要講的是主從復(fù)制。 前言 只有光頭才能變強(qiáng) 好的,今天我們要上鉑金段位了,如果還沒(méi)經(jīng)歷過(guò)青銅和白銀和黃金階段的,可以先去蹭蹭經(jīng)驗(yàn)再回來(lái): 從零單排學(xué)Redis【青銅】 從零單排學(xué)Redis【白銀】 從零單排學(xué)Redis【黃金...

    wizChen 評(píng)論0 收藏0
  • 從零單排學(xué)Redis【黃金】

    摘要:當(dāng)被監(jiān)聽(tīng)的準(zhǔn)備好執(zhí)行連接應(yīng)答讀取等等操作時(shí),與操作相對(duì)應(yīng)的文件事件就會(huì)產(chǎn)生,根據(jù)文件事件來(lái)為關(guān)聯(lián)對(duì)應(yīng)的事件處理器,從而實(shí)現(xiàn)功能。服務(wù)器使用單線程單進(jìn)程的方式處理命令請(qǐng)求。 前言 只有光頭才能變強(qiáng) 好的,今天我們要上黃金段位了,如果還沒(méi)經(jīng)歷過(guò)青銅和白銀階段的,可以先去蹭蹭經(jīng)驗(yàn)再回來(lái): 從零單排學(xué)Redis【青銅】 從零單排學(xué)Redis【白銀】 看過(guò)相關(guān)Redis基礎(chǔ)的同學(xué)可以知道Re...

    Mr_houzi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<