On Tue, Oct 30, 2018 at 11:51:05PM -0700, Han Zhou wrote:
> On Tue, Oct 30, 2018 at 11:15 AM Ben Pfaff <b...@ovn.org> wrote:
> >
> > On Wed, Oct 24, 2018 at 05:42:15PM -0700, Han Zhou wrote:
> > > On Tue, Sep 25, 2018 at 10:18 AM Han Zhou <zhou...@gmail.com> wrote:
> > > >
> > > >
> > > >
> > > > On Thu, Sep 20, 2018 at 4:43 PM Ben Pfaff <b...@ovn.org> wrote:
> > > > >
> > > > > On Thu, Sep 13, 2018 at 12:28:27PM -0700, Han Zhou wrote:
> > > > > > In scalability test with ovn-scale-test, ovsdb-server SB load is
> not a
> > > > > > problem at least with 1k HVs. However, if we restart the
> ovsdb-server,
> > > > > > depending on the number of HVs and scale of logical objects, e.g.
> the
> > > > > > number of logical ports, ovsdb-server of SB become an obvious
> > > bottleneck.
> > > > > >
> > > > > > In our test with 1k HVs and 20k logical ports (200 lport * 100
> > > lswitches
> > > > > > connected by one single logical router). Restarting ovsdb-server
> of SB
> > > > > > resulted in 100% CPU of ovsdb-server for more than 1 hour. All HVs
> > > (and
> > > > > > northd) are reconnecting and resyncing the big amount of data at
> the
> > > same
> > > > > > time. Considering the amount of data and json rpc cost, this is
> not
> > > > > > surprising.
> > > > > >
> > > > > > At this scale, SB ovsdb-server process has RES 303848KB before
> > > restart. It
> > > > > > is likely a big proportion of this size is SB DB data that is
> going
> > > to be
> > > > > > transferred to all 1,001 clients, which is about 300GB. With a
> 10Gbps
> > > NIC,
> > > > > > even the pure network transmission would take ~5 minutes.
> Considering
> > > the
> > > > > > actual size of JSON RPC would be much bigger than the raw data,
> and
> > > the
> > > > > > processing cost of the single thread ovsdb-server, 1 hour is
> > > reasonable.
> > > > > >
> > > > > > In addition to the CPU cost of ovsdb-server, the memory
> consumption
> > > could
> > > > > > also be a problem. Since all clients are syncing data from it,
> > > probably due
> > > > > > to the buffering, RES increases quickly, spiked to 10G at some
> point.
> > > After
> > > > > > all the syncing finished, the RES is back to the similar size as
> > > before
> > > > > > restart. The client side (ovn-controller, northd) were also seeing
> > > memory
> > > > > > spike - it is a huge JSON RPC for the new snapshot of the whole
> DB to
> > > be
> > > > > > downloaded, so it is just buffered until the whole message is
> > > received -
> > > > > > RES peaked at the doubled size of its original size, and then went
> > > back to
> > > > > > the original size after the first round of processing of the new
> > > snapshot.
> > > > > > This means for deploying OVN, this memory spike should be
> considered
> > > for
> > > > > > the SB DB restart scenario, especially the central node.
> > > > > >
> > > > > > Here is some of my brainstorming of how could we improve on this
> (very
> > > > > > rough ones at this stage).
> > > > > > There are two directions: 1) reducing the size of data to be
> > > transferred.
> > > > > > 2) scaling out ovsdb-server.
> > > > > >
> > > > > > 1) Reducing the size of data to be transferred.
> > > > > >
> > > > > > 1.1) Using BSON instead of JSON. It could reduce the size of data,
> > > but not
> > > > > > sure yet how much it could help since most of the data are
> strings. It
> > > > > > might be even worse since the bottleneck is not yet the network
> > > bandwidth
> > > > > > but processing power of ovsdb-server.
> > > > > >
> > > > > > 1.2) Move northd processing to HVs - only relevant NB data needs
> to be
> > > > > > transfered, which is much smaller than the SB DB because there is
> no
> > > > > > logical flows. However, this would lead to more processing load on
> > > > > > ovn-controller on HVs. Also, it is a big/huge architecture change.
> > > > > >
> > > > > > 1.3) Incremental data transfer. The way IDL works is like a cache.
> > > Now when
> > > > > > connection reset the cache has to be rebuilt. But if we know the
> > > version
> > > > > > the current snapshot, even when connection is reset, the client
> can
> > > still
> > > > > > communicate with the newly started server to tell the difference
> of
> > > the
> > > > > > current data and the new data, so that only the delta is
> transferred,
> > > as if
> > > > > > the server is not restarted at all.
> > > > > >
> > > > > > 2) Scaling out the ovsdb-server.
> > > > > >
> > > > > > 2.1) Currently ovsdb-server is single threaded, so that single
> thread
> > > has
> > > > > > to take care of transmission to all clients with 100% CPU. If it
> is
> > > > > > mutli-threaded, more cores can be utilized to make this much
> faster.
> > > > > >
> > > > > > 2.2) Using ovsdb cluster. This feature is supported already but I
> > > haven't
> > > > > > tested it in this scenario yet. If everything works as expected,
> > > there can
> > > > > > be 3 - 5 servers sharing the load, so the transfer should be
> > > completed 3 -
> > > > > > 5 times faster than it is right now. However, this is a limit of
> how
> > > many
> > > > > > nodes there can be in a cluster, so the problem can be alleviated
> but
> > > may
> > > > > > still be a problem if the data size goes bigger.
> > > > > >
> > > > > > 2.3) Using readonly copies of ovsdb replications. If
> ovn-controller
> > > > > > connects to readonly copies, we can deploy a big number of
> > > ovsdb-servers of
> > > > > > SB, which replicates from a common source - the read/write one
> > > populated by
> > > > > > ovn-northd. It can be a multi-layered (2 - 3 layer is big enough)
> tree
> > > > > > structure, so that each server only serves a small number of
> clients.
> > > > > > However, today there are some scenarios requires ovn-controller to
> > > write
> > > > > > data to SB, such as dynamic mac-binding (neighbor table
> populating),
> > > nb_cfg
> > > > > > sync feature, etc.
> > > > > >
> > > > > > These ideas are not mutual exclusive, and the order is random just
> > > > > > according to my thought process. I think most of them are worth to
> > > try, but
> > > > > > not sure about priority (except that 1.2 is almost out of question
> > > since I
> > > > > > don't think it is a good idea to do any architecture level change
> at
> > > this
> > > > > > phase). Among the ideas, I think 1.3) 2.1) and 2.3) are the ones
> that
> > > > > > should have the best result (if they can be implemented with
> > > reasonable
> > > > > > effort).
> > > > >
> > > > > It sounds like reducing the size is essential, because you say that
> the
> > > > > sheer quantity of data is 5 minutes worth of raw bandwidth.  Let's
> go
> > > > > through the options there.
> > > > >
> > > > > 1.1, using BSON instead of JSON, won't help sizewise.  See
> > > > > http://bsonspec.org/faq.html.
> > > > >
> > > > > 1.2 would change the OVN architecture, so I don't think it's a good
> > > > > idea.
> > > > >
> > > > > 1.3, incremental data transfer, is an idea that Andy Zhou explored a
> > > > > little bit before he left.  There is some description of the
> approach I
> > > > > suggested in ovn/TODO.rst:
> > > > >
> > > > >   * Reducing startup time.
> > > > >
> > > > >     As-is, if ovsdb-server restarts, every client will fetch a fresh
> > > copy of
> > > > >     the part of the database that it cares about.  With hundreds of
> > > clients,
> > > > >     this could cause heavy CPU load on ovsdb-server and use
> excessive
> > > network
> > > > >     bandwidth.  It would be better to allow incremental updates even
> > > across
> > > > >     connection loss.  One way might be to use "Difference Digests"
> as
> > > described
> > > > >     in Epstein et al., "What's the Difference? Efficient Set
> > > Reconciliation
> > > > >     Without Prior Context".  (I'm not yet aware of previous
> > > non-academic use of
> > > > >     this technique.)
> > > > >
> > > > > When Andy left VMware, the project got dropped, but it could be
> picked
> > > > > up again.
> > > > >
> > > > > There are other ways to implement incremental data transfer, too.
> > > > >
> > > > > Scaling out ovsdb-server is a good idea too, but I think it's
> probably
> > > > > less important for this particular case than reducing bandwidth
> > > > > requirements
> > > > >
> > > > > 2.1, multithreading, is also something that Andy explored; again,
> the
> > > > > project would have to be resumed or restarted.
> > > >
> > > > Thanks Ben! It seems 1.3 (incremental data transfer) is the most
> > > effective approach to solve this problem.
> > > > I had a brief study on the "Difference Digests" paper. For my
> > > understanding it is particularly useful when there is no prior context.
> > > However, in OVSDB use case, especially in this OVN DB restart scenario,
> we
> > > do have the context about the last data received from the server. I
> think
> > > it would be more efficient (no full data scanning and encoding) and
> maybe
> > > simpler to implement based on the append-only (in most cases, for the
> part
> > > of data that hasn't been compressed yet) nature of OVSDB. Here is what I
> > > have in mind:
> > > >
> > > With some more study, here are some more details added inline:
> > >
> > > > - We need a versioning mechanism. For each transaction record in OVSDB
> > > file, it needs a unique version. The hash string may be used for this
> > > purpose, so that the file format doesn't need to be changed. If we allow
> > > the file format to be changed, it may be better to have a version number
> > > that is sequentially increased.
> > > >
> > > For standalone format, the hash value can be used as unique version id.
> > > (what's the chance of the 10 bytes hash value having a conflict?)
> > > For clustered DB format, the eid is perfect for this purpose.
> > > (Sequentially increasing seems not really necessary, since we only need
> to
> > > keep a small amount of history transactions for the DB restart scenario)
> > >
> > > > - We can include the latest version number in every OVSDB notification
> > > from server to client, and the client IDL records the version.
> > > >
> > > > - When a client reconnects to server, it can request to get only the
> > > changes after “last version”.
> > > >
> > > > - When a server starts up, it reads the DB file and keeps track of the
> > > “version” for last N (e.g. 100) transactions, and maintains the changes
> in
> > > memory of that N transactions.
> > >
> > > The current implementation keeps track in monitors for the transactions
> > > that haven't been flushed to all clients. We can extend this by keeping
> > > track of extra N previous transactions. Now for the DB restart scenario,
> > > the previous N transactions are read from DB file.
> > >
> > > Currently, during reading the DB file, there is no monitoring connected
> > > yet, so replaying transactions will not trigger monitor data
> population. We
> > > can create a fake monitor for all tables beforehand so that we can reuse
> > > the code to populate monitor data while replaying DB file transactions.
> > > When a real monitor is created, it copies and converts the data in the
> fake
> > > monitor to its own table according to the monitor criteria. Flushing the
> > > data for the fake monitor can be done so that maximumly M transactions
> will
> > > be kept in the monitor (because there is no real client to consume the
> fake
> > > monitor data).
> > >
> > > >
> > > > - When a new client asks data after a given “version”, if the version
> is
> > > among the N transactions, the server sends the data afterwards to the
> > > client. If the given version is not found (e.g. when client reconnect,
> > > there is already lot of changes happened in server and the old changes
> were
> > > already flushed out, or a DB compression has been performed thus the
> > > transaction data is gone), server can:
> > > >     - Option1: return an error telling the client the version is not
> > > available, and client can re-request the whole snapshot
> > > >     - Option2: server directly send the whole snapshot, with a flag
> > > indicating this is the whole snapshot instead of the delta
> > > >
> > > Option2 seems better.
> > >
> > > As to the OVSDB protocol change, since we need to add a version id to
> every
> > > update notification, it would be better to have a new method
> > > "monitor_cond_since":
> > >
> > > "method": "monitor_cond_since"
> > > "params": [<db-name>, <json-value>, <monitor-cond-requests>,
> > > <latest_version_id>]
> > > "id": <nonnull-json-value>
> > >
> > > <latest_version_id> is the version id that identifies the latest data
> the
> > > client already has. Everything else is same as "monitor_cond" method.
> > >
> > > The response object has the following members:
> > > "result": [<found>, <latest_version_id>, <table-updates2>]
> > > "error": null
> > > "id": same "id" as request
> > >
> > > <found> is a boolean value that tells if the <latest_version_id>
> requested
> > > by client is found in history or not. If true, the data after that
> version
> > > up to current is sent. Otherwise, all data is sent.
> > > <latest_version_id> is the version id that identifies the latest change
> > > involved in this response, so that client can keep track.
> > > Following changes will be notified to client using "update3" method:
> > >
> > > "method": "update3"
> > > "params": [<json-value>, <latest_version_id>, <table-updates2>]
> > > "id": null
> > >
> > > Similar as the response to "monitor_cond_since", <latest_version_id> is
> > > added in the update3 method.
> > >
> > > > - Client will not destroy the old copy of data, unless the requested
> > > version is not available and it has to reinitialize with the whole DB.
> > > >
> > > > This is less general than the Difference Digests approach, but I
> think it
> > > is sufficient and more relevant for OVSDB use case. I am sure there
> will be
> > > details need more consideration, e.g. OVSDB protocol update, caching in
> > > server, etc., but do you think this is a right direction?
> > >
> > > Ben, please suggest if this is reasonable so that I could go ahead with
> a
> > > POC, or please let me know if you see obvious problems/pitfalls.
> >
> > I think that a lot of this analysis is on point.
> >
> > I'm pretty worried about the actual implementation.  The monitor code is
> > already hard to understand.  I am not confident that there is a
> > straightforward way to keep track of the last 100 transactions in a
> > sensible way.  (Bear in mind that different clients may monitor
> > different portions of the database.)  It might make sense to introduce
> > a multiversioned data structure to keep track of the database
> > content--maybe it would actually simplify some things.
> 
> I understand the concern about the complexity. Thinking more about it, the
> problem is only about DB restart, so we don't really need to keep track of
> the last N transactions all the time. We only need to have them available
> within a short period after the initial DB read. When all the old clients
> are reconnected and requested the difference, these data are useless, and
> going forward, new clients won't need any previous transactions either. So
> instead of always keeping track of last N and maintaining a sliding-window,
> we just need the initial part, which can be generated by using the "fake
> monitor" approach I mentioned before, and then each new real monitor
> (created after clients reconnecting) just selectively copy the data with a
> *timestamp* added to the data entry, so that we can free them after a
> certain amount of time (e.g. 5 minutes). For the entries that are NOT
> copied from the fake monitor, which means they are new transactions, they
> can be freed any time their predecessors are freed. The "fake monitor"
> itself will have a timestamp, too, so that it can be deleted after the
> initial period. Would this simplify the problem? (or maybe my description
> makes it sounds more complex :))
>
> Could you explain a little more about the multiversioned data structure
> idea? I am not sure I understand it correctly.

Well, how do you plan to maintain the multiple copies of the database
that will be necessary?  Presumably each monitor needs a copy of a
slightly different database.  Or maybe I just don't understand your plan
yet.

> > If we do this, we need solid and thorough tests to ensure that it's
> > reliable.  It might make sense to start by thinking through the tests,
> > rather than the implementation.
> 
> Good point, I may start with tests first.
_______________________________________________
discuss mailing list
disc...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-discuss

Reply via email to