Redis的內存
127.0.0.1:6379> INFO memory
# Memory
used_memory:87057136
used_memory_human:83.02M
used_memory_rss:22122496
used_memory_rss_human:21.10M
used_memory_peak:87057136
used_memory_peak_human:83.02M
total_system_memory:1027096576
total_system_memory_human:979.52M
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:134217728
maxmemory_human:128.00M
maxmemory_policy:allkeys-lru
mem_fragmentation_ratio:0.25
mem_allocator:jemalloc-4.0.3
重點關註:
used_memory,Redis內部存儲數據的內存占用量。
used_memory_rss,從操作系統角度看,Redis占用的物理內存總量。
used_memory_rss-used_memory,多出來的內存被碎片消耗。
Redis內存消耗主要包括:緩沖內存,子進程,Redis進程自身,存儲數據對象和內存碎片,主要看前兩者。
緩沖內存
1.客戶端緩沖
指所有接入到Redis服務器的TCP連接的輸入輸出緩沖。
輸入緩沖無法控制,最大空間1G,若超過,將斷開連接。
輸出緩沖有3類:普通客戶端,從客戶端和訂閱客戶端,大小通過參數client-output-buffer-limit控制。一般普通客戶端內存消耗可以忽略不計,但當有大量慢連接客戶端接入時,就要關註這部分內存了。
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
2.復制積壓緩沖
#define CONFIG_DEFAULT_REPL_BACKLOG_SIZE (1024*1024) /* 1mb */
對於主節點只有一個復制積壓緩沖區,所有從節點共享該緩沖區,默認1MB,可設置較大的緩沖區(repl-backlog-size),有效避免全量復制。
3.AOF緩沖
sds aof_buf; /* AOF buffer, written before entering the event loop */
list *aof_rewrite_buf_blocks; /* Hold changes during an AOF rewrite. */
開啟AOF時,命令會先append進入aof_buf緩沖區中,在aof_buf緩沖區中根據appendfsync指定的策略刷新到磁盤。
當觸發AOF重寫時,主進程fork操作後,依然響應命令,Redis使用aof_rewrite_buf_blocks緩沖區保存這部分新數據,防止新AOF文件生成期間丟失這部分數據。
4.子進程內存消耗
子進程內存消耗主要是指在RDB快照/AOF重寫時,Redis創建子進程消耗的內存。為了保證該過程順暢,註意兩點。
a.關閉Linux內核的Transparent Huge Pages機制(echo never > /sys/kernel/mm/transparent_hugepage/enabled),防止copy-on-write期間內存過度消耗。
b.設置vm.overcommit_memory=1,允許內核可以分配所有的物理內存,防止Redis進行fork時內存不足而失敗。
內存管理
Redis是通過控制內存上限,和回收策略實現內存管理的。
1.設置內存上限(maxmemory <bytes>)
使用maxmemory參數限制最大可用內存,其限制的是Redis實際使用的內存量,即used_memory統計項值。由於內存碎片,實際消耗的內存可能比maxmemory設置的大,使用時要小心這部分內存溢出。 另可通過CONFIG SET maxmemory <bytes>動態調整內存上限。
2.內存回收策略,體現在,刪除達到過期時間的鍵對象,和內存使用達到maxmemory上限觸發內存溢出控制策略。
2.1刪除到達過期時間的鍵對象
a.被動方式
當用戶讀取帶有超時屬性的鍵時,若已超過鍵設置的超時時間,會執行刪除操作並返回空。當過期鍵一直沒有被訪問時,會由主動方式將其刪除。
b.主動方式
Redis會定期進行下面的操作(通過hz設置頻率)。
1.定期隨機對20個鍵進行過期檢測。
2.刪除過期的鍵。
3.如果多於25%的鍵過期,重復步驟1。
2.2內存溢出控制策略
當Redis使用內存達到maxmemory上限時會觸發溢出控制策略,共有6種策略,由參數maxmemory-policy控制。
volatile-lru -> remove the key with an expire set using an LRU algorithm
allkeys-lru -> remove any key according to the LRU algorithm
volatile-random -> remove a random key with an expire set
allkeys-random -> remove a random key, any key
volatile-ttl -> remove the key with the nearest expire time (minor TTL)
noeviction -> don't expire at all, just return an error on write operations
對於Redis用於緩存業務,一般使用allkeys-lru策略;用於存儲業務,使用noeviction策略。
若感興趣可關註訂閱號”數據庫最佳實踐”(DBBestPractice).
Redis的內存