Redis設計與實現-客戶端服務端與事件

事件
  1. redis服務器是事件驅動的,事件分爲文件事件與時間事件
    • 文件事件是服務器經過套接字與客戶端鏈接,二者之間的通訊會產生相應的文件事件,服務器監聽並處理這些事件完成網絡操做;
    • 時間事件是指redis服務器的定時操做
  2. redis基於reactor模式的文件事件處理器以單線程方式運行,並使用I/O多路複用程序來監聽多個套接字,並根據套接字目前執行的任務來爲套接字關聯不一樣的事件處理器。;
  3. 文件事件處理器由四部分組成:
    • 套接字
    • I/O多路複用程序:監聽多個套接字產生的文件事件並放到一個隊列,而後以有序同步,每次一個套接字的方式把產生對應事件的套接字傳送給文件事件分派器,待事件處理器處理完後再傳送下一個;
    • 文件事件分派器:接收I/O多路複用程序傳來的套接字,並根據套接產生的事件類型,調用相應的事件處理器處理;
    • 事件處理器:處理具體事件。如命令請求、回覆、鏈接應答等。
  4. 若是一個套接字便可讀又可寫,服務器會先讀後寫。
  5. 時間事件分爲定時事件與週期性事件,一個時間事件有3個屬性:全局惟一ID、到達時間when、事件處理器timeProc;
  6. 服務器將全部時間事件都放在一個無序鏈表中,每當時間事件執行器運行時,遍歷此鏈表,查找已到達的事件並調用相應的事件處理器。
  7. redis服務器變等待處理文件事件,並檢查當前是否有已經能夠處理的時間事件了,對它們的處理是同步有序原子的,不會中途中斷事件處理也不會進行搶佔,所以各事件處理器要儘量地減小阻塞時間。好比寫入字節超預設常量大小,命令服務器會主動用break跳出寫循環並將餘下的數據留到下次再寫。

以上文字來自Dimmacro,轉載請說明來源:http://www.cnblogs.com/dimmacro/ react

客戶端
  1. 每一個創建鏈接的客戶端,服務端都會爲期創建相應的redisClient結構,並追加到redisServer數據機構中用來保存客戶端的clients鏈表中;
  2. 客戶端通常有三種:
    • 普統統過connect函數鏈接到服務器,並有鏈接事件處理器建立的;
    • Lua腳本僞客戶端,服務器初始化時建立並一直存在直到關閉服務器;
    • AOF僞客戶端,執行載入AOF時使用,載入完成後會被關閉
  3. redisClient數據結構中重要的一些屬性及說明:
    • int fd:表示客戶端類型,-1表示僞客戶端,大於-1表示普通客戶端;
    • name:客戶端名字,須要使用CLIENT setname命令設置了纔有;
    • flags:客戶端目前所處的狀態,如主服務器、正在執行事務、阻塞等多種狀態;
    • sds querybuf:輸入緩衝區用於保存客戶端發送過來的命令請求,最大不能超過1GB,不然服務器會關閉此客戶端;
    • robj **argv:服務器對命令請求解析後獲得的命令及參數,argv[0]表示命令,其餘項表示參數
    • struct redisCommand *cmd:保存該命令對應的實現函數,須要的參數,命令總執行次數及消耗時間等;
    • 保存執行命令所獲得的回覆結果的輸出緩衝區,一個固定大小用於短小的回覆,最大16KB,一個可變大小用於大數據量的回覆;
    • int authenticated:身份驗證結果,0表示未經過,1表示經過
    • ctime:客戶端被建立的時間戳;
    • lastinteraction:客戶端與服務區最後一次交互的時間;
    • obuf_soft_limit_reached_time:輸出緩衝區第一次達到軟性限制的時間
  4. 客戶端被關閉的幾種狀況:
    • 客戶端進程退出或被殺死;
    • 客戶端發送了非法命令請求,被服務端關閉;
    • 客戶端處於非主從服務器狀態,或阻塞訂閱狀態,且超過timeout設置的時間時,被服務端關閉;
    • 發送命令請求超過1GB;
    • 命令回覆超過輸出緩衝區的硬性限制,或超過軟性限制時間內一致大於軟性限制的大小
  5.  

