Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

 

Status

Current stateUnder discussion and up for votingAccepted.

Discussion threadhere

Vote threadhere

JIRAKAFKA-3487

Released:  0.11.0.0

Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).

...

Kafka Connect is a highly extensible framework, designed to run software modules that integrate a wide variety of data sources and destinations with Kafka and, by definition, are developed independently of the framework. Examples of such software modules are connectorstransformations and data converters, which hereafter will be called plugins to honor Kafka Connect terminology. Because such independent development, dependency conflicts might arise naturally, between the framework and the modulesplugins, as well as among the modules plugin themselves. This happens when, for instance, one connector is using the latest version of a package that added a new feature, while another connector depends on a previous version of the same package where this feature is missing. 

...

The only publicly visible change that is proposed in order to implement class loading isolation in Kafka Connect is the addition of a new Connect worker config property:

This is a framework level configuration property that will affect all the connectors running within a Connect worker. 

The new configuration property moduleplugin.path will accept a list of locations, represented as strings and separated by commas. The strings representing locations should be able to be transformed into URLs in order to offer maximum flexibility in terms of module plugin discovery. Nevertheless, in the first implementation of class loading isolation such locations will be paths to the local filesystem, that, in turn, can be easily transformed into URLs. 

Examples of valid values for moduleplugin.path:

  • moduleplugin.path=/usr/local/share/java
  • moduleplugin.path=/usr/share/java, /usr/local/share/java, /opt/connectors

When a filesystem path is used as location for imported modules plugins (connectors, transformations and converters), the convention is that each module plugin is storing all its required dependencies in a single directory under each location path listed in moduleplugin.pathFor instance, if the location /usr/local/share/java is given in moduleplugin.path then modules plugins such as my-kafka-source-connectormy-kafka-sink-connectormy-connect-smt and my-converter should store all of their dependencies (usually in the form of jar files, but possibly as raw class files with the appropriate java package structure) under directories immediately below each moduleplugin.path entry as follows:

/usr/local/share/java

...

/my-converter/(converter jars and dependency jars)

A more nested storing of module plugin and dependency jars will not make them discoverable.

Again with moduleplugin.path set to /usr/local/share/java an incorrect example would be: 

 /usr/local/share/java

/more-modulesplugins/another-kafka-source-connector/(connector jars and dependency jars)

In this case, in order to make this module plugin discoverable,  /usr/local/share/java/more-modulesplugins should be added to moduleplugin.path instead.

Additionally, specifically regarding Connect modulesplugins, each connector, transformation or converter jar should be listed only once across the module plugin path. If multiple copies of the same version of modules plugins exist under moduleplugin.path the selection of which module plugin will be loaded will be deterministic but implementation specific.

While the introduction of the new configuration property moduleplugin.path is the only change proposed to the public interfaces of Kafka Connect, next are also described the main implementation steps that will be carried out within the framework to support class loading isolation.

Proposed Changes

Add moduleplugin.path configuration property for workers running both in standalone and distributed mode. By default moduleplugin.path is empty. In this case isolation is not active and loading of connectors depends on the CLASSPATH. In general, when a user wants to run a connector is isolation, its packages along with its dependencies should be stored under a directory that is listed in moduleplugin.pathOtherwise if non-isolated execution is desired, the connector jars should be listed in the CLASSPATH. 

Given that moduleplugin.path is set appropriately, the Connect framework will be able to instantiate a custom module plugin classloader for each module plugin under the list of locations supplied in the moduleplugin.pathThe main characteristics of such a module plugin classloader are that:

  • it delegates loading of Connect framework classes as well as java library classes to the appropriate classloader. Optionally, warnings could be issued when a module plugin path contains Connect framework classes.
  • it applies a child-first policy for the rest of the classes, aiming to load module plugin specific dependencies directly.

...

  • the Connect framework controls the threads that run module plugin code (e.g. connector tasks).
  • module plugin classes and dependencies are required to be supplied explicitly through moduleplugin.path.

Compatibility, Deprecation, and Migration Plan

  • Existing users will not be impacted since an non-existent/empty moduleplugin.path means that isolation is not in effect. 
  • Users enabling class loading isolation might experience higher demands in memory usage due to additional loading of otherwise common classes. However this increase is not expected to be prohibitive in most cases.

...

In a subsequent version of class loading isolation, the following enhancements will be targeted: 

  • Support versioned modulesplugins. Users will have the ability to load and run different versions of the same moduleplugin. Although connectors are versioned already, this capability needs to be enabled for transformations and converters as well. 
  • Extend moduleplugin.path to support module plugin locations beyond the local filesystem. Such locations might include web addresses, packages repositories (e.g. maven repositories) and other locations. 

...