Redis简单概括

Redis是一个NoSql非线性的数据库,它与MySQL不同在于它将数据存储在内存当中,MySQL则是保存在硬盘中。

Redis与MySQL的优缺点进行比较

Redis
优点:
(1)速度快,数据存储在内存当中。
(2)支持事务,所有的操作都是原子性的 (原子性:刘关张)
缺点:
(1)Redis本身具有key过期策略,但还是需要提前预估来节约内存,定期删除数据
(2)修改配置文件、重启、将硬盘当中的数据加载进内存中都需要一定时间,在此过程中Redis并不提供服务
MySQL
优点:
(1)将数据持久化保存到硬盘当中,功能强大
(2)ACID
缺点:
(1)每次请求数据库时,都会存在I/O的操作,效率慢,如果多次请求的话会造成数据库过载

Redis的五种基本数据类型

List, String, Hash, Set, zSet

//zSet是set的增强版相当于List和Set的缝合,提供score是分数,是有序集合的关键。可以说双精度或整数

其实准确来说,是八种数据类型,bitmaps,hyperloglogs,地理空间 geospatial.但这三种并不常用,了解不用怎么了解。

Redis数据持久化

RDB持久化

将Redis在内存当中的数据记录定时dump(抓取保存)到磁盘上。简单来说就是存数据本身

在指定时间间隔内将内存的数据集快照写入硬盘:用fork的一个子线程,将数据集写入临时文件,写入成功后再将之前的文件替换,用二进制压缩储存。

AOF持久化

Append Only File,将Redis的操作日志用追加的方式写入文件。简单来说就是存的操作命令

用日志的方式将对数据的操作,列如增删改(查询操作不会)以文本的方式进行记录。

优缺点比较

RDB由于存储的只是数据本身,在重启Redis时数据恢复地会更快。但如果Redis突然宕机情况下,那么假设我给RDB设置的时间将为5秒,在第4秒的时候Redis宕机,那么我这4秒内所作出的数据改动全部都会丢失。如果是在高并发的情况下宕机,那么丢失的数据量会非常非常多。

AOF它存储的方式只是存的操作命令,所以在重启时的时间会更长,因为它要把我们记录下来的命令再重新运行一遍,命令运行肯定是不如数据直接加载的速度快。但好处也非常直观,就是在Redis的宕机情况下,AOF要比RDB所记录的数据更加多。

Redis回收机制

Redis回收机制分为过期删除策略内存淘汰策略两部分

在这里插入图片描述
过期删除

  • 定时删除

    删除过期的key。虽然可以立即清除过期的数据,对内存较友好,但是会影响Redis的吞吐量和响应时间。为什么会占用大量的性能,因为要给每一个设置过期时间的key再设置一个定时器,一旦到时这个key就会删除。

  • 惰性删除

    当访问一个key时,才判断该key是否过期。虽然能节省性能但对内存不友好,为什么不友好因为我不知道这个key有没有过期,我要去看,看了就会保存在内存当中不再做处理。

    过期删除的两个策略都不能完美解决问题才有内存淘汰的引入。而内存淘汰我们只有allkeys-lru常用,其他都很恶心很傻逼。

内存淘汰策略

  • allkeys-lru: 当内存不足以容纳新的数据时,就会删除较少使用的key以此来达到新的内存腾出来。

Redis的四种模式

  • 单机模式

    顾名思义就是简单的一个Redis,启动调用就行。缺点也非常致命,一旦Redis服务挂了服务访问不了缓存,那么就会直接访问数据库,导致性能极其低。而且单台Redis受限于服务器内存,如果服务器内存过小,相应的Redis也掀不起什么大浪。

  • 主从模式

    主从模式也被称为分片,采用多台Redis服务器共同维护一整块内存空间大小,最终实现内存数据的扩容。一台作为主数据库,而其他的则为从数据库。主的就只负责写的命令操作,而从的就只用负责读的命令操作。

    那么问题相应就来了,shard Jedis怎么分配数据存储呢?数据倾斜又该怎么办?

    由于主从模式虽然实现了内存数据的扩容,但却没有实现高可用,如果主Redis突然宕机,那么从的就不能再正常执行。为了解决这个问题,哨兵模式由此诞生。

  • 哨兵模式

    所谓”哨兵“其实就是一种节点。哨兵只干两件事,监管和投票。既然会投票,那么哨兵的个数肯定是多个,因为要有多个人才会有投票这一动作吧。

    哨兵启动时首先会监管主机的状态,并且记录主机的全部信息。

    那又是如何判断主机是否宕机的呢?心跳知道吧,Ping-Pong,我们的哨兵首先会对主机发送Ping的信号,如果之后接受到了主机的Pong信号,那么这个主机就可以判断为是健康的,如果没收到,那么多半就是寄了。但我又不敢肯定主机死绝了,刚刚说了哨兵是有数量的,如果一半以上都没有收到来自主机的Pong信号,就可以直接判断主机宕机了。

    那主机驾崩了,我总该解决吧。那么哨兵就会进行投票,选出最合适登基的小皇上。没错,Redis里面也是采用的世袭制,谁跟之前的主机血脉最近最相似,谁就来做皇帝。这里指的是数据的相似性,两个从Redis,一个跟主机相似程度98%,另一个99%,那么肯定就会选择99%的对吧。

    虽然这样做放弃了大部分的一致性选择了高可用,并且哨兵中所有的Redis服务存放的数据额都相同,不支持扩容,但也足以应对大部分的问题了。

  • 集群模式

    如果你很不幸,Redis宕机了,哨兵也宕机不干了,那没事,还有集群模式做你后盾。

    之前的两种模式数据都是在同一个节点上,单个节点存储是有上限的。集群模式,当一个分片数据达到上限的时候,就会分成多个分片继续存储。

