Monthly Archives: April 2013

zookeeper锁的不可靠性

假设两个client竞争一个锁,拿到锁的client有资格处理指定的资源。系统的设计目标是同一时刻只有一个client在处理资源。

假设当前client1拿到锁了,client2等待中。 client1正在处理指定资源。

这时client1断开,client2拿到锁,开始处理指定资源;但由于client1并不知道自己已经断开了,所以会继续处理资源,结果造成两个client都在处理同一个资源。

解决办法是每个client在处理时要时不时地轮询自己跟zk是否已经断开连接。

见:

http://stackoverflow.com/questions/14275613/concerns-about-zookeepers-lock-recipe

理解Zookeeper的Connection和Session之间的关系

可以通过比较CONNECTION_LOSS和SESSION_EXPIRED这两种错误,来理解Connection和Session之间的关系:

  官方释义 底层本质 跟CONNECTION_LOSS的关系 跟SESSION_EXPIRED的关系 重连 连接保持机制
CONNECTION_LOSS link broken

TCP短连接超时?

或长连接心跳失败?

(待看代码)

N/A

如果在SESSION Timeout到期之间重连成功,则无SESSION EXPIRED;

否则,则意味着SESSION_EXPIRED

ZK客户端自动重连

tcp keepalive机制?

(待看代码)

SESSION_EXPIRED "partitioned"for more than the session timeout 应该跟底层无关(待看代码) 很有可能是由CONNECTION_LOSS导致的 N/A 客户端自己决定是否重连 ping心跳

消息中间件必须提供ack()机制

ack()机制 = 当消费者消费完消息、并回送ack()后,消息中间件才能认为此消息已被成功消费。

无ack机制 = 消费端拿到消息后,中间件就认为消费端已成功处理

在“ACK机制”下,如果消费端在拿消息A后出异常或者当机,当它从异常或当机中恢复时,又于出错前没有回送ACK,消息中间件就会重发消息,消费端就有了一次补偿处理的机会。

在“无ACK机制”下,就没有补偿处理的机会,也就会造成数据的不一致。