以上文字來自Dimmacro,轉載請說明來源:http://www.cnblogs.com/dimmacro/ redis

服務端
    1. redis服務端啓動初始化的前後過程:
      • 由redis.c/initServerConfig函數初始化服務器狀態結構server(此結構爲struct redisServer類型的實例變量),併爲結構中的各個屬性設置默認值,包括設置服務器的運行ID、運行頻率、配置文件路徑、運行架構、默認端口號、持久化條件、LRU時鐘以及建立命令表等通常屬性;
      • 載入用戶給定配置參數及配置文件,並對server對應默認屬性進行更新;
      • 調用initServer函數爲如下數據結構分配內存並根據須要爲其設置或管理初始化值:
        • server.clients鏈表:記錄全部與服務器相連的客戶端的狀態結構;
        • serer.db數組:包含全部數據庫;
        • 保存頻道訂閱信息的server.pubsub_channels字典以及保存模式訂閱信息的server.pubsub_patterns鏈表;
        • server.lua:執行lua腳本的lua環境;
        • server.slowlog:保存慢查詢日誌
      • initServer還會進行一些很是重要的設置,包括:
        • 爲服務器設置進程信號處理器;
        • 建立「OK」,「ERR"等經常使用共享對象,以免重複建立;
        • 打開服務器監聽端口,爲監聽套接字關聯應答事件處理器,等待服務器正式運行時接收客戶端的鏈接;
        • 打開或新建AOF文件,爲AOF寫入作好準備;
        • 初始化後臺I/O模塊(bio),爲未來的I/O作好準備
      • 載入RDB或AOF文件還原數據庫狀態
      • 打印ready to accept connections on port XXX,開始接收客戶端的鏈接請求並處理;    
    2. 客戶端發送請求命令到獲得回覆處理的全執行過程:
      • 客戶端將redis命令轉化成協議格式併發送到服務端;
      • 服務端讀取協議格式數據並保存到客戶端狀態的輸入緩衝區;
      • 對輸入緩衝區的數據jinx 分析,提取出命令、參數及參數個數;
      • 根據命令在命令表中查找對應的redisCommand對象;
      • 預備及執行前的檢測工做:包括參數個數、用戶身份、服務器內存佔用量、訂閱檢查、服務器是否正載入、是否開監視器等;
      • 執行redisCommand裏的方法,並把回覆信息保存到客戶端狀態的輸出緩衝區;
      • 執行後回覆前的檢測工做:是否增長到慢查詢、更新命令耗時及計數器、根據須要寫到AOF、必要的命令傳播到從服務器;
      • 將輸入緩衝區裏的回覆數據發送到客戶端
    3. serverCon函數默認每隔100毫秒執行一次,負責管理服務器資源,其主要執行如下操做:
      • 更新服務器時間緩存unixtime、mstime;
      • 更新LRU時鐘;
      • 更新服務器每秒執行命令次數;
      • 更新服務器內存峯值記錄;
      • 處理關閉sigterm信號,主要爲了關閉前作一些持久化;
      • 管理客戶端資源,包括檢查客戶端與服務端之間鏈接是否超時、釋放過長的客戶端緩衝區;
      • 管理數據庫資源,調用databaseCron函數對一些數據庫檢查,刪除過時鍵,並根據須要進行字典收縮;
      • 執行因bgsave被延遲的bgrewriteaof;
      • 檢查持久化操做的運行狀態,包括是否完成、是否正在進行或是否須要進行持久化等;
      • 若是開啓了AOF,將AOF緩衝區中的內容寫到AOF文件;
      • 關閉輸出緩衝區大小超過顯示的客戶端;
      • 增長記錄serverCron函數執行次數的cronloops計數器值

以上文字來自Dimmacro,轉載請說明來源:http://www.cnblogs.com/dimmacro/ 數據庫

相關文章
相關標籤/搜索