Managing Clusters Using the PHP SDK with Couchbase Server

This section covers the convenience functionality in the Couchbase PHP SDK for managing buckets, managing indexes used by N1QL and managing views.

The primary means for managing clusters is through the Couchbase Web UI which provides an easy to use interface for adding, removing, monitoring and modifying buckets. In some instances you may wish to have a programmatic interface. For example, if you wish to manage a cluster from a setup script, or if you are setting up buckets in test scaffolding.

The PHP SDK also comes with some convenience functionality for common Couchbase management requests.

Management operations in the PHP SDK may be performed through several interfaces depending on the object. There are two to consider:

  • The CouchbaseClusterManager class (obtained via CouchbaseCluster#manager(string $username, string $password) passing administrative user name and password)

  • The CouchbaseBucketManager class (obtained via CouchbaseBucket#manager()).

Getting Information About the Cluster

When you call CouchbaseClusterManager#info() it returns a mixed object that contains information on the overall cluster state.

$cluster = new CouchbaseCluster('couchbase://localhost');
$manager = $cluster->manager('Administrator', 'password');
$info = $manager->info();
printf("cluster has %d nodes, %d buckets and %d megabytes used\n",
       count($info['nodes']), count($info['buckets']),
       $info['storageTotals']['ram']['usedByData'] / 1024 / 1024);

Output:

cluster has 1 nodes, 3 buckets and 105 megabytes used

Creating and Removing Buckets

The CouchbaseClusterManager class may be used to create and delete buckets from the Couchbase cluster. It is instantiated through the CouchbaseCluster's manager() method, providing the administrative user name and password.

$cluster = new CouchbaseCluster('couchbase://localhost');
$clusterManager = $cluster->manager('Administrator', 'password');

To create a bucket, use the CouchbaseClusterManager's createBucket(string $name, array $opts) method. The $opts array is used to provide the configuration of the new bucket, while the string is the name given to the bucket. These are the default configuration options:

array(
  'authType' => 'sasl',
  'bucketType' => 'couchbase',
  'ramQuotaMB' => 100,
  'replicaNumber' => 1
);
Note that any property that is not explicitly set when building the BucketSettings will use the default value. In the case of the update, this is not necessarily the currently configured value, so you should be careful to set all properties to their correct expected values when updating an existing bucket configuration.

Only the $name and $opts['bucketType'] parameters are mandatory for configuring a bucket. This list of parameters is recognized for the $opts array, corresponding to those available in the REST API:

  • name: The name of the bucket (actually taken from the $name method parameter, cannot be updated).

  • bucketType: The type of the bucket (mandatory to specify one, cannot be changed). Defaults to 'couchbase', but can also be 'memcached' to create a cache bucket.

  • ramQuotaMB: How much memory should each cluster node use for the bucket. This number is specified in megabytes, defaults to 100MB

  • saslPassword: If specified, makes this bucket password protected, forcing future connects (using the Bucket) to specify the password parameter. Must be used together with $opts['authType'] = 'sasl' (which is the default).

  • flushEnabled: Enables the CouchbaseBucketManager->flush() operation to be performed on this bucket .

  • replicaNumber: The number of replicas to use for the bucket, default to 1.

  • replicaIndex: Whether or not to replicate indexes.

The following example creates a "hello" bucket. Note how all parameters are set:

$bucketSettings = array(
  'bucketType' => 'couchbase',
  'ramQuotaMB' => 120,
  'saslPassword' => '',
  'flushEnabled' => true,
  'replicaNumber' => 1,
  'replicaIndex' => true
);

$manager = $cluster->manager('Administrator', 'password');
$manager->createBucket('hello', $bucketSettings);

Once you no longer need to use the bucket, you may delete the bucket using the CouchbaseClusterManager#removeBucket($name) method:

$cluster->removeBucket('hello');

N1QL Index Management

You can create and drop N1QL indexes using the SDK. This is especially useful when setting up new applications, or simply when ensuring that a given bucket has certain indexes defined. Indexes can be defined using actual N1QL statements or by using convenience functions within the SDK.

You can manage indexes in the PHP SDK using the CouchbaseBucketManager class, with its various N1QL related methods: listN1qlIndexes(), createN1qlIndex(...), etc...

The following example creates a N1QL secondary index named "fullName" on the "test" bucket, indexing fields "firstName" and "lastName" (Boolean flags as the last argument mean do not throw an error if the index with the same name already exists):

$cluster = new CouchbaseCluster('couchbase://localhost');
$bucket = $cluster->openBucket("test");
$manager = $bucket->manager();

$manager->createN1qlIndex("fullName", array("firstName", "lastName" ), '`state` = "active"',
                          true, false);

View Management

Views are stored in design documents. The SDK provides convenient methods to create, retrieve, and remove design documents. To set up views, you create design documents that contain one or more view definitions, and then insert the design documents into a bucket. Each view in a design document is represented by a name and a set of MapReduce functions. The mandatory map function describes how to select and transform the data from the bucket, and the optional reduce function describes how to aggregate the results.

In the PHP SDK, design documents and view definitions are represented by associative arrays. All operations on design documents are performed on a CouchbaseBucketManager instance.

To inspect design documents, you can either retrieve them by name ($bucketManager->getDesignDocument("landmarks");) or iterate through an array of documents ($bucketManager->getDesignDocuments();).

To create or update design documents, use the insertDesignDocument($name, $data) and upsertDesignDocument($name, $data) methods.

The following example inserts design documents with two regular views and one spatial view into a bucket named travel-sample:

// Initialize design document
$designDoc = array(
    'views' => array(
        'by_country' => array(
            'map' => "function (doc, meta) {
                        if (doc.type == 'landmark') {
                           emit([doc.country, doc.city], null);
                        }
                      }"
        ),
        'by_activity' => array(
            'map' => "function (doc, meta) {
                        if (doc.type == 'landmark') {
                          emit(doc.activity, null);
                        }
                      }",
            'reduce' => "_count"
        )
    )
);

