共計 1700 個字符,預計需要花費 5 分鐘才能閱讀完成。
這篇文章主要介紹 redis 字符串類型的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
我們都知道 redis 是采用 C 語言開發,那么在 C 語言中表示 string 都是采用 char[] 數組的,然后你可能會想,那還不簡單,當我執行如下命令,肯定是直接塞給 char[] 數組的。
如果你真的這么想的話,會有幾個問題就要過來砍你了,先我們來找一個 redis 手冊,http://doc.redisfans.com/
第一:如果你每次都執行 Append 函數,那是不是 redis 的 char[] 每次都需要再次擴容,這樣是不是每次都是耗時操作呢?
第二:如果你每次執行 String 中的 StrLen,那 redis 底層是不是每次都要遍歷 char 數組來得到結果呢?
一、探索 Redis 中的 String 是如何存儲的
根據上面說的那些小情況,所以 redis 的作者沒有那么傻,正常的邏輯應該是在 char[] 數組的層面上自己再來封裝一層。
1. SDS 結構體
在 redis 里面是采用 SDS(simple dynamic string) 來封裝 char[] 的,這個也是 redis 存儲的最小單元,下一個問題就是哪里能看得到呢?我在 wget 壓縮包的時候,里面就有 redis 源碼啦,據說還只有 3w 多行,這就告訴我們,有什么問題,自己動手豐衣足食,對吧,為查找方便,我就把 redis 的源碼拖到 window 上用 vs 打開,接下來我們看看 SDS 長成啥樣???
可以看到它是定義在 redis 源碼中的 sds.h 源文件中的,你可能會奇怪,這三個屬性是干嘛用的???下面我簡單說一下。
1 len:標記 char[] 的長度, 有點類似我們 C# 中 List 的 length 一個意思。
2 free: 標記 char[] 中未使用的元素個數,就是有幾個空坑的意思。
3 buf[]: 存放元素的坑,不一定和元素的實際個數相等,比如前面說的 cnblogs。也有可能是 [c][n][b][l][o][g][s][/0][][][]。
二、探索 Redis 對象 (RedisObject)
前面說到的 SDS 僅僅是 char[] 數組的封裝,并不能標識 redis 中的 5 大類型,所以可想而知,redis 還需要在 SDS 上面進行封裝,所以就有了接下來的
RedisObject 對象,我們先看看它長成啥樣。
可以看到 RedisObject 是在 redis.h 源代碼文件中的,下面我簡單說說 type 和 ptr 屬性,詳細的東西在后續說。
1 type 這個就是用來標識 redisObject 是哪種類型,既然是哪種類型,肯定就有一個類型枚舉,對吧,肯定有了,給你看看。
2 *ptr 可以看到這玩意還是個指針類型,它所指向的內存地址,你應該也知道了,就是所謂的 SDS 枚舉類型。
好了,到現在你可以整合一下博客開始處的:
127.0.0.1:6379 set name cnblogs
127.0.0.1:6379 get name
cnblogs
127.0.0.1:6379
針對上面的 set 命令,redis 其實會創建兩個 RedisObject 對象,鍵的 RedisObject 和值的 RedisOjbect 其中它們的 type=REDIS_STRING,也就都是字符串對象類型,其中的 SDS 分別存儲的就是 name 和 cnblogs 的字符咯,好了,大概就這樣了。
三、挑選幾個有意思的命令
1. incr,incrby,decr,decrby
這四個命令有點像 C# 中的 Interlocked 類的方法,如果你了解 Interlocked,你應該就知道下面有各種原子自增,自減等等方法,如下圖:
redis 這個自增有什么好處呢?我覺得用這個生成訂單號還是蠻好的,我記得在攜程的時候,生成訂單號是專門的一個 OrderIDDB 中的 func 函數來生成的,這樣 OrderID 是不依賴于任何業務庫的,然后我們就可以相對方便的分庫分表了,現在用 redis 這樣做也挺好的。
其他的一些命令也沒什么好說的了,大家可以對照 redis 手冊看一看就好了。
以上是“redis 字符串類型的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注丸趣 TV 行業資訊頻道!