04-Redis的內存對象及內部編碼_String

Redis支持5種對象類型,而每種都至少有兩種編碼,這樣做的好處在於:

一方面接口與實現分離,當需要增加或改變內部編碼時,用戶使用不受影響;另一方面可以根據不同的應用場景切換內部編碼,提高效率。

Redis各種對象類型支持的內部編碼如下圖所示(部分)

關於Redis內部編碼的轉換,都符合以下規律:編碼轉換在Redis寫入數據時完成,且轉換過程不可逆,只能從小內存編碼向大內存編碼轉換。

字符串

1.1 概況
字符串是最基礎的類型,因爲所有的鍵都是字符串類型,且字符串之外的其他幾種複雜類型的元素也是字符串。

字符串長度不能超過512MB。

1.2 內部編碼
字符串類型的內部編碼有3種,它們的應用場景如下:

  • int:8個字節的長整型。 字符串值是整型時,這個值使用long整型表示。
  • embstr:<=44字節的字符串。 embstr與raw都使用redisObject和sds保存數據,區別在於,embstr的使用只分配一次內存空間(因此redisObject和sds是連續的),而raw需要分配兩次內存空間(分別爲redisObject和sds分配空間)。因此與raw相比,embstr的好處在於創建時少分配一次空間,刪除時少釋放一次空間,以及對象的所有數據連在一起,尋找方便。而embstr的壞處也很明顯,如果字符串的長度增加需要重新分配內存時,整個redisObject和sds都需要重新分配空間,因此redis中的embstr實現爲只讀
  • raw:大於44個字節的字符串
127.0.0.1:6379> set key1 123
OK
127.0.0.1:6379> object encoding key1
"int"
127.0.0.1:6379> set key2 helloworld
OK
127.0.0.1:6379> object encoding key2
"embstr"
127.0.0.1:6379> set key2 helloworldhelloworldhelloworldhelloworld
OK
127.0.0.1:6379> strlen key2
(integer) 40
127.0.0.1:6379> object encoding key2
"embstr"
127.0.0.1:6379> set key3 helloworldhelloworldhelloworldhelloworldhell
OK
127.0.0.1:6379> strlen key3
(integer) 44
127.0.0.1:6379> object encoding key3
"embstr"
127.0.0.1:6379> set key4 helloworldhelloworldhelloworldhelloworldhello
OK
127.0.0.1:6379> strlen key4
(integer) 45
127.0.0.1:6379> object encoding key4
"raw"

1.3 編碼轉換
當int數據不再是整數,或大小超過了long的範圍時,自動轉化爲raw。
而對於embstr,由於其實現是隻讀的,因此在對embstr對象進行修改時,都會先轉化爲raw再進行修改
因此,只要是修改embstr對象,修改後的對象一定是raw的,無論是否達到了44個字節。

127.0.0.1:6379> set key1 hello
OK
127.0.0.1:6379> object encoding key1
"embstr"
127.0.0.1:6379> append key1 .world
(integer) 11
127.0.0.1:6379> get key1
"hello.world"
127.0.0.1:6379> object encoding key1
"raw"

參考鏈接:

https://blog.csdn.net/xsc_c/article/details/21176645

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章