Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Scalable slice queries for many consumers #31957

Merged
merged 23 commits into from
Jun 14, 2023

Conversation

patriknw
Copy link
Member

@patriknw patriknw commented Jun 2, 2023

No description provided.


final class SlowConsumerException(message: String) extends RuntimeException(message) with NoStackTrace

final case class FirehoseKey(pluginId: String, entityType: String, sliceRange: Range)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intend to create a follow up ticket about colocating shards. So when several projections are started with ShardedDaemonProcess they would try to allocate slice ranges to the same nodes, so that firehose for a slice range is not started in more places than necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was #31967

Copy link
Member

@johanandren johanandren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good so far (also reviewed several rounds in the original PR).

Copy link
Member

@octonato octonato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a first pass last Friday. I have a bunch of questions but need to re-review and refine them.

I'm leaving a nitpick formatting suggestion though. 😄

Copy link
Member

@octonato octonato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking really good.

Leaving some comments already.
I want to do a second pass to review more in detail the slow consumer detection.

Comment on lines +212 to +241
else if (diffFastest < 0) s"ahead of fastest [$diffFastest] ms" // not possible
else "same as fastest"
val diffSlowest = slowestConsumer.offsetTimestamp.toEpochMilli - tracking.offsetTimestamp.toEpochMilli
val diffSlowestStr =
if (diffSlowest > 0) s"behind slowest [$diffSlowest] ms" // not possible
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it's not possible, but what if we have a bug and it shows up in logs. Wouldn't that be confusing?

Shall we log something else or fail the stream?

Copy link
Member

@octonato octonato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm finding it a really cool feature.

Copy link
Member

@johanandren johanandren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More detailed review of the slow-consumer-detection.

if (existing.history.size <= settings.broadcastBufferSize)
existing.history :+ offset
else
existing.history.tail :+ offset // drop one, add one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expensive ops with vector tail + append for each element, is there a better data structure we could use, some form of queue?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think tail is that bad, still listed as eC. Scala immutable Queue is probably faster for this, but then we also use size, which is not good for Queue since it's delegating to the underlying Lists.

I think I'll leave it as Vector for now.

val slowestConsumer = trackingValues.minBy(_.offsetTimestamp)
val fastestConsumer = trackingValues.maxBy(_.offsetTimestamp)

val behind = elementsBehind(fastestConsumer.history, slowestConsumer.history)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, the slowest consumer will hold back the fastest so that it should always have the timestamp of the slower in its history, because we keep as long offset history as the size of the buffer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. Not great to have to keep the history for each consumer but I couldn't think of another way. It's just small objects, and probably held in memory by other things.

There is a case when the fastest is a new consumer and then it wouldn't have the full history yet. Then it keeps going.

patriknw and others added 17 commits June 12, 2023 16:00
* it's also possible to have more than one events-by-slice-firehose,
  each can have it's own underlying plugin, and creating its own Firehose
  instance
Co-authored-by: Francisco Lopez-Sancho <franciscolopezsancho@gmail.com>
Co-authored-by: Renato Cavalcanti <renato@cavalcanti.be>
Co-authored-by: Renato Cavalcanti <renato@cavalcanti.be>
Co-authored-by: Johan Andrén <johan@markatta.com>
@patriknw patriknw force-pushed the wip-firehose-queries-patriknw branch from 96acc5c to 338edcb Compare June 12, 2023 14:56
Copy link
Member

@johanandren johanandren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, great work @patriknw

@patriknw patriknw merged commit 362ab93 into main Jun 14, 2023
@patriknw patriknw deleted the wip-firehose-queries-patriknw branch June 14, 2023 14:48
@patriknw patriknw added this to the 2.8.3 milestone Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants