It also adds 2 sample of devstack's local.conf file for deploying Neutron with OVN mechanism driver. Needed to create PNG files out of the existing SVG ones in order to pass the pdf doc build. Co-Authored-By: Aaron Rosen <aaronorosen@gmail.com> Co-Authored-By: Akihiro Motoki <amotoki@gmail.com> Co-Authored-By: Amitabha Biswas <abiswas@us.ibm.com> Co-Authored-By: Andreas Jaeger <aj@suse.com> Co-Authored-By: Anh Tran <anhtt@vn.fujitsu.com> Co-Authored-By: Assaf Muller <amuller@redhat.com> Co-Authored-By: Babu Shanmugam <bschanmu@redhat.com> Co-Authored-By: Brian Haley <bhaley@redhat.com> Co-Authored-By: Chandra S Vejendla <csvejend@us.ibm.com> Co-Authored-By: Daniel Alvarez <dalvarez@redhat.com> Co-Authored-By: Dong Jun <dongj@dtdream.com> Co-Authored-By: Emilien Macchi <emilien@redhat.com> Co-Authored-By: Flavio Fernandes <flavio@flaviof.com> Co-Authored-By: Gal Sagie <gal.sagie@huawei.com> Co-Authored-By: Gary Kotton <gkotton@vmware.com> Co-Authored-By: Guoshuai Li <ligs@dtdream.com> Co-Authored-By: Han Zhou <zhouhan@gmail.com> Co-Authored-By: Hong Hui Xiao <xiaohhui@cn.ibm.com> Co-Authored-By: Jakub Libosvar <libosvar@redhat.com> Co-Authored-By: Jeff Feng <jianhua@us.ibm.com> Co-Authored-By: Jenkins <jenkins@review.openstack.org> Co-Authored-By: Jonathan Herlin <jonte@jherlin.se> Co-Authored-By: Kyle Mestery <mestery@mestery.com> Co-Authored-By: Le Hou <houl7@chinaunicom.cn> Co-Authored-By: Lucas Alvares Gomes <lucasagomes@gmail.com> Co-Authored-By: Matthew Kassawara <mkassawara@gmail.com> Co-Authored-By: Miguel Angel Ajo <majopela@redhat.com> Co-Authored-By: Murali Rangachari <muralirdev@gmail.com> Co-Authored-By: Numan Siddique <nusiddiq@redhat.com> Co-Authored-By: Reedip <rbanerje@redhat.com> Co-Authored-By: Richard Theis <rtheis@us.ibm.com> Co-Authored-By: Russell Bryant <rbryant@redhat.com> Co-Authored-By: Ryan Moats <rmoats@us.ibm.com> Co-Authored-By: Simon Pasquier <spasquier@mirantis.com> Co-Authored-By: Terry Wilson <twilson@redhat.com> Co-Authored-By: Tong Li <litong01@us.ibm.com> Co-Authored-By: Yunxiang Tao <taoyunxiang@cmss.chinamobile.com> Co-Authored-By: Yushiro FURUKAWA <y.furukawa_2@jp.fujitsu.com> Co-Authored-By: chen-li <shchenli@cn.ibm.com> Co-Authored-By: gong yong sheng <gong.yongsheng@99cloud.net> Co-Authored-By: lidong <lidongbj@inspur.com> Co-Authored-By: lzklibj <lzklibj@cn.ibm.com> Co-Authored-By: melissaml <ma.lei@99cloud.net> Co-Authored-By: pengyuesheng <pengyuesheng@gohighsec.com> Co-Authored-By: reedip <rbanerje@redhat.com> Co-Authored-By: venkata anil <anilvenkata@redhat.com> Co-Authored-By: xurong00037997 <xu.rong@zte.com.cn> Co-Authored-By: zhangdebo <zhangdebo@inspur.com> Co-Authored-By: zhangyanxian <zhang.yanxian@zte.com.cn> Co-Authored-By: zhangyanxian <zhangyanxianmail@163.com> Change-Id: Ia121ec5146c1d35b3282e44fd1eb98932939ea8c Partially-Implements: blueprint neutron-ovn-merge
5.9 KiB
Distributed OVSDB events handler
This document presents the problem and proposes a solution for handling OVSDB events in a distributed fashion in ovn driver.
Problem description
In ovn driver, the OVSDB Monitor class is responsible for listening to the OVSDB events and performing certain actions on them. We use it extensively for various tasks including critical ones such as monitoring for port binding events (in order to notify Neutron/Nova that a port has been bound to a certain chassis). Currently, this class uses a distributed OVSDB lock to ensure that only one instance handles those events at a time.
The problem with this approach is that it creates a bottleneck because even if we have multiple Neutron Workers running at the moment, only one is actively handling those events. And, this problem is highlighted even more when working with technologies such as containers which rely on creating multiple ports at a time and waiting for them to be bound.
Proposed change
In order to fix this problem, this document proposes using a Consistent Hash Ring to split the load of handling events across multiple Neutron Workers.
A new table called ovn_hash_ring
will be created in the
Neutron Database where the Neutron Workers capable of handling OVSDB
events will be registered. The table will use the following schema:
Column name | Type | Description |
---|---|---|
node_uuid |
String |
Primary key. The unique identification of a Neutron Worker. |
hostname |
String |
The hostname of the machine this Node is running on. |
created_at |
DateTime |
The time that the entry was created. For troubleshooting purposes. |
updated_at |
DateTime |
The time that the entry was updated. Used as a heartbeat to indicate that the Node is still alive. |
This table will be used to form the Consistent Hash Ring. Fortunately, we have an implementation already in the tooz library of OpenStack. It was contributed by the Ironic team which also uses this data structure in order to spread the API request load across multiple Ironic Conductors.
Here's how a Consistent Hash Ring from tooz works:
from tooz import hashring
hring = hashring.HashRing({'worker1', 'worker2', 'worker3'})
# Returns set(['worker3'])
hring[b'event-id-1']
# Returns set(['worker1'])
hring[b'event-id-2']
How OVSDB Monitor will use the Ring
Every instance of the OVSDB Monitor class will be listening to a series of events from the OVSDB database and each of them will have a unique ID registered in the database which will be part of the Consistent Hash Ring.
When an event arrives, each OVSDB Monitor instance will hash that event UUID and the ring will return one instance ID, which will then be compared with its own ID and if it matches that instance will then process the event.
Verifying status of OVSDB Monitor instance
A new maintenance task will be created in ovn driver which will
update the updated_at
column from the
ovn_hash_ring
table for the entries matching its hostname
indicating that all Neutron Workers running on that hostname are
alive.
Note that only a single maintenance instance runs on each machine so the writes to the Neutron database are optimized.
When forming the ring, the code should check for entries where the
value of updated_at
column is newer than a given timeout.
Entries that haven't been updated in a certain time won't be part of the
ring. If the ring already exists it will be re-balanced.
Clean up and minimizing downtime window
Apart from heartbeating, we need to make sure that we remove the Nodes from the ring when the service is stopped or killed.
By stopping the neutron-server
service, all Nodes
sharing the same hostname as the machine where the service is running
will be removed from the ovn_hash_ring
table. This is done
by handling the SIGTERM event. Upon this event arriving, ovn driver
should invoke the clean up method and then let the process halt.
Unfortunately nothing can be done in case of a SIGKILL, this will leave the nodes in the database and they will be part of the ring until the timeout is reached or the service is restarted. This can introduce a window of time which can result in some events being lost. The current implementation shares the same problem, if the instance holding the current OVSDB lock is killed abruptly, events will be lost until the lock is moved on to the next instance which is alive. One could argue that the current implementation aggravates the problem because all events will be lost where with the distributed mechanism some events will be lost. As far as distributed systems goes, that's a normal scenario and things are soon corrected.
Ideas for future improvements
This section contains some ideas that can be added on top of this work to further improve it:
- Listen to changes to the Chassis table in the OVSDB and force a ring re-balance when a Chassis is added or removed from it.
- Cache the ring for a short while to minimize the database reads when the service is under heavy load.
- To greater minimize/avoid event losses it would be possible to cache the last X events to be reprocessed in case a node times out and the ring re-balances.