日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Redis源碼分析精通PDF版(redis源碼分析pdf)

Redis源碼分析:精通PDF版

Redis是一款開源的Key-Value存儲數(shù)據(jù)庫,其原理和特點已被廣泛涵蓋在其他文章中,因此這里不再贅述。本文將由淺入深,逐一分析Redis的源代碼,并為初學(xué)者提供一份精通Redis源碼的PDF版本。

一、基礎(chǔ)知識

在開展Redis源碼的分析之前,我們需要準(zhǔn)備好所需的開發(fā)環(huán)境,包括Redis的編譯環(huán)境、C語言基礎(chǔ)等。以下是關(guān)于Redis基礎(chǔ)知識的推薦學(xué)習(xí)資料:

1.《Redis開發(fā)與運維》(原書第2版)

2.《Redis設(shè)計與實現(xiàn)》

3.《C Primer Plus》(中文版)

4. 《C程序設(shè)計語言》

對于已經(jīng)具備相關(guān)基礎(chǔ)知識的開發(fā)者,下面將介紹Redis源碼的分析。

二、源碼結(jié)構(gòu)

Redis的源代碼核心代碼存放在src目錄下,同時還包括一些其他文件,如:

1.測試代碼存放在tests目錄下

2.默認(rèn)配置文件存放在配置目錄下

3.文檔和手冊存放在doc目錄下

4.擴展模塊存放在modules目錄下

我們需要在源代碼中查找我們需要修改或了解的地方,并編譯出Redis的可執(zhí)行文件。

三、代碼分析

從mn函數(shù)開始,我們可以看到Redis的啟動流程。

首先加載并解析配置文件,然后初始化其他模塊(例如網(wǎng)絡(luò)模塊、數(shù)據(jù)庫模塊等),最后進入主循環(huán)。在主循環(huán)中,Redis等待客戶端的命令,并根據(jù)收到的命令執(zhí)行相應(yīng)的操作。

以下是Redis源代碼的一部分(src/server.c):

“`c

#include “server.h”

int mn(int argc, char **argv) {

struct timeval tv;

int j;

srand(time(NUll)^getpid());

initServerConfig();

if (argc == 2) {

j = serverLoadConfig(argv[1]);

} else {

j = serverLoadConfig(“/etc/redis/redis.conf”);

if (j == REDIS_ERR) serverLog(LL_WARNING,”Warning: no config file specified, using the default config. In order to specify a config file use %s /path/to/redis.conf”,argv[0]);

}

if (j == REDIS_ERR) exit(1);

initServer();

if (server.daemonize) daemonize();

if (server.pidfile) createPidFile();

if (server.rdb_filename == NULL) server.rdb_filename = zstrdup(“dump.rdb”);

if (server.aof_filename == NULL) server.aof_filename = zstrdup(“appendonly.aof”);

aclInit();

moduleInitModulesSystem();

loadDataFromDisk();

moduleLoadFromQueue();

if (server.cluster_enabled) {

if (verifyClusterConfigWithData() == REDIS_ERR) {

serverLog(LL_WARNING,

“Fled to verify cluster configuration agnst online data. “

“Retrying verification… (Check for errors before the server ‘is able to work’)”);

if (verifyClusterConfigWithData() == REDIS_ERR) {

serverLog(LL_WARNING,”Aborting now.”);

exit(1);

}

}

}

moduleFireServerEvent(REDISMODULE_EVENT_LOADING,0,NULL);

aclLoadUsersFromDisk();

bioInit();

if (server.repl_state == REDIS_REPL_SLAVE) {

if (syncWithMaster(1) == REDIS_ERR) {

serverLog(LL_WARNING,”%s”, “FATAL: The server is not able to synchronize with\nthe master server.”);

exit(1);

}

}

if (server.cluster_enabled && nodeIsSlave(myself)) {

replicationSetMaster(getClusterNodeMaster(), server.port);

}

aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL);

if (!serverSentinelMode) {

if (server.bindaddr_count > 0) {

char ip[16];

int j;

for (j = 0; j

sockaddrToIp(server.bindaddr[j],&ip[0],sizeof(ip));

serverLog(LL_NOTICE,”Binding %s:%d”,ip,server.port);

}

} else {

serverLog(LL_NOTICE,”Server started, Redis version ” REDIS_VERSION);

}

}

adjustOpenFilesLimit();

dictSetHashFunctionSeed(server.hash_seed);

showLogo();

/* When log gets enabled we print an initial log line. */

if (logLevel != LL_NOTICE)

serverLog(logLevel,

“Server started, Redis version ” REDIS_VERSION);

gettimeofday(&tv,NULL);

server.stat_starttime = tv.tv_sec;

/* Things not needed to be done every time the server restarts. */

if (server.stat_starttime != server.lastbgsave_try) {

server.mstime_at_initiate_last_save = mstime();

}

/* Open the listening sockets. */

if (listenToPort(server.port,server.ipfd,&server.ipfd_count) == REDIS_ERR) {

serverLog(LL_WARNING,”O(jiān)pening port %d: %s”, server.port, strerror(errno));

exit(1);

}

aeCreateFileEvent(server.el, server.ipfd[0], AE_READABLE,

acceptTcpHandler,NULL);

if (server.port && listenToPort(server.tls_port,server.tlsfd,&server.tlsfd_count) == REDIS_ERR) {

serverLog(LL_WARNING,”O(jiān)pening TLS port %d: %s”, server.tls_port, strerror(errno));

} else if (server.tls_port) {

aeCreateFileEvent(server.el, server.tlsfd[0], AE_READABLE|AE_READ_THREADSAFE,

acceptTLSHandler,NULL);

}

moduleFireServerEvent(REDISMODULE_EVENT_LOADED,0,NULL);

serverLog(LL_NOTICE,”Ready to accept connections”);

aeMn(server.el);

aeDeleteEventLoop(server.el);

return 0;

}


我們可以看到這段代碼主要包括加載配置文件、初始化模塊、加載數(shù)據(jù)等操作,最后進入事件處理循環(huán)。

在主循環(huán)中,Redis使用了一個事件框架(ae),所有的事件被封裝成文件事件(File Event)或時間事件(Time Event)進行處理。以下是Redis處理時間事件的示例:

```c
/* =========================== ServerCron ================================ */
void serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
int j;
UNUSED(eventLoop);
UNUSED(id);
UNUSED(clientData);

