1. 客戶端
1.1 客戶端屬性
客戶端狀態包含的屬性分為兩類:
- 一類是比較通用的屬性,無論客戶端執行什么作業,都需要用到這些屬性,本節主要涉及這些屬性
- 另外一類是和特定功能相關的屬性,比如操作資料庫時用到的db屬性和dictid屬性,執行事務時需要用到的mstate屬性,以及執行WATCH命令時要用到的watched_keys屬性等等,
1.1.1 套接字描述符
CLIENT list命令可以顯示所有連接到服務器的普通客戶端,fd即為服務器連接客戶端所使用的套接字描述符,當fd=-1時,表示偽客戶端,用于載入AOF檔案并還原資料庫狀態,或者用于執行Lua腳本中包含的命令,

1.1.2 名字
默認情況下,一個連接到服務器的客戶端是沒有名字的,可以使用CLIENT setname命令為客戶端設定一個名字,讓客戶端身份變得更清晰,
1.1.3 標志
客戶端的標志屬性flags記錄了客戶端的角色以及客戶端目前的狀態
flags = <flag1> | <flag2> | ...
有關標志的含義可以在redis.h檔案中查看,
1.1.4 輸入緩沖區
客戶端的輸入緩沖區用于保存客戶端發送的命令請求,當超過1GB時,服務器會關閉該客戶端
1.1.5 命令與命令引數
在服務器會對客戶端的命令請求內容進行分析,并將得出的命令引數以及命令引數的個數分別保存在客戶端狀態的argv屬性和argc屬性,argv是一個陣列,argv[0[是要執行的命令,之后的其他項是傳給命令的引數,

1.1.6 命令的實作函式
當服務器從協議內容中分析得出argv屬性和argc屬性的值后,服務器會根據argv[0]的值,在命令表(字典結構)中查找命令所對應的命令實作函式,
redisCommand 結構保存了命令的實作函式、命令的標志、命令應該給定的引數個數、命令的總執行次數和總消耗時長等資訊,

1.1.7 輸出緩沖區
執行命令所得的命令回復會被保存在客戶端狀態的輸出緩沖區里,每個客戶端有兩個輸出緩沖區:
- 固定大小的緩沖區
buf 是一個大小為REDIS_REPLY_CHUNK_BYTES位元組的位元組陣列,而bufpos屬性記錄buf陣列目前已經使用的位元組數量,
- 可變大小的緩沖區
由reply鏈表和一個或多個字串物件組成
1.1.8 身份驗證
客戶端狀態的authenticated屬性用于記錄客戶端是否通過了身份驗證,若為0,沒有通過;為1表示通過了身份驗證,可以執行命令,
1.1.9 時間
ctime屬性記錄了創建客戶端的時間,即客戶端和服務器已經連接了多少秒,通過CLIENT list命令的age引數記錄,
lastinteraction屬性記錄了客戶端和服務器最后一次進行互動的時間,可以用來計算客戶端的空閑(idle)時間,
obuf_soft_limit_reached_time屬性記錄了輸出緩沖區第一次到達軟性限制(soft limit)的時間,如果輸出緩沖區的大小超過軟性限制所設定的大小,且持續時間超過了服務器設定的時長,那么服務器會關閉客戶端,

2. 服務器
2.1 serverCron函式
2.1.1 更新服務器時間快取
Redis服務器中有不少功能需要獲取系統的當前時間,而每次獲取系統時間都需要執行系統呼叫,為了減少系統呼叫執行次數,服務器狀態中的unixtime屬性和mstime屬性被用作當前時間的快取
serverCron函式默認以每100毫秒一次的頻率更新unixtime屬性和mstime屬性,所以這兩個屬性記錄的時間并不準確:
- 服務器只會在列印日志、更新服務器的LRU時鐘、決定是否執行持久化任務、計算服務器上線時間這種對時間精度要求不高的情況下使用unixtime屬性和mstime屬性
- 對于為鍵設定過期時間、添加慢查詢日志這種需要高精度時間的功能來說,服務器還是會執行系統呼叫
2.1.2 更新LRU時鐘
服務器狀態中lruclock屬性保存了服務器的LRU時鐘,默認每10秒更新一次時鐘快取,程式用服務器的lruclock屬性記錄的時間減去物件lru屬性記錄的時間來得出資料庫鍵的空轉時間,
2.1.3 更新服務器每秒執行命令次數
trackOperationsPerSecond函式會以每100毫秒一次的頻率執行,通過抽樣計算的方式估算并記錄服務器在最近一秒鐘處理的命令請求數量,
2.1.4 更新服務器記憶體峰值記錄
每次serverCron函式執行時,都會查看服務器當前使用的記憶體數量,并與stat_peak_memory保存的數值進行比較,保留較大的值,
2.1.5 處理SIGTERM信號
在啟動服務器時,Redis會為服務器行程的SIGTERM信號關聯處理器sigtermHandler函式,這個信號處理器在接到SIGTERM信號時,打開服務器的shutdown_asap標識,每次serverCron函式運行時,程式都會對服務器狀態的shutdown_asap屬性進行檢查,值為1時,關閉服務器,值為0時,不做動作,當服務器接收到SIGTERM信號后,會先進行持久化操作,然后關閉服務器,
2.1.6 管理客戶端資源
serverCron函式每次執行都會呼叫clientsCron函式,clientsCron函式會對一定數量的客戶端進行以下兩個檢查:
- 如果客戶端和服務器之間的連接已經超時,那么程式釋放這個客戶端
- 如果客戶端上一次執行命令請求之后,輸入緩沖區的大小超過了一定的長度,那么程式會釋放客戶端當前的輸入緩沖區,并重新創建一個默認大小的輸入緩沖區,防止客戶端的輸入緩沖區耗費過多記憶體
2.1.7 管理資料庫資源
serverCron函式每次執行都會呼叫databasesCron函式,這個函式對服務器中的一部分資料庫進行檢查,洗掉其中的過期鍵,在滿足條件時,對字典進行收縮,
2.1.8 執行被延遲的BGREWRITEAOF
在服務器執行BGSAVE命令期間,如果客戶端向服務器發來BGREWRITEAOF命令,那么服務器會將BGREWRITEAOF命令的執行時間延遲到BGSAVE命令執行完畢之后,
aof_rewrite_scheduled表示記錄了服務器是否延遲了BGREWRITEAOF命令,如果為1,則表示命令被延遲了,
2.1.9 檢查持久化操作運行狀態
rdb_child_pid屬性為-1表示沒有執行BGSAVE命令;aof_child_pid屬性為-1表示沒有執行GREWRITEAOF命令,
下面的流程圖展示了檢查程序:

2.1.10 AOF緩沖區中的內容寫入AOF檔案
第四章持久化有介紹
2.1.11 關閉異步客戶端
服務器會關閉輸出緩沖區大小超出了限制的客戶端
2.1.12 增加cronloops計數器的值
cronloops屬性記錄了serverCron函式執行的次數,用于某些serverCron函式執行N次,就執行一次的程式,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296144.html
標籤:其他
上一篇:第五章 事件與事務
下一篇:第七章 復制
