5.5 Configuration management
That parenthetical is the interesting bit: check more often than retention, because if the topic silently reverted to delete-retention, you want to notice before your data ages ou…
Altering configs
- 4
- overrides kept
- 0
- reset to default
Only the named configs change. incrementalAlterConfigs takes SET / DELETE / APPEND operations per key, so existing overrides survive. Use this one; the legacy call is a trap in any cluster you did not configure entirely yourself.
Config resources come in three types:
ConfigResource.Type.BROKERConfigResource.Type.BROKER_LOGGERConfigResource.Type.TOPIC
"Checking and modifying broker and broker logging configuration is typically done using tools like
kafka-config.shor other Kafka management tools, but checking and updating TOPIC configuration from the applications that use them is quite common."
The motivating self-healing pattern:
"many applications rely on compacted topics for correct operation. It makes sense that periodically (more frequently than the default retention period, just to be safe), those applications will check that the topic is indeed compacted and take action to correct the topic configuration if it is not."
That parenthetical is the interesting bit: check more often than retention, because if the topic silently reverted to delete-retention, you want to notice before your data ages out.
ConfigResource configResource =
new ConfigResource(ConfigResource.Type.TOPIC, TOPIC_NAME); // ①
DescribeConfigsResult configsResult =
admin.describeConfigs(Collections.singleton(configResource));
Config configs = configsResult.all().get().get(configResource); // ②
// print nondefault configs
configs.entries().stream().filter(
entry -> !entry.isDefault()).forEach(System.out::println);
// Check if topic is compacted
ConfigEntry compaction = new ConfigEntry(TopicConfig.CLEANUP_POLICY_CONFIG,
TopicConfig.CLEANUP_POLICY_COMPACT);
if (!configs.entries().contains(compaction)) {
// if topic is not compacted, compact it
Collection<AlterConfigOp> configOp = new ArrayList<AlterConfigOp>();
configOp.add(new AlterConfigOp(compaction, AlterConfigOp.OpType.SET)); // ③
Map<ConfigResource, Collection<AlterConfigOp>> alterConf = new HashMap<>();
alterConf.put(configResource, configOp);
admin.incrementalAlterConfigs(alterConf).all().get();
} else {
System.out.println("Topic " + TOPIC_NAME + " is compacted topic");
}① "You can specify multiple different resources from different types in the same request."
② Result is "a map from each ConfigResource to a collection of configurations."
isDefault() — subtler than it looks
"Each configuration entry has an
isDefault()method that lets us know which configs were modified. A topic configuration is considered nondefault if a user configured the topic to have a nondefault value, OR if a BROKER-LEVEL configuration was modified and the topic that was created inherited this nondefault value from the broker."
isDefault() == false means either:
- someone set it explicitly on this topic, or
- the broker default was changed and this topic inherited it
So “nondefault” ≠ “topic-level override”. Don't conflate them.
③ The four AlterConfigOp.OpType operations
| OpType | Effect |
|---|---|
SET | Sets the configuration value |
DELETE | Removes the value and resets to the default |
APPEND | "apply only to configurations with a List type" — add values without sending the entire list |
SUBTRACT | Same, for removal |
APPEND/SUBTRACT exist to avoid read-modify-write races on list configs (a lost-update hazard if two operators edit the same list simultaneously).
💡 The war story — why describeConfigs is an SRE tool
"Describing the configuration can be surprisingly handy in an emergency. We remember a time when during an upgrade, the configuration file for the brokers was accidentally replaced with a broken copy. This was discovered after restarting the first broker and noticing that it failed to start. The team did not have a way to recover the original, and we prepared for significant trial and error as we attempted to reconstruct the correct configuration and bring the broker back to life. A site reliability engineer (SRE) saved the day by connecting to one of the remaining brokers and dumping its configuration using the AdminClient."
The generalizable lesson: a running broker is a live, authoritative backup of its own configuration. If you have one surviving node, you have your config — but only if you know this API exists before the incident.
5.4 Essential topic management
① describeTopics() with a list of names → DescribeTopicsResult, "which wraps a map of topic names to Future descriptions."
5.6 Consumer group management
valid() is the right choice for tooling that must degrade gracefully; all() is the right choice when partial results would be misleading.