Okay let me describe what you can do with PHP SDK now
Lets say that you have /etc/hosts
record like this
127.0.0.1 localhost localhost0 localhost1 localhost2 localhost3 localhost4 localhost5 localhost6 localhost7 localhost8 localhost9
By default PHP will cache and reuse bucket connections with the same connection strings. So compare two following examples:
for ($i = 0; $i < 10; $i++) {
$cluster = new CouchbaseCluster("couchbase://localhost1");
$bucket = $cluster->openBucket('travel-sample');
$bucket->upsert('foo', 'bar');
}
$ strace -e trace=connect php test.php
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(3, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
+++ exited with 0 +++
Here we can see single network socket with id 3
. And when connecting to localhost using different aliases
for ($i = 0; $i < 10; $i++) {
$cluster = new CouchbaseCluster("couchbase://localhost" . $i);
$bucket = $cluster->openBucket('travel-sample');
$bucket->upsert('foo', 'bar');
}
$ strace -e trace=connect php test.php
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(3, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(4, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(5, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(5, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(6, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(6, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(7, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(7, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(8, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(8, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(9, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(9, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(9, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(10, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(10, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(11, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(11, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(12, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(12, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
+++ exited with 0 +++
As expected, we have 10 connections with ids from 3
to 12
.
The optimisation with caching shared configuration you mentioned still exists and would make sense if you are using HTTP to bootstrap the client (i.e. CCCP provider disabled with LCB_NO_CCCP=1 or HTTP provider selected explicitly
). Lets see it in action:
for ($i = 0; $i < 10; $i++) {
$cluster = new CouchbaseCluster("couchbase://localhost" . $i . "?bootstrap_on=http");
$bucket = $cluster->openBucket('travel-sample');
$bucket->upsert('foo', 'bar');
}
$ strace -e trace=connect php test.php
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(3, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(4, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(5, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(5, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(6, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(6, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(7, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(7, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(8, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(8, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(9, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(9, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(10, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(10, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(11, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(11, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(12, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(12, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(13, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(13, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(14, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(14, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(15, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(15, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(15, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(16, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(16, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(16, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(17, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(17, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(18, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(18, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(19, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(19, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(20, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(20, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(21, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(21, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(22, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(22, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
+++ exited with 0 +++
Here we could see that for each data connection, it also opens HTTP connection to listen the changes. And here we can get rid of these 8091
sockets if we instruct the library to read configuration from the file.
for ($i = 0; $i < 10; $i++) {
$cluster = new CouchbaseCluster("couchbase://localhost" . $i . "?bootstrap_on=http&config_cache=/tmp/cache.json");
$bucket = $cluster->openBucket('travel-sample');
$bucket->upsert('foo', 'bar');
}
It will reduce HTTP connections to only one and use file as a cache for the configuration:
$ strace -e trace=connect php test.php
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(3, {sa_family=AF_INET, sin_port=htons(8091), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(4, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(5, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(5, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(6, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(6, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(7, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(7, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(8, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(8, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(9, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(9, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(10, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(10, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(11, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(11, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(12, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(12, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(13, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(13, {sa_family=AF_INET, sin_port=htons(11210), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
+++ exited with 0 +++
Also which is more important, other processes see this cache file and will not create HTTP bootstrap connection at all. The cache invalidated when the library detects stale topology.