Redis高并发问题的解决方法
本文讲述了Redis高并发问题的解决办法。分享给大家供大家参考,具体如下:
redis为什么会有高并发问题
redis的出身决定
redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。
同时,单线程的天性决定,高并发对同一个键的操作会排队处理,如果并发量很大,可能造成后来的请求超时。
在远程访问redis的时候,因为网络等原因造成高并发访问延迟返回的问题。
解决办法
1.在客户端将连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。
2.服务器角度,利用setnx变向实现锁机制。这个方法在实际环境中如何使用,本人并不清楚。
jedis常见错误分析
异常代码1:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
问题分析:redis.clients.util.Pool.getResource
会从JedisPool池中返回一个可用的redis连接,关于JedisPool中可用连接的配置有几个重要的参数如下:
1.MaxActive:可用连接实例的最大数目,为负数的时候没有限制。
2.MaxIdle:空闲连接实例的最大数目,为负值时没有限制。
3.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单线程本身不支持锁,在对同一个键进行并发操作会产生竞争的问题。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。
相关推荐
-
Redis数据库中实现分布式锁的方法
分布式锁是一个在很多环境中非常有用的原语,它是不同进程互斥操作共享资源的唯一方法.有很多的开发库和博客描述如何使用Redis实现DLM(Distributed Lock Manager),但是每个开发库使用不同的方式,而且相比更复杂的设计与实现,很多库使用一些简单低可靠的方式来实现. 这篇文章尝试提供更标准的算法来使用Redis实现分布式锁.我们提出一种算法,叫做Relock,它实现了我们认为比vanilla单一实例方式更安全的DLM(分布式锁管理).我们希望社区分析它并提供反馈,以做为更加复杂
-
redis实现加锁的几种方法示例详解
前言 本文主要给大家介绍了关于redis实现加锁的几种方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 1. redis加锁分类 redis能用的的加锁命令分表是INCR.SETNX.SET 2. 第一种锁命令INCR 这种加锁的思路是, key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作进行加一. 然后其它用户在执行 INCR 操作进行加一时,如果返回的数大于 1 ,说明这个锁正在被使用当中. 1. 客户端A请求服务器获取key的值为1表示
-
详解Java如何实现基于Redis的分布式锁
前言 单JVM内同步好办, 直接用JDK提供的锁就可以了,但是跨进程同步靠这个肯定是不可能的,这种情况下肯定要借助第三方,我这里实现用Redis,当然还有很多其他的实现方式.其实基于Redis实现的原理还算比较简单的,在看代码之前建议大家先去看看原理,看懂了之后看代码应该就容易理解了. 我这里不实现JDK的java.util.concurrent.locks.Lock接口,而是自定义一个,因为JDK的有个newCondition方法我这里暂时没实现.这个Lock提供了5个lock方法的变体,可以
-
php结合redis实现高并发下的抢购、秒杀功能的实例
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis. 重点在于第二个问题 常规写法: 查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数 <?php $conn=mysql_connect("localho
-
Redis瞬时高并发秒杀方案总结
1.Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含任意类型的数据;: 一个字符串类型的值最多能存储512M字节的内容: 利用INCR命令簇(INCR, DECR, INCRBY)来把字符串当作原子计数器使用: 使用APPEND命令在字符串后添加内容. 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序: 你可以添加一个元素到列表的头部(左边:LPUSH)或者尾部(右边:RPUSH): 一个列表最多可以包含232-1个
-
Redis实现分布式锁的几种方法总结
Redis实现分布式锁的几种方法总结 分布式锁是控制分布式系统之间同步访问共享资源的一种方式.在分布式系统中,常常需要协调他们的动作.如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁. 我们来假设一个最简单的秒杀场景:数据库里有一张表,column分别是商品ID,和商品ID对应的库存量,秒杀成功就将此商品库存量-1.现在假设有1000个线程来秒杀两件商品,500个线程秒杀第一个商品,
-
Redis上实现分布式锁以提高性能的方案研究
背景: 在很多互联网产品应用中,有些场景需要加锁处理,比如:秒杀,全局递增ID,楼层生成等等.大部分是解决方案基于DB实现的,Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系. 项目实践 任务队列用到分布式锁的情况比较多,在将业务逻辑中可以异步处理的操作放入队列,在其他线程中处理后出队,此时队列中使用了分布式锁,保证入队和出队的一致性.关于redis队列这块的逻辑分析,我将在下一次对其进行总结,此处先略过. 接下来对redis实现的分
-
解锁redis锁的正确姿势
解锁redis锁的正确姿势 redis是php的好朋友,在php写业务过程中,有时候会使用到锁的概念,同时只能有一个人可以操作某个行为.这个时候我们就要用到锁.锁的方式有好几种,php不能在内存中用锁,不能使用zookeeper加锁,使用数据库做锁又消耗比较大,这个时候我们一般会选用redis做锁机制. setnx 锁在redis中最简单的数据结构就是string.最早的时候,上锁的操作一般使用setnx,这个命令是当:lock不存在的时候set一个val,或许你还会记得使用expire来增加锁
-
如何利用Redis锁解决高并发问题详解
redis技术的使用: redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动... redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘),提高了访问效率,解决了数据库服务器压力. 为什么redis的地位越来越高,我们为何不选择memcache,这是因为memcache只能存储字符串,而redis存储类型很丰富(例如有字符串.LIST.SET等),memcache每个值最大只能存储1M,存储资源非常有限,十分消耗内
-
Redis高并发问题的解决方法
本文讲述了Redis高并发问题的解决办法.分享给大家供大家参考,具体如下: redis为什么会有高并发问题 redis的出身决定 redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘.由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题.发生连接超时.数据转换错误.阻塞.客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成. 同时,单线程的天性决定,高并发对同一个键的操作会
-
Redis高并发场景下秒杀超卖解决方案(秒杀场景)
目录 1 什么是秒杀 2 为什么要防止超卖 3 单体架构常规秒杀 3.1 常规减库存代码 3.2 模拟高并发 3.3 超卖现象 3.4 分析原因 4 简单实现悲观乐观锁解决单体架构超卖 4.1 悲观锁 4.2 乐观锁 4.3 redis锁setnx 4.4 使用Redision 5 分布式锁的解决方案 6 采用缓存队列防止超卖 1 什么是秒杀 秒杀最直观的定义:在高并发场景下而下单某一个商品,这个过程就叫秒杀 [秒杀场景] 火车票抢票 双十一限购商品 热度高的明星演唱会门票 … 2 为什么要防止
-
PHP+MySQL高并发加锁事务处理问题解决方法
本文实例讲述了PHP+MySQL高并发加锁事务处理问题解决方法.分享给大家供大家参考,具体如下: 1.背景: 现在有这样的需求,插入数据时,判断test表有无username为'mraz'的数据,无则插入,有则提示"已插入",目的就是想只插入一条username为'mraz'的记录. 2.一般程序逻辑如下: $conn = mysqli_connect('127.0.0.1', 'root', '111111') or die(mysqli_error()); mysqli_selec
-
Java 处理高并发负载类优化方法案例详解
java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据) 一:高并发高负载类网站关注点之数据库 没错,首先是数据库,这是大多数应用所面临的首个SPOF.尤其是Web2.0的应用,数据库的响应是首先要解决的. 一般来说MySQL是最常用的,可能最初是一个mysql主机,当数据增加到100万以上,那么,MySQL的效能急剧下降.常用的优化措施是M-S(主-从)方式进行同步复制,将查询和操作和分别在不同的服务器上进行操作.我推荐的是M-M-Slaves
-
Redis高并发防止秒杀超卖实战源码解决方案
目录 1:解决思路 2:添加 redis 常量 3:添加 redis 配置类 4:修改业务层 1:秒杀业务逻辑层 2:添加需要抢购的代金券 3:抢购代金券 5:postman 测试 6:压力测试 8:配置Lua 9:修改业务层 1:抢购代金券 10:压力测试 1:解决思路 将活动写入 redis 中,通过 redis 自减指令扣除库存. 2:添加 redis 常量 commons/constant/RedisKeyConstant.java seckill_vouchers("seckill_v
-
浅谈Redis高并发缓存架构性能优化实战
目录 场景1: 中小型公司Redis缓存架构以及线上问题实战 场景2: 大厂线上大规模商品缓存数据冷热分离实战 场景3: 基于DCL机制解决热点缓存并发重建问题实战 场景4: 突发性热点缓存重建导致系统压力暴增 场景5: 解决大规模缓存击穿导致线上数据库压力暴增 场景6: 黑客工资导致缓存穿透线上数据库宕机 场景7: 大V直播带货导致线上商品系统崩溃原因分析 场景8: Redis分布式锁解决缓存与数据库双写不一致问题实战 场景9: 大促压力暴增导致分布式锁串行争用问题优化 场景10: 利用多级缓
-
java应用cpu占用过高问题分析及解决方法
使用jstack分析java程序cpu占用率过高的问题 1,使用jps查找出java进程的pid,如3707 2,使用top -p 14292 -H观察该进程中所有线程的CPU占用. [root@cp01-game-dudai-0100.cp01.baidu.com ~]# top -p 14292 -H top - 22:14:13 up 33 days, 7:29, 4 users, load average: 25.68, 32.11, 33.76 Tasks: 113 total, 2
-
Redis高并发情况下并发扣减库存项目实战
目录 第一种方案:纯MySQL扣减实现 MySQL架构升级 第二种方案:缓存实现扣减 第三种方案:数据库+缓存 顺序写的性能更好 顺序写的架构 扣减流程 相信大家从网上学习项目大部分人第一个项目都是电商,生活中时时刻刻也会用到电商APP,例如淘宝,京东等.做技术的人都知道,电商的业务逻辑简单,但是大部分电商都会涉及到高并发高可用,对并发和对数据的处理要求是很高的.这里我今天就讲一下高并发情况下是如何扣减库存的? 我们对扣减库存所需要关注的技术点如下: 当前剩余的数量大于等于当前需要扣减的数量,不
-
jedispool连redis高并发卡死的问题
java端在使用jedispool 连接redis的时候,在高并发的时候经常死锁,或报连接异常,JedisConnectionException,或者getResource 异常等各种问题 在使用jedispool 的时候一定要注意两点 1. 在获取 jedisPool和jedis的时候加上线程同步,保证不要创建过多的jedispool 和 jedis 2. 用完Jedis实例后需要返还给JedisPool 整理了一下redis工具类,通过大量测试和高并发测试的 package com.casp
-
安装SQL Server 2016出错提示:需要安装oracle JRE7 更新 51(64位)或更高版本问题的解决方法
错误提示原因:安装时检测出电脑没有安装JDK,而且是版本7(其他版本不行) 解决方法:先进下面这个网站安装JDK,安装好后配置环境变量,然后重新安装SQL Server 2016即可 http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html 先勾选接受协议,然后开始下载 我的电脑系统是Windows x64,所以下载的是红线框起来的,具体下载哪个看自己的电脑
随机推荐
- SQL Injection with MySQL 注入分析
- swift 单例的实现方法及实例
- iOS实现从背景图中取色的代码
- ASP.NET的实用技巧详细介绍
- php使用iconv中文截断问题的解决方法
- python使用三角迭代计算圆周率PI的方法
- python中global用法实例分析
- C#中使用ADOMD.NET查询多维数据集的实现方法
- PHP实现字节数Byte转换为KB、MB、GB、TB的方法 原创
- 学习理解Android菜单Menu操作
- 完美解决无法无法显示隐藏文件的问题(svohost.exe xsx.exe)
- jQuery使用中可能被XSS攻击的一些危险环节提醒
- Android 列表形式的切换的示例代码
- JavaScript中数组成员的添加、删除介绍
- Android实现兼容的水波纹效果
- Nginx中报错:Permission denied与Connection refused的解决
- 解决spring boot 1.5.4 配置多数据源的问题
- 通过java字节码分析学习对象初始化顺序
- JAVA获取CLASSPATH路径的方法详解
- jquery中live()方法和bind()方法区别分析