java进阶之Redis篇章

    首先子月带大家先了解一下什么是Redis,Redis是一个非关系型 开源的 内存中的数据结构存储系统   可以做缓存 用作数据库  消息中间件。想必大家都熟悉MySql吧!MySql作为关系型数据库,数据是持久化到磁盘上的,当高并发的时候是存在IO瓶颈的,而且还要遵循ACID原则。那么Redis就可以解决这个问题。Redis中的数据是以key value的形式存在的。支持多种的数据类型结构 字符串  集合 散列 列表 范围查询。

    非关系型数据库一般不保证ACID原则的数据结构存储系统。键值对存储,结构不稳定。

redis 是用来做缓存的 存放的是频繁被访问然而很少被修改的数据。当用户搜索数据的时候,我们可以直接将缓存数据返回给用户,极大地减少了服务器的响应时间。

关系型数据库要求的是强一致性,而非关系型数据库要求的是最终一致性,事务能力是比较弱的。

    Redis相比于MySQL的性能要高是因为他是运行在内存上的,但是这个也就出现了一个问题,就是关于数据丢失的问题。你需要把数据持久化到磁盘上。

    Redis中存在着三种持久化的方案bgsave,aof,rdb。(Redis的安装我会另外再写一篇博客的,建议大家安装到Linux系统下)

    bgsave:这个命令是需要手动输入的,就是在你修改了一个数值之后,直接输入bgsave,优点呢就是可以保证数据绝对不会丢失,但是缺点就是总不能操作一次数据就进行一次这个操作吧!主要是不现实。

    rdb:这个是Redis自带的持久化的方案,我们进入配置文件中 vim redis.conf 大概在14%的位置我们可以看到这三段代码

这代表的意思是假如在九百秒内发生了一个操作,或者三百秒内发生了十个操作,或者六十秒内发生了一万个操作,那么redis就会自行进行持久化到磁盘。 数据会存到和配置文件同级目录下的dump.rdb 文件中。但是这个也是有缺点的 假如在第五十九秒的时候服务器宕机了。那么数据就会丢失。

   aof:这个持久化方案也是在配置文件中,大概是在50%的位置

 

 把这个no修改为yes,这样就开启了aof持久化方案,这个方案可以实时地保存数据,同时也会禁用rdb方案。缺点嘛,就是随着时间的退移 储存数据的appendonly.aof文件会越来越大。但是这个缺点也无关紧要,也是最能接受的。

接下来子月带大家了解一下集群问题(读写分离,哨兵模式)

为了更好地节省资源,集群的配置原则一般都是奇数,遵循大于百分之五十不可用。从服务器一般都是 读取数据,心跳机制保证着服务器的通信。主服务器的数据通过订阅机制 传给从服务器。

读写分离是什么 简单地来说就是假设我们这里有一个集群,总共有三个节点,a,b,c。假如a是主节点,那么在a节点set name zhangsan 那么在b节点get name 就可以得到zhangsan.

那哨兵模式是什么呢?首先我们来思考一个问题,假如在读写分离的模式下主节点突然宕机了要怎么保证服务器的正常运行呢?这里就需要我们的哨兵模式了。在哨兵模式里面有着选举机制,当主节点突然宕机后,剩下的几个从节点中会自动选举一个主节点出来,然后进行数据的同步,以保证服务器的正常运行,但是在这个选举机制中,假如有a,b,c,d,e五个节点,a是主节点,突然a宕机了,然后选举出了c作为主节点,那么c这个主节点是需要得到超过剩下的半数节点的支持的。这就像国王议会的时候,假如一个人想当国王,至少是需要半数元老同意的。

Redis经典缓存问题(缓存击穿,缓存穿透,缓存雪崩)

缓存击穿:让我们设想一下这个场景,在一次秒杀活动的时候,一部手机总共就放出了100台,可是在秒杀活动开启的时候,控制着这个手机数量的热点数据突然失效了,全国一百万人都在秒杀这个手机,那么会造成什么后果呢,想必大家也都想到了吧,业务逻辑的混乱以及周期性地对数据库造成压力。

