本周 Ilya 在社区发起了一个Neutron数据库对象在并发情况下存在一些问题的讨论,此类问题屡见不鲜。本周就这一问题我们来共同探讨如何改进规避。
如何规避在高并发、时序上的问题?
llya希望能为ContextManager提供一个acquire_object的方法,当开发者希望修改对象时,需要先提前获取相关的锁,具体到锁的实现上,有几个方案,前两个是llya提的:
1、基于数据库的SELECT FOR UPDATE
这个其实社区之前就有用,但只是在出 bug 之后才会添加,默认的话ContextManager只能保证本进程或者本机的锁,目前OpenStack的程序一般使用oslo.concurrency 实现锁,这个是从以前的各个项目的openstack/commmon中抽出来的,它目前只能实现两种锁,分别是基于Python的线程锁和基于文件的外部锁,CPython的线程锁的实现实际是基于POSIX系统的信号量(PyThread_allocate_lock),因此这个锁是线程安全的,但不是进程安全的;外部锁是基于文件的实现,所以它是进程安全的(IPC),当然你可以试试将文件锁放在共享存储上。SELECT FOR UPDATE对Gelera多写并不友好,造成个死锁分分钟的事。
2、Lock-free CAS
最近社区对这个很是热衷,但CAS的比较简单,为了能让我们顺利加、放锁,需要对SqlAlchemy的对象做版本,这样子是无锁实现,性能显然好很多,但它只能解决同时修改的冲突问题,并没有实际上保证在Context内是不被修改的。
3、将资源的变化通过AMQP发出通知
目前有一个正在做的工作是对核心资源增加版本机制,然后可能的一种思路是将这些资源的变化通过AMQP发出通知。
4、使用update_with_where
CInder的开发者提到可以使用update_with_where,与CAS相比,它将对一些state用where做限制,但这个似乎并不是被SQLAlchemy推荐的方案。
5、Tooz项目
Tooz可以提供分布式的组管理,包括Group membership、Leader选举、分布式锁,后端号称支持Kazoo (ZooKeeper)、Zake、redis、Memcached、SysV IPC、PostgreSQL、MySQL、Etcd,但好像发展的不温不火的,可能只有Ceilometer在用吧。
让 OpenStack 支持外部 VxLan VTEP?
来自 IBM 的几位贡献者还在继续推进OpenStack支持外部的VxLan VTEP这一功能。过去如果使用Open vSwitch Driver作为核心网络实现的话,VTEP地址是由Agent上报给Server,保存到数据库后在各个计算节点起VxLan隧道。但这样的话外部的VxLan VTEP是无法被探测到的。计划的修改是添加一个 SegmentFloodingVTEP 表,保存外部的VxLan VTEP信息,与NetworkSegment建立外键。那么当你想创建一个可以和外部VxLan通的网络的话,就可以这样创建:
net-create –provider:flooding_vtep ip_address=10.0.1.1,dstport=4789 net-1
我比较好奇VNI是谁分配的,如果是Neutron自动分配的话,可能需要额外的Mechanism Driver。当然也有别的方法,比如VxLan 的 Segments范围预先定好配在 Neutron 的配置文件里。