天天看點

Redis代碼閱讀1--Redis啟動原理



前面寫了一篇文章簡單介紹Redis的list結構。再寫完之後,我覺得有必要熟悉Redis的啟動過程和如何讀取Redis的指令,是以本文将通過分析代碼來介紹Redis的啟動過程,通過檢視Redis 的啟動腳本,得知Redis的啟動時從Redis.c的main方法開始的。Redis啟動可以分為以下幾個步驟:

  1. 初始化Redis伺服器全局配置
  2. 重置伺服器Save參數(具體下文詳解)和加載配置檔案
  3. 初始化伺服器
  4. 加載資料庫
  5. 開始網絡監聽

   一,初始化Redis伺服器全局配置。這一步驟主要是主要是根據Redis.h中設定的Static值來初始化Redis伺服器配置,這裡設定是Redis伺服器的預設配置。如:

  • TCP Port,Redis Client的預設Timeout;
  • Redis預設的資料庫數目;
  • Redis Append 持久化方式的參數設定;
  • Redis的所支援的各種資料結構的預設值的設定;
  • Redis記憶體Swap相關設定;
  • Redis Master & Slave相關的配置;
  • Redis Command Table初始化。

  二,加載配置檔案:

      這一步是通過讀取的配置檔案來對Redis伺服器進行設定,将會覆寫上一步的某些預設設定。打開下載下傳下來的Redis源代碼,我們可以看到其根目錄下有一個預設的配置檔案redis.conf。需要注意的是,如果在啟動Redis的時候沒有指定配置檔案,則Redis伺服器在啟動的時候是不會加載這個預設的配置檔案進行配置的。而且這個預設的配置檔案和第一步中得全局預設預設配置不盡相同,比如針對Redis的Append模式的資料儲存政策的配置,redis.conf裡面的設定是:

save 900 1 -------15分鐘内一次更新

save 300 10 ------5分鐘内10次更新

save 60 10000 ---1分鐘内10000次更新。

而上一步裡面的預設預設配置确實:

save 60*60 1 -------一個小時内1次更新

save 300 100 ------5分鐘内100次更新

    是以我們在啟動Redis的時候如果預設配置不能滿足要求,則需要指明配置檔案進行配置。

   三,初始化伺服器:

   初始化伺服器是在initServer()方法中完成的,次方法利用上兩步設定的參數進一步初始化伺服器:

  • 建立用來維護clients和slaves的list
  • 建立共享對象。redisObject這個struct裡有個變量叫做refcount,這個變量就是用來實作共享的。Redis的對象目前Redis隻支援共享StringObject。Redis的共享對象有兩大類比:第一類:Redis server的各種操作需要經常用到的各類對象,如:Redis Command的分隔符 "\r\n",用于Redis command的reply的"+OK\r\n"或者"-ERR\r\n"等對象,因為在Redis的各種操作這類對象要被頻繁使用,是以就在啟動Redis的時候建立好,然後共用這些對象,減少時間成本和空間成本;第二,類的共享對象就是對應于數字的StringObject,如:Set

    "olylakers1" 1234; Set "olylakes2" 1234;在Redis内部,"olylakers1"和"olylakers2"這兩個key都指向由數字1234轉化的StringObject。這樣在海量資料和特定存儲内容下,可以節省大量的記憶體空間。可用通過REDIS_SHARED_INTEGERS這個參數來指定Redis啟動的時候建立多少個第二類共享對象,預設的參數是10000,即建立的StrongObject個取值範圍是0-9999之間。

  • 建立Pub/Sub通道
  • 初始化網絡監聽EventLoop的相關内容,如eventLoop,timeEvent,fileEvent等
  • 如果開啟了VM,則初始化虛拟記憶體相關的IO/Thread

  四,加載資料:

   根據配置的不同,Redis加載資料的源也不一樣,如果在配置檔案裡設定了appendonly  yes(預設是no),那麼就從appendfile加載資料,反之則從RedisDb加載資料

  •   從appendfile加載資料:我們先來看一下appendfile的内容是什麼。下面的一條記錄摘取自appendfile:SET $9 olylakers $3 oly。很顯,appendfile儲存的就是redis server接收到的各種指令,那麼從appendfile加載資料就是redis server從appenfile裡面讀取這些指令的記錄,然後重新把這些指令執行一遍即可。需要注意的是,如果開啟了VM,那麼在從appendfile加載資料的時候可能要涉及swap操作。
  • 從redisdb加載資料:如果沒有開啟appendonly,那麼則需要從db file加載資料到記憶體,其過程是:
    1. 通過處理select指令,選擇DB
    2. 然後從db file讀取key和value
    3. 檢查key是否過期,如果過期則跳過這個key,如果不過期,則把資料Add到對應的db的dict中
    4. 如果開啟了VM,則從db file中load資料,也可能涉及到swap操作

  五,開始網絡監聽:

         Redis的網絡監聽沒有采用libevent等,而是自己實作了一套簡單的機遇event驅動的API,具體見ae.c。因為這一部分内容比較多,是以後面會單獨寫篇文章來描述其過程。

   以上五個部分就是Redis啟動的全部過程,

Redis代碼閱讀1--Redis啟動原理
http://olylakers.iteye.com/blog/1228198