前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式基础概念-分布式服务之ZK[2]

分布式基础概念-分布式服务之ZK[2]

作者头像
@派大星
发布2023-11-03 15:55:47
1450
发布2023-11-03 15:55:47
举报
文章被收录于专栏:码上遇见你码上遇见你

ZK的数据同步原理

主要是根据这三个参数的大小对比结果,选择对应的数据同步方式。

  • peerLastZxid:Learner服务器(Follower或observer)最后处理的zxid。
  • minCommittedLog:Leader服务器proposal缓存队列committedLog中的最小的zxid。
  • maxCommittedLog:Leader服务器proposal缓存队列committedLog中的最大的zxid。

Zookeeper中数据同步一共有四类,如下:

  • DIFF:直接差异化同步

peerlastZxid介于minCommittedLog和maxCommittedLog之间

  • TRUNC+DIFF:先回滚再差异化同步

当Leader服务器发现某个Learner包含了一条自己没有的事务记录,那么就需要让该Learner进行事务回滚到Leader服务器上存在的

  • TRUNC:仅回滚同步

peerlastZxid大于maxCommittedLog,Leader会要求Learner回滚到ZXID值为maxCommitedLog对应的事务操作

  • SNAP:全量同步

peerLastZxid小于minCommittedLog

在初始化阶段,Leader服务器会优先初始化以全量同步方式来同步数据。learner先向leader注册,上报peerLastZxid

ZK中一个客户端修改了某个节点的数据,其他客户端能够马上获取到这个最新数据吗?

不能确保任何客户端能够获取(即Read Request)到一样的数据,除非客户端自己要求,方法是客户 端在获取数据之前调用函数sync,再调用getData()

ZK客户端A对节点的内容从v1->v2,但是ZK客户端B对内容获取,依然得到的是v1.这个是实际存在的 现象,存在同步时延

ZooKeeper对事务性的支持

ZooKeeper对于事务性的支持主要依赖于四个函数,zoo_create_op_initzoo_delete_op_initzoo_set_op_init以及zoo_check_op_init

每一个函数都会在客户端初始化一个operation,客户端程序有义务保留这些operations。当准备好一 个事务中的所有操作后,可以使用zoo_multi来提交所有的操作,由zookeeper服务来保证这一系列操 作的原子性。也就是说只要其中有一个操作失败了,相当于此次提交的任何一个操作都没有对服务端的 数据造成影响。zoo_multi的返回值是第一个失败操作的状态信号。

ZK中的观察者机制

代码语言:javascript
复制
peerType=observer
server.1:localhost:2181:3181:observ
  • 观察者的设计是希望能动态扩展zookeeper集群又不会降低写性能。
  • 如果扩展节点是follower,则写入操作提交时需要同步的节点数会变多,导致写入性能下降,而follower又是参与投票的、也会导致投票成本增加
  • observer是一种新的节点类型,解决扩展问题的同时,不参与投票、只获取投票结果,同时也可以处理读写请求,写请求转发给leader。负责接收leader同步过来的提交数据,observer的节点故障也不会影响集群的可用性,
  • 跨数据中心部署。把节点分散到多个数据中心可能因为网络的延迟会极大拖慢系统。使用observer的话,更新操作都在一个单独的数据中心来处理,并发送到其他数据中心,让其他数据中心的节点消费数据。
  • 无法完全消除数据中心之间的网络延迟,因为observer需要把更新请求转发到另一个数据中心的leader,并处理同步消息,网络速度极慢的话也会有影响,它的优势是为本地读请求提供快速响应。

ZK的会话管理机制

客户端连接zk,有zk分配一个全局唯一的sessionId,客户端需要配置超时时间timeOut并传到zk,zk会据此计算会话下一次超时的时间点,zk根据这个时间点按照分桶策略进行分开存放,zk会给session设置一个isClosing属性、如果检测到超时会将该属性标记为关闭

会话状态:CONNECTINGCONNECTEDRECONNECTINGRECONNECTEDCLOSE

SessionTracker:zk中的会话管理器,负责会话的创建、管理和清理

  • sessionsWithTimeout:一个ConcurrentHashMap,用来管理会话的超时时间
  • sessionsById:HashMap,维护sessionId到session的映射
  • sessionsSets:HashMap,会话超时后进行归档,便于恢复和管理

ExpiractionTime = CurrentTime + SessionTimeout

SessionTracker根据ExpiractionTime将session进行分桶管理,同时按照一定的时间间隔进行定期检查,

同时客户端读写请求都可以将session的超时时间重置,SessionTracker会将session进行分桶迁移,如果没有读写请求,客户需要发送ping心跳链接,否则session超时会被清除

会话清理:
  • 标记isClosing为关闭,此时该会话有新的请求也无法处理
  • 发起会话关闭请求,同步到整个集群,使用提交的方式
  • 收集需要清理的临时节点,先获取内存数据库中会话对应的临时节点集合,如果此时有删除节点的请求到达,将请求对应的节点路径从集合中移除,避免重复删除,如果有创建节点请求到达、则将请求中的路径添加到集合中
  • 添加删除事务变更,将节点删除事务添加到outstandingChanges中,触发watch
  • 删除临时节点
  • 移除会话
  • 关闭连接

连接断开后客户端可以重连zk,如果该session未过期,session重新变为CONNECTED

如果时间超过sessinTimeout,服务器则会进行会话的清理工作,如果此时ZK客户端才恢复连接,则会收到State为Expired的WatchedEvent,并断开与服务器的连接。

重连:断开后更换服务器链接,RECONNECTING状态,会将会话迁移到新连接的服务器上

当一个客户端发一个心跳请求个服务端,但是网络延时,导致服务端没有收到,过一会后,客户端连接上了另一个新的服务端,在这之后,之前的心跳被旧的服务端收到了,这时候旧的服务端会被提醒,当前session已经被转移了,然后旧的服务端会关闭这个连接。客户端一般不会感知到这个异常,因为旧连接一般都会被关闭。但是还有一个特殊情况,两个客户端同时使用保存这的session id+密码来重新连接服务端,第一个连接成功,紧着第二个又连接成功,这会导致第一个连接被关闭,然后就是这两个客户端无限重连了

ZK和Eureka的对比

  1. zk保证的是CP,即分区容错和一致性,eureka保证的是AP、即可用性和分区容错
  2. zk的master如果挂掉,需要进行选举,此时zk无法使用。
  3. eureka的各个节点是平等的。只要有一台是正常的就能提供服务,

eureka还有一种自我保护机制,如果15分钟内超过85%的节点没有正常心跳会开启保护机制。eureka 不再从注册列表移除长时间没有心跳的服务、eureka仍能接受新的服务注册和查询,只不过不会同步到 其他节点。网络稳定后再同步到其他节点。同时eureka的客户端也会缓存服务信息。eureka对于服务 注册发现来说是非常好的选择

如有问题,欢迎加微信交流:w714771310,备注- 技术交流 。或关注微信公众号【码上遇见你】。


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上遇见你 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ZK的数据同步原理
  • ZK中一个客户端修改了某个节点的数据,其他客户端能够马上获取到这个最新数据吗?
  • ZooKeeper对事务性的支持
  • ZK中的观察者机制
  • ZK的会话管理机制
    • 会话清理:
    • ZK和Eureka的对比
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档