如何在生产环境中运行 Metabase
如果您是自行托管 Metabase,这里有一些基准和最佳实践。
本文介绍 Metabase 生产环境的设置,包括服务器规模、最佳实践和应避免的陷阱。本文面向对自行托管 Metabase 感兴趣的用户。如果您希望我们为您运行 Metabase,只需注册免费试用版。
Metabase JAR 文件包含什么
背景信息:Metabase 是一个 Web 应用程序。其后端使用 Clojure 编写,前端使用 JavaScript、Typescript 和 Clojurescript 结合 React 框架编写。
默认情况下,整个应用程序是自包含的:后端和为前端提供服务的 Web 服务器打包在同一个捆绑包中。该捆绑包是一个 JAR 文件,可以在安装了 Java 运行时环境的任何地方运行。
Metabase 还提供了一个包含 JRE 和 Metabase JAR 的容器镜像(您也可以使用 Podman 运行)。
一个 JAR 文件和一个数据库即可满足您的需求
要在生产环境中运行 Metabase,您需要两样东西:
- Metabase JAR 文件或容器镜像。
- 一个专用的 PostgreSQL 数据库来存储 Metabase 的应用程序数据库
您也可以使用 MySQL/MariaDB 来存储 Metabase 的应用程序数据库,但我们强烈推荐使用 Postgres。
为什么您需要使用独立的应用程序数据库
Metabase 将其所有实体(仪表板、问题、账户、配置)保存在其应用程序数据库中。
如果您坚持使用默认的、基于文件的应用程序数据库,您的数据库最终将变得不可恢复地损坏,并且您将不得不从头开始(在丢失所有工作之后:您的所有问题、仪表板等)**。
因此,您需要避免使用 Metabase JAR 文件随附的默认应用程序数据库。该嵌入式数据库仅供本地使用。我们包含该嵌入式数据库,是为了方便那些只想在自己机器上试用 Metabase 的人。该嵌入式 H2 数据库还包含一些可供人们试用的示例数据。它不适用于生产环境。
同样,如果您在容器中运行 Metabase,每当您的容器被新版本替换时,您将丢失所有工作。容器旨在是短暂的,因此不要将数据保存在其中。
通过使用专用的 PostgreSQL 应用程序数据库,您可以避免所有这些问题。
如果您已开始使用默认的 H2 数据库
没关系。但您应该尽快迁移到生产数据库。
Metabase 应用程序和数据库服务器及其规模
我们建议您至少运行两个实例(理想情况下在同一网络上)
- 一个或多个 Metabase 应用程序实例.
- 一个用于 Postgres 或 MySQL Metabase 应用程序数据库的实例,Metabase 将在此处存储其应用程序数据。我们建议该数据库实例不用于除 Metabase 应用程序数据库之外的任何其他目的。
您希望在同一网络上运行这些实例的原因是为了减少 Metabase(应用程序)从存储其应用程序数据的数据库获取响应所需的时间。绝大多数 Metabase 操作都需要调用 Metabase 的 API,该 API 使用应用程序数据库来检索有关问题、仪表板、表元数据等信息。
Metabase 应用程序服务器规模
Metabase 基线至少需要 1 核 CPU 和 1GB 内存。在此基础上,每 20 个并发用户,Metabase 将额外需要 1 个 CPU 和 2GB 内存。这些系统建议适用于您以 JAR 或容器镜像形式运行 Metabase 的情况。例如,如果您有 40 个并发用户,您将总共需要 3 个 CPU 核和 5GB 内存。
注意:在 v52 之前,我们建议每 20 个并发用户仅分配 1GB 内存,但为了安全起见,我们在新版本中提高了此要求。
Metabase 应用程序数据库服务器规模
应用程序数据库可能是整个架构中最重要的组成部分:它是单点故障,并且应用程序数据库向 Metabase 应用程序服务器返回查询的速度越快越好。作为起点,为运行应用程序数据库的服务器分配 1 个 CPU 核和 2GB 内存。作为一般规则,对于每 40 个并发用户,PostgreSQL 应用程序数据库将需要 1 个 CPU 核和 1GB 内存。
每个 Metabase 环境都必须有其自己的专用应用程序数据库
就环境而言,我们指的是一个或多个 Metabase JAR 文件(或容器镜像)以及一个应用程序数据库。如果您运行多个环境,您可以在同一应用程序数据库服务器上为每个环境运行多个应用程序数据库,但每个环境都必须有其自己的专用应用程序数据库。
维护
保持系统平稳运行。
Metabase 服务器维护
您无需做任何事情。它应该可以正常工作。
Metabase 应用程序数据库维护
所有数据库都需要维护以实现最佳性能,PostgreSQL 和 MySQL 也不例外。请遵循 PostgreSQL 的维护最佳实践 (https://postgresql.ac.cn/docs/current/maintenance.html)(尤其是备份
此应用程序数据库应进行:
- 每日备份。
- 每周清理和分析。
此外,不再需要的卡片和仪表板应定期归档和删除。
数据仓库服务器维护
您的数据仓库维护取决于您使用的数据仓库类型。请参阅相应数据库的文档以获取指导。
负载测试示例
在这个简单的负载测试中,Metabase API 在 K6 上记录了以下指标。
- 红色:性能不佳
- 绿色:性能良好
指标 / 系统 | 2 核 / 2GB 内存 | 3 核 / 3GB 内存 | 4 核 / 4GB 内存 | 8 核 / 8GB 内存 | 16 核 / 16GB 内存 |
---|---|---|---|---|---|
处理的总请求数 成功处理的 Web 请求总数 |
278,303 | 303,420 | 311,740 | 311,350 | 313,625 |
每秒请求数 系统每秒能处理多少请求(越高越好) |
121.3 req/s | 132.0 req/s | 136.2 req/s | 135.8 req/s | 136.1 req/s |
平均响应时间 平均获取响应所需时间(越低越好) |
78.59ms | 38.89ms | 26.82ms | 27.45ms | 24.46ms |
最慢的 10% (p90) 最慢的 10% 请求至少需要这么长时间 |
204.97ms | 88.58ms | 66.00ms | 66.73ms | 65.78ms |
最慢的 5% (p95) 最慢的 5% 请求耗时甚至超过此时间 |
389.85ms | 118.88ms | 81.79ms | 83.01ms | 76.72ms |
数据接收时间 发送请求后接收数据的时间 |
6.16ms | 2.54ms | 1.56ms | 1.52ms | 1.62ms |
数据发送时间 发送请求到服务器所花费的时间(通常非常快) |
16.74µs | 17.46µs | 15.07µs | 16.04µs | 17.79µs |
等待响应时间 发送请求与获取响应之间的延迟 |
72.41ms | 36.32ms | 25.24ms | 25.90ms | 22.82ms |
每次迭代测试时长 一次测试迭代完成的总时间 |
30.92s | 28.36s | 27.57s | 27.62s | 27.42s |
总迭代次数 测试完全完成的次数 |
4,273 | 4,666 | 4,796 | 4,790 | 4,825 |
接收到的总数据 测试期间下载的数据量 |
16GB | 17GB | 17GB | 17GB | 17GB |
发送的总数据 测试期间上传的数据量 |
103MB | 112MB | 115MB | 115MB | 116MB |
负载测试的一些背景信息
- 此负载测试是在一台笔记本电脑(Ryzen 7840HS)上使用 Metabase v53.5 运行的,通过更改分配给 Metabase 容器的 CPU 核数和内存,并设置最高电源配置文件进行。
- 为了给非堆内存留出空间,我们使用环境变量
JAVA_TOOL_OPTIONS: -Xmx<80% of total RAM>m
配置了 Metabase。 - 应用程序数据库是 Postgres 17 版本,配置为 2 核 CPU 和 8GB 内存。
- 无 HTTPS。
- 我们进行的这项特定负载测试使用的资源少于我们推荐的(对于 100 个并发用户,我们建议 6 核 CPU 和 11GB 内存)。我们特意使用较少资源,是为了表明当应用程序拥有足够的核数和可用内存时,它可以承受流量峰值而不会显著降低性能。
- 尽管此负载测试检查了多个 API 端点,但它没有测试 CPU/内存密集型操作,例如 X-Rays,或异步操作,例如订阅、警报、数据库同步或数据库扫描/指纹识别。
然而,负载测试无法模拟实际使用情况。用户在 Metabase 中的活动会生成各种不同的 API 调用模式。您还将有异步进程在后台运行。如果 Metabase 缺少足够的 CPU 资源,它会使操作排队并开始消耗更多内存。如果队列溢出,Metabase 可能会因处理所有请求而崩溃。在这种情况下,您将需要分配更多的 CPU 核和内存。
异步进程
Metabase 会定期运行异步进程,这些进程会根据您的表数量和表中列的数量使用 CPU 和内存。
这些进程包括:
- 同步
- 扫描
- 指纹识别
- 字段值
- 模型缓存
- 问题元数据
如果您发现 Metabase 在某个时间段内使用了大量 CPU,请检查日志以查看 Metabase 是否正在运行这些进程中的任何一个。如果是,您可以安排这些任务在用户不使用 Metabase 时运行。
Metabase 会将这些任务中的每一个分配给一个单独的 CPU 核。如果您的服务器有四个核,Metabase 将运行的最大异步进程数为三个,因为一个核应该用于服务用户请求(一个核应该能够同时服务大约 10 个 Metabase 用户请求)。
可观测性及一些要监控的指标
Metabase 暴露了一个可由 Prometheus 抓取的指标端点。理想情况下,您应该设置一些警报,以便在任何这些数字超过阈值时采取行动。
Metabase 应用程序
- API 响应时间
- CPU:最高 80%-90%
- 内存:最高 80%
Metabase 应用程序数据库
- CPU:最高 90%
- 内存:最高 80%
- 磁盘使用率:最高 80%。
- 磁盘 IOPS:检查您的磁盘是否支持 IOPS。如果您用于运行应用程序数据库的磁盘超出了其声称支持的 IOPS,那么您的磁盘将排队操作,这将影响性能。
何时增加连接池大小
默认情况下,Metabase 的连接池大小限制为 15 个连接。Metabase 将为每个连接的数据库管理一个连接池,包括一个用于应用程序数据库的连接池,每个连接池限制为 15 个连接。
为了处理更多并发用户使用 Metabase,您可以使用 MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE
环境变量覆盖应用程序数据库的连接限制。如果您增加此限制,您可能需要为应用程序数据库分配更多内存,因此您应该监控应用程序数据库的内存使用情况。如果数据库缺乏可用内存,数据库将排队连接,这意味着某些用户会发现 Metabase 无法响应,因为它正在等待内存释放。
Metabase 在任何给定时间都只使用其所需的连接。但是有些请求可能会占用这些连接中的大部分。例如,如果有人加载了一个包含 20 张卡片的仪表板,Metabase 将使用其 15 个可用连接来检索结果,并在连接可用时加载剩余的五张卡片。
使用负载均衡器
一个良好的架构实践是在 Metabase 之上使用负载均衡器,即使您只有一个服务器在运行且未进行任何水平扩展。稍后部署负载均衡器可能会更难实现,并且负载均衡器还可以执行 TLS 终止(即加密和解密 HTTP 流量)、WAF(Web 应用程序防火墙)、重定向以及其他常见任务。
请参阅简单的负载均衡。
日志
Metabase 会生成您应该保留的应用程序日志。这些日志对于调试和审计很有用。请查看我们关于日志配置的文档。
如果您在 Metabase 之上部署了负载均衡器或反向代理,我们建议您将这些日志保存到日志聚合器。这些日志将帮助您识别模式并在需要时进行调查。
通过 HTTPS 运行 Metabase
您可以通过 HTTPS 运行 Metabase,而无需使用负载均衡器或反向代理。
请注意,如果您使用同一台服务器同时运行 Metabase 和 TLS 终止(即 HTTPS),Metabase 将损失宝贵的 CPU 资源,这些资源将用于加密/解密流量。因此,您可能需要使用负载均衡器。
需要避免的陷阱
从他人的经验中学习。
我们建议您避免使用声称能够自动扩展的服务
根据我们的经验,许多声称能够自动扩展的服务,嗯,并不神奇。我们建议您设置一些可观测性指标,对其进行监控,并根据这些观测结果进行必要的扩展更改,因为您的 Metabase 使用量将随着您公司的发展而增长。
避免使用在服务器不使用时关闭的服务
如果您必须使用自动扩缩服务,请避免使用任何定期关闭不使用服务器的服务。
原因有二:
- 异步进程。Metabase 会运行一些异步进程,例如获取表的元数据、刷新模型或获取筛选器值。如果这些进程无法运行,用户将无法看到 Metabase 提供的许多功能。
- 启动时间。第二天首次登录您应用程序的用户将遭受巨大的性能损失,因为服务器必须从完全冷启动状态启动。
在其他云提供商上运行的问题
需要注意的是:许多云服务提供商会在共享基础设施上托管您的服务。在这种情况下,租户共享对 CPU 的访问。多租户服务器租用成本较低,并且只要您的 CPU 使用率保持在 100% 以下,它们就可以提供不错的性能。如果您的 Metabase 服务器在一段时间内使用了 100% 的 CPU,提供商可能会限制您分配的 CPU 性能,从而导致您的性能显著下降。共享基础设施中的磁盘 IOPS 也可能发生相同的限制。
升级到 Metabase 的新主要版本
通常,我们在次要版本之间(例如,从 1.51.1 到 1.51.2)不会对应用程序数据库的架构进行任何更改,因此您可以在次要版本之间无问题地升级和降级。
升级到主要版本时(例如,从 1.50.9 到 1.51.3),您应该预期会有一些停机时间,因为 Metabase 可能需要处理应用程序数据库的架构更改。架构更改所需的时间取决于您的应用程序数据库的大小。
下一步:管理 Metabase 中的用户
如何从管理数十个用户到数千个用户。