Redis 設計與實現 (二)--資料庫

K戰神發表於2018-01-24
typedef struct redisDb {
    dict *dict;                 /* The keyspace for this DB */
    dict *expires;              /* Timeout of keys with a timeout set */
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP) */
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
    struct evictionPoolEntry *eviction_pool;    /* Eviction pool of keys */
    int id;                     /* Database ID */
    PORT_LONGLONG avg_ttl;          /* Average TTL, just for stats */
} redisDb;

一、資料庫  預設是16個

二、切換資料庫:select 0~15

三、資料庫鍵空間  *dict  

  儲存了資料庫中的所有鍵值對,它是一個字典稱之為鍵空間

  鍵空間的鍵 =資料庫的鍵;

  鍵空間的值=資料庫的值;

  3.1 新增新鍵:新鍵新增到鍵空間字典中

  3.2 刪除鍵:鍵空間 刪除鍵所對應的鍵值對物件

  3.3 更新鍵:對鍵空間的鍵對應的值進行更新

四、讀寫鍵控制元件時的維護操作

  4.1 讀取一個鍵之後,判斷鍵是否存在,更新伺服器的鍵空間命中次數或者鍵空間未命中次數。 

127.0.0.1:6379> INFO stats
# Stats
total_connections_received:3
total_commands_processed:20
instantaneous_ops_per_sec:0
total_net_input_bytes:1026
total_net_output_bytes:31711
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:8  //命中次數
keyspace_misses:0 //未命中次數
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:261
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

 

  4.2  伺服器會更新LRU(最後一次使用)時間,用於計算鍵的空閒時間

    OBJECT idletime key   毫秒

127.0.0.1:6379> OBJECT idletime sun
(integer) 827

 

    4.3 如果發現鍵過期,先刪除這個鍵,然後執行後續操作

  4.4 如果這個鍵被監視 WATCH key  ,標記為髒(dirty)。伺服器每次修改一個鍵,都會對髒鍵進行+1

  4.5 資料庫開通通知功能,每次修改鍵,都會傳送通知。

 

 五、設定鍵的生存時間或者過期時間 

   EXPIRE key ttl    秒數

   PEXPIRE key ttl   毫秒數

   EXPIREAT key timestamp  秒數時間戳

   PEXPIREAT  key timestamp  毫秒數時間戳

 六、儲存過期時間

   dict *expires 過期時間鍵的集合
   過期字典鍵-指標,指向資料庫的鍵
   過期字典值-long,毫秒精度時間戳

七、移除過期時間
  PERSIST
  在過期字典集合中,查詢鍵,解除過期設定。
  TTL
  秒為單位鍵的剩餘生存週期
  PTTL 毫秒級
127.0.0.1:6379> get msg
(nil)
127.0.0.1:6379> set msg "sun"
OK
127.0.0.1:6379> PEXPIREAT msg 1161680467300000
(integer) 1
127.0.0.1:6379> get msg
"sun"
127.0.0.1:6379> TTL msg
(integer) 1160163662408
127.0.0.1:6379> PERSIST msg
(integer) 1
127.0.0.1:6379> TTL msg
(integer) -1

 

八、過期鍵的刪除策略
惰性刪除+定期刪除

九、過期鍵的影響
9.1 RDB檔案 -- SAVA 和 BGSAVE,已經過期的鍵不儲存
  主伺服器載入RDB--忽略過期間
  從伺服器載入RDB--全域性匯入,主從同步時,從資料會被清空。
9.2 AOF檔案
 AOF檔案寫入
  執行惰性或者定期刪除之前 -- 過期間不受影響
  執行惰性或者定期刪除之後 -- 追加一條刪除記錄
AOF重寫
  過期鍵不會寫入到AOF檔案中
9.3 複製
  複製模式,從伺服器依賴於主伺服器,從伺服器即便接收到刪除命令,也不會刪除。

十、資料庫通知
  客戶端訂閱指定的變化通知
  
127.0.0.1:6379> SUBSCRIBE __KEYSPACE@0__:MSG
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "__KEYSPACE@0__:MSG"
3) (integer) 1

相關文章