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),当内存达到一定量后,根据不同的优先级对内存进行回收。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章