Hi
I’m still doing some tests with Couchbase, and I’m running into another issue that I can’t explain.
I’ve already detailed most of my configuration in another thread: https://www.couchbase.com/forums/t/n1ql-performances-are-2-5k-requests-by-second-at-2ms-each-an-expected-average
For this current test, I’m running a very simple client code, that I can give in its entirety here:
var bucket = new Cluster(new ClientConfiguration()
{
Servers = new List<Uri>
{
new Uri("http://172.25.83.136:8091/pools")
}
}).OpenBucket("catalog");
for (var i = 0; i < 15; i++)
{
// N1QL Request
var query = new QueryRequest()
.Statement($"select catalog.* from catalog where type = 'Product' and ean = '9782742715572' limit 1")
.Metrics(true);
var sw = Stopwatch.StartNew();
var result = bucket.Query<Product>(query);
Console.Write($"watch: {sw.Elapsed.TotalMilliseconds} ms / metrics: {result.Metrics.ElaspedTime} | {result.Metrics.ExecutionTime}");
// For comparison, I'm doing a GET request on the same document
var id = result.First().DocId;
sw.Restart();
var doc = bucket.Get<Product>($"Product,,{id}");
Console.WriteLine($" - watch GET: {sw.Elapsed.TotalMilliseconds} ms");
// To be sure that the same document is read and processed
if (doc.Value.DocId != id)
{
throw new Exception();
}
}
Here is the result of running that test:
watch: 143.1797 ms / metrics: 7.1795ms | 7.0735ms - watch GET: 36.0626 ms
watch: 10.8588 ms / metrics: 7.912117ms | 7.799014ms - watch GET: 0.7447 ms
watch: 47.3252 ms / metrics: 6.21117ms | 6.000764ms - watch GET: 0.7551 ms
watch: 9.6933 ms / metrics: 6.806686ms | 6.692383ms - watch GET: 0.8618 ms
watch: 46.9134 ms / metrics: 5.82196ms | 5.769658ms - watch GET: 0.9948 ms
watch: 10.9039 ms / metrics: 8.229678ms | 8.154777ms - watch GET: 0.7501 ms
watch: 8.9132 ms / metrics: 6.212758ms | 6.149458ms - watch GET: 0.8672 ms
watch: 48.1615 ms / metrics: 6.498861ms | 6.451461ms - watch GET: 0.8513 ms
watch: 46.723 ms / metrics: 5.558152ms | 5.48675ms - watch GET: 0.8383 ms
watch: 9.2646 ms / metrics: 6.501361ms | 6.435361ms - watch GET: 0.6954 ms
watch: 46.583 ms / metrics: 5.327646ms | 5.274444ms - watch GET: 0.7096 ms
watch: 7.475 ms / metrics: 5.151701ms | 5.096201ms - watch GET: 0.8223 ms
watch: 46.6962 ms / metrics: 5.5509ms | 5.5134ms - watch GET: 0.8153 ms
watch: 47.4582 ms / metrics: 5.9329ms | 5.9043ms - watch GET: 0.7256 ms
watch: 47.4179 ms / metrics: 5.7938ms | 5.7344ms - watch GET: 0.8471 ms
That timing pattern is very common (and consistent): some of the requests will end in less than 10 ms, and most of the rest is in 45 / 50 ms. The elapsed time according to the metrics is constant, around 6 ms.
There’s multiple things that I don’t understand here:
- What is taking 2 to 4 ms in the “quick” requests ?
- Why do I have so much “long” requests ?
- Why is the response time not constant client side, when the request metrics say that the server side time is constant ?
For each N1QL request, I’m also running a GET request. Those are running in constant time, in around 0.8ms. The fact that I’m able to fetch and deserialize a document in a negligible time is (I think) proof that this is not where the problem lie.
I tried to do the same thing with the Java client, and I got roughly the same result. Interestingly enough, the timing are more regular with the Java client: 1 out of 3 request is done in around 50ms, and the the other in less than 10.
I tried to change the cluster topology, and to move the indexes (I still have two, one for the “type” field, and one for the “ean” field), but without noticing any significant change.
The baseline index topology is to have the “index type” on one server, and the “index ean” on another.
The only topology change that bring a noticeably different outcome is if I remove (failover) the only node without any index. In that case, especially with the java client, I go from 1 request out of 3 at 50ms to 1 request out of 2 at 50ms (and I have no idea why).
If any of you have any clue to what is happening to my requests, it would be great
Thanks for your help,
Regards