標籤:使用 資料 art 工作 演算法 管理
以下筆記主要是關注tcp模式下memcached的啟動過程。
main()
設定訊號處理函數為sig_handler()
初始化系統設定,儲存在全域變數settings裡面
settings_init();
解析啟動參數,使用settings局變數儲存配置
根據啟動參數初始化系統具體使用的hash函數,預設為jenkins_hash()雜湊函數
hash_init() ;
根據tcp_specified的值設定網路監聽模式,預設為tcp模式
之後設定可使用的cpu核的數量以及最大連結數量
限制啟動的許可權,通常需要root許可權啟動應用
設定是否以守護進程方式啟動
調用libevent庫獲得一個事件監聽執行個體,libevent基本使用方法event_init() => evtimer_set() => event_add() =>event_dispatch()
event_init();
初始化系統全域狀態資訊變數
stats_init();
初始化雜湊表,參數為雜湊表buckets的級數,即buckets = ((unsigned long int)1<<(n))
assoc_init(int hashpower_init);
設定並初始化連結數組,用於儲存每個連結的fd, 預設為最大fd不大於max_conn + 10
conn_init();
記憶體管理的初始化,參數為:總申請記憶體的大小,預設為64m, 塊大小變化因子,是否預劃分記憶體
factor的使用主要是在每一個記憶體page中劃分chunck時使用,每個page最大為1m, 例如slab_class1每一個chunck 為80bytes, 則slab_class2每一個chunck大小為80*factor
factor的值在1.4.20版本預設為1.25,chunck的預設最小為48byte
preallocate預設為false,若為true則系統預設將為每一種slab_class申請一個執行個體,但是有可能有些始終不會被用到,因此預設啟動時為false
slabs_init(maxbytes, factor, preallocate);
啟動並初始化worker線程
num_threads表示worker線程的數量,主線程負責接受並建立連結,而worker線程則負責連結命令的I/O操作
初始化各種多線程同步鎖,建立主線程與worker線程通訊的pipe通道,主要用於分配新連結,分配過程負載平衡使用round-robin輪詢調度演算法
使用pthread庫建立線程並使用同步鎖確保worker線程都啟動完成才結束函數
thread_init(settings.num_threads, main_base);
啟動雜湊表的維護線程,主要負責雜湊表的擴容
start_assoc_maintenance_thread();
根據啟動參數決定是否啟動記憶體模組的管理線程,主要是考慮資料存放區的value值比較極端的情況,例如可能某一種chunck分配之後很久沒有被訪問,而其他經常被訪問的則申請儲存不成功,根據LRU演算法策略可考慮將最近最少訪問的記憶體塊重新劃分,slab_maintenance_thread主要做這些工作
if (settings.slab_reassign &&
start_slab_maintenance_thread() == -1)
init_lru_crawler();
啟動定時器,用一個全域變數維持一個目前時間的記錄,這樣多線程都訪問全域變數獲得目前時間,減少擷取時間系統調用
clock_handler();
啟動socket監聽
server_sockets();
啟動事件迴圈監聽
eventevent_base_loop();