/* Update the time cache. */
updateCachedTime();
/* Increment various statistics tracked by our "slowlog". */
server.slowlog_tick++;
/* Sample the RSS and other metrics here since it is very cheap to grab
* and we can collect stats with a resolution up to the cron loop
* period if we do so. */
if (server.cronloops % 10 == 0)
processCpuUsed();

/* Record the max length of the client output buffer. */
if (listLength(server.clients) > 0) {
size_t max = getClientOutputBufferMemoryUsage(server.clients->head->value);
if (server.stat_peak_client_output_buffer
server.stat_peak_client_output_buffer = max;
}
/* Close clients that need to be closed asynchronous */
freeClientsInAsyncFreeQueue();
/* Update information about connected clients. */
trackInstantaneousMetric(REDIS_METRIC_COMMAND, (long long) server.stat_numcommands);
trackInstantaneousMetric(REDIS_METRIC_NET_INPUT, server.stat_net_input_bytes);
trackInstantaneousMetric(REDIS_METRIC_NET_OUTPUT, server.stat_net_output_bytes);
trackInstantaneousMetric(REDIS_METRIC_NET_INPUT_BYTES_PER_SEC, server.stat_net_input_bytes_sec);
trackInstantaneousMetric(REDIS_METRIC_NET_OUTPUT_BYTES_PER_SEC, server.stat_net_output_bytes_sec);
trackInstantaneousMetric(REDIS_METRIC_EXPIRED_KEYS, server.stat_expiredkeys);

/*定期執(zhí)行的操作*/
server.cronloops++;
/* Replication cron function -- used to reconnect to master and
* detect transfer flures. */
replicationCron();
moduleHandleSystemTimerEvents();
aeDeleteTimeEvents(server.el, AE_TIME_EVENT_ALL_IDS);
for (j = 0; j
int i;

/* We have just 10 milliseconds to do everything. The mn goal of
* this first loop is serving the clients: all the other operations
* should be executed as a consequence of the processing we do
* in this loop. */
long long start = ustime();
if (server.cluster_enabled) clusterUpdateState();
if (server.lua_timedout) handleClientsTimeout();
if (server.cluster_migration_barrier_time &&
server.cluster_migration_barrier_time
{
server.cluster_migration

成都創(chuàng)新互聯(lián)科技公司主營:網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、小程序制作、成都軟件開發(fā)、網(wǎng)頁設(shè)計、微信開發(fā)、成都小程序開發(fā)、網(wǎng)站制作、網(wǎng)站開發(fā)等業(yè)務(wù),是專業(yè)的成都做小程序公司、成都網(wǎng)站建設(shè)公司、成都做網(wǎng)站的公司。創(chuàng)新互聯(lián)公司集小程序制作創(chuàng)意,網(wǎng)站制作策劃,畫冊、網(wǎng)頁、VI設(shè)計,網(wǎng)站、軟件、微信、小程序開發(fā)于一體。


網(wǎng)站名稱:Redis源碼分析精通PDF版(redis源碼分析pdf)
當(dāng)前地址:http://www.5511xx.com/article/cdgsess.html