Weird change of "memory used"

問題背景

起因是Stackoverflow上的問題,看到這個問題第一反應是,可能是因為OBJ_ENCODING_ZIPLIST/OBJ_ENCODING_HT或者redis rehash吧。然而,仔細看了問題描述之后,發(fā)現(xiàn)和這兩個原因沒有一丁點關(guān)系。
自詡為資深troubleshooter的某球,認為troubleshooting有以下3個步驟:

  1. 理解問題
  2. 重現(xiàn)問題
  3. 解決問題

鄙以為很多同學在“理解問題”這一環(huán)節(jié)上投入得很不夠,要么是客戶的描述不是很清楚,不能很好地引導客戶去描述自己的問題;要么是主觀上過于武斷,通過一點點蛛絲馬跡就判斷是某個問題,不通過從多方的數(shù)據(jù)佐證;要么是意識到這可能是一個復雜的問題,強行當作一個簡單的問題去處理,想避免受辱,殊不知“受辱一時而補牢,好于受辱一世而不知也”。當然,某球也有這樣的時候,諸君共勉。

理解問題

這位同學的回答感覺有些問題,于是和題主再三確認:

@Karthikeyan Gopall,I think it's better if you provide two more details: 1. How you get the momery used? use redis-cli to get 'info Memory' and get the value of field ''used_memory" or "used_memory_rss" or somewhere else 2. Your memory allocator which you can get by "./redis-cli info |grep mem_allocator"
@sel-fish 1) I will get it from "used_memory". Before starting the process I will take the used_memory, after the process I will do the same and difference of them is what I have mentioned in the graph. 2) mem_allocator:jemalloc-3.6.0

重現(xiàn)問題

重現(xiàn)了一下這個問題,結(jié)果和題主在問題中的貼圖不太一致,但是有一些有共性的地方:

解決問題

查代碼

查看redis源碼

hsetCommand
ziplistPush
ziplistResize
zrealloc

題主提到的場景下每次hset,都會引發(fā)zrelloc,但是realloc不一定會導致memory_used增加的,src/zmalloc.c中zrealloc的部分代碼:

    oldsize = zmalloc_size(ptr);
    newptr = realloc(ptr,size);
    if (!newptr) zmalloc_oom_handler(size);

    update_zmalloc_stat_free(oldsize);
    update_zmalloc_stat_alloc(zmalloc_size(newptr));

如果oldsize比size要大,realloc其實是不會申請新的空間的,這個時候memory_used不會增加,就出現(xiàn)了題主問題中提到的現(xiàn)象。對于libc的malloc,是不會出現(xiàn)這種情況的,每次realloc申請新的空間,至少從malloc_size接口拿到的值每次都會變的:

所以,猜想這個問題是jemalloc的邏輯導致的。

確認猜想

直接測試jemalloc在各個申請大小實際分配的內(nèi)存:

復審現(xiàn)象

得到的memory used變化和題主還是有區(qū)別的,在“理解問題”的部分已經(jīng)知道題主使用的mem_allocator是jemalloc-3.6.0,所以猜想是jemalloc邏輯有變化:

回答問題

As you have constantly 1000 keys in redis, only field number changes in each hash key, and you field number is lower than 512, so this phenomenon is only caused by jemalloc.

Here is the behavior when I use libc as my mem_allocator:

You can remake your redis by :

make MALLOC=libc

Run your test again, and see what you will get.

To answer your questions:

  1. Can someone explain me about the internal happenings of hashmap in terms of memory and resizing? What is the logic followed during resizing?

    As mentioned, what you encountered has nothing to do with redis itself. Jemalloc do it this way to improve its efficiency

  2. If I have to loose double the memory just for storing one more entry that is 215 to 216, why can't I restrict my application to have a hashes less than 215 always, unless and until the system needs it at the most.

    Of course, you can do it as long as you can restrict the field numbers

  3. Suppose if I want to store 1 million hashes each consisting of 250 values I need 800MB. If I split them into 2 hashes of 125 values ie, 2 million hashes of 125 values I need 500MB. In this way I am saving 300 MB which is huge!!. Is this calcuation right? Am I missing something in this case?

    I don't think that's a proper way to do that. Maybe you can save some memory by doing this. However, the disadvantages are: as you split 1 million hashes to 2 million, redis will do rehashing(which will take you some space) and it will take you more time to find one key, because it will leads to more chance of hash confliction.

問題延伸

任何問題總可以有延伸,問題的解決是階段性的。根據(jù)當前問題要盡量做到有所發(fā)散、舉一反三,這樣才能得到更多東西,有的是一些啟示,有的是更深層次或者其它方面的問題。比如這個問題會引發(fā):

  1. jemalloc的原理
  2. 我們自己的產(chǎn)品在內(nèi)存使用上能否提供更細維度的監(jiān)控數(shù)據(jù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,655評論 5 6
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 11,086評論 0 23
  • 識不足月,勝相伴數(shù)載。距千里,常念左右,望朗月,以寄心思。戚戚我我,嘆朝暮不足訴,甘苦自知。感蒼憐之,與汝相識,執(zhí)...
    丫頭愛張樂閱讀 497評論 2 0
  • 我和小星星斗得天昏地暗的時候,《甄嬛傳》正在熱播,助理說我倆是皇后和華妃,為爭寵上位無所不用其極。 小星星是我的同...
    綠喵咪閱讀 1,799評論 4 23
  • 小的時候媽媽問我想要個小弟弟還是小妹妹,我干脆的回答,我想要個哥哥。媽媽又說沒有哥哥,只有弟弟妹妹呢?我又很干脆的...
    樂小千閱讀 272評論 0 0

友情鏈接更多精彩內(nèi)容