// Insert design document into the bucket, as "landmarks"
$manager->insertDesignDocument('landmarks', $designDoc);

$designDoc = array(
    'spatial' => array(
        'by_coordinates' => "function (doc, meta) {
                               if (doc.type == 'landmark') {
                                 emit([doc.geo.lon, doc.geo.lat], null);
                               }
                             }"
    )
);
$manager->insertDesignDocument('landmarks_spatial', $designDoc);

When you want to update an existing document with a new view (or a modification of a view’s definition), you can use the upsertDesignDocument method.

However, this method needs the list of views in the document to be exhaustive, meaning that if you just create the new view definition as previously and add it to a new DesignDocument that you upsert, all your other views will be erased!

The solution is to perform a getDesignDocument, add your view definition to the DesignDocument’s views list, then upsert it. This also works with view modifications, provided the change is in the map or reduce functions (just reuse the same name for the modified View), or for deletion of one out of several views in the document.

// Get design document to be updated
$designDoc = $manager->getDesignDocument('landmarks');

// Update the "by_country" view, adding a reduce
$designDoc['views']['by_country'] += array('reduce' => "_count"); //added reduce function

// Resend to server
$bucketManager->upsertDesignDocument($designName, $designDoc);

To remove a design document from a bucket, call the removeDesignDocument method with the name of the design document.

Configuration Cache File

The legacy client configuration cache file records the current cluster configuration, which Couchbase Server uses at startup.

Client applications use libcouchbase to connect to Couchbase Server. By means of libcouchbase, the client can react to changes in cluster-topology. Whenever the client is started, libcouchbase is instantiated, and checks the local filesystem for a configuration cache file, containing information on the cluster-toplogy. If no such file exists, libcouchbase connects to the cluster by means of a REST method, in order to receive the latest topology details. Once acquired, these details are written to the configuration cache file, locally.

Subsequently, when starting, the client uses the local configuration cache file to acquire its topology data. If at any time, when using this data, the client attempts to access a data item on a node, and is informed by Couchbase Server that the node is incorrect (due to the cluster configuration having changed), the current configuration cache file is duly invalidated. The client then requests an updated set of toplogy details from Couchbase Server; which are themselves then saved locally by the client, as a new configuration cache file.

Use of the configuration cache-file is available only through PHP (not through Java or .NET), Node.js, and Python. Therefore, to use the cache file, add the following to the php.ini:

couchbase.config_cache = /tmp