In the introduction to this series, I discussed some of the motivation for rewriting .NET SDK, the goals, objectives and the major features of the upcoming 2.0 release, and we examined the high-level architecture (10000 feet view) of a Couchbase Server Client SDK. In this post we will go over the design and development of one of the core configuration components of a Couchbase SDK: Server Configuration.

Introduction

A Couchbase SDK client requires configuration from two sources: the Client Configuration, which defines the IP of the cluster to connect to, number of connections to use and other important information regarding how the client will interact with the cluster and the Server Configuration, which defines the current state of the cluster (e.g. number of nodes, buckets that are available, etc.), thus driving the internal state of a client (Cluster Map)

This post will only discuss the Server Configuration aspects and will largely revolve around implementing several well-defined interfaces or contracts.

HTTP Streaming Configuration

Currently, most clients use a “bootstrapping” technique via client configuration and a “Streaming Configuration” exposed by the Couchbase REST API. This is supported by versions of Couchbase from 2.2 and back. The usual approach is as follows:

  1. Within the “uris” element of a Client Configuration (semantics very per client), a URL is defined for which to start the bootstrapping process:
    http://[SERVER]:8091/pools
  2. The response is then parsed and the a request is made to get the buckets configuration:
    http://[SERVER]:8091/pools/default?uuid=[UUID]
  3. This response is parsed and another request is made to get streaming URL from:
    http://[SERVER]:8091/pools/default/buckets?v=[VERSION]&uuid=[UUID]
  4. Finally, the streaming URL connection is made which is long-lived and raises events in the client with respect to changes in the cluster:
    http://[SERVER]:8091/pools/default/bucketsStreaming/default?bucket_uuid=[UUID]
  5. The client will then change its internal state to match that of the current server configuration.

There are some problems with this approach, among others:

  • The “streaming URL” is resource intensive to create and maintain (mainly memory) on the server-side
  • During a rebalance or failover situation, the cluster configuration may change many, many times. Each time this happens the client must tear down all of its resources (socket connections, VBucket mappings) and build its state up again and again, which can leads to reduced throughput, latency, higher than expected memory and CPU usage, and so on and so forth…
  • Operations that are in-flight may be terminated and then re-tried on a new config state – it’s as if the “carpet has been pulled out from underneath them”.
  • Responding to NOT_MY_VBUCKET responses are handled in-efficiently by simple trying the next node in the list – there is no information to help the client in which node to re-direct the operation to.

A New Model for Configuration Management: CCCP Optimized connection management

While the streaming HTTP “bootstrapping” approach has worked reasonably well for most clients, the downsides have begun to outweigh the plusses, thus a new model for updating client configuration has been defined is available starting with the 2.5 version of the Couchbase Server: Client Cluster Configuration Publication or “CCCP” Optimized connection management. CCCP  Optimized connection management introduces a new operation to be used before or after authentication to request configuration as well as a mechanism for returning configuration information when a NOT_MY_VBUCKET response is returned for a failed operation.

In this case CCCP Optimized connection management supporting SDK, the client will react by using the configuration to update itself before resending the operation. Note that a NOT_MY_VBUCKET is the standard response that is returned by the cluster when the cluster itself has changed (during a rebalance or failover scenario for example) and the client has not yet “synched” up and is using a stale configuration, resulting in an invalid key mapping. Whereas the “bootstrapping” approach is somewhat of a “pull” type operation, CCCP Optimized connection management is either “push” or “pull” depending upon whether the request was initiated by the client (via an explicit CMD_GET_CLUSTER_CONFIG operation) or by the server itself (via a NOT_MY_VBUCKET response to an operation). We will go over CCCP Optimized connection management in more detail in a later post.

*Edit: CCCP is now known as “Optimized connection management”

File Based Configuration

One other semi-supported configuration option exists: file based configuration. File based configuration is primarily useful for testing and development and we will provide an implementation in the test projects to remove some of the dependencies that are difficult to replicate and or cause false positives when running the test suite.

Structural Architecture View

Internally the Server Configuration component of the client is a provider based model, in which multiple implementations of a configuration provider can be configured in the client and then a strategy can be chosen to determine which provider should be used. The default is a simple linear, fallback approach where the first configured provider is used and then if it fails the next provider in sequence will take its place.

Here is a diagram showing the main actor objects and the relationships with some of other key objects within the client which will be discussed in subsequent posts:

A description of each follows:

  • ConfigurationProvider: a source which shall yield a new ConfigInfo. It’s the responsibility of the provider to provide the mechanism for fetching the configuration from its source.
  • ConfigurationInformation: the configuration info contains a list of possible nodes and the VBucket map informing clients about which servers within said nodes a given key should be forwarded to.
  • ConfigurationManager: bridge between the client and the providers and the strategy taken to determine which provider to use and what retry logic to apply.

A more detailed document of this architecture can be found here. Please note that this, like all development, is an evolutionary process, so expect some changes and revisions over time.

Conclusion and Next Steps

This post discussed the history (HTTP Streaming) and the future (CCCP Optimized connection management) of Couchbase SDK Server Configuration Management. In the next post we will go into detail the implementation of the HTTP Streaming configuration provider which is required for clients targeting pre-2.5 versions of the Couchbase Server.

Author

Posted by Jeff Morris, Senior Software Engineer, Couchbase

Jeff Morris is a Senior Software Engineer at Couchbase. Prior to joining Couchbase, Jeff spent six years at Source Interlink as an Enterprise Web Architect. Jeff is responsible for the development of Couchbase SDKs and how to integrate with N1QL (query language).

2 Comments

  1. Hey Jeff,

    We are using .Net sdk 1.2 and want to get some advises from a real couchbase developer about how to write it in the best way.

    How can i contact you directly?

    1. Chen –

      You can reach me directly:
      IRC channel: #libcouchbase

      or via one of these methods:
      http://www.couchbase.com/commu

      or by creating an NCBC, if you have a specific issue (create an account):
      http://www.couchbase.com/issue

      I am bit hesitant post my email address (public Internet), but if you connect with me on linked-in, I\’ll send it to you privately.

      -Jeff

Leave a reply