日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

redis 启动加载mysql_Redis分析系列:启动加载过程

發(fā)布時(shí)間:2023/12/2 数据库 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis 启动加载mysql_Redis分析系列:启动加载过程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從本篇文章開始(命名為Redis分析系列),將會(huì)通過(guò)分析Redis的源代碼(以Redis 2.2.0 RC1為準(zhǔn)),來(lái)對(duì)它的內(nèi)部實(shí)現(xiàn)做一些探討。本文主要介紹Redis啟動(dòng)加載過(guò)程,總體上可以分為如下幾步:

1. 初始化全局服務(wù)器配置

2. 加載配置文件(如果指定了配置文件,否則使用默認(rèn)配置)

3. 初始化服務(wù)器

4. 加載數(shù)據(jù)庫(kù)

5. 網(wǎng)絡(luò)監(jiān)聽

整個(gè)啟動(dòng)加載過(guò)程如下圖所示:

下面對(duì)于上圖中的各個(gè)步驟一些介紹,有些部分(如數(shù)據(jù)庫(kù)加載、網(wǎng)絡(luò)監(jiān)聽)會(huì)在后面單獨(dú)用一篇文章詳細(xì)說(shuō)明。

初始化全局服務(wù)器配置

初始化全局服務(wù)器配置通過(guò)initServerConfig()函數(shù)完成,主要是初始化server變量,它是一個(gè)redisServer的結(jié)構(gòu)類型:

structredisServer server;

初始化的內(nèi)容包括下面幾個(gè)方面:

1. 網(wǎng)絡(luò)監(jiān)聽相關(guān),如綁定地址,TCP端口等

2. 虛擬內(nèi)存相關(guān),如swap文件、page大小等

3. 保存機(jī)制,多長(zhǎng)時(shí)間內(nèi)有多少次更新才進(jìn)行保存

4. 復(fù)制相關(guān),如是否是slave,master地址、端口

5. Hash相關(guān)設(shè)置

6. 初始化命令表

如其中的保存機(jī)制中,服務(wù)器初始化策略為:

// 1小時(shí)內(nèi)1次更新appendServerSaveParams(60*60,1);

// 5分鐘內(nèi)100次更新appendServerSaveParams(300,100);

// 1分鐘內(nèi)10000次更新appendServerSaveParams(60,10000);

如果在啟動(dòng)服務(wù)器時(shí),指定了配置文件,則會(huì)在下面的“加載配置文件”步驟中,根據(jù)配置文件內(nèi)容,更改其中的某些服務(wù)器配置。

加載配置文件

如果指定了配置文件,Redis使用loadServerConfig()函數(shù)加載配置文件,整個(gè)過(guò)程沒(méi)什么可以說(shuō)的,無(wú)非是使用標(biāo)準(zhǔn)I/O庫(kù)打開配置文件,循環(huán)讀取每一行然后覆蓋上一步進(jìn)行的默認(rèn)配置。

這里有一點(diǎn)需要注意的是,下載Redis后代碼包中有一個(gè)默認(rèn)配置文件,如果啟動(dòng)Redis服務(wù)器時(shí),不指定配置文件,Redis不會(huì)使用這個(gè)默認(rèn)文件的配置,而是使用上一步“初始化全局服務(wù)器配置”中的配置。在默認(rèn)配置文件中提供的配置項(xiàng)與上一步默認(rèn)初始化的配置有些事不一樣的,所以如果沒(méi)有指定配置文件,千萬(wàn)不能認(rèn)為Redis的行為會(huì)按照默認(rèn)配置文件進(jìn)行,最典型的一個(gè)例子,在默認(rèn)配置文件中的數(shù)據(jù)保存策略是:

#15分鐘內(nèi)1次更新

save 900 1

#5分鐘內(nèi)100次更新

save 300 10

#1分鐘內(nèi)10000次更新

save 60 10000

而默認(rèn)初始化的全局配置中數(shù)據(jù)保存策略:

// 1小時(shí)內(nèi)1次更新appendServerSaveParams(60*60,1);

// 5分鐘內(nèi)100次更新appendServerSaveParams(300,100);

// 1分鐘內(nèi)10000次更新appendServerSaveParams(60,10000);

初始化服務(wù)器

初始化服務(wù)器的工作在initServer()函數(shù)中,主要是完成前面未完成的工作,繼續(xù)對(duì)server變量初始化,如設(shè)置信號(hào)處理、創(chuàng)建clients、slaves列表,創(chuàng)建Pub/Sub通道列表,同時(shí)還會(huì)創(chuàng)建共享對(duì)象:

