redis性能调优笔记(can not get Resource from jedis pool和jedis connect time out)
对这段时间redis性能调优做一个记录。
1、单进程单线程
redis是单进程单线程实现的,如果你没有特殊的配置,redis内部默认是FIFO排队,即你对redis的访问都是要在redis进行排队,先入先出的串行执行。
之所以能够保持高性能是因为以下3点:
1)内存操作
2)数据结构简单
3)大多数是hash操作
redis基本的命令耗时都是us级别的,所以及时是单进程单线程,也能保证很高的QPS。
2、can not get Resource from jedis pool和jedis connect time out
如果你对redis访问不正常,表现为抛上面两个异常,基本可以判断你需要对redis使用方式或者性能进行调优了。
你可以尝试使用如下几个办法:
1)修改redis客户端最大链接数
这个配置很简单,默认是10000,一般来说,10000这个数字已经够大了。
################################### LIMITS #################################### # Set the max number of connected clients at the same time. By default
# this limit is set to clients, however if the Redis server is not
# able to configure the process file limit to allow for the specified limit
# the max number of allowed clients is set to the current file limit
# minus (as Redis reserves a few file descriptors for internal uses).
#
# Once the limit is reached Redis will close all the new connections sending
# an error 'max number of clients reached'.
#
maxclients
不过,对这个数字的设置你要参考你的linux系统文件打开数。
一般来说,maxclients不能大于linux系统的最大连接数。
当然你可以将使用redis的linux用户对应的最大链接数改大,方式是修改/etc/security/limits.conf,我们这里把arch用户的最大链接数改成了100000
#<domain> <type> <item> <value>
arch soft nofile
arch hard nofile
2)安全的释放链接!
一定要安全的释放链接,注意一些异常情况一定要能捕获到,并且释放链接,这里给出一个亲测有效的释放链接的方式,使用jedis set做例子吧
public void set(String key, String value) {
Jedis jedis = null;
boolean broken = false;
try {
jedis = jedisPool.getResource();
jedis.set(key, value);
} catch (JedisConnectionException ex) {
jedisPool.returnBrokenResource(jedis);
broken = true;
throw ex;
}finally {
if (jedis != null && !broken) {
jedisPool.returnResource(jedis);
}
}
}
3)jedis对超时的配置
一般来说有两个,maxWaitMillis和timeout,前者是链接等待时间,后者是cmd执行时间。
a)maxWaitMillis:客户端尝试与redis建立链接,当达到这个配置值,则抛出异常can not get Resource from jedis pool
b)timeout:客户端读超时时间,当超过这个配置值,抛出异常read timeout。
当然一般来说,如果大规模的爆发这两个异常,那么单纯修改这两个值其实没有什么用!
4)如果你是高并发场景,请注意慢查询
我遇到的慢查询场景有两个:
a)keys *
b)读写很大的数据块100M
如果高并发的有上面两种操作,那么问题就暴露了,回到redis单进程单线程的模式,那么当查询很慢的时候,势必会阻塞后面client的链接和cmd,如果慢查询并发量很高,造成超时和链接失败也就不足为奇了。
遇到这些情况,一般来说,都要改业务代码。方式是:
a)拆key,把key拆小,降低单个cmd的执行时间;
b)横向扩展redis集群,通过分桶将这种类型的操作均衡到多个实例上去。
当然你能通过修改业务实现,不用keys或者不在redis里缓存大量数据,最好了。
3、慢查询分析
如果你需要运维自己的redis,那么定期去查看redis的慢日志会给你一些很好的发现。
慢日志会帮你记录redis的慢查询,慢日志的配置如下。
就两个:
a)slowlog-log-slower-than, 单位是us,超过这个值就会被认为是慢查询了 (负数:禁用慢查询功能,0:记录所有执行命令,也就是所有命令都大于0,正数:大于该值则记录执行命令)
b)slowlog-max-len,单位是条数,这个值是保留最新redis缓存慢日志的条数List,一般你可以设置个1000条,分析够用了。
################################## SLOW LOG ################################### # The Redis Slow Log is a system to log queries that exceeded a specified
# execution time. The execution time does not include the I/O operations
# like talking with the client, sending the reply and so forth,
# but just the time needed to actually execute the command (this is the only
# stage of command execution where the thread is blocked and can not serve
# other requests in the meantime).
#
# You can configure the slow log with two parameters: one tells Redis
# what is the execution time, in microseconds, to exceed in order for the
# command to get logged, and the other parameter is the length of the
# slow log. When a new command is logged the oldest one is removed from the
# queue of logged commands. # The following time is expressed in microseconds, so is equivalent
# to one second. Note that a negative number disables the slow log, while
# a value of zero forces the logging of every command.
slowlog-log-slower-than # There is no limit to this length. Just be aware that it will consume memory.
# You can reclaim memory used by the slow log with SLOWLOG RESET.
slowlog-max-len
查询慢日志的方式是,通过redis-cli
1、slowlog get [n]
n:条数,可选
10.93.84.53:> slowlog get
) ) (integer)
) (integer)
) (integer)
) ) "KEYS"
) "prometheus:report:fuse:*"
) ) (integer)
) (integer)
) (integer)
) ) "KEYS"
) "prometheus:report:fuse:*"
4个值,从上到下依次是分日志id
、发生时间戳、命令耗时、执行命令和参数。
慢查询功能可以有效地帮助我们找到Redis
可能存在的瓶颈,但在实际使用过程中要注意以下几点:
slowlog-max-len
:线上建议调大慢查询列表,记录慢查询时Redis
会对长命令做阶段操作,并不会占用大量内存.增大慢查询列表可以减缓慢查询被剔除的可能,例如线上可设置为1000
以上.slowlog-log-slower-than
:默认值超过10
毫秒判定为慢查询,需要根据Redis
并发量调整该值.由于Redis
采用单线程相应命令,对于高流量的场景,如果命令执行时间超过1
毫秒以上,那么Redis
最多可支撑OPS
不到1000
因此对于高OPS场景下的Redis
建议设置为1
毫秒.慢查询只记录命令的执行时间,并不包括命令排队和网络传输时间.因此客户端执行命令的时间会大于命令的实际执行时间.因为命令执行排队机制,慢查询会导致其他命令级联阻塞,因此客户端出现请求超时时,需要检查该时间点是否有对应的慢查询,从而分析是否为慢查询导致的命令级联阻塞.
由于慢查询日志是一个先进先出的队列,也就是说如果慢查询比较多的情况下,可能会丢失部分慢查询命令,为了防止这种情况发生,可以定期执行
slowlog get
命令将慢查询日志持久化到其他存储中(例如:MySQL
、ElasticSearch
等),然后可以通过可视化工具进行查询.
4、Linux内存不足
当你启动redis的时候,你可能会看到如下warning
:M Aug ::18.354 # WARNING overcommit_memory is set to ! 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' for this to take effect.
如果overcommit_memory=0,linux的OOM机制在内存不足的情况下,会自动选择性Kill进程点数过高的进程。
如何修改这个值呢
// 修改这个文件
vim /etc/sysctl.conf
// 加上下面这个配置
vm.overcommit_memory =
// 在不重启机器的情况下生效
sysctl vm.overcommit_memory=
0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2:表示内核允许分配超过所有物理内存和交换空间总和的内存
redis性能调优笔记(can not get Resource from jedis pool和jedis connect time out)的更多相关文章
- Java性能调优笔记
Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多. ...
- Redis性能调优
Redis性能调优 尽管Redis是一个非常快速的内存数据存储媒介,也并不代表Redis不会产生性能问题.前文中提到过,Redis采用单线程模型,所有的命令都是由一个线程串行执行的,所以当某个命令执行 ...
- Redis性能调优建议
一. Redis部署结构优化建议 1. Master不做AOF或RDB持久化,Slave做AOF持久化,建议同时做RDB持久化 2. 所有Master全部增加Slave 3. Master挂载Slav ...
- .net ServiceStack.Redis 性能调优
最近在debug生产环境的问题时,发现了ServiceStack 4.0.60版本RedisClient存在一个非常严重的性能问题.在高并发下,PooledRedisClientManager.Get ...
- Redis性能调优:保存SNAPSHOT对性能的影响
前一段时间.开发环境反馈,Redisserver訪问很慢,每一个请求要数秒时间,重新启动之后2~3天又会这样. 我查看了一下Linux的性能,没有什么问题. 通过 # redis-cli --late ...
- StackExchange.Redis性能调优
大家经常出现同步调用Redis超时的问题,但改成异步之后发现错误非常少了,但却可能通过前后记日志之类的发现Redis命令非常慢. PS: 以后代码都在Windows bash中运行,StackExch ...
- Redis基础、高级特性与性能调优
本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ...
- Redis 基础、高级特性与性能调优
本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ...
- Redis 宝典 | 基础、高级特性与性能调优
转载:Redis 宝典 | 基础.高级特性与性能调优 本文由 DevOpsDays 本文由简书作者kelgon供稿,高效运维社区致力于陪伴您的职业生涯,与您一起愉快的成长. 作者:kelgon ...
随机推荐
- jdk源码研究1-HashMap
今天开始,研读下jdk的常用类的一些源码,下面是jdk中HashMap的研究.诚然,网上已经很多这方面的总结了,但是,个人只是想单纯地把自己的理解过程进行记录,大牛们就绕路吧,当然,欢迎扔砖头.下面是 ...
- css3新特性---(border,Background部分)
boder属性新特性: border-radius 设置或检索对象使用圆角边框 border-top-left-radius 设置或检索对象左上角圆角边框 border-top-right-rad ...
- 201521123078 《Java程序设计》 第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 1.List中指定元素的删除(题目4-1) 1.1 实验总结 public static vo ...
- 201521123055 《Java程序设计》第5周学习总结
1. 本章学习总结 2. 书面作业 Q1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 1. ...
- 201521123036 《Java程序设计》第3周学习总结
本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来. 书面作业 Q1:代码阅读 public class Test1 { private ...
- 201521123105《jave程序》第二周学习总结
1. 本周学习总结 学习了各种java数据类型以及各种运算符的使用 学习了一维,二维数组的用法 学习了String类对象使用 2. 书面作业 使用Eclipse关联jdk源代码,并查看String对象 ...
- 201521123016 《Java程序设计》第2周学习总结
1. 本周学习总结 JAVA中string对象创建后不可修改. 使用StringBuilder编写代码,减少内存空间的占用. 字符串使用"+"拼接,拼接后其他类型会被转化为字符串. ...
- 201521123044 《Java程序设计》第10周学习总结
1. 本章学习总结 2. 书面作业 本次PTA作业题集异常丶多线程 1.finally题目4-2 1.1 截图你的提交结果 1.2 4-2中finally中捕获异常需要注意什么? 1.无论try-ca ...
- 201521123070 《JAVA程序设计》第12周学习总结
1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...
- self、parent和$this关键字
self.parent和$this关键字的区别: self关键字用来指定当前的类,而且该关键字通常用来访问类的静态成员.方法和常量.parent关键字用于指向父类,所以使用该关键字调用父类的属性和方法 ...