內存分配
Redis進程的內存消耗主要包括:自身內存 + 對象內存 + 緩沖內存 + 內存碎片。
1 自身內存
Redis自身內存消耗非常少,通常used_memory在800KB左右,used_memory_rss在3M左右。Redis的內存消耗主要在於后面三個。(used_memory和used_memory_rss的概念在下面介紹)
2 對象內存
對象內存是Redis內存占用最大的一塊,存儲着用戶的所有數據,還包括慢查詢日志等Redis幫我們維護的一些內存數據。
3 緩沖內存
緩沖內存主要包括:客戶端緩沖、復制積壓緩沖、AOF重寫緩沖。
3.1 客戶端緩沖
客戶端緩沖指的是所有連到Redis服務器的TCP連接的輸入緩沖和輸出緩沖。
Redis為每個客戶端分配了輸入緩沖區,用於臨時保存客戶端發過來的命令,同時Redis服務器會從輸入緩沖區中拉取命令執行,輸入緩沖區為客戶端向服務端發送的命令提供了緩沖的功能。輸入緩沖區大小無法控制,每個客戶端的輸入緩沖區最大空間為1G,如果超出將斷開連接。
同樣的Redis為每個客戶端分配了輸出緩沖區,用於臨時保存服務端執行的命令結果,同時Redis服務器會從輸出緩沖區中拉取結果返回到客戶端,輸出緩沖區為服務端向客戶端返回結果提供了緩沖。
輸出緩沖區根據客戶端的類型又划分為三種:普通客戶端、發布訂閱客戶端、從客戶端(Redis復制的slave客戶端)。每種客戶端的輸出規則也不一樣,這里就不細說了。
3.2 復制積壓緩沖
Redis在2.8版本之后提供了一個可重用的固定大小的緩沖區用於實現增量復制的功能,根據repl-backlog-size參數來控制,默認大小1MB。
對於復制積壓緩沖區主節點只有一個,所有從節點共享一個,這個緩沖區可以有效地避免全量復制。
3.3 AOF重寫緩沖區
AOF重寫緩沖區用於在AOF重寫期間保存寫命令,所以AOF重寫緩沖區的大小取決於AOF的時間以及AOF重寫期間的寫命令數量。
等到AOF重寫完成之后,會將AOF重寫緩沖區中的數據寫到AOF文件,從而清空AOF重寫緩沖區。
4 內存碎片
Redis默認內存分配器采用jemalloc,可選的分配器還有:glibe、tcmalloc。
內存分配器是為了更好的管理和重復利用內存,分配內存策略一般采用固定范圍的內存塊進行內存分配。
這里不去深究jemalloc的內存分配原理,簡單地說jemalloc將內存空間划分為三個部分:Small class、Large class、Huge class,每個部分又划分為很多小的內存塊單位:
- Small class: [8byte], [16byte, 32byte, … 128byte], [192byte, 256byte, … 512byte], [768byte, 1024byte, … 3840byte]
- Large class: [4kb, 8kb, 12kb, … 4072kb]
- Huge class: [4mb, 8mb, 12mb …]
簡單來說就是采用不同大小的內存塊來存儲不同大小的內存對象,比如說一個5kb的對象就會存到8kb的內存塊中,那么剩下的3kb內存就變成了內存碎片,不能再被分配給其他對象。
通常在對key做頻繁更新操作和大量過期key被刪除的時候會導致碎片率上升,可以考慮重啟節點的方式重新整理碎片。
內存查看
使用 info 命令可以看到當前Redis內存使用情況:
192.168.1.4:0>info memory
"# Memory
used_memory:1938704
used_memory_human:1.85M
used_memory_rss:10444800
used_memory_rss_human:9.96M
used_memory_peak:2948848
used_memory_peak_human:2.81M
used_memory_peak_perc:65.74%
used_memory_overhead:1919050
used_memory_startup:786608
used_memory_dataset:19654
used_memory_dataset_perc:1.71%
total_system_memory:8083607552
total_system_memory_human:7.53G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:4294967296
maxmemory_human:4.00G
maxmemory_policy:noeviction
mem_fragmentation_ratio:5.39
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
其中:
屬性名 屬性說明
used_memory Redis內部存儲的所有數據占用的內存
used_memory_human used_memory 以M為單位顯示
used_memory_rss 操作系統為Redis進程分配的物理內存總量
used_memory_peak 內存使用過的最大值
maxmemory 給Redis分配的內存上限
total_system_memory 系統內存
used_memory_lua Lua腳本占用內存大小
需要注意的是其中 used_memory 表示Redis內部存儲的所有數據占用的內存,也就是對象內存,而 used_memory_rss 表示操作系統為Redis進程分配的物理內存總量,也就是上面四種內存的總和。
當used_memory < used_memory_rss時,說明used_memory_rss中多余出來的內存沒有被用來存儲對象。如果兩個值的差值很大,說明碎片率很高。
當used_memory > used_memory_rss時,說明操作系統采用了內存交換,把Redis內存交換(swap)到硬盤。內存交換(swap)對於Redis來說是致命的,Redis能保證高性能的一個重要前提就是讀寫都基於內存。如果操作系統把Redis使用的部分內存交換到硬盤,由於硬盤的讀寫效率比內存低上百倍,會導致Redis性能急劇下降,特別容易引起Redis阻塞。
今天這篇文章主要介紹了Redis的內存划分以及查看Redis的內存使用情況,后面將帶來Redis的內存上限設置以及Redis的回收策略。
---------------------
作者:Lebron_Chen
來源:CSDN
原文:https://blog.csdn.net/Leon_cx/article/details/82597722