Redis并发(转)

Redis技术之旅十 高并发问题

redis为什么会有高并发问题

  • redis的出身决定

    Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。

同时,单线程的天性决定,高并发对同一个键的操作会排队处理,如果并发量很大,可能造成后来的请求超时。

在远程访问redis的时候,因为网络等原因造成高并发访问延迟返回的问题。

解决办法

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

jedis常见错误分析

异常代码1:

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

问题分析: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单线程本身不支持锁,在对同一个键进行并发操作会产生竞争的问题。

时间: 2024-11-03 03:26:58

Redis并发(转)的相关文章

Redis 并发, 锁, 竞争锁问题.

Redis并发问题 Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问.Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时.数据转换错误.阻塞.客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成.对此有2种解决方法: 1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized. 2.服务器角度,利用setnx实

高并发架构系列:Redis并发竞争key的解决方案详解

需求由来 1.Redis高并发的问题 Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题:缓存击穿.缓存雪崩.缓存和数据一致性,以及今天要谈到的缓存并发竞争. 这里的并发指的是多个redis的client同时set key引起的并发问题. 2.出现并发设置Key的原因 Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘.由于单线程所以Redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端

redis并发竞争问题及解决方案

redis并发竞争问题及解决方案 为什么会出现竞争问题? 多客户端同时并发写一个key,一个key的值是1,本来按顺序修改为2,3,4,最后是4,但是顺序变成了4,3,2,最后变成了2. 如何解决? 第一种方案:分布式锁+时间戳 分布式锁可以使用redis自身的分布式锁,也可以使用zookeeper,但是一般使用后者, 由于上面举的例子,要求key的操作需要顺序执行,所以需要保存一个时间戳判断set顺序. 系统A key 1 {ValueA 7:00}系统B key 1 { ValueB 7:0

Redis学习笔记~Redis并发锁机制

回到目录 redis客户端驱动有很多,如ServiceStack.Redis,StackExchange.Redis等等,下面我使用ServiceStack.Redis为例,介绍一下在redis驱动中实现并发锁的方式,并发就是多线程同时访问和操作同一个资源,而对于redis来说,如果你多个线程共同修改一个key的value,这时就会出现并发,为了保证数据完整性,这时需要使用并发锁,在各大语言中,都有自己的实现方法,无论的C,C#,java还是sqlserver都有这个概念! using (IRe

redis并发环境下的使用

对于一个抽奖活动,以电话号码为校验入口,一个用户只能参加一次.预先录入的号码为"13311111111 0",入口处先要判断用户号码的状态为0,则为第一次参加活动,参加后讲状态更新为1.为了避免一个号码同时点击多次造成判断入口的并发判断错误.这里使用redis的  "SETGET  13311111111  1" .SETGET命令会反馈历史值.如果返回的是0,则该用户第一次参加活动,如果反馈1则该用户已经参加活动.截止提示用户已经参加过活动.SETGET在redi

Redis并发锁控制

为了防止用户在页面上重复点击或者同时发起多次请求,请求处理需要操作redis缓存,这个时候需要对并发边界进行并发锁控制,实现思路: 由于每个页面发起的请求带的token具备唯一性,可以将token作为锁(key),当前时间作为value进行并发锁控制,分为两个方法:acquireLock和realeaseLock /**尝试获取锁并设置有效时间*/ 53 + public boolean acquireLock(String lock, long expired){ 54 + boolean i

Redis并发问题

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问.Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时.数据转换错误.阻塞.客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成.对此有2种解决方法:1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized.比如java中的jedisPool. Jedis是一个J

Redis并发竞争

Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘.由于单线程所以Redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对Redis进行并发访问时会出现问题. 比如:同时有多个子系统去set一个key.这个时候要注意什么呢? 举一个例子:多客户端同时并发写一个key,一个key的值是1,本来按顺序修改为2,3,4,最后是4:但是顺序变成了4,3,2,最后变成了2. 并发竞争可用的解决方案如: 分布式锁+时间戳 利用消息队列 原

redis并发问题2

转自https://mp.weixin.qq.com/s?__biz=MzI1NDQ3MjQxNA==&mid=2247485464&idx=1&sn=8d690fc6f878aadf75977aa7e76cfd08&chksm=e9c5f1a9deb278bf512d8b40c30240d0168cdf2cf02142ee913bc11ec39637ca380a4dad524b&scene=21#wechat_redirect 缓存雪崩.缓存穿透.缓存预热.缓存更