redis代碼結構之一mem,bio

來源:互聯網
上載者:User

 Redis代碼結構 一mem,bio

1.       Redis代碼結構

事件庫

類型庫 網路程式庫 持久化 複製 訂閱 事務 main client 其它
ae.c
ae_epoll.c
ae_kqueue.c
ae_select.c
syncio.c
adlist.c
intset.c
object.c
sds.c
t_hash.c
t_list.c
t_set.c
t_string.c
t_zset.c
ziplist.c
zipmap.c
anet.c
networking.c
aof.c
rdb.c
redis-check-aof.c
redis-check-dump.c

replication.c

pubsub.c

multi.c config.c
redis.c
dict.c
db.c
redis-cli.c debug.c
lzf_c.c
lzf_d.c
pqsort.c
redis-benchmark.c
release.c
sha1.c
slowlog.c
sort.c
util.c
vm.c
zmalloc.c
bio.c
endian.c

 2.       zmalloc.c

該檔案用於封裝記憶體 Clerk:redis提供的記憶體 Clerk有c庫的malloc、jemalloc、acmalloc。這幾個分配器的適用情境見()。提供該層封裝的主要目的是統計記憶體的使用量,因為redis本身是為全memory設計的,所以要時刻觀察記憶體的使用方式。
void *zmalloc(size_t size)用於分配記憶體,它首先判斷使用的分配器是使用有頭部資訊,即把大小儲存到內容的正上方。預設的三種分配器都是有頭部資訊的,所以PREFIX_SIZE=0,然後會進行大小的sizeof(long)位元組對齊,(ms malloc分配出來的預設應該是大小對齊的,其它的兩種方式不清楚),對於沒有對齊的則擴充分配的大小,並且累加used_memory。
update_zmalloc_stat_alloc(__n,__size)
if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1));
used_memory += _n;
void *zcalloc(size_t size),其實跟zmalloc差不多,而不像c的calloc,因為它只有一個輸入參數。
void *zrealloc(void *ptr, size_t size)與c的realloc一樣,只是多了更新used_memory的大小。Zfree類似。
char *zstrdup(const char *s)與strdup類似,進行字串拷貝,該函數分配記憶體,要求調用它的函數在結束時釋放相應的記憶體,不然就會導致記憶體流失。
size_t zmalloc_used_memory(void)返回已使用的記憶體量。
void zmalloc_enable_thread_safeness(void)用於設計該分配器是否可支援多線程,redis的預設是不支援的。
size_t zmalloc_get_rss(void),該函數用於獲得redis-server的RSS即當前駐留在實體記憶體的頁數。該函數通過讀取/proc/pid/stat來擷取該資訊。上面的used_memory指是當前使用的虛擬記憶體量與RSS不一樣。 

3.       bio.c

該檔案用於提供後台線程的相關函數。Redis從 2.#引進了兩個後台線程用於主線程的aof檔案的close以及fsync操作。因為這兩個操作會導致主線程阻塞。詳細的應用情境見前面寫的“Redis Aof”的文章。這裡我們直接介紹該檔案裡的函數。
該檔案包含4個靜態全域變數以及一個bio_job的結構。

static pthread_mutex_t bio_mutex[REDIS_BIO_NUM_OPS]; //為訪問靜態全域變數bio_jobs,bio_pending提供互斥保障。static pthread_cond_t bio_condvar[REDIS_BIO_NUM_OPS];static list *bio_jobs[REDIS_BIO_NUM_OPS];  //儲存job的兩個adliststatic unsigned long long bio_pending[REDIS_BIO_NUM_OPS]; //當前等待處理的job數目struct bio_job { //job的結構體,現在用arg1來儲存fd    time_t time; /* Time at which the job was created. */    void *arg1, *arg2, *arg3;};

void bioInit(void),該函數被initServer調用,完成上面的全域變數的初始化,以及建立close job處理線程以及fsync處理線程(bioProcessBackgroundJobs)。
void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3),該函數用於建立bio_job並將該job加入到相應的bio_jobs[type] list裡。當前有三個地方會調用該函數:其一,建立REDIS_BIO_CLOSE_FILE job。當後台rewrite aof子進程結束時,主進程wait收到SIGCHLD訊號時,調用backgroundRewriteDoneHandler來進行相應的訊號處理:此時就需要close(oldaof),然後rename(tempfilename,oldaofname),如果直接按照這個過程操作則會導致阻塞,所以這邊採用的方法是如果oldaof是已經被關閉的則再開啟(非關閉則不需要),然後再rename此時oldaof因為有一個open的引用,所以不會unlink也就不會阻塞,最後再由剛才我們說的後台REDIS_BIO_CLOSE_FILE線程進行close,該線程會被阻塞,但這不會影響主線程;其二,建立REDIS_BIO_AOF_FSYNC
job,同樣是在backgroundRewriteDoneHandler裡,當把tempfile的fd重設為server.appendfd的fd時,if (server.appendfsync == APPENDFSYNC_EVERYSEC)則aof_background_fsync(newfd);該函數就會建立一個REDIS_BIO_AOF_FSYNC job。其三,flushAppendOnlyFile函數,我們在redis aof裡介紹過,在每次event loop之前的beforesleep函數裡都會調用該函數,顯然該函數是用於重新整理aof檔案(註:這裡有個write操作會導致主線程阻塞?為什麼不添加到file
event?),此時如果已經有REDIS_BIO_AOF_FSYNC job等待處理bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC) != 0,則不需要再aof_background_fsync增加fsync job(因為這裡只有這麼一個aof fd),否則如果是server.appendfsync == APPENDFSYNC_EVERYSEC則aof_background_fsync增加一個REDIS_BIO_AOF_FSYNC
job由後台fsync線程來進行sync操作。
上面就是目前的版本的使用到後台close及fsync線程的地方。
void *bioProcessBackgroundJobs(void *arg),該函數是兩個線程的處理函數,它們通過參數arg來辨別為不同的線程。該函數就是通過類型取得相應的bio_jobs list的job,然後調用close(job->arg1)或者aof_fsync(job->arg1)來完成相應的操作。
unsigned long long bioPendingJobsOfType(int type),返回當前等待type線程處理的jobs數目。對於fsync jobs顯然該pending數最多為1,上面我們已經講到了,因為它只對當前的aof fd有效,而任務時刻該檔案都是唯一的;對於close jobs的pending數可能會有多個,因為close 的是old aof file,顯然這個檔案每次都是不一樣的。
下面我們通過一張圖來描述一下當前的幾個進程及線程的關係。

圖1 redis中的進程與線程

註:關於bgsave,bgrewrite子進程的運行情況見前面文章的介紹。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.