国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Redis 內存優化

2019-11-08 20:38:43
字體:
來源:轉載
供稿:網友

非常感謝 http://blog.csdn.net/zhu_tianwei/article/details/44892765

Redis內部有很多的數據類型,這些在官方文檔上都可以看到,下面是其內部優化的一些細節點:

1. String 和 數字,在Redis中如果存儲的是“123”Redis是能夠識別出來這是一個數字并且按照數字來存儲,節省存儲空間,當然除了這個優化之外,Redis內部會構建一個數字池,默認是10000,那么如果是在這個池子的數字就只需要用一個簡單的索引來引用進來就可以,而不需要把重復的數字都分開存儲。這個數值可以調整源代碼的宏:REDIS_SHARED_INTEGERS來擴大和縮小池子的大小。

2.復雜類型的存儲優化,比如Map,List,Set等,這些集合都有一個特點可大可小,根據實際場景來定,一般情況下如果這些集合所包含的Entry不多,并且每個Entry所包含的Value不是很長的情況下,Redis內部使用緊湊格式來存儲數據,緊湊格式存儲數據在查詢場景的算法復雜度是O(N),而類似Map或者Set他們的查詢算法復雜度都是O(1)那為什么要這么做呢 ?為了能夠節省內存空間,在N很小的時候其實和O(1)沒什么區別。所以這里不的不介紹緊湊格式的代表ZipMap,

可以看出,這個結構中初始情況只有2個字節,隨著操作的增加它會變長,其中最關鍵的是一個關于Free這個字段的理解,以Map為例,如果新插入一個Key,那么對應ZipMap就會多出來一長串數據:<len><key><len><free><value>。從圖中可以看到插入key1的時候只有綠色的一串,當key2插入的時候就會又出來一個類似的黃色結構串。free的功能是在插入的時候用來冗余空間的,當key所對應的數值發生變化的時候,如果數據變的比之前短了,那么free的長度就變大,這個時候不需要做ZipMap的resize操作,如果數據長度變長了,并且在free能夠足以支持新數據的范圍之內,那么free就被利用起來,并且也不需要做Resize。這個時候會有空間的浪費或者說碎片。空間換時間吧,沒什么好說的。當然Redis的代碼中還有另外一個參數ZIPMAP_VALUE_MAX_FREE,這個參數可以用來設置如果Free的大小超過了這個值,那么ZipMap會發生Resize(收縮),從而節約空間。

常用內存優化手段與參數

redis實際上的內存管理成本非常高,即占用了過多的內存,作者對這點也非常清楚,所以提供了一系列的參數和手段來控制和節省內存,我們分別來討論下。1.首先最重要的一點是不要開啟Redis的VM選項,即虛擬內存功能,這個本來是作為Redis存儲超出物理內存數據的一種數據在內存與磁盤換入換出的一個持久化策略,但是其內存管理成本也非常的高,并且我們后續會分析此種持久化策略并不成熟,所以要關閉VM功能,請檢查你的redis.conf文件中 vm-enabled 為 no。2.其次最好設置下redis.conf中的maxmemory選項,該選項是告訴Redis當使用了多少物理內存后就開始拒絕后續的寫入請求,該參數能很好的保護好你的Redis不會因為使用了過多的物理內存而導致swap,最終嚴重影響性能甚至崩潰。3.另外Redis為不同數據類型分別提供了一組參數來控制內存使用,我們在前面詳細分析過Redis Hash是value內部為一個HashMap,如果該Map的成員數比較少,則會采用類似一維線性的緊湊格式來存儲該Map, 即省去了大量指針的內存開銷,這個參數控制對應在redis.conf配置文件中下面2項:hash-max-zipmap-entries 64 hash-max-zipmap-value 512 hash-max-zipmap-entries含義是當value這個Map內部不超過多少個成員時會采用線性緊湊格式存儲,默認是64,即value內部有64個以下的成員就是使用線性緊湊存儲,超過該值自動轉成真正的HashMap。hash-max-zipmap-value 含義是當 value這個Map內部的每個成員值長度不超過多少字節就會采用線性緊湊存儲來節省空間。以上2個條件任意一個條件超過設置值都會轉換成真正的HashMap,也就不會再節省內存了,那么這個值是不是設置的越大越好呢,答案當然是否定的,HashMap的優勢就是查找和操作的時間復雜度都是O(1)的,而放棄Hash采用一維存儲則是O(n)的時間復雜度,如果成員數量很少,則影響不大,否則會嚴重影響性能,所以要權衡好這個值的設置,總體上還是最根本的時間成本和空間成本上的權衡。同樣類似的參數還有:list-max-ziplist-entries 512說明:list數據類型多少節點以下會采用去指針的緊湊存儲格式。list-max-ziplist-value 64 說明:list數據類型節點值大小小于多少字節會采用緊湊存儲格式。set-max-intset-entries 512 說明:set數據類型內部數據如果全部是數值型,且包含多少節點以下會采用緊湊格式存儲。

最后想說的是Redis內部實現沒有對內存分配方面做過多的優化,在一定程度上會存在內存碎片,不過大多數情況下這個不會成為Redis的性能瓶頸,不過如果在Redis內部存儲的大部分數據是數值型的話,Redis內部采用了一個shared integer的方式來省去分配內存的開銷,即在系統啟動時先分配一個從1~n 那么多個數值對象放在一個池子中,如果存儲的數據恰好是這個數值范圍內的數據,則直接從池子里取出該對象,并且通過引用計數的方式來共享,這樣在系統存儲了大量數值下,也能一定程度上節省內存并且提高性能,這個參數值n的設置需要修改源代碼中的一行宏定義REDIS_SHARED_INTEGERS,該值默認是10000,可以根據自己的需要進行修改,修改后重新編譯就可以了。

參考文章

Redis內存存儲結構分析:http://www.searchtb.com/2011/05/redis-storage.html

Redis在實際應用中的優化:http://www.chepoo.com/redis-application-optimize.html

Redis幾個認識誤區:http://www.chepoo.com/redis-some-misunderstandings.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 南安市| 册亨县| 益阳市| 突泉县| 安远县| 南郑县| 澄城县| 积石山| 天镇县| 玉溪市| 赤壁市| 大洼县| 奇台县| 宜丰县| 马龙县| 湖州市| 婺源县| 绵阳市| 崇礼县| 陈巴尔虎旗| 常德市| 青铜峡市| 高安市| 银川市| 图木舒克市| 财经| 红原县| 庆安县| 安国市| 北安市| 奎屯市| 进贤县| 浮梁县| 正宁县| 营口市| 二连浩特市| 鸡西市| 寻甸| 泸定县| 乐安县| 博罗县|