業務場景:Redis 做爲目前主流的key-value 內存數據庫,由於其高併發,存儲查詢速率快,咱們不少的熱點數據均會存儲到Redis 中,若是數據量較大的話,昂貴的內存消耗也是一筆很大的支出,所以Redis 內存優化是頗有必要的。
上圖能夠看到:Redis內部的對象數高達:1,599,098,020(15億),其內存使用高達 371G ,而且持續的增多,須要咱們儘快優化,釋放多餘的空間。
{ "expireTime": "253402271999000", "value": "test_test_test_test" }
主要內存優化依據是:
Redis 內部Hash 數據結構的編碼方式主要有兩種:java
- OBJ_ENCODING_ZIPLIST(壓縮列表)
- OBJ_ENCODING_HT(哈希表)
Redis 內部會根據數量的狀況自適應的選擇這兩種編碼方式中 最優 的一種,這種操做徹底對用戶透明,選擇壓縮列表存儲的依據主要是:linux
- 數據條目較少(hash-max-ziplist-entries)即 Hash 的filed 較少 field 個數 默認小於 512
- 數據值較少(hash-max-ziplist-value)即Hash的value 值較少 value 值的長度小於64
即默認存儲爲壓縮列表存儲的條件爲git
field_num < hash-max-ziplist-entries && value.length < hash-max-ziplist-value綜上所述:根據前面看到的業務場景,徹底知足此種場景,這是選擇由string存儲變爲 Hash存儲的一個緣由github
OBJ_ENCODING_ZIPLIST 編碼的主要思想是:空間換時間,適應於字段個數比較少,字段值也比較小的場景。
爲了全方位的對內存進行優化,那麼key 以及 hash 的field 進行必要的壓縮redis
- 若是是字符串的話能夠進行分段優化,針對數據進行16進制轉換
- 字符串使用簡寫方式
爲保證測試的準確性,私有服務器安裝Redis 進行優化前與優化後內存空間測試
如下爲整個測試過程:docker
- docker 安裝 Redis
docker pull redis
docker ps # 查詢當前容器
docker exec -it ****** /bin/bash # 進入容器內部 redis-cli -a 123456 #打開Redis-cli鏈接Redis info memory # 查詢安裝完成後Redis 的內存使用狀況
以上爲Redis 服務搭建過程的簡單記錄數據庫
- 數據存儲測試(未優化前)
優化前 存儲 1000000 string 類型數據以下:json
-- string key 0:1:201155:100:545953888100 -- string value { "value": "3.6230093077568726-0.3630194103106919100", "expireTime": "2147483647" }
由上圖內存存儲可知:未優化前 1000000 條 string 消耗內存:200.12M
執行完測試,將此前存入的數據刪除bash
(1)數據存儲測試(優化key value)服務器
- 壓縮key的長度:將最後的無業務標識的字符串轉換爲:16進制
- 壓縮value 的長度:壓縮value的數據
優化後 存儲1000000數據使用內存:139.10M 相比較優化前優化內存:30%
偷偷竊喜下,若是進行這次優化:節省內存:115G
(2)數據存儲測試(優化key value)
- 壓縮key的長度:將最後的無業務標識的字符串轉換爲:64 進制
- 壓縮value 的長度:壓縮value的數據
這次優化變化不明顯,僅僅下降了 不到1M ,疑惑臉。。。
因而乎對於key的長度不進行壓縮,只對value值進行壓縮進行測試結果以下:
由以上測試可得:1000000數據,內存使用率爲 146.59M ,故此 16/64 進制對key的壓縮影響並不明顯。
(3)數據存儲測試(優化key value)
- 壓縮key的長度:將最後的無業務標識的字符串轉換爲:64 進制
- 壓縮value 的長度:壓縮value的數據,不在存儲json,只存儲,attr1:value,attr2:value2
以上優化後,存儲1000000數據使用內存:123.86M,優化達到:38%
(4)數據存儲測試(優化key value)
- 壓縮key的長度:將最後的無業務標識的字符串轉換爲:64 進制
- 壓縮value 的長度:壓縮value的數據,不在存儲json,只存儲,attr1:value
通過第4次進行優化,內存的佔用依舊與第三次相差很小,可是仍然在減小,這次內存佔用爲 123.71M,繼續對value值作壓縮
(5)數據存儲測試(優化key value)
- 壓縮key的長度:將最後的無業務標識的字符串轉換爲:64 進制
- 壓縮value 的長度:壓縮value的數據,只存儲,attr1:value, exp(過時時間戳)壓縮爲64進制
通過第5次進行優化,內存佔用達到了 116.27M ,優化達到:42%
- 數據存儲測試(優化key value的基礎上進行 數據結構變動:變動爲HASH)
見證奇蹟的時刻到了,變動HASH 結構後,1000000數據內存佔用 100.49M,優化50%
思考:
Redis 的內存優化,須要配合業務場景進行鍼對性的優化,並非一味的已減小內存爲主要的優化目標,咱們也應該在空間和時間上找到一個平衡點進行恰當的優化,就那這次優化來講,雖然內存減小了 50% ,可是在實際應用中考慮到,該數據對於效率要求比較高,因此在進行編碼解碼過程當中也存在時間的消耗,最終並非採用內存優化度最大的那種方案。
這次測試的代碼都可在github 傳送門: 項目測試