新聞中心
redis 就是一個(gè)數(shù)據(jù)庫,不過與傳統(tǒng)數(shù)據(jù)庫不同的是 redis 的數(shù)據(jù)是存在內(nèi)存中的,所以讀寫速度非常快,因此 redis 被廣泛應(yīng)用于緩存方向,本篇文章重點(diǎn)為大家講解一下redis內(nèi)部運(yùn)作機(jī)制。

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),三山企業(yè)網(wǎng)站建設(shè),三山品牌網(wǎng)站建設(shè),網(wǎng)站定制,三山網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,三山網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
當(dāng)Redis服務(wù)器初始化的時(shí)候會(huì)創(chuàng)建 redis.h/REDIS_DEFAULT_DBNUM(后面簡寫 N ) 個(gè)數(shù)據(jù)庫,且數(shù)據(jù)庫的id是從 0 到 N-1 , 所有的數(shù)據(jù)庫保存到 redis.h/redisServer.db 數(shù)組中 。
在客戶端可以通過 “SELECT” 命令進(jìn)行切換,其中程序是直接用 redis.h/redisServer.db[number] 進(jìn)行切換。 但是,一些內(nèi)部程序,比如 AOF 程序、復(fù)制程序和 RDB 程序,需要知道當(dāng)前數(shù)據(jù)庫的號碼, 如果沒有 id 域的話,程序就只能在當(dāng)前使用的數(shù)據(jù)庫的指針,和 redisServer.db 數(shù)組中所 有數(shù)據(jù)庫的指針進(jìn)行對比,以此來弄清楚自己正在使用的是那個(gè)數(shù)據(jù)庫。
Redis數(shù)據(jù)庫的結(jié)構(gòu):
typeof struct redisDb{
int id ; // 數(shù)據(jù)庫的id
dict *dict ; // 保存著該數(shù)據(jù)庫的所有鍵值對 也被稱為鍵空間
dict *expires ; // 保存著鍵的過期時(shí)間
…..
} redisDb ;
Redis 是一個(gè)鍵值對 字典表,同樣Redis數(shù)據(jù)庫存儲(chǔ)形式也是鍵值對 字典表
鍵是字符串
值可以是字符型、list 列表、 hash、集合以及 有序集合其中之一
Redis 數(shù)據(jù)庫增、刪、改、查等操作的鍵空間操作:
新增: Redis會(huì)在鍵空間字典中增加一個(gè)鍵-值對,其中鍵為一個(gè)字符串,值為任意一個(gè)值類型。 刪除: Redis會(huì)在鍵空間字典中刪去對應(yīng)鍵的鍵-值對 更新: Redis會(huì)在鍵空間字典中釋放之前對應(yīng)鍵的值對象,并讓鍵指向新的值對象 查詢: Redis會(huì)在鍵空間字典中查詢對應(yīng)鍵的值對象: 鍵不存在,返回NULL 鍵存在,且類型正確,返回正確的值 鍵存在,但類型不正確,返回類型錯(cuò)誤 其他操作: 除了上面展示的鍵值操作之外,還有很多針對數(shù)據(jù)庫本身的命令,也是通過對鍵空間進(jìn)行處理 來完成的: FLUSHDB 刪除鍵空間中的所有鍵值對 RANDOMKEY 從鍵空間中隨機(jī)返回一個(gè)鍵 DBSIZE 返回鍵空間中鍵值對的數(shù)量 EXISTS 檢查給定鍵是否存在于鍵空間中 RENAME 在鍵空間中,對給定鍵進(jìn)行改名
鍵的過期時(shí)間
在Redis數(shù)據(jù)庫中,所有鍵的過期時(shí)間都保存在RedisDb結(jié)構(gòu)體的expires字典中,其中鍵為一個(gè)指向dict 字典(鍵空間)里某個(gè)鍵的指針,值為改建的過期時(shí)間,用long long型表示。
Redis 有四個(gè)命令可以設(shè)置鍵的生存時(shí)間(可以存活多久)和過期時(shí)間(什么時(shí)候到期): EXPIRE 以秒為單位設(shè)置鍵的生存時(shí)間; PEXPIRE 以毫秒為單位設(shè)置鍵的生存時(shí)間; EXPIREAT 以秒為單位,設(shè)置鍵的過期 UNIX 時(shí)間戳; PEXPIREAT 以毫秒為單位,設(shè)置鍵的過期 UNIX 時(shí)間戳。
雖然有那么多種不同單位和不同形式的設(shè)置方式,但是 expires 字典的值只保存“以毫秒為單 位的過期 UNIX 時(shí)間戳” ,這就是說,通過進(jìn)行轉(zhuǎn)換,所有命令的效果最后都和 PEXPIREAT 命令的效果一樣。
過期鍵的清除
定時(shí)清除: 在創(chuàng)建KEY的時(shí)候創(chuàng)建一個(gè)定時(shí)任務(wù),在KEY到期時(shí)定時(shí)任務(wù)會(huì)被觸發(fā),第一時(shí)間清除過期KEY。 此種操作對內(nèi)存最友好,不會(huì)有垃圾數(shù)據(jù)占用內(nèi)存情況存在 缺點(diǎn)是會(huì)造成很大的服務(wù)器負(fù)載,特別是CPU負(fù)載高的時(shí)候,CPU很大一部分負(fù)載用在了刪除不必要的KEY上了
惰性清除: 放任鍵空間的鍵不管,每次查詢KEY的時(shí)候先去校驗(yàn)KEY是否過期,過期則刪除,不過期則正常返回相應(yīng)的VALUE。 此種操作對CPU最友好,這種策略僅限于當(dāng)前KEY,相關(guān)不必要的KEY不會(huì)造成CPU負(fù)載 缺點(diǎn)是:容易造成內(nèi)存空間浪費(fèi),特別是當(dāng)系統(tǒng)中存在大量過期KEY且很少被用到,這十分影響非常依賴于內(nèi)存大小Redis的性能
定期刪除: 由定時(shí)腳本cron定時(shí)對expires的鍵掃描判斷是否有過期的KEY存在,如存在,將其刪除掉。 這是一種折中方案,既不會(huì)過多消耗CPU,又可以定時(shí)清楚惰性刪除忽略到的不必要的內(nèi)存消耗
Redis采用的“惰性清除”和“定期清楚”相結(jié)合的方式,其中定期刪除模式是在規(guī)定的時(shí)間限制內(nèi),盡 可能地遍歷各個(gè)數(shù)據(jù)庫的 expires 字典,隨機(jī)地檢查一部分鍵的過期時(shí)間,并刪除其中的過期鍵。
偽代碼如下:
def activeExpireCycle():
# 遍歷數(shù)據(jù)庫(不一定能全部都遍歷完,看時(shí)間是否足夠)
for db in server.db:
# MAX_KEY_PER_DB 是一個(gè) DB 最大能處理的 key 個(gè)數(shù) # 它保證時(shí)間不會(huì)全部用在個(gè)別的 DB 上(避免饑餓) i=0 while (i # 數(shù)據(jù)庫為空,跳出 while ,處理下個(gè) DB if db.is_empty(): break # 隨機(jī)取出一個(gè)帶 TTL 的鍵 key_with_ttl = db.expires.get_random_key() # 檢查鍵是否過期,如果是的話,將它刪除 if is_expired(key_with_ttl): db.deleteExpiredKey(key_with_ttl) # 當(dāng)執(zhí)行時(shí)間到達(dá)上限,函數(shù)就返回,不再繼續(xù) # 這確保刪除操作不會(huì)占用太多的 CPU 時(shí)間 if reach_time_limit(): return i += 1
Redis 過期鍵刪除的主從同步問題(Redis的機(jī)制是由主節(jié)點(diǎn)統(tǒng)一控制)
如果服務(wù)器是主節(jié)點(diǎn),當(dāng)它刪除一個(gè)過期鍵之后,會(huì)顯式的向所有附屬節(jié)點(diǎn)發(fā)送一條DEL命令 如果服務(wù)器是附屬節(jié)點(diǎn),當(dāng)它判斷到當(dāng)前KEY已經(jīng)過期,會(huì)將該鍵過期的消息發(fā)送給主服務(wù)器,主服務(wù)器刪除后向所有的從服務(wù)器節(jié)點(diǎn)發(fā)送DEL命令。
從服務(wù)器節(jié)點(diǎn)不自主的對鍵進(jìn)行刪除是為了保持和主服務(wù)器數(shù)據(jù)的絕對一致性,即當(dāng)一個(gè)過期鍵還存在主服務(wù)器上,這個(gè)鍵在所有的從服務(wù)器上也不會(huì)被刪除。
分享名稱:詳解redis內(nèi)部運(yùn)作機(jī)制
本文來源:http://m.fisionsoft.com.cn/article/dhjoigi.html


咨詢
建站咨詢
