什么是 Redis ?
?1,相对于mysql ,oracle , 这种关系西数据库, 我们还有非关系数据库服务,他的产生是为了,解决常规数据库的并发能力,传统的关系型数据库受限于IO 和性能瓶颈, nosql 有着比较好的效率和性能,key-value 查询模式。
? ? 那redis 是nosql 中的佼佼者, 他是一块内存高速缓存数据库,(读的速度是 110000次/s , 写的速度是 81000次/s ,) 底层使用万物之母c 语言编写,试问谁与争锋?,他的数据类型 ,String ,LIst ,set zet hash, 并且他的所有操作的都是原子性,他也支持持久化,rdb (全量备份,节省磁盘空间,回复速度快,但可能丢失数据,) aoF(日志增量备份,数据保存完整,但是整的恢复效率低,占用空间。如果数据比较敏感的,建议两个都开启,如果纯缓存,都不开启,默认开启rdb ) 等持久化方式,而且支持集群,支持主从复制(主机会自动将数据同步到从机,可以进行读写分离)。
面试题:redis 为啥那么快,说说reids 线程模型?
1, 很多人都知道redis基于内存,所以快, 那么你是个初级开发,面试官向让你说说细点,。其实就是redis底层有一套完善的多的时间处理机制来保证执行高效的。
redis 内部使用文件事件处理器 file event handler, 这个文件事件处理器是单线程的,所以redis 叫单线程模型。(面试题问,redis, 是单线程还是多线程啊, 单线程,那为啥是单线程啊,不要给你自挖坑那你旧的知道为啥?),它采用io多路复用机制同时监听多个socket ,根据socket 上的事件选择对饮的事件处理器进行处理。
线程模型?
?redis 内部使用文件事件处理器file event handle, 它包含几个部分
1, 多个socket ,2 io多路复用程序, 2, 文件事件分派器, 3 文件处理器(连接应答处理器,命令请求处理器,命令回复 处理器)
之所以说redis 是个单线程其实值文件事件处理器单线程,采用多路复用的方式监听系统上多个soket ,将socket 上产生的事件压入队列中,由文件处理分派器从队列选一个socket 根据事件类型发给相应的事件处理器,
redis 6? 版本引入了多线程,上边已经提到redis 单线程处理有着很快地速度,那为啥用多线程?
单线程的瓶颈在于网络io 操作,上, 越纪事读写网络系统会占用大量的cpu ,如果你要对一些大的键值删除,短时间删除不玩,那么对于单线程,后边请求就会阻塞。
Redis 在设计上采用将网络数据读写和协议解析通过多线程的方式来处理,对于命令执行来说,仍然使用单线程操作(在网络数据传输,数据解析使用了多线程,但是数据操作还是单线程)
2, 他的应用场景 :? 缓存 , 事件的发布订阅。
1, 缓存, 读取前先去redis ,如果没有,读取数据库,将数据拉到redis 对数据库有一定保护,
插入数据时,先写入redis。
? ?这里涉及到三个比较记混 名字 ,也是面试常问的:
击穿 、穿透 、 雪崩 :
? ?1.1? 击穿 :??请求的数据 redis 不存在,捉着数据热点过期, 导致缓存失效, 直接去读取数据库,数据扛不住大量的请求,这就是像是 子弹击穿了 redis (防弹衣)到了数据库实体上.。 解决办法: 1、 互斥锁,保证同一时间只有一个业务员线程更新缓存,为鞥你获取互斥锁的请求,要么等待锁释放重新读取缓存,要么叫返回空,
2.不给热点数据设置过期时间,有后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间。
1.2? 穿透: 缓存穿透是,用户或者黑客不断的发起请求访问缓存和数据库中没有的数据,导致数据库压力过大。子弹打过来,击穿了防弹衣reids,穿透了数据库。
解决办法:? 1,首先一般我们的系统都是有接口鉴权校验的一般是 token 什么的,这种防止随便请求,或者是防止1s 多次请求一个资源。
2,对于缓存取不到, 数据库也没有的请求这时候可以将key-value 写出,key-null, 缓存有效时间可以设置30s,
3,布隆过滤器,bitmap(除了五种基础类型之外的数据结果)? 默认为0对请求三次hash 值分别设置1,假设一个没有匹配上就说数据库中没有,直接返回。
1.3? 雪崩?
缓存雪崩是,一段时间,缓存集中失效,导致全部走数据库,有可能把数据库瘫痪,
1,雪崩就是缓存中大批数据过期后系统涌入大量请求,redis失效了,就会渗透到数据库,导致数据库宕机,(和击穿类似,就是大量的数据同时过期,缓存实力宕机,就是雪崩)
? 解决办法: 让redis 永不过期,2, 将缓存失效时间分散开,防止同一时间过期,3,可以启动服务熔断机制,暂停业务访问服务4,创建redis 集群读写分离。
?redis? 的高可用?
? 1 ,主从模式
2, 哨兵模式
3, 集群模式
主从模式中,一旦节点由于故障不能提供服务,需要人工将节点升级为主节点,同时还要通知应用更新主节点地址,多数业务场景是不能接收这种故障处理方式的,redis 在2.8开始提供了哨兵架构,
,哨兵模式,由一个或者多个sentienel 实力组成的sentinel系统,它可以监视所有的redis 主节点和从节点,并在被监视的主节点下线后,自动将下线的主服务属下的某个节点升级为新的主节点,但一个哨兵进程对redis 节点进行监控,就可能出现问题,因此可以使用多个哨兵进行监控redis 节点,并且各个哨兵之间还会进行监控(ping)
?总结 : 哨兵是一个独立的进程,每个哨兵监控一个服务器,哨兵实现消息通知选举
?(1) 发送命令,等待redis 服务器*(主服务和从服务)返回监控其运行状态:(2) 哨兵检测到主节点宕机,会自动将从节点切换成主节点,然后通过发布订阅模式通知其他从节点修改配置文件,让他们切换主机;(3)哨兵之间会相互监控
(1)每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他Sentinel实例发送一个 PING命令。
(2)如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel标记为主观下线。
(3)如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
(4)当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线。
(5)在一般情况下, 每个 Sentinel 会以每10秒一次的频率向它已知的所有Master,Slave发送 INFO 命令。
(6)当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
(7)若没有足够数量的 Sentinel同意Master已经下线, Master的客观下线状态就会被移除;若Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除
补充: redis 作为缓存的时候,随着访问量的增肌,对redis 读写很快,一个节点压力大,通常会使用主从复制,master写为主,slave 读为主,并用哨兵进行监控?
配置方式:首先复制redis.conf
[root@localhost ~]# cd /usr/local/redis/bin/
[root@localhost bin]# cp redis.conf redis6379.conf
[root@localhost bin]# cp redis.conf redis6380.conf
[root@localhost bin]# cp redis.conf redis6381.conf
然后对这3个配置文件redis6379.conf、redis6380.conf、redis6381.conf分别进行修改
①、修改配置端口,分别改成对应的端口即可 port 6380? |? 6381 ,
②、修改daemonize为yes
③、配置pid文件路径 pidfile? ? pidfile? /var/run/redis_6380.pid
④、配置log 文件名字? ? logfile "6380.log"
⑤、配置rdb文件名? ? ? ?dbfilename dump_6380.rdb
⑥、看情况选择:如果redis配置了密码(requirepass 123456),则还需在从redis服务中设置这一项,如果没有设置密码则忽略这一项
当三份都配置完成后,分别启动这三个服务:
使用? ps -ef | grep redis 查看:
然后通过如下命令选择不同的端口进入到这三个Redis客户端:
01 |
|
①、设置一主二从:
通过?INFO?replication?命令查看发现,三个默认的都是Master角色,
然后我们将 6380 和 6381设置为Slave角色,可以使用如下命令:
这时 6380 和 6381成为了Slave,然后查看一下主机(Master)信息:
可以发现主机下面有两个Slave节点。
注:通过这种方式来设置主从关系,一旦服务重启,那么角色关系将不复存在。想要保存这种关系,可以通过Slave的 配置文件来进行配置。
分别编辑 redis6380.conf 和 redis6381.conf 配置文件,加入(约在286行):
01 |
|
①、给主节点设置值:set k1 v1
从节点也可以获取到值,说明没问题。
在没有设置主从关系之前,如果主节点内有数据,那么在设置主从关系后,Slave从节点也能获取到主节点原来的数据。
如果Master主节点挂掉了,Slave从节点的角色不会发生变化,一直处于等待状态,直到Master主节点重新启动。
如果要将Slave从节点变成Master节点,可以使用如下命令:
01 |
|