数据库

介绍

通常建议运行一个 Galera 集群(使用 MySQL 或 MariaDB)作为您的数据库。它的主动-主动特性允许快速且简便的故障转移。

请注意,OpenStack 不太适合并行写入多个 Galera 节点,请参阅下面的配置建议。

一个数据库统治它们?

您可以考虑以两种方式部署数据库

  • 为每个 OpenStack 服务使用一个 Galera 集群

  • 为所有 OpenStack 服务使用一个大型 Galera 集群

建议将您的 Galera 分割成独立的集群,原因如下

  • 降低 Galera 集群宕机的影响

  • 允许对基础设施的较小部分进行干预

此外,将多个服务放在同一个 Galera 集群上没有任何好处。

配置建议

本节分为三个部分

  • Galera 本身的配置

  • Galera 前面的反向代理配置

  • OpenStack 服务的配置

Galera 配置

所有这些设置都需要在 Galera 集群的所有节点上保持一致。

请注意,本指南不包括设置 Galera 集群的一般要求。有关更多信息,请参阅 https://mariadb.com/kb/en/getting-started-with-mariadb-galera-cluster/

常规健康配置

[mysqld]
max_connections=4000
max_statement_time=20

为了确保您的集群平稳运行,我们建议您限制连接数量以及语句可以执行的时间。

max_connections 的值应根据实际测试设置(使用大量空闲连接进行测试是可以的)。

对于 max_statement_time20 秒的值足以满足我们所知的所有正常用例。如果您经常运行 Nova 清理作业,可能会遇到问题。

复制稳定性

[galera]
wsrep_provider_options=gcomm.thread_prio=rr:2;gcs.fc_limit=160;gcs.fc_factor=0.8;gcache.size=2G

如果您有大量连接到 Galera 集群的连接,这些连接可能会使 Galera 复制线程饥饿。如果复制线程没有获得足够的 CPU 时间,Galera 集群将失去其成员并崩溃。

此设置将复制线程设置为内核侧的实时调度。如果您以非特权用户身份运行 Galera(希望您这样做),Galera 需要 CAP_SYS_NICE 才能允许更改优先级。如果您在容器环境中运行,可能需要设置 kernel.sched_rt_runtime_us=-1(尽管这并非最佳选择)。

性能

[mysqld]
tmp_table_size=64M
max_heap_table_size=64M
optimizer_switch=derived_merge=off

如果您有大量的 Neutron RBAC 规则,临时表和 derived_merge 优化器是一个重要的设置。

反向代理配置

您需要在 Galera 集群前面运行一个反向代理,以确保 OpenStack 始终只与 Galera 集群的单个节点进行通信以进行 write 请求。这是必需的,因为 OpenStack 无法很好地处理并行写入不同节点时发生的死锁。

如果您选择运行 haproxy,可以使用如下配置

defaults
  timeout client 300s

listen db_master
  bind 0.0.0.0:3306
  balance first
  option mysql-check
  server server-1 server-1.with.the.fqdn check inter 5s downinter 15s fastinter 2s resolvers cluster id 1
  server server-2 server-2.with.the.fqdn check inter 5s downinter 15s fastinter 2s resolvers cluster backup id 2
  server server-3 server-3.with.the.fqdn check inter 5s downinter 15s fastinter 2s resolvers cluster backup id 3

listen db_slave
  bind 0.0.0.0:3308
  balance roundrobin
  option mysql-check
  server server-1 server-1.with.the.fqdn check inter 5s downinter 15s fastinter 2s resolvers cluster id 3 backup
  server server-2 server-2.with.the.fqdn check inter 5s downinter 15s fastinter 2s resolvers cluster id 1 weight 10
  server server-3 server-3.with.the.fqdn check inter 5s downinter 15s fastinter 2s resolvers cluster id 2 weight 10

通过使用两个块,我们可以将仅 read SQL 请求(此处在端口 3308 上侦听)与 read/write 请求(此处在端口 3306 上侦听)分开,并稍微降低第一个(主)mysql 后端的负载。

您应该注意这里的 timeout client 设置,因为它与 OpenStack 配置相关。

OpenStack 配置

数据库连接设置

数据库配置通常位于配置的 [database] 部分。您应该设置以下内容

connection = mysql+pymysql://login:pass@proxy:3306/db?charset=utf8
slave_connection = mysql+pymysql://login:pass@proxy:3308/db?charset=utf8
connection_recycle_time = 280
max_pool_size = 15
max_overflow = 25

connection 由 OpenStack 服务用于执行 readwrite 请求。

slave_connection 由 OpenStack 服务用于执行仅 read 请求。

connection_recycle_time 应该比反向代理中的 timeout client 小一点(5% 到 10%)。这可确保在反向代理强制终止连接之前,OpenStack 侧首先重新创建连接。

max_pool_sizemax_overflow 定义了一个线程允许的连接数量。您需要根据经验设置此值(尽管上述值应该是一个好的起点)。

数据库清理

Nova 和 Cinder 在其数据库中使用软删除。这意味着已删除的条目仍然存在于数据库中,只是设置了 deleted 标志。

为了防止数据库表无限增长,需要定期删除这些已删除的条目。为此,您可以使用

如果您以前从未运行过这些清理(或者您的环境具有大量被删除的资源),由于数据库集群上的 max_statement_time,可能会遇到超时。为了解决此问题,nova-manage 命令支持一个 --max-rows 参数。对于 Cinder,您可能需要手动运行 SQL 语句并在其中添加 limit 1000(语句是命令错误的组成部分)。