那么有解决方案呢?第一种:可以设置Redis中的数据不过期,在缓存对象上加上一个属性标识过期时间,每次获取对象的时候,获取对象上的属性过期时间,进行校验,当数据快过期的时候,异步地发起一个线程进行数据的更新,但是这样也可能会导致有些请求请求到过期的数据。这个就要看实际业务了。

第二种:设置热点数据永不过期,然后加上互斥锁保证单个线程写入。

缓存穿透:就是假如我们业务中的商品的ID都是大于1的,但是有人恶意进行访问,发起了大量的请求,但是这些请求都是ID小于1的,因为缓存中没有小于1的ID,那么这些请求都会直接越过缓存打到数据库上,很可能会造成数据库的宕机。

解决方案:我们可以在缓存中加上可能会发生的恶意请求,来防止缓存穿透。或者使用布隆过滤。

缓存雪崩:在同一时间,缓存集体过期失效,大量的请求直接打到了数据库上,造成了服务器的宕机。(当雪崩来临,没有一个缓存是无辜的。)

解决方案:可以设置缓存的失效时间为随机的,以防止集体失效。(推荐)

或者让热点数据永不过期。

使用互斥锁,但是会造成系统的吞吐量明显降低。

使用双缓存,缓存A和缓存B 缓存A的失效时间为三十分钟,缓存B永不过期。这里子月画了一张图来以便于大家的理解。(推荐)

 

 嗯~~~子月最后再补充一下关于key的过期淘汰机制

Redis 可以对存储在 Redis 中的缓存数据设置过期时间,比如我们获取的短信验证码一般十分钟过期,我们这时候就 需要在验证码存进Redis 时添加一个 key 的过期时间,但是这里有一个需要格外注意的问题就是:并非 key 过期时间到 了就一定会被Redis 给删除。

 定期删除策略:Redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 Key,检查其是否过期,如果过期就删除。为什么是 随机抽取而不是检查所有key?因为你如果设置的key成千上万,每100毫秒都将所有存在的key检查一遍,会给CPU 带来比较大的压力。

惰性删除策略:定期删除由于是随机抽取可能会导致很多过期 Key 到了过期时间并没有被删除。所以用户在从缓存获取数据的时 候,redis会检查这个key是否过期了,如果过期就删除这个key。这时候就会在查询的时候将过期key从缓存中清除。

内存淘汰机制:仅仅使用定期删除 + 惰性删除机制还是会留下一个严重的隐患:如果定期删除留下了很多已经过期的key,而且用 户长时间都没有使用过这些过期key,导致过期key无法被惰性删除,从而导致过期key一直堆积在内存里,最终造成 Redis内存块被消耗殆尽。那这个问题如何解决呢?这个时候Redis内存淘汰机制应运而生了。

Redis内存淘汰机制提 供了6种数据淘汰策略:

volatile - lru :从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
volatile - ttl :从已设置过期时间的数据集中挑选将要过期的数据淘汰。
volatile - random :从已设置过期时间的数据集中任意选择数据淘汰。
allkeys - lru :当内存不足以容纳新写入数据时移除最近最少使用的 key
allkeys - random :从数据集中任意选择数据淘汰。
no - enviction (默认) :当内存不足以容纳新写入数据时,新写入操作会报错。
一般情况下,推荐使用 volatile - lru 策略,对于配置信息等重要数据,不应该设置过期时间,这样 Redis 就永远 不会淘汰这些重要数据。对于一般数据可以添加一个缓存时间,当数据失效则请求会从DB 中获取并重新存入 Redis 。

哇,能把Redis写得这么清楚的,纵观csdn,除了子月还有谁?还有谁?(嘻嘻,自恋了)子月可是写了整整一下午加一晚上啊!Ծ‸Ծ

这篇文章中偏理论多一些,子月会努力在剩下的文章中多写一些关于实际的配置比如如何配置哨兵模式啊,和其他的一些暂时还没想起来的知识点,因为写这个完全是即兴发挥啊!(*╹▽╹*)

                                                                                                                                                  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值