Redis技術知識總結之四——Redis內存優化

接上篇《Redis技術知識總結之三——Redis數據淘汰機制》

四. Redis 內存優化

參考地址:
《一文深入瞭解 Redis 內存模型,Redis 的快是有原因的!》
《Redis集羣與插槽分配(動態新增或刪除結點)》

瞭解 redis 的內存模型,對優化 redis 內存佔用有很大幫助。下面介紹幾種優化場景。

  1. 利用 jemalloc 特性進行優化
    • 由於 jemalloc 分配內存時數值是不連續的,因此 key/value 字符串變化一個字節,可能會引起佔用內存很大的變動(比如兩個 SDS 分別佔據 32/33Bytes,實際佔用值是 32/64Bytes);在設計時可以利用這一點。
      • 例如,如果 Key 的長度如果是 8 個字節,則 SDS 爲 17 字節,jemalloc 分配 32 字節;此時將 key 長度縮減爲 7 個字節,則 SDS 爲 16 字節,jemalloc 分配 16 字節;則每個key所佔用的空間都可以縮小一半。
    • 使用整型/長整型:如果是整型/長整型,Redis 會使用 int 類型(8字節)存儲來代替字符串,可以節省更多空間。因此在可以使用長整型/整型代替字符串的場景下,儘量使用長整型/整型。
  2. 共享對象
    • 利用共享對象,可以減少對象的創建(同時減少了 redisObject 的創建),節省內存空間。
    • 目前 Redis 中的共享對象只包括 10000 個整數(0-9999);可以通過調整 REDIS_SHARED_INTEGERS 參數提高共享對象的個數;例如將 REDIS_SHARED_INTEGERS 調整到 20000,則 0-19999 之間的對象都可以共享。
      • 例:論壇網站在 redis 中存儲了每個帖子的瀏覽數,而這些瀏覽數絕大多數分佈在 0-20000 之間,這時候通過適當增大 REDIS_SHARED_INTEGERS 參數,便可以利用共享對象節省內存空間。
  3. 避免過度設計
    • 需要注意的是,不論是哪種優化場景,都要考慮內存空間與設計複雜度的權衡;而設計複雜度會影響到代碼的複雜度、可維護性。如果數據量較小,那麼爲了節省內存而使得代碼的開發、維護變得更加困難並不划算;例如如果只有 90000 個鍵值對,實際上節省的內存空間只有幾MB。但是如果數據量有幾千萬甚至上億,考慮內存的優化就比較必要了。
  4. 關注內存碎片率
    • 內存碎片率是一個重要的參數,對 Redis 內存的優化有重要意義。定義如下:
    • mem_fragmentation_ratio = used_memory_rs / used_memory,即 Redis 進程佔據內存大小,與 Redis 分配器分配內存大小的比值;
    • 內存碎片率越高( 在 1.03 左右比較正常),說明內存碎片越多,內存浪費越嚴重;這時便可以考慮重啓 redis 服務,在內存中對數據進行重排,減少內存碎片。
    • 如果內存碎片率小於 1,說明 redis 內存不足,部分數據使用了虛擬內存(即 swap);由於虛擬內存的存取速度比物理內存差很多(2-3個數量級),此時 redis 的訪問速度可能會變得很慢。因此必須設法增大物理內存(可以增加服務器節點數量,或提高單機內存),或減少 redis 中的數據。
  5. 回收策略
    • 設置合理的數據回收策略(maxmemory-policy),當內存達到一定量後,根據不同的優先級對內存進行回收。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章