summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Maximets <i.maximets@ovn.org>2023-03-27 21:43:01 +0200
committerIlya Maximets <i.maximets@ovn.org>2023-04-24 22:42:25 +0200
commit07c27226ee96a3715126c50e1dbf6d8a1886b305 (patch)
tree761aa7a49c1b6c5d0d47d747298e2a24e0021537
parent172c935ed9a8332004fcc15fbf4ab43c9f5fe043 (diff)
downloadopenvswitch-07c27226ee96a3715126c50e1dbf6d8a1886b305.tar.gz
ovsdb: Monitor: Keep and maintain the initial change set.
Change sets in OVSDB monitor are storing all the changes that happened between a particular transaction ID and now. Initial change set basically contains all the data. On each monitor request a new initial change set is created by creating an empty change set and adding all the database rows. Then it is converted into JSON reply and immediately untracked and destroyed. This is causing significant performance issues if many clients are requesting new monitors at the same time. For example, that is happening after database schema conversion, because conversion triggers cancellation of all monitors. After cancellation, every client sends a new monitor request. The server then creates a new initial change set, sends a reply, destroys initial change set and repeats that for each client. On a system with 200 MB database and 500 clients, cluster of 3 servers spends 20 minutes replying to all the clients (200 MB x 500 = 100 GB): timeval|WARN|Unreasonably long 1201525ms poll interval Of course, all the clients are already disconnected due to inactivity at this point. When they are re-connecting back, server accepts new connections one at a time, so inactivity probes will not be triggered anymore, but it still takes another 20 minutes to handle all the incoming connections. Let's keep the initial change set around for as long as the monitor itself exists. This will allow us to not construct a new change set on each new monitor request and even utilize the JSON cache in some cases. All that at a relatively small maintenance cost, since we'll need to commit changes to one extra change set on every transaction. Measured memory usage increase due to keeping around a shallow copy of a database is about 10%. Measured CPU usage difference during normal operation is negligible. With this change it takes only 30 seconds to send out all the monitor replies in the example above. So, it's a 40x performance improvement. On a more reasonable setup with 250 nodes, the process takes up to 8-10 seconds instead of 4-5 minutes. Conditional monitoring will benefit from this change as well, however results might be less impressive due to lack of JSON cache. Reviewed-by: Simon Horman <simon.horman@corigine.com> Acked-by: Dumitru Ceara <dceara@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
-rw-r--r--ovsdb/monitor.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
index 191befcae..3cdd03b20 100644
--- a/ovsdb/monitor.c
+++ b/ovsdb/monitor.c
@@ -609,7 +609,10 @@ ovsdb_monitor_untrack_change_set(struct ovsdb_monitor *dbmon,
ovs_assert(mcs);
if (--mcs->n_refs == 0) {
if (mcs == dbmon->init_change_set) {
- dbmon->init_change_set = NULL;
+ /* The initial change set should exist as long as the
+ * monitor itself. */
+ mcs->n_refs++;
+ return;
} else if (mcs == dbmon->new_change_set) {
dbmon->new_change_set = NULL;
}