apache / apache/openwhisk

Healthcheck Protocol Bug / Edge Case when Unhealthy or Unresponsive

Open
#5,053 11 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
6.8k
Forks
1.2k
Avg merge
2d 14h
Merged PRs (30d)
2

Description

We're facing an issue where the Invoker becomes Unhealthy (not processing activations), but it is still sending pings to the controller. This works as intended that the controller marks it as unhealthy or unresponsive. However, it is still sending healthcheck messages on the invoker topic which are not being read when the invoker is in this state. Coincidentally the other eager marking as healthy bug that was identified this week probably isn't helping too. The problem then starts on the restart of the invoker which brings the invoker back to a healthy state:

1. There is a huge backlog of healthcheck messages on the invoker topic (say it took days before the invoker restart)
2. After the invoker restarts, it starts processing these healthchecks finally.
3. Invoker tells the controller it's healthy from the first healthcheck messages processing.
4. Controller starts sending activations onto an invoker topic with a huge healthcheck backlog
5. These activations ultimately timeout, which results in the host unresponsive.
6. Then more healthchecks are completed from the backlog and back to healthy.
7. Sends more activations. Controller flaps the invoker between unresponsive and healthy until the backlog completes.

The easiest solution I thought for this would be to just when the invoker consumes an activation from kafka and it is a healthcheck to drop the message if it is older than a few minutes. This should be fine since once the controller views it as unhealthy or unresponsive, it sends a new healthcheck once a minute. The one potential issue with this is time drift. If the controller internal clock is behind the invoker by more than the threshold, than the invoker will drop every healthcheck and never become healthy. This might be edge casey enough though that we don't care.

As to why things are no longer being read off kafka, I'm not sure yet. I think there might be some edge case bugs with container management in the ContainerPool and ContainerProxy fsm logic. My theory is that there is a dead lock with requesting more activation messages from the feed when the invoker is under heavy load.

I have my eyes on this commit right now when the `processBufferOrFeed` function was introduced for reading messages from the feed since it's somewhat recent; looking for something, but haven't been able to identify anything yet. I'll update this issue as I find anything of concern in the code.

https://github.com/apache/openwhisk/commit/a7482ca22694eee9b578c1003cd2c847953273e8

Contributor guide

Open the contributing guide

Research direction

Start with the processBufferOrFeed function introduced in commit a7482ca22694eee9b578c1003cd2c847953273e8, then inspect the ContainerPool and ContainerProxy FSM logic. Reproduce the restart scenario with a healthcheck backlog and determine why feed messages stop being read under load. Done means stale healthchecks cannot make the controller flap the invoker or send activations into a backlog.

Written by the indexing model from the issue text.

Assessment

Tech stack
kafka, scala
Domain
backend, distributed-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.