shared.crlf= createObject(REDIS_STRING,sdsnew("\r\n"));

shared.ok= createObject(REDIS_STRING,sdsnew("+OK\r\n"));

shared.err= createObject(REDIS_STRING,sdsnew("-ERR\r\n"));

shared.emptybulk= createObject(REDIS_STRING,sdsnew("$0\r\n\r\n"));

最后,如果啟用了虛擬內(nèi)存機(jī)制,還需要初始化虛擬內(nèi)存相關(guān),如Thread I/O等。

加載數(shù)據(jù)庫(kù)

在完成了上面的所有的初始化工作之后,Redis開始加載數(shù)據(jù)到內(nèi)存中,如果啟用了appendonly了(不知道這個(gè)參數(shù)做什么的,請(qǐng)先看配置文件篇),則Redis從appendfile加載數(shù)據(jù),否則就從dbfile加載數(shù)據(jù)。

1. 從appendfile中加載數(shù)據(jù):loadAppendOnlyFile()函數(shù)

在此之前,我們先來(lái)看一下appendfile里面保存了什么,如我執(zhí)行了下面兩條命令(記得在配置文件中開啟appendonly):

redis> SET mykey001 myvalue001

OK

redis> GET mykey001

"myvalue001"

使用cat命令查看appendonly.aof文件內(nèi)容:

$ cat appendonly.aof

*2

$6

SELECT

$1

0

*3

$3

SET

$8

mykey001

$10

myvalue001

嗯,相信大家都能看明白(看不明白的請(qǐng)先看這篇文章),在appendonly.aof文件中保存的正是從客戶端發(fā)過(guò)來(lái)的請(qǐng)求命令,還可以看到對(duì)于GET命令,并沒(méi)有保存。既然appendonly.aof中保存了所有寫入數(shù)據(jù)的請(qǐng)求命令,那么在加載數(shù)據(jù)的時(shí)候只要重新執(zhí)行一遍這些命令即可。

事實(shí)上Redis也正是這么做的,在開始加載之前暫時(shí)關(guān)閉appendonly,然后Redis創(chuàng)建一個(gè)假的Redis客戶端:

server.appendonly= 0;

fakeClient = createFakeClient();

startLoading(fp);

然后讀取appendonly.aof文件中的命令,在假的Redis客戶端上下文中執(zhí)行,同時(shí)服務(wù)器也不對(duì)該客戶端做任何應(yīng)答:

fakeClient->argc= argc;

fakeClient->argv= argv;

cmd->proc(fakeClient);

/* The fake client should not have a reply */redisAssert(fakeClient->bufpos== 0 && listLength(fakeClient->reply) == 0);

如果加載過(guò)程中物理內(nèi)存不夠用,并且Redis開啟了VM,則還需要處理swap操作,最后加載完成后重新設(shè)置appendonly標(biāo)志。

2. 從dbfile中加載數(shù)據(jù):rdbLoad()函數(shù)

如果Redis沒(méi)有開啟appendonly,就需要從數(shù)據(jù)庫(kù)文件中加載數(shù)據(jù)到內(nèi)存,基本步驟如下:

a. 處理SELECT命令,即選擇數(shù)據(jù)庫(kù)

b. 讀取key

c. 讀取value

d. 檢測(cè)key是否過(guò)期

e. 添加新的對(duì)象到哈希表

f. 設(shè)置過(guò)期時(shí)間(如果需要)

g. 如果開啟了VM,處理swap操作

網(wǎng)絡(luò)監(jiān)聽

在完成了初始化配置和數(shù)據(jù)加載后,Redis啟動(dòng)監(jiān)聽。Redis的網(wǎng)絡(luò)庫(kù)沒(méi)有使用libevent或者libev,而是作者自己實(shí)現(xiàn)的一個(gè)非常輕量級(jí)的庫(kù)(主要實(shí)現(xiàn)在ae.c文件中),這部分內(nèi)容在后面分析Redis的網(wǎng)絡(luò)庫(kù)的時(shí)候單獨(dú)寫篇文章。

通過(guò)本文,介紹了Redis的啟動(dòng)加載過(guò)程,希望對(duì)大家有所幫助。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的redis 启动加载mysql_Redis分析系列:启动加载过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。