zoukankan      html  css  js  c++  java
  • redis- info调优入门-《每日五分钟搞定大数据》

    本文根据redis的info命令查看redis的内存使用情况以及state状态,来观察redis的运行情况以及需要作出的相应优化。

    info

    1.memory
    used_memory:13409011624 #used_memory=实际缓存占用的内存+Redis自身运行所占用的内存(如元数据、lua)。
                            #这个值是由Redis使用内存分配器分配的内存,不包括内存碎片浪费的内存。
    used_memory_rss:13740019719  #从操作系统上显示已经分配的内存总量。
    used_memory_peak:13409011624  #内存使用的峰值大小
    total_system_memory:33567678464  #系统总内存
    used_memory_lua:37888  #Lua脚本引擎所使用的内存大小。
    maxmemory:0  #最大可用内存(可配置,默认为total_system_memory)
    maxmemory_policy:noeviction  #淘汰机制,noneviction为禁止淘汰数据
    mem_fragmentation_ratio:1.02;  #内存碎片率
    mem_allocator:jemalloc-4.0.3; #编译时指定的Redis内存分配器,可以是libc、jemalloc、tcmalloc。
    
    2.stats
    total_commands_processed:3500  #自启动起Redis服务处理命令的总数

    1.used_memory 过大导致的问题

    1.1.引发内存交换

      当Redis内存使用率超过可用内存(maxmemory可配置)的95%时,操作系统会进行内存与swap空间数据交换。把内存中旧的或不再使用的内容写入硬盘上即Swap分区,以便腾出新的物理内存给新页或活动页(page)使用。 在硬盘上进行读写操作要比在内存上进行读写操作,时间上慢了近5个数量级,内存是0.1μs单位、而硬盘是10ms。如果Redis进程上发生内存交换,那么Redis和依赖Redis上数据的应用会受到严重的性能影响。

    1.2.rdb持久化风险

      在没有开启持久化的情况下,redis宕机或者内存使用率超过95%会有丢数据的风险。若使用快照(rdb)持久化,Redis会fork一个子进程把当前内存中的数据完全复制一份写入到硬盘上(fork使用的内存和redis当前使用的内存会一样多)。因此若是当前使用内存超过可用内存的45%时触发快照功能,那么此时进行的内存交换会变的非常危险(可能会丢失数据)。 倘若在这个时候实例上有大量频繁的更新操作,问题会变得更加严重。

    2.避免used_memory 过大

    • 尽可能的使用Hash数据结构

      因为Redis在储存小于100个字段的Hash结构上,其存储效率是非常高的。所以在不需要集合(set)操作或list的push/pop操作的时候,尽可能的使用Hash结构。比如,在一个web应用程序中,需要存储一个对象表示用户信息,使用单个key表示一个用户,其每个属性存储在Hash的字段里,这样要比给每个属性单独设置一个key-value要高效的多。 通常情况下倘若有数据使用string结构,用多个key存储时,那么应该转换成单key多字段的Hash结构。 如上述例子中介绍的Hash结构应包含,单个对象的属性或者单个用户各种各样的资料。Hash结构的操作命令是HSET(key, fields, value)和HGET(key, field),使用它可以存储或从Hash中取出指定的字段。

    • 设置key的过期时间

      一个减少内存使用率的简单方法就是,每当存储对象时确保设置key的过期时间。倘若key在明确的时间周期内使用或者旧key不大可能被使用时,就可以用Redis过期时间命令(expire,expireat, pexpire, pexpireat)去设置过期时间,这样Redis会在key过期时自动删除key。 假如你知道每秒钟有多少个新key-value被创建,那可以调整key的存活时间,并指定阀值去限制Redis使用的最大内存。

    • 回收key

      在Redis配置文件Redis.conf中,通过设置“maxmemory”属性的值可以限制Redis最大使用的内存,修改后重启实例生效。 也可以使用客户端命令config set maxmemory 去修改值,这个命令是立即生效的,但会在重启后会失效,需要使用config rewrite命令去刷新配置文件。

    1. 若是启用了Redis快照功能,应该设置“maxmemory”值为系统可使用内存的45%,因为快照时需要一倍的内存来复制整个数据集,也就是说如果当前已使用45%,在快照期间会变成95%(45%+45%+5%),其中5%是预留给其他的开销。
    2. 如果没开启快照功能,maxmemory最高能设置为系统可用内存的95%。
    • 淘汰策略

      当内存使用达到设置的最大阀值时,需要选择一种key的回收策略,可在Redis.conf配置文件中修改“maxmemory-policy”属性值。 若是Redis数据集中的key都设置了过期时间,那么“volatile-ttl”策略是比较好的选择。但如果key在达到最大内存限制时没能够迅速过期,或者根本没有设置过期时间。那么设置为“allkeys-lru”值比较合适,它允许Redis从整个数据集中挑选最近最少使用的key进行删除(LRU淘汰算法)。

    Redis还提供了一些其他淘汰策略,如下:

    volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据。
    volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰。
    volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰。
    allkeys-lru:使用LRU算法从所有数据集合中淘汰数据。
    allkeys-random:从数据集合中任意选择数据淘汰
    no-enviction:禁止淘汰数据。

      通过设置maxmemory为系统可用内存的45%或95%(取决于持久化策略)和设置“maxmemory-policy”为“volatile-ttl”或“allkeys-lru”(取决于过期设置),可以比较准确的限制Redis最大内存使用率,在绝大多数场景下使用这2种方式可确保Redis不会进行内存交换。倘若你担心由于限制了内存使用率导致丢失数据的话,可以设置noneviction值禁止淘汰数据。

    3. used_memory_rss 过大解决办法

      当mem_fragmentation_ratio远大于1时即used_memory_rss/used_memory(稍大于1正常),说明redis中存在大量的内存碎片,一个比较好的解决办法就是重启redis,这里需要注意的是如果用的是aof持久化,那么重启之前要进行rewriteaof操作,否则会无效。还有可以指定Redis使用的内存分配器,一般管理员不推荐,麻烦而且要重新编译。

    参考:

    1. redis官方文档
    2. 不错的英文文档

    评论不能及时回复可直接加公众号提问或交流,知无不答,谢谢 。
    欢迎关注大叔

    转载于:https://blog.51cto.com/9587671/2176114

  • 相关阅读:
    POJ 2112 Optimal Milking (Floyd+二分+最大流)
    hdu5444 Elven Postman
    hdu5442 Favorite Donut
    hdu5437 Alisha’s Party
    hdu5433 Xiao Ming climbing
    hdu5432 Pyramid Split
    Codeforces Round #316 (Div. 2) C. Replacement
    hdu5396 Expression
    hdu3506 Monkey Party
    hdu3516 Tree Construction
  • 原文地址:https://www.cnblogs.com/twodog/p/12135935.html
Copyright © 2011-2022 走看看