Configurable kafka producer parameters - #2789
Conversation
Hello sylvainsenechal,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (75.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files
@@ Coverage Diff @@
## development/9.5 #2789 +/- ##
================================================
Coverage 75.43% 75.43%
================================================
Files 201 201
Lines 13928 13929 +1
================================================
+ Hits 10507 10508 +1
Misses 3411 3411
Partials 10 10
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
c772858 to
38ef032
Compare
| site: joi.string(), | ||
| compressionType: joi.string().default(KAFKA_PRODUCER_DEFAULT_COMPRESSION_TYPE), | ||
| requiredAcks: joi.number().default(KAFKA_PRODUCER_DEFAULT_REQUIRED_ACKS), | ||
| producerParams: joi.object().unknown(true).default({}), |
There was a problem hiding this comment.
kafka.producerParams is added to the global config, but only IngestionPopulator._setupProducer forwards it when creating a BackbeatProducer. Other producer call sites (LogReader._setupProducer, LifecycleQueuePopulator._setupProducer, BackbeatConsumer, GarbageCollectorProducer, etc.) pass compressionType/requiredAcks/maxRequestSize from kafkaConfig but skip producerParams — so the global setting silently has no effect on them.
Either forward producerParams in the other _setupProducer methods too, or move this config under extensions.ingestion only to avoid the misleading global scope.
There was a problem hiding this comment.
This is intentional, the objective is to have config that will later be extensible
There was a problem hiding this comment.
That's a good call from claude, should we define config per producer type or having a global one. What do you mean by extensible ?
There was a problem hiding this comment.
The idea is we have
kafka.producerParams
extensions.ingestion.producerParams
extensions override the first one when provided. But for now we only have extension for ingestion, and aren't gonna bother doing it for all backbeat extensions.
I think its fine as is, but yeah eventually we should update all other backbeat extension to use this global kafka params, else its a bit weird @francoisferrand
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
|
There was a problem hiding this comment.
Pull request overview
This PR extends Backbeat’s Kafka producer configuration to support additional, user-defined librdkafka producer parameters, enabling more flexible tuning (e.g., buffering settings) via Backbeat’s global config and the ingestion extension config.
Changes:
- Add
producerParamssupport toBackbeatProducerconfig validation and include it in the generatedproducerConfig(while keeping built-in critical params authoritative). - Merge global
kafka.producerParamswith ingestion extensionproducerParamsinIngestionPopulator(extension overrides global). - Extend Joi schemas and add unit tests covering both
BackbeatProducerbehavior and ingestion merge semantics.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/ingestion/IngestionPopulator.js | Adds unit tests verifying merge/override behavior for global vs ingestion producerParams. |
| tests/unit/backbeatProducer.js | Adds unit tests verifying producerParams inclusion and protection of built-in producer config keys. |
| lib/queuePopulator/IngestionPopulator.js | Merges global and ingestion producer params when constructing the ingestion producer. |
| lib/config.joi.js | Adds kafka.producerParams to the main Backbeat config schema (default {}). |
| lib/BackbeatProducer.js | Accepts producerParams, stores them, and includes them in producerConfig. |
| extensions/ingestion/IngestionConfigValidator.js | Adds producerParams to ingestion extension config schema (default {}). |
| processor: joi.object({ | ||
| circuitBreaker: joi.object().optional(), | ||
| }).optional(), | ||
| producerParams: joi.object().unknown(true).default({}), |
There was a problem hiding this comment.
Why should we accept unknown ? Here we don't really define them neither validate them, why ? We should define what is behind object ?
There was a problem hiding this comment.
there are dozens of potentials parameters here : https://docs.confluent.io/platform/current/clients/librdkafka/html/md_CONFIGURATION.html
So we went with this to not have to enumerate all, we are only using one or two for now, but wanna be able to use more without having to do another backbeat pr
Honestly debatable though, an ai could write down instantly the ~50 different params available 🤔
There was a problem hiding this comment.
@francoisferrand Should we enumerate all params, or enumerate only the ones we use now, or keep it that way.
| producerParams: joi.object().unknown(true).default({}), | |
| producerParams: joi.object({ | |
| 'queue.buffering.max.kbytes': joi.number().optional(), | |
| 'queue.buffering.max.messages': joi.number().optional(), | |
| }).optional().default({}), |
There was a problem hiding this comment.
No enumerate all of them. We use only a few, and we can use only a few. So just them should be enough. The goal of Joi is to validate, here we just skip it. Also we can make sure for example that we don't insert critical one (I remember the host later that is skipped for example).
| requiredAcks: this.kafkaConfig.requiredAcks, | ||
| producerParams: { | ||
| ...this.kafkaConfig.producerParams, | ||
| ...this.ingestionConfig.producerParams, // Extension params override global params |
There was a problem hiding this comment.
| ...this.ingestionConfig.producerParams, // Extension params override global params | |
| ...this.ingestionConfig.producerParams, |
There was a problem hiding this comment.
I wanna keep this one, i know its more obvious for you but not for me 🧐
There was a problem hiding this comment.
🤝 let's go then. You just describe the code but why not
| maxRequestSize: joi.number().default(KAFKA_PRODUCER_MESSAGE_MAX_BYTES), | ||
| compressionType: joi.string().default(KAFKA_PRODUCER_DEFAULT_COMPRESSION_TYPE), | ||
| requiredAcks: joi.number().default(KAFKA_PRODUCER_DEFAULT_REQUIRED_ACKS), | ||
| producerParams: joi.object().unknown(true).default({}), |
There was a problem hiding this comment.
Same here, we should define them ? Maybe also factorise them between both (three with kafka params?)?
There was a problem hiding this comment.
discussion ongoing in the other topic
| site: joi.string(), | ||
| compressionType: joi.string().default(KAFKA_PRODUCER_DEFAULT_COMPRESSION_TYPE), | ||
| requiredAcks: joi.number().default(KAFKA_PRODUCER_DEFAULT_REQUIRED_ACKS), | ||
| producerParams: joi.object().unknown(true).default({}), |
There was a problem hiding this comment.
That's a good call from claude, should we define config per producer type or having a global one. What do you mean by extensible ?
| assert.strictEqual(config['queue.buffering.max.messages'], 200000); | ||
| }); | ||
|
|
||
| it('should not let producerParams override critical built-in params', () => { |
There was a problem hiding this comment.
Should it be rejected by joi directly by disallow some keys ?
There was a problem hiding this comment.
Let's rediscuss after we've finalized joi config, some ongoing discussion on it
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
The following reviewers are expecting changes from the author, or must review again: |
DarkIsDude
left a comment
There was a problem hiding this comment.
Keeping request changes. Waiting for Joi decision to finish the review 🙏
Issue: BB-685
Related Zenko Operator : https://github.com/scality/zenko-operator/pull/625