Redis/Zookeeper/Kafka

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgsxzdl/article/details/89460060

Redis:

持久化

RDB

快照,快照过程如下:

  • 使用fork函数复制一份当前进程(父进程)的副本(子进程)
  • 父进程继续接受和处理(采用copy-on-write策略),子进程开始将内存数据写入临时文件
  • 子进程写入完成之后,用临时文件替换旧的RDB文件

AOF

开启AOF持久化后,每执行一条更改,将命令写入磁盘的AOF文件。
AOF重写:为了解决AOF文件冗余的问题,触发时机,当前大小超过上次重写大小的百分比(有最小重写文件的限制)
同步参数:

  • always: 每次命令同步
  • everysec:每秒同步一次
  • no:不同步

集群

  1. 数据备份
  • 复制初始化:从库启动后,向主库发送SYNC命令;主库收到SYNC命令保存快照,并将快照期间的命令缓存起来。快照完成后,主库将快照和缓存的命令发给从库。从库载入快照和执行缓存命令。

  • 同步命令:复制初始化之后,主库将后面的写命令同步给从库,从而保证主从一致

  • 增量复制(2.8新增)
    从库发送PSYNC请求,带上从库存储的主库id,当前从库的偏移量。
    主库收到PSYNC请求后,判断主库id为自己,偏移量在积压队列,将积压队列后面的命令同步给从库;否则执行一次全部同步

  1. 系统监控和故障恢复
    通过哨兵实现,它的功能主要是两个:
  • 监控数据库是否正常运行
  • 主库故障时自动将从库转换为主库

哨兵监控数据库和其他哨兵
哨兵只需要配置主库,从主库获取info,自动发现从库。
哨兵和主库建立连接之后,会进行3个操作:

  • 每10秒向主库和从库发送INFO命令
  • 每2秒向主库和从库的__sentinel__:hello 频道发送自己的信息
  • 每1秒向主库、从库和其他哨兵发送PING命令

主库故障恢复流程:

  • 在配置的时间发现PING 主库未回复,认为主观下线
  • 哨兵发送命令询问其他哨兵是否主观下线
  • 达到数量的哨兵认为主观下线,就认为其客观下线,开始故障恢复
  • 选举首领哨兵
  • 从首领哨兵的从库中选取主库:优先级最高 -> 偏移量最新 -> id最小
  • 设置主库,让从库跟随主库
  1. 无硬盘复制
    主库在与从库进行复制初始化是,不将快照存储到磁盘,而是直接通过网络发给从库

zookeeper

持久化

  • 快照数据:snapShot.{zxid},后缀是该快照文件生成时已执行的最新的事务的zxid
  • 事务日志:log.{zxid},后缀是该日志文件存储的第一个事务的zxid

事务日志:

  1. 由于事务日志要不断的写入,会触发底层磁盘I/O为文件开辟新的磁盘块,为了减少分配新磁盘块对写入的影响,Zookeeper使用预分配策略,默认每次分配新文件或扩容时,一次分配64MB
  2. 事务日志剩余空间 < 4KB 时,将文件大小增加 64 MB
  3. 事务操作次数等于snapCount/2~snapCount 中的某个值时,会触发快照生成操作,随机值是为了避免所有节点同时生成快照,导致集群影响缓慢。同时将当前事务日志的输出流置null,这样下次写事务日志时自动创建新的事务日志文件
  4. 为了提高事务日志持久化的性能,Zookeeper使用批处理策略,并不是每一个request都立即持久化到磁盘中,而且持久化到磁盘的优先级较低.只有当没有待处理的request或者积攒了1000个待刷新的request时,才会执行flush()

集群

zk服务器启动时,先从快照中恢复,然后从事务日志中恢复之后的操作。
然后进行leader的选举,选举之后,更改服务器状态。

服务器状态:

  • LOOKING:寻找Leader状态,处于该状态需要进入选举流程
  • LEADING:领导者状态,处于该状态的节点说明是角色已经是Leader
  • FOLLOWING:跟随者状态,表示Leader已经选举出来,当前节点角色是follower
  • OBSERVER:观察者状态,表明当前节点角色是observer

Leader选举

启动时,

  1. 每个server发起一个投票包:(myid, ZXID)
  2. 接受来自各个服务器的投票:判断有效性,如是否来自于FOLLOWING
  3. 处理投票:循环等待,将收到投票跟自身记录投票比较,并将结果广播出去,比较原则:
  • 优先检查ZXID。ZXID比较大的服务器优先作为Leader。
  • 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。
  1. 统计投票:循环等待时,判断是否有过半的服务器有投票结果,有则需要判断leader是否在赞同者之中,在则退出循环,选举结束
  2. 改变状态

运行期间Leader重新选:
leader挂掉之后,余下的非OBSERVER机器改变状态为LOOKING,开始选举阶段,同启动时

数据同步

整个集群完成Leader选举之后,Learner会向Leader服务器进行注册。当Learner服务器向Leader完成注册后,就进入数据同步环节。

Learner注册 -> 获取Learner状态 -> 数据同步初始化

数据同步初始化:从内存中获取提案的缓存队列,初始化:

  • peerLastZxid:该Learner服务器最后处理的ZXID。
  • minCommittedLog:Leader服务器提议缓存队列committedLog中的最小ZXID。
  • maxCommittedLog:Leader服务器提议缓存队列committedLog中的最大ZXID。

根绝三个值分别进行:
min < peerLastZxid < max 且peerLastZxid在缓存队列:DIFF同步
min < peerLastZxid < max 且peerLastZxid不在缓存队列:先回滚后DIFF同步
peerLastZxid > max: 回滚同步
peerLastZxid < min: 全量同步

leader构建NEWLEADER包,内含leader最大数据的zxid, 广播给follows,然后leader根据follower数量为每个follower创建一个LearnerHandler线程来处理同步请求:leader主线程阻塞,等待超过半数follower同步完数据之后成为正式leader。

一致性

ZAB协议:

Redis和ZK的快照对比:

  1. ZK 使用「异步线程」生成快照:线程之间共享内存空间,导致 Fuzzy 快照
  2. 这就要求 ZK 的所有事务操作是幂等的,否则产生数据不一致的问题
  3. 实际上 ZK 的所有操作都是幂等的
    类比:Redis 中使用「异步进程」生成快照 RDB(Redis Dump Binary)
  4. RDB 文件是精确的快照,原因:进程之间内存空间隔离
  5. 系统内核使用「写时复制」(Copy-On-Write)技术,节省大量内存空间

kafka

TODO

猜你喜欢

转载自blog.csdn.net/zgsxzdl/article/details/89460060
今日推荐