用css做網(wǎng)站的好處百度指數(shù)的主要用戶是
初始化服務(wù)器
一個(gè)Redis服務(wù)器從啟動(dòng)到能夠接受客戶端的命令請(qǐng)求,需要經(jīng)過(guò)一系列的初始化和設(shè)置過(guò)程,比如初始化服務(wù)器狀態(tài),接受用戶指定的服務(wù)器配置,創(chuàng)建相應(yīng)的數(shù)據(jù)結(jié)構(gòu)和網(wǎng)絡(luò)連接等等
初始化服務(wù)器狀態(tài)結(jié)構(gòu)
初始化服務(wù)器的第一步就是創(chuàng)建一個(gè)struct redisServer類型的實(shí)例變量server作為服務(wù)器的狀態(tài),并為結(jié)構(gòu)中的各個(gè)屬性設(shè)置默認(rèn)值。初始化server變量的工作由redis.c/initServerConfig函數(shù)完成,
void initServerConfig(void) {// 設(shè)置服務(wù)器的運(yùn)行idgetRandomHexChars(seerver.runid, REDSI_RUN_ID_SIZE);// 為運(yùn)行id加上結(jié)尾字符server.runid[REDIS_RUN_ID_SIZE] = '\0';// 設(shè)置默認(rèn)配置文件路徑server.configfile = NULL;// 設(shè)置默認(rèn)服務(wù)器頻率server.hz = REDIS_DEFAULT_HZ;// 設(shè)置服務(wù)器的運(yùn)行架構(gòu)server.arch_bits = (sizeof(long) == 8) ? 64 :32;// 設(shè)置默認(rèn)服務(wù)器端口號(hào)server.port = REDIS_SERVERPORT;// ...
}
以下是initServerConfig函數(shù)完成的主要工作:
- 1.設(shè)置服務(wù)器的運(yùn)行ID
- 2.設(shè)置服務(wù)器的默認(rèn)運(yùn)行頻率
- 3.設(shè)置服務(wù)器的默認(rèn)配置文件路徑
- 4.設(shè)置服務(wù)器的運(yùn)行結(jié)構(gòu)
- 5.設(shè)置服務(wù)器的默認(rèn)端口號(hào)
- 6.設(shè)置服務(wù)器的默認(rèn)RDB持久化條件和AOF持久化條件
- 7.初始化服務(wù)器的LRU時(shí)鐘
- 8.創(chuàng)建命令表
initServerConfig函數(shù)設(shè)置的服務(wù)器狀態(tài)屬性基本都是一些整數(shù)、浮點(diǎn)數(shù)、或者字符串屬性,除了命令表之外,initServerConfig函數(shù)沒(méi)有創(chuàng)建服務(wù)器狀態(tài)的其他數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)庫(kù)、慢查詢?nèi)罩?、Lua環(huán)境、共享對(duì)象這些數(shù)據(jù)結(jié)構(gòu)在之后的步驟才會(huì)被創(chuàng)建出來(lái)。當(dāng)initServerConfig函數(shù)執(zhí)行完畢之后,服務(wù)器就可以進(jìn)入初始化的第二個(gè)節(jié)點(diǎn)——載入配置選項(xiàng)
載入配置選項(xiàng)
在啟動(dòng)服務(wù)器時(shí),用戶可以通過(guò)給定配置參數(shù)或者指定配置文件來(lái)修改服務(wù)器的默認(rèn)配置。舉個(gè)例子,如果我們?cè)诮K端輸入:
redis-server --port 10086
那么我們就通過(guò)給定配置參數(shù)的方式,修改了服務(wù)器的運(yùn)行端口號(hào)。另外,如果在終端輸入:
redis-server redis.conf
并且redis.conf文件中b包含以下內(nèi)容:
# 將服務(wù)器的數(shù)據(jù)庫(kù)數(shù)量設(shè)置為32個(gè)
databases 32
# 關(guān)閉RDB文件的壓縮功能
rdbcompression no
那么我們就通過(guò)指定配置文件的方式修改了服務(wù)器的數(shù)據(jù)庫(kù)數(shù)量,以及RDB持久化模塊的壓縮功能。服務(wù)器在用initServerConfig函數(shù)初始化server變量之后,就會(huì)開(kāi)始載入用戶給定的配置參數(shù)和配置文件,
并根據(jù)用戶設(shè)定的配置,對(duì)server變量相關(guān)屬性的值進(jìn)行修改。例如,在初始化server變量時(shí),程序會(huì)為決定服務(wù)器端口號(hào)的port屬性設(shè)置默認(rèn)值:
void initServerConfig(void) {// ...// 默認(rèn)值為6379server.port = REDIS_SERVERPORT;
}
不過(guò),如果用戶在啟動(dòng)服務(wù)器時(shí)為配置選項(xiàng)port指定了新值10086,那么server.port屬性的值就會(huì)被更新為10086,
這將使得服務(wù)器的端口號(hào)從默認(rèn)的6379變?yōu)閥oghurt指定的10086.
例如,在初始化server變量時(shí),程序會(huì)為決定數(shù)據(jù)庫(kù)數(shù)量的dbnum屬性設(shè)置默認(rèn)值:
void initServerConfig(void) {// ...// 默認(rèn)值為16server.dbnum = REDIS_DEFUALT_DBNUM;
}
不過(guò),如果用戶在啟動(dòng)服務(wù)器時(shí)為選項(xiàng)databases設(shè)置了值32,那么server.dbnum屬性的值就會(huì)被更新為32,這將使得服務(wù)器的數(shù)據(jù)庫(kù)數(shù)量從默認(rèn)的16個(gè)變?yōu)橛脩糁付ǖ?2個(gè)。其他配置選項(xiàng)相關(guān)的服務(wù)器狀態(tài)屬性的情況與上面列舉的port屬性和dbnum屬性一樣:
- 1.如果用戶為這些屬性的相應(yīng)選項(xiàng)指定了新的值,那么服務(wù)器就使用用戶指定的值來(lái)更新相應(yīng)的屬性
2.如果用戶沒(méi)有為屬性的相應(yīng)選項(xiàng)設(shè)置新的值,那么服務(wù)器就沿用之前initServerConfig函數(shù)為屬性的默認(rèn)值。服務(wù)器在載入用戶指定的配置選項(xiàng),并對(duì)server狀態(tài)進(jìn)行更新之后,服務(wù)器就可以進(jìn)入初始化的第三個(gè)階段——初始化服務(wù)器數(shù)據(jù)結(jié)構(gòu)
初始化服務(wù)器數(shù)據(jù)結(jié)構(gòu)
在之前執(zhí)行initServerconfig函數(shù)初始化server狀態(tài)時(shí),程序只創(chuàng)建了命令表一個(gè)數(shù)據(jù)結(jié)構(gòu),不過(guò)除了命令表之外,服務(wù)器狀態(tài)還包括其他數(shù)據(jù)結(jié)構(gòu),比如:
- 1.server.clients鏈表,這個(gè)鏈表記錄了所有與服務(wù)器相連的客戶端的狀態(tài)結(jié)構(gòu),鏈表的每隔節(jié)點(diǎn)都包含了一個(gè)redisClient結(jié)構(gòu)實(shí)例
- 2.server.db數(shù)組,數(shù)組中包含了服務(wù)器的所有數(shù)據(jù)庫(kù)
- 3.用于執(zhí)行Lua腳本的Lua環(huán)境server.lua
- 4.用于保存慢查詢?nèi)罩镜膕erver.slowlog屬性
當(dāng)初始化服務(wù)器進(jìn)行到這一步,服務(wù)器將調(diào)用initServer函數(shù),為以上提到的數(shù)據(jù)結(jié)構(gòu)分配內(nèi)存,并在有需要時(shí),為這些數(shù)據(jù)結(jié)構(gòu)設(shè)置或者關(guān)聯(lián)初始化值。服務(wù)器到現(xiàn)在才初始化數(shù)據(jù)結(jié)構(gòu)的原因在于,服務(wù)器必須先載入用戶指定的配置選項(xiàng),然后才能正確地對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化。如果在執(zhí)行initServerConfig函數(shù)時(shí)就對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化,那么一旦用戶通過(guò)
配置選項(xiàng)修改了和數(shù)據(jù)有關(guān)地服務(wù)器狀態(tài)屬性,服務(wù)器就要重新調(diào)整和修改已創(chuàng)建地?cái)?shù)據(jù)結(jié)構(gòu)。為了避免出現(xiàn)這種麻煩的情況,服務(wù)器選擇了將server狀態(tài)的初始化分為兩步進(jìn)行,initServerConfig函數(shù)主要負(fù)責(zé)
初始化一般屬性,而initServer函數(shù)主要負(fù)責(zé)初始化數(shù)據(jù)結(jié)構(gòu)。除了初始化數(shù)據(jù),initServer還進(jìn)行了一些非常重要的設(shè)置操作,其中包括: - 1.為服務(wù)器設(shè)置進(jìn)程信號(hào)處理器
- 2.創(chuàng)建共享對(duì)象,這些對(duì)象包含Redis服務(wù)器經(jīng)常用到的一些值,比如包含"OK"回復(fù)的字符串對(duì)象,包含"ERR"回復(fù)的字符串對(duì)象,包含整數(shù)1到10000的字符串對(duì)象等等,服務(wù)器通過(guò)重用這些共享對(duì)象來(lái)避免反復(fù)
創(chuàng)建相同的對(duì)象 - 3.打開(kāi)服務(wù)器的監(jiān)聽(tīng)端口,并為監(jiān)聽(tīng)套接字關(guān)聯(lián)連接應(yīng)答事件處理器,等待服務(wù)器正式運(yùn)行時(shí)接受客戶端的連接
- 4.為serverCron函數(shù)創(chuàng)建時(shí)間事件,等待服務(wù)器正式運(yùn)行時(shí)執(zhí)行serverCron函數(shù)
- 5.如果AOF持久化功能已經(jīng)打開(kāi),那么打開(kāi)現(xiàn)有的AOF文件,如果AOF文件不存在,那么創(chuàng)建并打開(kāi)一個(gè)新的AOF文件,為AOF寫(xiě)入做好準(zhǔn)備
- 6.初始化服務(wù)器的后臺(tái)IO模塊(bio),為將來(lái)的IO操作做好準(zhǔn)備。
當(dāng)initServer函數(shù)執(zhí)行完畢之后,服務(wù)器將用ASCII字符在日志中打印出Redis的圖標(biāo),以及Redis的版本號(hào)信息
file use E:\redis\redis-server.exe /path/to/redis.conf_.__.-``__ ''-.__.-`` `. `_. ''-._ Redis 3.0.504 (00000000/0) 64 bit.-`` .-```. ```\/ _.,_ ''-._( ' , .-` | `, ) Running in standalone mode|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379| `-._ `._ / _.-' | PID: 20212`-._ `-._ `-./ _.-' _.-'|`-._`-._ `-.__.-' _.-'_.-'|| `-._`-._ _.-'_.-' | http://redis.io`-._ `-._`-.__.-'_.-' _.-'|`-._`-._ `-.__.-' _.-'_.-'|| `-._`-._ _.-'_.-' |`-._ `-._`-.__.-'_.-' _.-'`-._ `-.__.-' _.-'`-._ _.-'`-.__.-'[20212] 01 Apr 21:06:44.205 # Server started, Redis version 3.0.504
[20212] 01 Apr 21:06:44.210 * DB loaded from disk: 0.005 seconds
[20212] 01 Apr 21:06:44.210 * The server is now ready to accept connections on port 6379
還原數(shù)據(jù)庫(kù)狀態(tài)
在完成了對(duì)服務(wù)器狀態(tài)server變量的初始化之后,服務(wù)器需要載入RDB文件或者AOF文件,并根據(jù)文件記錄的內(nèi)容來(lái)還原服務(wù)器的數(shù)據(jù)庫(kù)狀態(tài)。根據(jù)服務(wù)器是否啟用了AOF持久化功能,服務(wù)器載入數(shù)據(jù)時(shí)所使用的目標(biāo)文件會(huì)有所不同:
- 1.如果服務(wù)器啟用了AOF持久化功能,那么服務(wù)器使用AOF文件來(lái)還原數(shù)據(jù)庫(kù)裝填。
- 2.相反地,如果服務(wù)器沒(méi)有啟用AOF持久化功能,那么服務(wù)器使用RDB文件來(lái)還原數(shù)據(jù)庫(kù)裝填。當(dāng)服務(wù)器完成數(shù)據(jù)庫(kù)狀態(tài)還原工作之后,服務(wù)器將在日志中打印出載入文件并還原數(shù)據(jù)庫(kù)狀態(tài)所耗費(fèi)地時(shí)長(zhǎng):
[7256] 01 Apr 21:07:11.795 * DB loaded from disk: 0.000 seconds
執(zhí)行事件循環(huán)
在初始化地最后一步,服務(wù)器將打印出以下日志:
[7256] 01 Apr 21:07:11.795 * The server is now ready to accept connections on port 6379
并開(kāi)始執(zhí)行服務(wù)器的事件循環(huán)(loop).至此,服務(wù)器的初始化工作圓滿完成,服務(wù)器現(xiàn)在開(kāi)始可以接受客戶端的連接請(qǐng)求,并處理客戶端發(fā)來(lái)的命令請(qǐng)求了