Kafka系列之:连接器客户端配置覆盖策略

Kafka系列之:连接器客户端配置覆盖策略

  • 一、背景
  • 二、公共接口
  • 三、推荐的改动
  • 四、兼容性、弃用和迁移计划

一、背景

KAFKA引入了每个源连接器和接收器连接器从工作线程属性继承其客户端配置的功能。在工作线程属性中,任何具有“生产者”或“消费者”前缀的配置。分别应用于所有源连接器和接收器连接器。虽然最初的提案允许覆盖源连接器和接收器连接器,但它在允许连接器的不同配置方面仍然受到限制。通常,连接用户希望能够执行以下操作:-

  • 对于每个连接器使用不同的主体,以便它们可以在细粒度级别控制 ACL
  • 能够优化每个连接器的生产者和消费者配置,以便根据其性能特征设置连接器

KIP-296:客户端配置的连接器级别可配置性旨在通过允许覆盖所有配置来解决此问题。但 KIP 不提供连接操作员控制连接器可以覆盖的内容的能力。如果没有这种能力,连接器和工作人员之间将不会有清晰的分隔线,因为连接器本身现在可以假设覆盖可用。但从操作角度来看,最好执行以下规定。

  • 能够控制可以覆盖的配置键。例如管理员可能永远不希望代理端点被覆盖
  • 能够控制被覆盖的配置的允许值。这有助于管理员定义其集群的边界并有效地管理多租户集群。管理员可能永远不希望“send.buffer.bytes”超过 512 kb
  • 能够根据连接器类型、客户端类型(管理员、生产者、消费者)等控制上述内容。

基于上述上下文,该提案允许管理员围绕可以覆盖的内容定义/实施策略,与“CreateTopicPolicy”非常相似,“CreateTopicPolicy”允许和控制在主题级别指定的配置。

二、公共接口

在较高层面上,该提案旨在引入类似于 Core Kafka 中可用的 CreateTopicPolicy 的可配置策略,用于连接器客户端配置覆盖。更具体地说,我们将引入一个新的工作配置,该配置将允许管理员配置连接器客户端配置覆盖的策略。

新配置

Connector.client.config.override.policy - 这将是连接 API 中引入的新接口 ConnectorClientConfigOverridePolicy 的实现。默认值为“None”,不允许任何覆盖。由于用户已经使用建议的前缀进行配置的可能性非常小,因此向后兼容性通常不是问题。在极少数情况下,用户在现有配置中拥有这些配置,他们必须删除配置才能使其再次工作。

可以使用以下前缀在连接器配置中指定覆盖

  • Producer.override. - 用于 SinkConnector 上下文中的源连接器的生产者和 DLQ 生产者
  • consumer.override. - 用于接收器连接器
  • admin.override. - 用于在 Sink Connector 中创建 DLQ 主题(KIP 还允许使用 admin 前缀在工作线程中指定 DLQ 设置,以便与生产者和消费者保持一致)

管理员可以指定 ConnectorClientConfigOverridePolicy 实现的完全限定类名或别名(别名被计算为接口名称“ConnectorClientConfigOverridePolicy”的前缀,这正是大多数现有连接插件计算其别名的方式)。

新接口将被视为新的连接插件,并将通过插件路径机制加载。这些插件将通过类似于 RestExtension 和 ConfigProvider 的服务加载器机制来发现。新接口的结构及其请求描述如下:-

import org.apache.kafka.common.config.ConfigValue;
 
/**
 * 

An interface for enforcing a policy on overriding of client configs via the connector configs. * *

Common use cases are ability to provide principal per connector, sasl.jaas.config * and/or enforcing that the producer/consumer configurations for optimizations are within acceptable ranges. */ public interface ConnectorClientConfigOverridePolicy extends Configurable, AutoCloseable { /** * Worker will invoke this while constructing the producer for the SourceConnectors, DLQ for SinkConnectors and the consumer for the * SinkConnectors to validate if all of the overridden client configurations are allowed per the * policy implementation. This would also be invoked during the validate of connector configs via the Rest API. * * If there are any policy violations, the connector will not be started. * * @param connectorClientConfigRequest an instance of {@code ConnectorClientConfigRequest} that provides the configs to overridden and * its context; never {@code null} * @return List of Config, each Config should indicate if they are allowed via {@link ConfigValue#errorMessages} */ List<ConfigValue> validate(ConnectorClientConfigRequest connectorClientConfigRequest); }

public class ConnectorClientConfigRequest {
 
    private Map<String, Object> clientProps;
    private ClientType  clientType;
    private String connectorName;
    private ConnectorType connectorType;
    private Class<? extends Connector> connectorClass;
 
    public ConnectorClientConfigRequest(
        String connectorName,
        ConnectorType connectorType,
        Class<? extends Connector> connectorClass,
        Map<String, Object> clientProps,
        ClientType clientType) {
        this.clientProps = clientProps;
        this.clientType = clientType;
        this.connectorName = connectorName;
        this.connectorType = connectorType;
        this.connectorClass = connectorClass;
    }
 
