redis源碼分析(5)-- redis數據庫

1、服務器中的數據庫redis

Redis服務器將全部數據庫信息保存在redis.h/redisServer, redisServer包含db數組,以下:數據庫

1 struct redisServer {
2 //...
3 redisDb *db;
4 //...
5 };

每一個Redis客戶端都有本身的目標數據庫,默認狀況是db[0],客戶端能夠經過SELECT命令切換數據庫。數組

例如,某個客戶端使用SELECT 1命令切換到1號數據庫,服務器

每一個redisDb的結構爲:性能

 1 typedef struct redisDb {
 2     dict *dict;                 /* The keyspace for this DB */
 3     dict *expires;              /* Timeout of keys with a timeout set */
 4     dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP) */
 5     dict *ready_keys;           /* Blocked keys that received a PUSH */
 6     dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
 7     struct evictionPoolEntry *eviction_pool;    /* Eviction pool of keys */
 8     int id;                     /* Database ID */
 9     long long avg_ttl;          /* Average TTL, just for stats */
10 } redisDb;

下面介紹各個部分做用。this

2、數據庫鍵空間spa

Redis是一個key-value數據庫,redisDb中的dict字典元素存儲了DB中的全部key-value pair,這個字典dict即爲數據庫的鍵空間。指針

鍵空間的鍵即爲數據庫的鍵,每一個鍵是一個字符串對象code

鍵空間的值即爲數據庫的值,每一個值能夠是字符串對象、hash對象、列表對象等。對象

一個典型的鍵空間以下:

2.1 數據庫增刪查改

一、增長鍵

直接調用SET <key> <value>。

二、刪除鍵

調用DEL <key>

三、更新鍵

一樣使用SET 命令,覆蓋以前的value。

4 獲取鍵內容

GET <key>

 

2.2 鍵的超時時間

經過EXPIRE <key> <ttl>能夠設置鍵的生存時間,通過指定的秒數之後,服務器會自動刪除超過生存時間的鍵。

redisDb中的expires字典保存數據庫中全部鍵的過時時間,記爲過時字典。

過時字典中的鍵是一個指針,指向鍵空間dict中的某個對象。

過時字典的值是一個long long類型的整數,保存過時字典鍵指向的數據庫對象的過時時間。

 過時刪除策略包括:

  • 定時刪除
    • 含義:在設置key的過時時間的同時,爲該key建立一個定時器,讓定時器在key的過時時間來臨時,對key進行刪除
    • 優勢:保證內存被儘快釋放
    • 缺點:
      • 若過時key不少,刪除這些key會佔用不少的CPU時間,在CPU時間緊張的狀況下,CPU不能把全部的時間用來作要緊的事兒,還須要去花時間刪除這些key
      • 定時器的建立耗時,若爲每個設置過時時間的key建立一個定時器(將會有大量的定時器產生),性能影響嚴重
      • 沒人用
  • 惰性刪除
    • 含義:key過時的時候不刪除,每次從數據庫獲取key的時候去檢查是否過時,若過時,則刪除,返回null。
    • 優勢:刪除操做只發生在從數據庫取出key的時候發生,並且只刪除當前key,因此對CPU時間的佔用是比較少的,並且此時的刪除是已經到了非作不可的地步(若是此時還不刪除的話,咱們就會獲取到了已通過期的key了)
    • 缺點:若大量的key在超出超時時間後,好久一段時間內,都沒有被獲取過,那麼可能發生內存泄露(無用的垃圾佔用了大量的內存)
  • 按期刪除
    • 含義:每隔一段時間執行一次刪除過時key操做
    • 優勢:
      • 經過限制刪除操做的時長和頻率,來減小刪除操做對CPU時間的佔用--處理"定時刪除"的缺點
      • 按期刪除過時key--處理"惰性刪除"的缺點
    • 缺點
      • 在內存友好方面,不如"定時刪除"
      • 在CPU時間友好方面,不如"惰性刪除"
    • 難點
      • 合理設置刪除操做的執行時長(每次刪除執行多長時間)和執行頻率(每隔多長時間作一次刪除)(這個要根據服務器運行狀況來定了)

、Redis採用的過時策略

惰性刪除+按期刪除

  • 惰性刪除流程(實如今db.c/expireIfNeed
    • 在進行get或setnx等操做時,先檢查key是否過時,
    • 若過時,刪除key,而後執行相應操做;
    • 若沒過時,直接執行相應操做
  • 按期刪除流程(簡單而言,對指定個數個庫的每個庫隨機刪除小於等於指定個數個過時key,實如今redis.c/activeExpireCycle
    • 遍歷每一個數據庫(就是redis.conf中配置的"database"數量,默認爲16)
      • 檢查當前庫中的指定個數個key(默認是每一個庫檢查20個key,注意至關於該循環執行20次,循環體時下邊的描述)
        • 若是當前庫中沒有一個key設置了過時時間,直接執行下一個庫的遍歷
        • 隨機獲取一個設置了過時時間的key,檢查該key是否過時,若是過時,刪除key
        • 判判定期刪除操做是否已經達到指定時長,若已經達到,直接退出按期刪除。
相關文章
相關標籤/搜索