summaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2020-04-07 12:07:09 +0200
committerantirez <antirez@gmail.com>2020-04-07 12:07:54 +0200
commitf69876280c630d49574fa094808d3a4791c5039b (patch)
tree66cb40c3a7729a5ef801ee3e2dd39c26cbbbce20 /src/server.c
parent9a9109431b31a46da9c45fc1fd8c91b4f7bb9dc6 (diff)
downloadredis-faster-info.tar.gz
Speedup INFO by counting client memory incrementally.faster-info
Related to #5145. Design note: clients may change type when they turn into replicas or are moved into the Pub/Sub category and so forth. Moreover the recomputation of the bytes used is problematic for obvious reasons: it changes continuously, so as a conservative way to avoid accumulating errors, each client remembers the contribution it gave to the sum, and removes it when it is freed or before updating it with the new memory usage.
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/server.c b/src/server.c
index 56feb09a3..996e0f5d2 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1593,6 +1593,28 @@ int clientsCronTrackExpansiveClients(client *c) {
return 0; /* This function never terminates the client. */
}
+/* Iterating all the clients in getMemoryOverheadData() is too slow and
+ * in turn would make the INFO command too slow. So we perform this
+ * computation incrementally and track the (not instantaneous but updated
+ * to the second) total memory used by clients using clinetsCron() in
+ * a more incremental way (depending on server.hz). */
+int clientsCronTrackClientsMemUsage(client *c) {
+ size_t mem = 0;
+ int type = getClientType(c);
+ mem += getClientOutputBufferMemoryUsage(c);
+ mem += sdsAllocSize(c->querybuf);
+ mem += sizeof(client);
+ /* Now that we have the memory used by the client, remove the old
+ * value from the old categoty, and add it back. */
+ server.stat_clients_type_memory[c->client_cron_last_memory_type] -=
+ c->client_cron_last_memory_usage;
+ server.stat_clients_type_memory[type] += mem;
+ /* Remember what we added and where, to remove it next time. */
+ c->client_cron_last_memory_usage = mem;
+ c->client_cron_last_memory_type = type;
+ return 0;
+}
+
/* Return the max samples in the memory usage of clients tracked by
* the function clientsCronTrackExpansiveClients(). */
void getExpansiveClientsInfo(size_t *in_usage, size_t *out_usage) {
@@ -1653,6 +1675,7 @@ void clientsCron(void) {
if (clientsCronHandleTimeout(c,now)) continue;
if (clientsCronResizeQueryBuffer(c)) continue;
if (clientsCronTrackExpansiveClients(c)) continue;
+ if (clientsCronTrackClientsMemUsage(c)) continue;
}
}
@@ -2792,6 +2815,8 @@ void initServer(void) {
server.stat_rdb_cow_bytes = 0;
server.stat_aof_cow_bytes = 0;
server.stat_module_cow_bytes = 0;
+ for (int j = 0; j < CLIENT_TYPE_COUNT; j++)
+ server.stat_clients_type_memory[j] = 0;
server.cron_malloc_stats.zmalloc_used = 0;
server.cron_malloc_stats.process_rss = 0;
server.cron_malloc_stats.allocator_allocated = 0;