黄村专业网站开发公司,深圳58网站建设,外贸营销平台,北京网站建设公司华网天下官网(一)redis技术的使用#xff1a;redis真的是一个很好的技术#xff0c;它可以很好的在一定程度上解决网站一瞬间的并发量#xff0c;例如商品抢购秒杀等活动。。。redis之所以能解决高并发的原因是它可以直接访问内存#xff0c;而以往我们用的是数据库(硬盘),提高了访问效…(一)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 jsonjedis.get(key),判断是否获取的值empty.equal(json),如果相等则抛出自定义异常给用户提示或者直接return null。这样用户再次查询的时候由于先从reids缓存中查询redis会有对应的Key获取之前设置的value值这样就不会再次调用数据库影响效率等问题。具体代码如下Overridepublic SkuInfo getSkuInfo(String skuId) {try {Thread.sleep(3*1000);//自定义从redis工具类中获取jedis对象Jedis jedis redisUtil.getJedis();//拼接字符串创建Redis里面的Key值String skuInfoKey JedisConst.SKU_PREFIXskuIdJedisConst.SKU_SUFFIX;//根据key值获取value值String skuInfoJson jedis.get(skuInfoKey);//如果返回为空则调用本地数据库连接if (skuInfoJsonnull || skuInfoJson.length()0){System.out.println(Thread.currentThread().getName()当前缓存中未找到数据);//判断是否有人去取锁String skuLockKeyJedisConst.SKU_PREFIXskuIdJedisConst.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 (skuInfonull){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来源简书著作权归作者所有。商业转载请联系作者获得授权非商业转载请注明出处。