redis 的優化以及配置參數

redis使用了兩種文件格式:全量數據和增量請求。

全量數據格式是把內存中的數據寫入磁盤,便於下次讀取文件進行加載;

增量請求文件則是把內存中的數據序列化爲操作請求,用於讀取文件進行replay得到數據,序列化的操作包括SET、RPUSH、SADD、ZADD。

redis的存儲分爲內存存儲、磁盤儲存和log文件三部分,配置文件中有三個參數對其進行配置。

save seconds updates,save配置,指出在多長時間內,有多少次更新操作,就將數據同步到數據文件。這個可以多個條件配合,比如默認配置文件中的設置,就設置了三個條件。

appendonly yes/no ,appendonly配置,指出是否在每次更新操作後進行日誌記錄,如果不開啓,可能會在斷電時導致一段時間內的數據丟失。因爲redis本身同步數據文件是按上面的save條件來同步的,所以有的數據會在一段時間內只存在於內存中。

appendfsync no/always/everysec ,appendfsync配置,no表示等操作系統進行數據緩存同步到磁盤,always表示每次更新操作後手動調用fsync()將數據寫到磁盤,everysec表示每秒同步一次。

        通過我們上面的一些實現上的分析可以看出redis實際上的內存管理成本非常高,即佔用了過多的內存,所以提供了一系列的參數和手段來控制和節省內存,我們分別來討論下。
  首先最重要的一點是不要開啓Redis的VM選項,即虛擬內存功能,這個本來是作爲Redis存儲超出物理內存數據的一種數據在內存與磁盤換入換出的一個持久化策略,但是其內存管理成本也非常的高,並且我們後續會分析此種持久化策略並不成熟,所以要關閉VM功能,請檢查你的redis.conf文件中 vm-enabled 爲 no。
  其次最好設置下redis.conf中的maxmemory選項,該選項是告訴Redis當使用了多少物理內存後就開始拒絕後續的寫入請求,該參數能很好的保護好你的Redis不會因爲使用了過多的物理內存而導致swap,最終嚴重影響性能甚至崩潰。
  另外Redis爲不同數據類型分別提供了一組參數來控制內存使用,我們在前面詳細分析過Redis Hash是value內部爲一個HashMap,如果該Map的成員數比較少,則會採用類似一維線性的緊湊格式來存儲該Map, 即省去了大量指針的內存開銷,這個參數控制對應在redis.conf配置文件中下面2項:

  1. hash-max-zipmap-entries 64

  2. hash-max-zipmap-value 512

  3. 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 的6種過期策略redis 中的默認的過期策略是volatile-lru 。設置方式
  config set maxmemory-policy volatile-lru
  maxmemory-policy 六種方式
  volatile-lru:只對設置了過期時間的key進行LRU(默認值)
  allkeys-lru : 是從所有key裏 刪除 不經常使用的key
  volatile-random:隨機刪除即將過期key
  allkeys-random:隨機刪除
  volatile-ttl : 刪除即將過期的
  noeviction : 永不過期,返回錯誤
  maxmemory-samples 3 是說每次進行淘汰的時候 會隨機抽取3個key 從裏面淘汰最不經常使用的(默認選項)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章