zookeeper| 青训营笔记

95 阅读4分钟

这是我参与「第五届青训营」伴学笔记创作活动的第18天

一开始,我带着以下问题学习zookeeper:

  • 像Mysql、Hbase这样的数据库都实现了高可用,为什么还要用zookeeper? (比如为什么我们一般要用zookeeper来实现主从、选举、分布式配置中心?)
  • 分布式锁的实现有很多种,比如使用Redis或者Zookeeper,那么它们的实现有什么区别呢?
  • Zookeeper的缺点是什么

问题一

关于第一个问题

像Mysql、Hbase这样的数据库都实现了高可用,为什么还要用Zookeeper? (比如为什么我们一般使用Zookeeper来实现主从、选举、分布式配置中心?)

我是这样理解的。 Mysql、HBase等数据库通过某种机制实现了高可用(例如Mysql通过主备设计实现了高可用),可以用来替代Zookeeper。 比如我们用Mysql实现一个选举机制:

1.首先我们创建一个表proposal

2.服务初始化时,我们每个服务器都INSERT到这个表中(其中type为1)。 2.由于插入本身,因此ID最小的插入物已成功选举产生。 是不是很简单。 2、被选举的服务器(A)向表中插入一条type=2的数据,表示它已经上任。

  4.2 服务器A的insert操作也要优化,使用INSERT IF NOT EXIST
  4.3 当某服务器发现A被关闭时,立即开始下一次选举,重新从步骤2开始

2、服务器A定期更新自己选举记录的heart_beat,这样一旦挂掉,其他服务器可以马上发现,然后开始下一次选举。

从上面的步骤可以看出,使用mysql实现选举似乎是可行的。 但我只是简单体会了步骤,不能保证选举的可靠性。 例如在步骤4.1中,其他服务通过时间戳来计算自己是否可靠。 要知道在分布式环境下是没有可靠的时钟系统的,所以补救的办法可能就是延长过期时间,或者让Mysql来判断。 其次,上述实现采用了心跳和轮训机制,在性能上存在一定的问题。

总之,我想表达的是,分布式算法可能并不复杂,但是陷阱很多。 即使我们使用可靠的数据库,我们的实现仍然可能存在很多问题。 而这种问题在普通测试中是极难发现的。 与其自己维护一套定时炸弹,还不如使用开源软件,除了出问题,还可以怪罪,对不对? 其次,Zookeeper采用了一套专门为分布式业务设计的API。 可以说使用Zookeeper比使用Mysql自己实现分布式业务更有用,也更容易扩展。

问题二

分布式锁的实现有很多种,比如使用Redis或者Zookeeper,那么它们的实现有什么区别呢?

如何用Redis实现分布式锁

这是一道热门的面试题,答案无非就是

  • 使用SetNX、Lua脚本保证锁的原子性
  • 设置一个过期时间保证锁,保证锁会被释放

当然,使用上面的实现也有一些问题:

1.过期时间设置的太短,任务还没执行完就释放了锁。 1、过期时间设置过长,等待服务挂掉的时间会很长。 1.等待锁的服务会一直轮询,存在一定的性能问题 1、主从切换时,可能会丢失数据。 (当然也可以设置每次数据更新等待slave节点写完再回复,但是会影响性能)

针对以上问题,1和2可以通过增加WatchDog来更新过期时间。 3也可以通过Redis的watch功能来实现。 唯一比较棘手的是问题4,这也是Redis分布式锁的核心问题。

Zookeeper实现分布式锁

Zookeeper实现分布式锁就更简单了,这是写在它基因里的东西。 使用 Persitent 节点,或使用 Ephemeral 节点。 其中,使用Persitent虽然简单(其实并没有那么简单),但是会造成羊群问题(因为太多客户端看这个Node,一旦更新,需要多次同步,造成流量 峰)。 使用Ephemeral可以有效解决这个问题。