使用 Tooz 替换本地文件锁¶
https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support
目前 cinder-volume 服务只能以 Active/Passive HA 方式运行。其中一些原因是
在 manager 中用于保护资源的文件锁。例如,当从 volume B 创建 volume A 时,会在 B 上创建一个锁,以防止在创建 A 期间删除 B。
在驱动程序(如 RemoteFS 等)中的本地文件锁。这些锁用于阻止不能并发运行的操作(例如,在基于 RemoteFS 的驱动程序中获取快照)。
此蓝图建议切换到使用 Tooz 库进行分布式锁。
问题描述¶
当前每个 volume 后端只能有一个活动的 cinder-volume 服务。这意味着为了实现其高可用性,我们需要一个外部服务(如 Pacemaker),它会监控 c-vol 的状态,并在之前的实例发生故障时激活新的实例。这也使得 c-vol 无法扩展,因为操作员不能仅仅启动额外的服务来处理高负载,而需要依赖于只有一个实例。
在 c-vol 的 manager 和一些驱动程序中使用的本地文件锁阻止了这一点,因为锁不能在运行在不同主机上的不同 c-vol 服务之间共享。这可能会导致多种问题,甚至导致数据丢失。
用例¶
操作员希望部署多个 cinder-volume 服务。动机可能是运行多个 cinder-volume,它们连接到单个存储后端,以提高请求吞吐量,从而提高性能。另一个优势是在运行服务的多个实例时,提高了对硬件故障的弹性。
云用户将获得更好的云。
提议的变更¶
在 Mitaka 设计峰会上,有一个关于 允许项目对 DLM 软件有硬性要求的会议。会议的主要结论是
项目可以硬性依赖于 DLM 的存在。
Tooz 将是抽象层。
因此,建议的解决方案是将当前本地锁转换为使用 Tooz 抽象层。
这将需要统一当前的方法(因为一些锁是通过 cinder.utils.synchronized 方法完成的,而另一些则直接使用 oslo.concurrency.lockutils)。默认情况下,Tooz 将配置为使用文件锁,因此一切都将像今天一样工作。如果操作员希望运行多个 cinder-volume 服务,则需要配置 Tooz 后端服务并在 cinder.conf 中设置它。目前最可靠的 Tooz 后端是 ZooKeeper 和 Redis。
Tooz 中的 Redis 后端需要发送周期性的心跳,因此 cinder-volume manager 将启动一个新线程来处理此任务。这将是一个常规线程(非 eventlet),以防止 eventlet green 线程被阻塞。 仅当 Tooz 需要时才打算生成此线程,因此如果使用 FileDriver 或 ZooKeeper 作为后端,则不会执行此操作。
备选方案¶
为了解决基于 RemoteFS 的 volume 驱动程序中的锁问题,我们可以简单地弃用它们,并让操作员切换到使用无锁驱动程序。但这可能很难实现,因为根据 OpenStack 用户调查,19% 的 Cinder 部署使用这些驱动程序。 此外,一些非 RemoteFS 驱动程序也使用本地锁。
我们也可以用一些基于 DB 的锁来替换当前的锁。 gegulieo 在 specs 中提出了这个建议,以从 manager 和 drivers 中删除本地锁,但这会增加解决方案的复杂性,并且可能比依赖于广泛使用的 DLM 软件需要更多的测试。
在未来,我们可能希望尝试使用其他方式(例如基于状态的锁)从 volume manager 中删除锁。这将使我们能够在没有 DLM 的情况下以 A/A 方式运行 c-vol(在运行不进行锁定的 volume 驱动程序时)。
数据模型影响¶
无
REST API 影响¶
无
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
使用外部服务进行锁会影响性能。 geguileo 进行了一些 性能测试。 此外,心跳线程可能会增加很小的性能开销。
如果用户坚持使用文件锁并决定以今天的方式运行 c-vol,这些将不存在。
其他部署者影响¶
部署工具将会在 [coordination] 部分拥有新的选项
backend_url=file://$state_path - Tooz 后端连接字符串。
heartbeat=1.0 - 分布式协调的心跳间隔秒数。
initial_reconnect_backoff=0.1 - 失败后重新连接到 Tooz 后端的秒数。
max_reconnect_backoff=60.0 - 重新连接到 Tooz 后端的连续重试之间的最大秒数。
部署工具维护者需要决定是否希望使用新的可能性。 如果是,他们需要在其环境中设置一个 Tooz 后端(ZooKeeper、Redis 或不太推荐的 memcached)。
开发人员影响¶
开发人员只需要通过 Tooz 库抽象层在 cinder-volume 服务中使用锁,并意识到可以运行服务的多个实例。
实现¶
负责人¶
- 主要负责人
Michal Dulko (dulek)
- 其他贡献者
Szymon Wroblewski (bluex-pl)
工作项¶
Cinder 中的 Tooz 锁实现(已完成)。
将当前锁切换为使用 Tooz 实现。
我们已经完成了一些 工作。 我们应该将其拆分为每个驱动程序,并与驱动程序维护者合作以合并补丁。
添加 DevStack 补丁以设置 CI 测试 Cinder,使用 Redis 或 ZooKeeper 作为 Tooz 后端。
依赖项¶
无
测试¶
将添加 Tooz 代码的单元测试,并配置 CI 以使用 Redis 或 ZooKeeper 作为锁后端来测试 Cinder。 也许我们可以使用 multinode Tempest 来完成此操作。
文档影响¶
需要更新文档和 Openstack HA 指南,以包含有关如何配置 Tooz 以及以 A/A 方式部署 cinder-volume 的说明。