java redis并发问题_Redis 高并发问题,及解决方案!

(一)redis技术的使用:

redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动。。。

redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘),提高了访问效率,解决了数据库服务器压力。

为什么redis的地位越来越高,我们为何不选择memcache,这是因为memcache只能存储字符串,而redis存储类型很丰富(例如有字符串、LIST、SET等),memcache每个值最大只能存储1M,存储资源非常有限,十分消耗内存资源,而redis可以存储1G,最重要的是memcache它不如redis安全,当服务器发生故障或者意外关机等情况时,redsi会把内存中的数据备份到硬盘中,而memcache所存储的东西全部丢失;这也说明了memcache不适合做数据库来用,可以用来做缓存。

下面用redis解决瞬间秒杀活动来说明:

下面这个程序模拟了20w人一瞬间涌入这个页面进行秒杀,能够秒杀成功的只有500人,我们把先进来的用户放入redis队列中,当队列中的用户达到500时,后来用户就转到秒杀结束页面。这里用随机数来表示不同的用户。

这里我们可以看到秒杀成功的第一个用户的id是208522,秒杀成功的最后一个用户是176260,参与秒杀人数总共是20w。(让大家注意这些的原因是为了验证下面的准确性)。

接下来我们依次从队列中把秒杀成功的500个用户取出来并观察第一个用户和最后一个用户是否跟之前的记录值一样

我们可以看到从秒杀成功队列中依次取出的第一个用户id是208522,最后一个用户是176260,可以看出结果是很准确的。

redis在解决高并发这方面的能力是真的挺不错的。

(二)Redis高并发可能产生的问题,解决:

1、 如果redis宕机了,或者链接不上,怎么办?

解决方法:

①配置主从复制,配置哨兵模式(相当于古代门派的长老级别可以选择掌门人的权利),一旦发现主机宕机,让下一个从机当做主机。

②如果最坏的情况,只能关闭Redis连接,去往数据库连接。但由于数据量大,这样SQL数据库也会宕掉的。

2、 如果redis缓存在高峰期到期失效,在这个时刻请求会向雪崩一样,直接访问数据库如何处理?

设置条件查询判断,判断redis缓存里是否有数据,如果没有,则去往数据库连接。当然要加分布式锁,利用redis的单线程+多路IO复用技术,原子性原理,让其它的线程请求等待,假若第一个线程进去获取到分布式锁在查询数据的途中宕掉了,不能让其它线程一直等待,设置等待一定时间判断是否取回数据,如果没有,递归调用自己的方法让第二个线程继续拿分布式锁查询数据库。当第二个锁从数据库拿到数据时,把数据值设置到redis数据库缓存中,设置失效时间,避免占内存,方便使用提高效率。

如果用户不停地查询一条不存在的数据,缓存没有,数据库也没有,那么会出现什么

如果数据不存在,缓存中没有,数据库也没有,当然如果不设置判断,会一直调用数据库,使数据库效率降低,访问量大时甚至会宕机。

解决方案:从数据库查询,如果数据库没有,则返回值为Null,判断数据库返回的值,如果为Null,则自定义把标识的字段存到Redis中,用key,value的方法,jedis.setex(key,"empty"),设置失效时间跟具体情况而定,然后调用String json=jedis.get(key),判断是否获取的值"empty".equal(json),如果相等,则抛出自定义异常,给用户提示,或者直接return null。这样用户再次查询的时候由于先从reids缓存中查询,redis会有对应的Key获取之前设置的value值,这样就不会再次调用数据库,影响效率等问题。

具体代码如下:

@Override

