Redis使用性能优化建议

本文介绍Redis存储优化策略,包括利用ziplist节省内存、优化key管理、合理设置过期时间、调整Linux内核参数及Jedis客户端配置,以提升Redis性能。

存储结构优化
        尽量保证单个结构中存储的数据量(这里的数据量即包括散列中的key个数、也包括值大小),不要超过ziplist的临界条件,尽量让Redis使用ziplist短结构来存储。比如当某个Hash结构中的元素在不足一定数量时会被压缩成ziplist存储结构,所以可以大量节约内存。

# 表示当hash表中的条目数小于512条<即键值对数量>
# 且每个value的长度不超过64字节时,就将该hash结构转换成ziplist结构存储。
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
 
# 当存储个数小于512的时候,并且数据全为整型时  转换成ziplist。
# 否则退化为hash结构。
set-max-intset-entries 512
 
# 与上面的hash一样,只是这里为zset结构进行设置
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

Key的名称尽量简单明了
       
原因同下

注意控制Key的数量
        随着业务的扩展,存储在Redis中的Key也会越来越多,但考虑到key本身的占用,以及集群模式下维护slot与key的映射关系等原因,key过多的情况下也会造成巨大的浪费(比如上亿)。所以减少key的个数很有必要,通常采用的方案是转Hash结构存储,比如将原来使用Redis String结构存储的多个具有关联的key,转化成Hash结构。
       举例:以前有三个key,
                set user.stz.id 1,
                set user.stz.name zst,
                set user.stz.h 180。
        上述三个key,有很明显的关系,那么我们就可以将这转成hash结构来存储,这样redis中就只存在一个key:user.stz
                hmset user.stz id 1 name stz h 180

        如果多个String类型的Key之间无关联,同样也可以放到Hash中,关键在于确定所在hash。比如说将3W个无关联关系的String Key,存到100个hash中,每个hash中存300个,这样就可以减少29900个key。我们只需要确定对某个key存取都会映射到同一个桶就可以了。这种情况下,采用普通hash算法即可实现,比如: hash(key) % 100即可以确定所在桶。

为每个key设置过期时间
     
  这一点基本上无可争议,并且应该尽量错开时间,防止缓存雪崩。针对不同情况设置不同时间,比如说短信校验码这种通常5到10分钟就可以了;排行榜数据可能每小时、每天更新一次;而缓存的一些活动商品,可能会有好几天,甚至跟活动挂勾。
        其中一些特殊的情况,比如使用Redis实现分布式锁时,在最后甚至你需要手动删除该key,而不应该仅仅依赖Redis自己的过期策略

注意value的大小

  • 单个key存储的value很大:这种情况得根据value的结构来确定方案,比如说value是一种对象的Json化表示,那么可以考虑将转换成Hash进行存储。
  • value中存在太多元素:比如说hash结构的值中有过多的key,同样可以考虑拆分,最好经过拆分之后,让单个hash达到转换成ziplist的条件。

修改linux中TCP监听的最大容纳数量

WARNING: The TCP backlog setting of 511 cannot be enforced because 
/proc/sys/net/core/somaxconn is set to the lower value of 128.

        在高并发环境下你需要一个高backlog值来避免慢客户端连接问题。注意Linux内核默默地将这个值减小到/proc/sys/net/core/somaxconn的值,所以需要确认增大somaxconn和tcp_max_syn_backlog两个值来达到想要的效果。

echo 511 > /proc/sys/net/core/somaxconn

注意:这个参数并不是限制redis的最大链接数。如果想限制redis的最大连接数需要修改maxclients,默认最大连接数为10000

修改linux内核内存分配策略

        原因:避免fork子进程时,内存不足,造成redis服务器的down机或者IO负载过高,应将内存分配策略应该设置为 1 ,表示内核允许分配所有的物理内存,而不管当前的内存状态如何 

错误日志:WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. 
To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or 
run the command 'sysctl vm.overcommit_memory=1'

    内存分配策略有三个可选值:

  • 0: 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

  • 1:不管需要多少内存,都允许申请。

  • 2: 只允许分配物理内存和交换内存的大小(交换内存一般是物理内存的一半)

关闭Transparent Huge Pages(THP)

    THP会造成内存锁影响redis性能,建议关闭

Transparent HugePages :用来提高内存管理的性能
Transparent Huge Pages在32位的RHEL 6中是不支持的
执行命令 echo never > /sys/kernel/mm/transparent_hugepage/enabled
把这条命令添加到这个文件中/etc/rc.local

Jedis客户端优化

  • 当想要一次添加多条数据时可以使用管道,比如jedis.pipelined()
  • 设置testOnBorrow=false,testOnBorrow是指在每次Jedis在跟Redis服务器发起请求之前, 先发一个test命令去检查Redis是否准备就绪,主要来应对网络和服务器不稳定性的,生产环境下高并发的情况下可以关闭,避免不必要的请求。
  • 避免长耗时的查询命令。
            比如不要使用keys *,原因在于keys命令会以阻塞的方式执行的,而且keys是以遍历的方式实现的,复杂度是 O(n),Redis库中的key越多,查找实现代价越大,产生的阻塞时间越长;
            也尽量不要用smembers ,避免一次查询所有的成员,应该通过scan 命令进行分批的,游标式的增量遍历;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值