    /**
     * 
     * Provides Config with prefix {@code producer.override.} for {@link ConnectorType#SOURCE}.
     * Provides Config with prefix {@code consumer.override.} for {@link ConnectorType#SINK}.
     * Provides Config with prefix {@code producer.override.} for {@link ConnectorType#SINK} for DLQ.
     * Provides Config with prefix {@code admin.override.} for {@link ConnectorType#SINK} for DLQ.
     * 
* * @return The client properties specified in the Connector Config with prefix {@code producer.override.} , * {@code consumer.override.} and {@code admin.override.}. The configs returned don't include these prefixes. */
public Map<String, Object> clientProps() { return clientProps; } /** *
     * {@link ClientType#PRODUCER} for {@link ConnectorType#SOURCE}
     * {@link ClientType#CONSUMER} for {@link ConnectorType#SINK}
     * {@link ClientType#PRODUCER} for DLQ in {@link ConnectorType#SINK}
     * {@link ClientType#ADMIN} for DLQ  Topic Creation in {@link ConnectorType#SINK}
     * 
* * @return enumeration specifying the client type that is being overriden by the worker; never null. */
public ClientType clientType() { return clientType; } /** * Name of the connector specified in the connector config. * * @return name of the connector; never null. */ public String connectorName() { return connectorName; } /** * Type of the Connector. * * @return enumeration specifying the type of the connector {@link ConnectorType#SINK} or {@link ConnectorType#SOURCE}. */ public ConnectorType connectorType() { return connectorType; } /** * The class of the Connector. * * @return the class of the Connector being created; never null */ public Class<? extends Connector> connectorClass() { return connectorClass; } public enum ClientType { PRODUCER, CONSUMER, ADMIN; } }

KIP 引入了 ConnectorClientConfigOverridePolicy 的以下实现,如下表所示

类名 别名 描述
AllConnectorClientConfigOverridePolicy All 允许覆盖生产者、消费者和管理员前缀的所有配置。
NoneConnectorClientConfigOverridePolicy None 不允许任何配置覆盖。这将是默认策略。
PrincipalConnectorClientConfigOverridePolicy Principal 允许覆盖生产者、消费者和管理员前缀的“security.protocol”、“sasl.jaas.config”和“sasl.mechanism”。能够为每个连接器使用不同的主体。

由于用户可以指定任何这些策略,因此连接器本身不应依赖于这些配置的可用性。这些覆盖纯粹是从操作角度使用的。

当用户尝试创建连接器或验证连接器时,将强制执行策略本身。当任何 ConfigValue 有错误消息时

  • 验证期间,响应将包含错误,并且不符合策略的特定配置也会包含响应中包含的错误消息
  • 在创建/更新连接器期间,连接器将无法启动

三、推荐的改动

如上一节所述,设计将包括引入新的工作配置和定义覆盖策略的接口。

工作人员将在创建连接器流程期间应用该策略,如下所示。被覆盖的配置将在没有策略前缀的情况下传递:-

  • 为 WorkerSourceTask 构建生产者 - 使用“ Producer.override ”调用所有配置的验证。 prefix , ClientType=Producer, ConnectorType=Source 并覆盖(如果没有违反策略)

  • 为 DLQ 主题构建 DeadLetterQueueReporter 的管理客户端和生产者

    • 使用“ Producer.override ”调用所有配置的验证。 prefix , ClientType=Producer, ConnectorType=Sink 并覆盖(如果没有违反策略)
    • 使用“admin.override”调用所有配置的验证。 prefix , ClientType=Admin, ConnectorType=Sink 并覆盖(如果没有违反策略)
  • 为 WorkerSinkTask 构建 Consumer - 使用“consumer.override”调用所有配置的验证。 prefix , ClientType=Consumer, ConnectorType=Sink 并覆盖(如果没有违反策略)

在 validate() 流程中,herder(AbstractHerder) 将按如下所示对所有覆盖应用该策略。被覆盖的配置将在没有前缀的情况下传递:-

  • 如果它是源连接器,请在每个带有“生产者”的连接器配置上应用策略。添加前缀并更新 ConfigInfos 结果(验证 API 的响应)
  • 如果是水槽连接器,将策略应用到每个带有“consumer”的连接器配置上。添加前缀并更新 ConfigInfos 结果(验证 API 的响应)
  • 使用“admin”在每个连接器配置上应用该策略。启用 DLQ 时添加前缀并更新 ConfigInfos 结果(验证 API 的响应)

四、兼容性、弃用和迁移计划

有人拥有带有建议前缀的连接器的可能性非常小,因此向后兼容性并不是真正的问题。在极少数情况下,如果用户具有带有这些前缀的配置,他们必须删除配置或更改策略才能使其正常工作。

你可能感兴趣的:(日常分享专栏,Kafka系列,连接器客户端配置覆盖策略)