public SkuInfo getSkuInfo(String skuId) {

try {

Thread.sleep(3*1000);

//自定义从redis工具类中获取jedis对象

Jedis jedis = redisUtil.getJedis();

//拼接字符串创建Redis里面的Key值

String skuInfoKey= JedisConst.SKU_PREFIX+skuId+JedisConst.SKU_SUFFIX;

//根据key值获取value值

String skuInfoJson = jedis.get(skuInfoKey);

//如果返回为空,则调用本地数据库连接

if (skuInfoJsonnull || skuInfoJson.length()0){

System.out.println(Thread.currentThread().getName()+"当前缓存中未找到数据");

//判断是否有人去取锁

String skuLockKey=JedisConst.SKU_PREFIX+skuId+JedisConst.SKULOCK_SUFFIX;

String result = jedis.set(skuLockKey, "OK", "NX", "PX", JedisConst.SKULOCK_EXPIRE_PX);

if ("OK".equals(result)){

System.out.println(Thread.currentThread().getName()+"获得分布式锁");

SkuInfo skuInfo= getSkuInfoDB(skuId);

//如果数据库里面没有值,别人恶意攻击的话,直接设置到redis缓存中

if (skuInfo==null){

jedis.setex(skuInfoKey,JedisConst.TIME_OUT,"empty");

return null;

}

skuInfoJson = JSON.toJSONString(skuInfo);

jedis.setex(skuInfoKey, JedisConst.TIME_OUT, skuInfoJson);

jedis.close();

return skuInfo;

} else {

//假设之后有人取锁后dang掉了,递归调用自己去寻找钥匙。

System.out.println(Thread.currentThread().getName()+"未获得分布式锁,开启自旋模式俗称递归.");

//等待1秒钟

Thread.sleep(1*1000);

jedis.close();

return getSkuInfo(skuId);

}

}else if (skuInfoJson.equals("empty")){

return null;

}

else {

System.out.println(Thread.currentThread().getName()+"缓存中已有数据正在查询");

SkuInfo skuInfo = JSON.parseObject(skuInfoJson, SkuInfo.class);

jedis.close();

return skuInfo;

}

}catch (JedisConnectionException e){

e.printStackTrace();

} catch (InterruptedException e) {

e.printStackTrace();

}

return getSkuInfoDB(skuId);

redis的缺点有哪些?

是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

作者:Java微服务

链接:https://www.jianshu.com/p/6ce40dcbf3fe

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/468314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle中scott/tiger、sys、SYSDBA、system都是什么用

oracle中scott/tiger、sys、SYSDBA、system都是什么用点我,点我~ 点我,点我,Oracle,用户和角色说明~ 转载于:https://www.cnblogs.com/tangshengwei/p/7080956.html

python 类似wordpress_python,_python 有没有类似WordPress的这种库?,python - phpStudy

python 有没有类似WordPress的这种库? 例如:WordPress博客这种插件Eyes Only: User Access Shortcode https://www.wpdaxue.com/eyes-... /** * WordPress 根据用户名/用户角色/能力/是否登录等隐藏部分文章内容 * https://www.wpdaxue.com/eyes-only-us…

频繁跳槽,这谁顶得住~

最近应该是校招的时候,相信很多人都面临择业的问题,正念同学的文章,记录了自己一个嵌入式工程师这几年找工作换工作的经历。加我好友的都知道,我这几天发了一个朋友圈,说不要乱跳槽,我想表达的是&#xff0…

java script object_javascript Object与Array用法

引用类型:引用类型是一种数据结构,用于将数据和功能组织在一起。引用类型的值是引用类型的一个实例。一、ObjectECMAScript中的对象其实就是一组数据和功能的结合。Object类型其实是所有它的实例的基础,换句话说,Object类型所有具…

王立平--poser

Poser是Metacreations公司推出的一款三维动物、人体造型和三维人体动画制作的极品软件。用过Poser2与Poser3的朋友一定能感受到Poser的人体设计和动画制作是那么的轻松自如,制作出的作品又是那么生动。而今Poser更能为你的三维人体造型增添发型、衣服、饰品等装饰。…

Linux内核编程广泛使用的前向声明(Forward Declaration)

前向声明编程定律先强调一点:在一切可能的场景,尽可能地使用前向声明(Forward Declaration)。这符合信息隐蔽的原则。一个例子regmap那么前向声明究竟是个什么鬼?在内核写代码和看代码的童鞋,经常发现Linux内核里面充斥着这样的代…

python文字游戏 生成数字菜单_python自学日记5——文字游戏

学习python时记录自己或观察别人从错误到正确的思路远比只看正确答案效果好——傅查理 1.判断单词中是否有字母“e" 写一个函数has_no_e,当给定的单词不包含字母‘e时,返回True 刚开始我写的是这样的: def has_no_e(word): for letter in word: if …

Top 10 Project Management Software

转载于:https://www.cnblogs.com/shy1766IT/p/7082910.html

java 二维数组 floyd_Floyd算法(一)之 C语言详解

本章介绍弗洛伊德算法。和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现。后续再分别给出C和Java版本的实现。弗洛伊德算法介绍和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短…

南拳北腿

昨晚,熬夜看了篮球综艺节目,《我要打篮球》,实在话,我是林书豪的球迷,所以我肯定是希望林书豪球队能获胜,最后也如我所愿,两场3v3,电光飞侠都是在处于被动的情况下完成自我救赎&…

[systemd]systemd使用

转自:https://blog.linuxeye.cn/400.html 转载于:https://www.cnblogs.com/aaronLinux/p/7084294.html

怎么改java的gre_GRE怎样完成60天小白到大神的蜕变?

首先声明,我不是什么英语大牛,也不是什么写作能手,普通工科女生一名,和大部分G友基础差不多。但可能是鉴于比较正确的备考方法,Toefl和GRE都考到了满意的成绩。身边也有朋友因为方法不当,准备的时间较长却也…

C语言const 关键字

面试的时候,应该有遇到const相关的,毕竟也是学习中的一个知识点,看完我们这篇文章,我觉得你应该可以在面试中完完全全的吃透const这个点。const和变量const uint32_t hello 3;编译的时候,编译器就知道了 hello 这个变…

pandas 第一行_Pandas数据预处理相关经验

在这里记录一些平常用的pandas操作以供参考。学习相关操作的最好方法还是找官方的文档最好,否则就会产生百度1小时,查文档3分钟的尴尬处境,之前为了找python里类似 in 的操作搜了半天资料也没找到,结果文档里就是 isin 函数就好了…

单机 amp; 弱联网手游 防破解、金币改动 简单措施

单机 & 弱联网手游 防破解、金币改动 简单措施 手游经常使用破解方法 对于一个弱联网或者单机游戏,能够从下面方面去破解: 1、找得到存档文件的,直接破解改动存档文件。 2、找不到存档文件,就在游戏执行时借助一些软件来改…

java中自定义异常的_java中的自定义异常(标准)

自定义“无效名字异常”1.编译时异常,直接继承Exception2.运行时异常,直接继承RuntimeExceptionpublic class IllegalNameException extends Exception{//编译时异常//public class IllegalNameException extends RuntimeException{//运行时异常public I…

Linux 内核通知链和例程代码

概念大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生的事件感兴趣。为了满足这个需求,也即是让某个子系统在发生某个事件时通知其它的子系统,Linux内核提供了通知链的机制。通知链表只能够在内核的子系统之间使用&#x…

faster rcnn resnet_RCNN系列、Fast-RCNN、Faster-RCNN、R-FCN检测模型对比

RCNN系列、Fast-RCNN、Faster-RCNN、R-FCN检测模型对比一.RCNN问题一:速度经典的目标检测算法使用滑动窗法依次判断所有可能的区域。本文则预先提取一系列较可能是物体的候选区域,之后仅在这些候选区域上提取特征,进行判断。问题二…

啰嗦一二三

第一点之前有一个抽奖,抽取野火开发板的,我记得有很多人参加了,20号的时候,获奖的同学都主动找我填写了收获地址,但是有一个同学特别调皮,到今天都没有来找我,我等了好久好久,还是没…

java agent 监控tomcat_promethues监控tomcat

promethues监控tomcat:mkdir /var/lib/tomcat7/prometheuscp -rv jmx_prometheus_javaagent-0.3.1.jar /var/lib/tomcat7/prometheus/cp -rv config.xml /var/lib/tomcat7/prometheus/chown tomcat7:tomcat7 /var/lib/tomcat7/prometheus -Rvi /etc/default/tomcat7…