cache 的簡單認識與思考

m47g 9年前發布 | 32K 次閱讀 緩存組件 Cache
 

之前對NOSQL的總結是:基本功能是key-value, 然后各自附加特殊功能. 現在簡單的來認識一下cache.

背景

大家都知道NoSQL, 大多數都是 key-value 型的數據庫.

有些內存型的數據庫甚至可以當做遠程cache來使用, 比如memcache, redis, 或者公司內部的TMEM等數據庫.

cache 的簡單認識與思考

有時候,我們認為遠程cache依舊太慢,畢竟一次網絡操作來回至少幾十毫秒, 加上網上不穩定等因素, 本地cache還是很有必要的.

目前,我使用的本地cache往往是開一個共享內存, 然后服務會開若干進程, 這些進程同時讀寫本地cache, 基本上解決了服務高訪問量的問題.

cache 的簡單認識與思考

這個本地cache使用的是一個通用的cache庫, 特點是使用hashtable實現, 缺點是key和value的長度是固定的.

固定的長度, 會導致幾個問題.

  1. key和value 最大長度限制.
  2. 很浪費空間, 所有的value占用相同的空間. 我們的value及時只有很小的長度, 占用的空間依舊很大.

cache 的簡單認識與思考

后來, 我遇到這么一個問題: 有大量的數據, value在短時間內只有一個值:0或者1.

看到這個, 大家第一個想到的應該是位壓縮吧.

但是注意這里有兩個問題: 1.我們不能把所有的key儲存下來, 2.value只是在短時間內不變,過了時間就失效了.

其實, 這就是cache能夠滿足的事情, 只不過這個cache的value比較極端,只有幾字節.

再后來,我又遇到一個問題:有大量的數據, value在短時間內非常大,有時候高大30K.

這個問題cache還是可以滿足的, 只是這個cache的value又是另一個極端: value非常大.

針對這兩個問題, 我們需要改造cache, 來分別適應兩個極端情況.

小value極端

對于小value極端情況, 解決方案簡單點: 初始化共享內存時動態指定value的長度即可.

當然儲存的數據結構的參數也要調整一下, 目的是讓key在hash的時候足夠的分散, 畢竟我們的value長度可能還沒有key的長度長.

當然我們也可以換一下數據結構, 使用hash list 或者 平衡樹.不過一般情況下不要使用樹這個數據結構吧, 實現復雜(正確性難以保證),復雜度還是log級別的(和hash相比,還是差一個數量級).

大value極端

對于大value極端情況, 我們就不能簡單的增大value來解決問題了.

因為這個大value只是說明極端情況下, 有些value很大, 一般情況下, value還是中等大小的.

如果我們簡單增大value, 將會浪費很大內存(內存還是很寶貴的).

PS:我第一次簡單的增大value時,增大前占用共享內存是1.6G, 單純的增大value值,沒有減小節點數的時候, 機器瞬時死了,一查內存,申請了24G內存, 16G是虛擬內存,嚇尿了.

面對上面的問題,我們目前的儲存方式是不能解決的, 所以需要換一種儲存方式.

最直接的想法就是key和value分開儲存, 我們key的數據結構中只需要儲存value的一些元信息即可.

這個時候,對于value的儲存,很容易想到操作系統內存分配算法, 對,就是這個方法, 對value分頁, 然后保存每一頁的信息即可.

cache 的簡單認識與思考

這個時候,再回過頭看看這個儲存方式, 可以支持任意大小的value值了, 對于小value, 浪費頂多不到一頁的內存.當然, 代價是我們需要另外預留一片內存,來管理value的頁塊.

尾記

這種value極小, 極大, 一般的情況在我的一個服務中都遇到了, 起初是固定value值比較小, 對于大value,直接報寫cache錯誤.后來增大value后, 寫cache正常了, 但是cache的節點數講了一個數量級:由30000變成2000, 根據監控, cache的利用率瞬時飆到80%.

目前比較偷懶的方法是把cache庫改造拆分成三個庫, 極小情況下使用極小value的cache庫, 極大情況下使用極大value的cache庫.

PS: 之前感覺共享內存很高大上, 看了源代碼, 發現我們先得到共享內存的指針,然后, 共享內存也僅僅只是一片內存而已了,怎么干還是自己說了算.

PS: 關于共享內存加鎖的問題, 不在該文章范圍內, 故不許考慮多寫加鎖問題.

 本文由用戶 m47g 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!