redis学习笔记二

http://redisbook.readthedocs.io/en/latest/java

redis为何会有高并发问题redis

  • redis的出身决定

redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。因为单线程因此redis自己并无锁的概念,多 个客户端链接并不存在竞争关系,可是利用jedis等客户端对redis进行并发访问时会出现问题。发生链接超时、数据转换错误、阻塞、客户端关闭链接等 问题,这些问题均是因为客户端链接混乱形成。sql


同时,单线程的天性决定,高并发对同一个键的操做会排队处理,若是并发量很大,可能形成后来的请求超时。数据库

在远程访问redis的时候,由于网络等缘由形成高并发访问延迟返回的问题。服务器

解决办法网络

  • 在客户端将链接进行池化,同时对客户端读写Redis操做采用内部锁synchronized。
  • 服务器角度,利用setnx变向实现锁机制。这个方法在实际环境中如何使用,本人并不清楚。

jedis常见错误分析并发

异常代码1:nosql

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the poolsocket

问题分析:redis.clients.util.Pool.getResource会从JedisPool池中返回一个可用的redis链接,关于JedisPool中可用链接的配置有几个重要的参数以下:高并发

MaxActive:可用链接实例的最大数目,为负数的时候没有限制。

MaxIdle:空闲链接实例的最大数目,为负值时没有限制。

MaxWait:等待获取连接的超时时间。

也就是说当链接池中没有active/idle的链接时,会等待maxWait时间,若是等待超时尚未可用链接,则抛出Could not get a resource from the pool异常。因此为避免这样的错误,
咱们应该根据程序实际状况合理设置这三个参数的值,同时在咱们获取一个链接的程序方法中也应该合理的处理这个异常,当没有链接可用时,等待一段时间再获取也许是个比较好的选择。

异常代码2:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out

遇到这个异常,可能会比较疑惑,redis是对内存的操做,速度一个在毫秒级别,在对redis操做出现秒级别的操做时会让人感受疑惑,可是本文开头已经说过了,在一些特殊状况下,redis出现超时并不奇怪。jedis在初始化JedisPool时应该根据实际状况经过redis.clients.jedis.JedisPoolConfig合理设置链接池参数,经过redisPool构造方法,设置socket读取输入InputStream的超时时间。

`pool = new JedisPool(config, host, port, 100000)`;

第四个参数是time out,单位是毫秒。能够经过合理的设置这个值来规避问题。可是这不能彻底解决超时的为题。有些高并发状况下,延时返回时间甚至会达到几十秒的极端状况。 这个问题要经过代码层面解决redis单线程自己不支持锁,在对同一个键进行并发操做会产生竞争的问题。

相关文章
相关标签/搜索