Versions Compared

Key

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

...

  1. The default value of Linux  tcp_syn_retries is 6. It means the default timeout value is 127 seconds and too long in some scenarios. For  
  2. Currently, the leastLoadedNode() provides a cached node with the criteria below. 

    1. Provide the connected node with least number of inflight requests
    2. If no connected node exists, provide the connecting node with the largest index in the cached list of nodes.
    3. If no connected or connecting node exists, provide the disconnected node which respects the reconnect backoff with the largest index in the cached list of nodes.

A node will remain the "connecting" status until the system timeout and close the socket, even if the requests binding to this node timed out. So the leastLoadedNode() might keep providing this same node and other nodes won't get a chance to process any requests. For example, when the user specifies a list of N bootstrap-servers and no connection has been built between the client and the servers, the least loaded node provider will poll all the server nodes specified by the user. If M servers in the bootstrap-servers list are offline, the client may take (127 * M) seconds to connect to the cluster. In the worst case when M = N - 1, the wait time can be several minutes

...

Currently, the leastLoadedNode() provides a cached node with the criteria below. 

...

.

...

    If we do not 

Public Interfaces

We propose a new common client config

connections.setup.timeout.ms: The configuration controls the maximum amount of time the client will wait for the initial socket connection to be built. If the connection is not built before the timeout elapses the network client will close the socket channel. The default value will be 10 seconds.


Proposed Changes

The new config will be a common client config. The NetworkClient will keep the config as a property.

I'm proposing to do a lazy socket connection time out. That is, we the NetworkClient will only check if we need to timeout a socket when we consider the corresponding node as a candidate in the node provider.

NetworkClient

public Node leastLoadedNode(long now)

and disconnect timeout connections in leastLoadedNode(). 

  1. NetworkClient only cares about timing out the connecting node when it needs to send new requests. 
  2. NodeProviders other than LeastLoadedNodeProvider are specifying which node to connect. The connection status changes should be done at the upper level. 

The node providing criteria 3 in the least LoadedNode() will also change since

  1. Provide the connected node with least number of inflight requests
  2. If no connected node exists, provide the connecting
  3. This function iterates over all cached nodes and provides a node for the AdminClient to send the request. We can add our timeout checking logic inside the iteration, which won't downgrade the performance. If the connection establishment timeout hits, the connection state will change to DISCONNECTED
  4. Currently, when no active connection exists, the provider will provide the node with the largest index in the node cached list of nodes.
  5. If no connected or connecting node exists, provide the disconnected node which respects the reconnect backoff with the least number of failed attempts. Consider by qualifying nodes using canConnect(), which is checking if the connection state is DISCONNECTED and if the reconnect backoff is meet. This is not appropriate because we need to poll every node (probably round-robin). Consider the case when we have multiple DISCONNECTED nodes and the time interval between the two provide() invokes is greater than reconnect.backoff.ms. The Provider can provide the same nodes all the time. Thus, the provider should provide the nodes with the least failed attempts among all nodes passing the canConnect() check.

Compatibility, Deprecation, and Migration Plan

...