扩展补充

有个方法,是一般小公司的常用的方法—双机热备,这种方法保证服务高可用并且还能保障数据的安全性。

所谓双机热备其实原理很简单,就是准备两台主机,双击热备又分为两种方式,主备方式和双主机方式。

  1. 主备方式:两台主机,一台主用另一台备用,当主用主机宕机了那么备用的就顶上,直到我主用的被修理好健康了,那么再由我的主用主机上场。

  2. 双主机方式:同样是两台主机,两种不同的业务分别在两台服务器上互为主备状态。

Redis雪崩/击穿/穿透

  • 雪崩

    多个key查询并出现高并发,缓存中失效或者是查不到,然后都去前往MySql中去查找,从而导致MySql压力飙升,会造成查询堵塞甚至是MySql崩溃。

    解决方案:将缓存时间分散开,比如每个key的过期时间是随机,防止在同一时间大量数据出现过期现象,这样就不会在同 一时间全部请求全落在数据库上;如果是分布式部署,那么将热点数据均匀分布在不同Redis和MySql当中。

    再说地道一点缓存雪崩,假设每天高峰期的每秒5000个请求,本来缓存在高峰期可以扛住每秒4000个请求,但是缓存机器全盘死绝。Redis挂了,此时1秒5000个请求全都交给MySql,MySql肯定跑不了,就会报一声警,然后就挂了。此时,如果没有什么解决策略,我非常着急重启数据库,结果就只是MySql反复去世。

    解决方案
    事前:Redis高可用,主从 + 哨兵,Redis Cluster(一种集群模式),避免全盘崩溃
    事中:本地EhCache缓存 + Hystrix限流&降级,避免MySql死绝
    事后:Redis持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据

    //这样做数据库绝对不会死,只要数据库不死,对用户来说,2/5的请求是可以被处理的。可能就是多点几次页面出不来,再多点两三次页面就会刷新出来了。

  • 击穿

    某个key非常火热,访问非常频繁,处于集中式高并发的情况,当这个key在失效的瞬间,大量请求就击穿了缓存,Redis死了,直接访问MySql,然后MySql也给我等死。相比于雪崩整面墙崩塌,击穿则是墙被打穿了一个洞。

    解决方案:这个key不是非常火热吗,那我就设置这个key永不过期;或者基于redis or zookeeper 实现互斥锁,等待第一个 请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据

  • 穿透

    看名字就非常显而易见了。还是用之前的案例打个比方,每天处理5000个请求,但有4000个请求是由黑客发出来的。黑客发出的4000次攻击,缓存中查不到,去MySql中也查不到!

    就比如数据库表的id都是从1开始,但是黑客发出的请求id都是负数。这样的情况中,缓存中不存在,所以黑客的请求就会直接略过缓存,万军丛中取敌将首级,我直接杀爆你的MySql。

    解决方案:从数据库只要没查到,就写一个空值到缓存当中,比如 set -999 UNKNOWN。然后设置一个过期时间,这样的话 下次有相同的key来访问时,在缓存消失前都可以直接从缓存中获取数据。

Redis常用性能问题就解决方案

  1. Mater(主机)最好不要做任何持久化工作,如果数据重要,可以由Slave开启AOF备份,策略设置为每秒同步一次。

  2. 为了主从复制的速度和稳定,Matser和Slave最好在同一个局域网类。

  3. 尽量避免在压力很大的主库上增加从库

    我当时看到这一点非常疑惑,我增加从库不就是为了解决主库压力以防主库宕机吗,为什么还要避免呢?在一个高并发的状态下,假设主库一秒要操作8万条数据,这时候你突然加进来一台从库来,那么我的工作量又要增大,我又要向从库推数据,不然就会导致主从数据不一致,可是推数据的同时我的操作又不能停止,这样可能就会导致延迟

  4. 主从复制相比图状结构,用单向链表结构会更加稳定,即:Master <- Slave1 <- Slave2 <- …

    //这样的结构方便解决单点故障问题
    

Redis应用场景

排行榜、计数器、消息队列推送、好友关注、粉丝。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值