校招后端面经--数据库
缓存( redis)
1. redis如何实现数据的持久化
两种方式:RDB和AOF
RDB
通过快照的方式,当符合一定条件时就会自动将内存中的所有数据生成一份副本存到磁盘中,根据配置文件,SAVE或BGSAVE命令。
配置文件:配置文件中设置了两个参数,一个是时间串口M,一个是改动的键的个数N,每当时间M内被改动的键的个数大于N时,就生成新的RDB文件替换原来的RDB文件存到磁盘。
SAVE:用户执行save命令同步执行快照时,在快照执行过程中会阻塞所有来自客户端的请求,导致redis长时间不响应。
BGSAVE:后台异步执行快照
过程:(1)redis使用fork函数复制一份当前进程(父进程)的副本(子进程)
(2)父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件
(3)当子进程写入完所有数据后会用该临时文件替换旧的RDB文件
AOF
默认不开启,开启之后在每次执行命令后将命令本身记录下来。
当AOF记录冗余的命令时,会在配置文件中设置一定的参数,当达到当前参数的值时(比如文件大小超过了配置文件中设置的大小的值),重写AOF文件。
2. Redis的集群
主从复制
-
主数据库可以进行读写操作,从数据库保留主数据的副本,当主数据库写操作导致数据变化时,会自动把数据同步给从数据库,而从数据库一般是只读的。
-
过程:当一个从数据库启动后,会向主数据库发送SYNC的命令,主数据库收到连接命令后会开始在后台保存快照,并将保存期间接收到的命令缓存起来。当快照完成后,就会把快照文件和缓存命令发送给从数据库。从数据库收到之后就会载入快照文件并执行命令。这个过程也叫复制初始化。
-
若主从的连接断开重连:以前的版本是重新进行复制初始化,缺点是恢复过程的效率低下;现在的版本的一个改进是能够支持有条件的增量传输,重连后,主数据库只要将断连期间执行的命令发送给从数据库即可。
-
读写分离,适合读多写少的场景;当主数据库崩溃时,可以从从数据库恢复。
-
增量复制(重连使用):
三个基础:(1)从数据库会存储主数据库的运行ID(每个redis运行实例都有自己唯一的ID)
(2)在复制同步阶段,主数据库每将一个命令传送给从数据库时,都会同时把该命令存放到一个
积压队列中,并记录下当前积压队列中存放命令的偏移量的范围
(3)同时,从数据库接收到主数据库传来的命令时,会记录下该命令的偏移量
过程:(1)首先主数据库会判断从数据库传过来的ID跟自己的ID是不是一样的,确保从数据库之前是和自己
同步的。
(2)判断从数据库最后同步成功的命令的偏移量是否在积压队列中,如果在则可以执行增量复制,并
将积压队列中相应的命令发送给从数据库
哨兵
-
作用:(1)监控主数据库和从数据库是否正常运行(哨兵之间可以相互监控)
(2)主数据库出现故障时自动将从数据库转换为主数据库
-
哨兵定时执行的3个操作:
(1)每10s哨兵会向主数据库和从数据库发送INFO命令,可以获得当前数据库的相关信息从而实现新节点的
自动发现
(2)每2s哨兵会向主数据库和从数据库发送自己的信息(哨兵的地址,端口等)
(3)每1s哨兵会向主数据库,从数据库和其他哨兵发送ping命令,监控数据库是否还在服务
-
RAFT算法(选哨兵)
作用:当监控到主数据库下线时,哨兵们会选举一个领头哨兵对主数据库进行故障恢复
过程:(1)发现主数据库下线的哨兵节点(A)向每个哨兵节点发送命令,要求对方选自己成为领头哨兵
(2)如果目标哨兵没有选过其他人,则会统一将A设置成领头哨兵
(3)如果A发现又半数且超过quorm参数值的哨兵统一选择其成为领头哨兵,则A成功成为领头哨兵
(4)如果又多个哨兵节点同时参与选举,则会出现没有任何哨兵当选的可能。此时随机等待一个时
间后重新选举
集群
-
原因:即使使用哨兵,redis集群的每个数据库依然存有集群中的所有数据,从而导致集群的总数据存储量受限于可用存储内存最小的数据库节点,形成木桶效应。
-
原理是:不同的节点管理不同的插槽,一个集群中共有16384个插槽
-
节点的增加:在集群中的任一节点(B)向新节点(A)发送CLUSTER MEET ip port的命令,新节点A接收到这个命令后,会与B进行握手,使B把A当作当前集群中的一员。握手成功后,B会使用Gossip协议将节点A的消息通知给集群中的每一个节点。
-
插槽分配:
新的节点加入集群后,要么复制每个主数据库来以从数据库的形式运行,要么向集群申请分配插槽来以主数据库的形式运行
在一个集群中,所有的键会被分配给16384的插槽,而每个主数据库会负责处理其中的一部分插槽。
两种情况:
(1)插槽之前没有被分配过,现在想分配给指定节点
使用CLUSTER ADD SLOT S的命令实现
(2)插槽之前被分配过,现在想移动到指定节点
若槽中无数据,可用CLUSTER SETSLOT 插槽号 NODE 新节点的运行ID,若槽中有数据,数据是不会被
迁移的,会导致数据的丢失。因此还要把数据迁移过去
迁移过