[Redis原始碼閱讀]當你啟動Redis的時候,Redis做了什麼

hoohack發表於2018-05-26

直奔主題,當啟動Redis的時候,Redis執行了哪些操作?

假設Redis安裝在了/usr/local/目錄下,那麼啟動Redis是通過執行/usr/local/bin/redis-server -c xxx.conf的方式執行。 redis-server是一個通過編譯server.c檔案生成的程式,因此想了解redis是怎麼啟動的,應該從server.c/main函式入手。

具體程式碼可見:server.c

閱讀main函式,可以知道,整個啟動大致分為五個步驟:初始化server結構體、從配置資料夾在載入引數、初始化伺服器、載入持久化檔案、開始監聽事件。

redis用redisServer結構體來儲存伺服器的屬性和資訊,在server.c檔案中,定義了一個全域性伺服器變數:

struct redisServer server;
複製程式碼

另外,還定義了一個redis命令表,表裡包含了命令以及命令對應的函式:

struct redisCommand redisCommandTable;
複製程式碼

在main函式裡,redis先呼叫initServerConfig函式初始化server結構體。

初始化server結構體

main函式呼叫initServerConfig函式為server的屬性設定一些預設值,比如:

伺服器的執行ID

redis使用的預設埠號,是在server.h定義的CONFIG_DEFAULT_SERVER_PORT = 6379

LRU時鐘

主從備份相關引數

命令表

慢查詢引數

接著會儲存當前執行的路徑和引數,為之後的伺服器重啟使用相同的引數做準備:

server.executable = getAbsolutePath(argv[0]);
server.exec_argv = zmalloc(sizeof(char*)*(argc+1));
server.exec_argv[argc] = NULL;
for (j = 0; j < argc; j++) server.exec_argv[j] = zstrdup(argv[j]);
複製程式碼

從配置檔案載入引數

redis的啟動引數有很多,其中一個是指定配置檔案。初始化server結構體後,大部分的屬性都會設定到結構體了,但是有部分引數可以通過配置檔案重現設定,比如redis的埠號。

初始化完server結構體後,函式會判斷是否有指定配置檔案,如果有,呼叫loadServerConfig函式,從配置檔案載入相關的配置,把配置檔案對應的引數設定到server結構體。

讀取配置檔案載入引數的流程如下:

  • 1、分割引數項
  • 2、跳過空行和註釋行
  • 3、逐項檢查,如果引數合法,設定配置值到server屬性

至此,redisServer大部分屬性已經設定好,server還有很多資料結構沒有初始化,initServer函式就繼續接下來的初始化工作。

初始化伺服器資料結構

main函式會呼叫initServer函式初始化伺服器狀態,比如:

程式ID

客戶端連結串列

從庫連結串列

為常用值建立共享物件

初始化事件迴圈器

開啟TCP開始監聽套接字

建立伺服器的資料庫,並初始化內部狀態

為serverCron定時器建立時間事件定時器

如果開啟了AOF,開啟AOF檔案,之後恢復資料時需要用到

初始化慢查詢日誌模組

初始化後臺IO模組

載入持久化檔案,還原資料庫

初始化完伺服器的狀態後,伺服器已經處於一個可啟動狀態,因為redis有持久化特性,伺服器還需要載入相應的檔案來還原之前資料庫的資料。 判斷Redis當前開啟了哪種模式,如果是AOF,則通過AOF還原資料庫的資料,否則,載入RDB檔案,通過RDB檔案還原資料庫的資料。

開始監聽事件

main函式會設定beforeSleep和afterSleep回撥函式,然後呼叫aeMain函式啟動事件迴圈器,開始監聽事件。aeMain函式是一個死迴圈,不斷的監聽新請求的到來。

/*
 * server啟動後,main函式的最終步驟,不斷地呼叫beforesleep和aeProcessEvents
 */
void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);
        aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
    }
}
複製程式碼

綜上所述,伺服器整個啟動簡化流程圖如下:

redisServer

原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

更多精彩內容,請關注個人公眾號。

[Redis原始碼閱讀]當你啟動Redis的時候,Redis做了什麼

相關文章