redis 記憶體概述

2021-09-29 08:39:40 字數 2094 閱讀 4899

redis通過自己的方法管理記憶體,,主要方法有zmalloc(),zrealloc(), zcalloc()和zfree(), 分別對應c中的malloc(), realloc()、

calloc()和free()。相關**在zmalloc.h和zmalloc.c中。

redis自己管理記憶體的好處主要有兩個:可以利用記憶體池等手段提高記憶體分配的效能;可以掌握更多的記憶體資訊,以便於redis虛擬記憶體(vm)等功能中,決定何時將資料swap到磁碟。

先回憶各個系統中常見的記憶體分配函式:

malloc()分配一塊指定大小的記憶體區域,並返回指向區域開頭的指標,若分配失敗,則返回null。

calloc()與malloc()一樣,分配一塊指定大小的記憶體區域,成功時返回區域頭指標,失敗返回null。

區別在於, calloc()的輸入引數為count和size,即分配的項的數

目,及每一項的大小。

calloc()在成功分配記憶體空間後,會將空間內所有值置0。

realloc()修改已分配的記憶體塊的大小。若已分配的記憶體塊後沒有足夠的空間用於擴充套件記憶體塊,則重新申請一塊滿足需要的記憶體塊,並將舊的資料拷貝到新位置,釋放舊的記憶體塊,返回指向新的記憶體塊的指標;否則直接擴充套件原有的記憶體塊。若分配失敗,返回null。

free()釋放已分配的記憶體塊。

記憶體分配

在redis中,如果系統中包含tcmalloc,則會使用tc_malloc()等tcmalloc中的方法代替malloc()等原有的分配記憶體方法。 tcmalloc是google perftools中的乙個元件。

#if defined(use_tcmalloc)

#define malloc(size) tc_malloc(size)

首先看zmalloc()和zfree()兩個最常用的方法。 redis在申請記憶體時,除了申請需要的size外,還會多申請一塊定長(prefix_size)的區域用於記錄所申請的記憶體塊的長度。如果申請成功, redis會使用巨集函式(redis中為效能考慮,大量使用巨集函式)

update_zmalloc_stat_alloc(size+prefix_size, size)記錄申請的記憶體塊的相關資訊,以便監控記憶體使用狀況;當記憶體塊被zfree()釋放時,根據頭部的資訊可以快速地獲知被釋放的記憶體區域的長度,然後通過巨集函式update_zmalloc_stat_free()標記釋放。源**中,若系統支援malloc_size()方法,則會使用它返回指標所指向的記憶體塊的大小(mac os x 10.4以上支援該方法[3])。 有疑惑的是,在支援malloc_size()的系統中,為何還要多申請prefix_size的記憶體?

void *zmalloc(size_t size)
巨集update_zmalloc_stat_alloc()中,首先將要分配的空間與記憶體對齊,然後會根據巨集zmalloc_thread_safe判斷是否需要對記憶體資訊記錄表的相關操作加鎖。雖然redis在大部分場景中是單執行緒讀寫的,即thread_safe的,但啟用虛擬記憶體(vm),或持久化dump到磁碟等操作時會啟動多執行緒,因此在多執行緒模式中,需要對部分操作加鎖。記憶體監控

used_memory記錄了redis使用的記憶體總數。而多執行緒下malloc()是執行緒安全的。

zmalloc_allocations記錄了各個size分配的記憶體塊的數目,大於256個位元組的按256算。應用程式可以通過zmalloc_allocations_for_size(size)獲得對應size的

記憶體塊的分配數目;也可以通過zmalloc_used_memory()獲得redis占用的總記憶體。這些監控類的方法在redis的日誌系統中被用到。

zcalloc(size)、 zrealloc()與zmalloc()的處理策略類似,不再詳述。

在部分作業系統中, redis可以通過zmalloc_get_rss()方法獲得自己的程序占用

的記憶體資訊。該資訊通過作業系統提供,往往比redis自己記錄的used_memory更準確,

但其獲取速度也較慢。這些資訊也是用於虛擬記憶體功能。

除了記憶體相關的操作外, redis在此還提供了乙個複製字串的方法zstrdup(char

*),該方法將申請一塊與源字串長度相同的記憶體區域,並用memcpy()拷貝字串的內

容。

Redis集群概述

redis cluster與redis3.0.0同時發布,以此結束了redis無官方集群方案的時代,目前,redis已經發布了3.0.7版本。redis cluster是去中心化,去中介軟體的,也就是說,集群中的每個節點都是平等的關係,都是對等的,每個節點都儲存各自的資料和整個集群的狀態。每個節點都...

Redis集群概述

redis cluster與redis3.0.0同時發布,以此結束了redis無官方集群方案的時代,目前,redis已經發布了3.0.7版本。redis cluster是去中心化,去中介軟體的,也就是說,集群中的每個節點都是平等的關係,都是對等的,每個節點都儲存各自的資料和整個集群的狀態。每個節點都...

redis結構概述

1 dictentry redis是key value資料庫,因此對每個鍵值對都會有乙個dictentry,裡面儲存了指向key和value的指標 next指向下乙個dictentry,與本key value無關。2 key 圖中右上角可見,key hello 並不是直接以字串儲存,而是儲存在sds...