You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kafka.apache.org by gu...@apache.org on 2016/11/09 18:38:04 UTC
kafka git commit: KAFKA-4360:Controller may deadLock when autoLeaderRebalance encounter zk expired
Repository: kafka
Updated Branches:
refs/heads/trunk 11766ad31 -> 6dbe202b6
KAFKA-4360\uff1aController may deadLock when autoLeaderRebalance encounter zk expired
Author: tuyang <tu...@meituan.com>
Author: xiguantiaozhan <ka...@126.com>
Reviewers: Ismael Juma, Jiangjie Qin, Guozhang Wang
Closes #2094 from xiguantiaozhan/rebalance_deadlock
Project: http://git-wip-us.apache.org/repos/asf/kafka/repo
Commit: http://git-wip-us.apache.org/repos/asf/kafka/commit/6dbe202b
Tree: http://git-wip-us.apache.org/repos/asf/kafka/tree/6dbe202b
Diff: http://git-wip-us.apache.org/repos/asf/kafka/diff/6dbe202b
Branch: refs/heads/trunk
Commit: 6dbe202b6dc3ba638d3a55ff89b594bd334bb8b0
Parents: 11766ad
Author: Tu Yang <tu...@meituan.com>
Authored: Wed Nov 9 10:37:59 2016 -0800
Committer: Guozhang Wang <wa...@gmail.com>
Committed: Wed Nov 9 10:37:59 2016 -0800
----------------------------------------------------------------------
.../kafka/controller/KafkaController.scala | 3 ++-
.../kafka/server/ZookeeperLeaderElector.scala | 23 ++++++++++++++------
2 files changed, 18 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kafka/blob/6dbe202b/core/src/main/scala/kafka/controller/KafkaController.scala
----------------------------------------------------------------------
diff --git a/core/src/main/scala/kafka/controller/KafkaController.scala b/core/src/main/scala/kafka/controller/KafkaController.scala
index b7b4d71..4a94aad 100755
--- a/core/src/main/scala/kafka/controller/KafkaController.scala
+++ b/core/src/main/scala/kafka/controller/KafkaController.scala
@@ -352,6 +352,7 @@ class KafkaController(val config : KafkaConfig, zkUtils: ZkUtils, val brokerStat
/**
* This callback is invoked by the zookeeper leader elector when the current broker resigns as the controller. This is
* required to clean up internal controller data structures
+ * Note:We need to resign as a controller out of the controller lock to avoid potential deadlock issue
*/
def onControllerResignation() {
debug("Controller resigning, broker id %d".format(config.brokerId))
@@ -1158,8 +1159,8 @@ class KafkaController(val config : KafkaConfig, zkUtils: ZkUtils, val brokerStat
@throws(classOf[Exception])
def handleNewSession() {
info("ZK expired; shut down all controller components and try to re-elect")
+ onControllerResignation()
inLock(controllerContext.controllerLock) {
- onControllerResignation()
controllerElector.elect
}
}
http://git-wip-us.apache.org/repos/asf/kafka/blob/6dbe202b/core/src/main/scala/kafka/server/ZookeeperLeaderElector.scala
----------------------------------------------------------------------
diff --git a/core/src/main/scala/kafka/server/ZookeeperLeaderElector.scala b/core/src/main/scala/kafka/server/ZookeeperLeaderElector.scala
index bb6caa0..73e7210 100755
--- a/core/src/main/scala/kafka/server/ZookeeperLeaderElector.scala
+++ b/core/src/main/scala/kafka/server/ZookeeperLeaderElector.scala
@@ -121,13 +121,16 @@ class ZookeeperLeaderElector(controllerContext: ControllerContext,
*/
@throws(classOf[Exception])
def handleDataChange(dataPath: String, data: Object) {
- inLock(controllerContext.controllerLock) {
+ val shouldResign = inLock(controllerContext.controllerLock) {
val amILeaderBeforeDataChange = amILeader
leaderId = KafkaController.parseControllerId(data.toString)
info("New leader is %d".format(leaderId))
// The old leader needs to resign leadership if it is no longer the leader
- if (amILeaderBeforeDataChange && !amILeader)
- onResigningAsLeader()
+ amILeaderBeforeDataChange && !amILeader
+ }
+
+ if (shouldResign) {
+ onResigningAsLeader()
}
}
@@ -137,12 +140,18 @@ class ZookeeperLeaderElector(controllerContext: ControllerContext,
* On any error.
*/
@throws(classOf[Exception])
- def handleDataDeleted(dataPath: String) {
- inLock(controllerContext.controllerLock) {
+ def handleDataDeleted(dataPath: String) {
+ val shouldResign = inLock(controllerContext.controllerLock) {
debug("%s leader change listener fired for path %s to handle data deleted: trying to elect as a leader"
.format(brokerId, dataPath))
- if(amILeader)
- onResigningAsLeader()
+ amILeader
+ }
+
+ if(shouldResign) {
+ onResigningAsLeader()
+ }
+
+ inLock(controllerContext.controllerLock) {
elect
}
}