面試官:Redis中字符串的內部實現方式是什么?


在面試間里等候時,感覺這可真暖和呀,我那冰冷的出租屋還得蓋兩層被子才能睡着。正要把外套脫下來,我突然聽到了門外的腳步聲,隨即門被打開,穿着干凈滿臉清秀的青年走了進來,一股男士香水的淡香撲面而來。

面試官:Redis中基本的數據類型有哪些?

我:Redis的基本數據類型有:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)。

面試官:字符串類型的內部實現方式是什么?

我還沉浸在上一個問題的沾沾自喜中,頓時表情凝固了,手心開始冒出冷汗。“這個。。沒有太深入了解”,我支支吾吾的說到。

面試官:回去等消息吧。

這句話說的干凈利落,然后就沒有然后了。失敗是成功的媽媽,我不氣餒,決定馬上惡補一下。

類型和編碼

首先,整明白什么是類型?什么是編碼?在Redis中使用對象來表示內存中的鍵和值。每個對象由一個叫做redisObject結構體表示,其中有三個屬性:類型(type)、編碼(encoding)、指向具體數據的指針(ptr)。

我們通常說的字符串、哈希、列表、集合、有序集合都是redisObject中的類型,實際上針對每一個數據結構在Redis內部都有自己底層的多種內部編碼實現,這樣是為了在合適的場景選擇合適的內部編碼,以達到內存空間和處理效率的平衡,這可能就是中庸之道吧。

在面試中,經常被問到的內部實現方式、內部構造、內部原理,一般指的就是redisObject中的編碼

字符串的編碼

字符串類型的編碼有如下三種:

  • int:8個字節的長整型。
  • embstr:小於等於44個字節的字符串。
  • raw:大於44個字節的字符串。

在3.2版本之后,embstr和raw變為了44字節為分界,之前是以39字節為分界。這里以較新版本為准。

為了驗證和理解,我們使用object encoding命令查看一下內部編碼。

整數類型效果如下:

127.0.0.1:6379> set one-more-num 1
OK
127.0.0.1:6379> object encoding one-more-num
"int"

短字符串類型效果如下:

127.0.0.1:6379> set one-more-str 萬貓學社
OK
127.0.0.1:6379> object encoding one-more-str
"embstr"

長字符串類型效果如下:

127.0.0.1:6379> set one-more-str 萬貓學社|萬貓學社|萬貓學社|萬貓學社|萬貓學社|萬貓學社|萬貓學社|萬貓學社
OK
127.0.0.1:6379> object encoding one-more-str
"raw"

當然,了解以上細節還沒能完全“征服”面試官,我們需要更深入一些:)

簡單動態字符串

在C語言中,字符串是以空字符表示結尾的字符數組。在Redis中沒有直接使用C語言的字符串,而是定義了一個叫做簡單動態字符串(Simple Dynamic String,SDS)的結構,並把其作為Redis默認的字符串表示。

簡單動態字符串有三個屬性:

  • len:記錄buf字符數組中已使用的字節數量
  • free:記錄buf字符數組中為使用的字節數量
  • buf[]:字符數組,用於保存字符串

為了理解,我們舉個例子:

127.0.0.1:6379> set one-more-str OneMore
OK

那么,對應的簡單動態字符串就是這樣的:

萬貓學社

其中,len為7,表示這個簡單動態字符串中保存了一個7個字節的字符串;free為0,表示這個簡單動態字符串沒有分配未使用的空間;buf是一個字符數組,數組的前7個字節分別保存了O、n、e、M、o、r、e字符,最后一個字節是空字符\0

相對於C語言的字符串,簡單動態字符串有什么好處呢?

  • 獲取字符串長度的時間復雜度為O(1)。
  • 可以保存字節數組,支持安全的二進制數據存儲。
  • 內部實現了內存空間的預分配機制,減少內存空間分配次數。
  • 內部實現了惰性刪除機制,字符串縮減后內存不釋放,做為預分配空間。
  • API是安全的,不會造成緩沖區溢出。

面試官你等着瞧吧,今天你對我愛答不理,明天我讓你高攀不起,哈哈哈。。。

參考文獻:
《Redis設計與實現》
《Redis開發與運維》
《Redis 深度歷險:核心原理與應用實踐》


竟然已經看到這里了,你我定是有緣人,留下你的點贊關注,他日必成大器。

微信公眾號:萬貓學社

微信掃描二維碼

關注后回復「電子書」

獲取12本Java必讀技術書籍


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM