c語言中的字串是基於陣列來實現的,每個字串會多出乙個空字元:
redis中的簡單動態字串是sds(****** dynamic string)型別:
sds遵循c語言中以空字元為結尾的慣例是為了利用c語言函式庫中的某些字串函式,而且新增空字元的這乙個操作是有sds函式自動完成的。
redis採用sds的原因是為了滿足字串在安全性、效率以及功能方面的要求【c語言中的字串並不能滿足】
c語言中的字串並不記錄長度資訊,所以需要對整個字串進行遍歷並計數,所以這個操作的時間複雜度為o(n);
sds在len屬性中記錄了字串的長度,所以它的時間複雜度為o(1),確保了獲取字串的長度不會成為redis的瓶頸
補充:獲取字串長度的命令
strlen key
除了獲取字串長度的複雜度高之外,c語言中的字串不記錄自身長度帶來的另乙個問題是容易造成緩衝區溢位。
例子:
假設程式裡有兩個在記憶體中緊鄰著的c語言字串s1和s2,如果在不給s1分配足夠的記憶體的情況下新增s1的內容,當strcat(新增函式)執行之後,s1中溢位的資料姜修改s2中的內容。sds的空間分配策略完全杜絕了發生緩衝區溢位的可能性:當api需要對sds進行修改的時候,api首先會檢查sds的空間是否滿足,若不滿足的話,api自動將sds的空間擴充套件到所需的大小,然後才執行實際的修改操作。
記憶體的重新分配涉及複雜的演算法,並且可能需要執行系統呼叫,所以它通常是乙個比較耗時的操作
c語言中的記憶體重新分配
c語言中的字串並不記錄自身的長度,所以對於乙個包含了n個字元的c字串來說,這個c字串的底層的hi先總是乙個n+1個字元長的陣列。因為c語言中字串的長度和底層陣列之間存在著這種關係性,所以每增長或者縮短乙個c字串,程式總要對這個c字串進行一次記憶體重新分配的操作:
sds中的記憶體分配機制
sds通過未使用的空間解除了字串長度和底層陣列長度之間的關聯,解決了c字串的這種缺陷:在sds中,buf陣列的長度不一定就是字元數量加一,陣列裡面可以包含未使用的子節,而這些位元組的數量就由sds的free屬性記錄。
通過未使用空間,sds實現了空間預分配和惰性空間釋放兩種優化策略。
1、空間預分配【減少連續執行字串增長操作所需的記憶體重分配次數】
空間預分配用於優化sds的字串增長操作:當sds的api對乙個sds進行修改,並且需要對sds進行空間擴充套件的時候,程式不僅會為sds分配修改所需要的空間還會分配額外的未使用空間。假如現在的sds的free空間滿足需求,則不需要空間的預分配
2、惰性空間釋放
惰性空間釋放用於優化sds的字串縮短操作:當sds的api需要縮短sds儲存的字串時,程式並不立即使用記憶體衝分配來**縮短後多出來的位元組,而是使用free屬性將這些子節的數量記錄起來,並等待將來增長的時候使用;在必要的時候也可以通過sds的api進行釋放。
為了確保redis可以適用於各種不同的使用場景,sds的api都是二進位制安全的(binary-safe),所有sdsapi都會已處理二進位制的方式來處理sds存放在buf陣列裡的資料,程式不會對其中的資料做任何限制、過濾或者假設,資料在寫入是什麼樣的,他被讀取時就是什麼樣。
這也是我們將sds的buf屬性稱為位元組陣列的原因-------redis不是用這個陣列來儲存字元,而是用它來儲存一系列的二進位制資料;之所以sds儲存之前提到的特殊資料格式沒有任何問題,是因為sds使用len屬性的值而不是空字串來判斷字串是否結束。
雖然sds的api都是二進位制安全的,但是他們一樣遵循c字串以空字元結尾的慣例:這些api總會將sds儲存的資料的末尾設定為空字元,並且總會在為buf陣列分配空間時多分配乙個子節來容納這個空字元,這是為了讓那些儲存文字資料的sds可以重用一部分函式庫裡的函式。
Redis 資料結構 簡單動態字串
redis 是基於 c 語言的記憶體資料庫,但是 redis 中並沒有使用 c 語言的字串 實質是 以空格結尾的字元陣列 作為預設的字串,而是自己構建了一種名為簡單動態字串 dynamic string 的抽象資料結構,將其用作預設的字串表示。通常而言,sds 在 redis 中被用於 1.預設的字...
Redis資料結構 SDS(簡單動態字串)
redis中所有字串都是用sds 簡單動態字串 實現的,該結構體內部定義如下 struct sdshdr 關於sds的特點,可以總結為以下幾點 1.sds遵循c字串以空字元結尾的風格,相容部分c字串函式,buf在末尾缺省會帶上乙個 0 字元,但是不會計算到len欄位裡面,因此buf的實際大小為len...
Redis資料結構 簡單動態字串SDS
最新 redis記憶體 三個重要的緩衝區 最新 redis記憶體 記憶體消耗 記憶體都去哪了?最新 redis持久化 如何選擇合適的持久化方式 最新 redis持久化 aof日誌 相信用過redis的人都知道,redis提供了乙個邏輯上的物件系統構建了乙個鍵值對資料庫以供客戶端使用者使用。這個物件系...