如何在生产环境中运行 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 个核心和 1GB 的 RAM 作为基准。除此之外,每 20 个同时使用你的 Metabase 的用户,Metabase 将需要 1 个 CPU 和 2GB 的 RAM。无论你是将 Metabase 作为 JAR 还是容器镜像运行,这些系统建议都适用。例如,如果你有 40 个并发用户,你总共需要 3 个 CPU 核心和 5GB 的 RAM。
注意:在 v52 之前,我们建议每 20 个并发用户仅需 1GB 内存,但我们在较新版本中提高了此要求,以确保安全。
Metabase 应用程序数据库服务器大小
应用程序数据库可能是整个架构中最重要的组件:它是单点故障,应用程序数据库向 Metabase 应用程序服务器返回查询的速度越快越好。作为起点,为运行你的应用程序数据库的服务器分配 1 个 CPU 核心和 2GB 的 RAM。作为一般规则,每 40 个同时使用你的 Metabase 的用户,PostgreSQL 应用程序数据库将需要 1 个 CPU 核心和 1 GB 的 RAM。
每个 Metabase 环境都必须有自己的专用应用程序数据库
环境是指一个或多个 Metabase jar(或容器镜像)和一个应用程序数据库。如果你运行多个环境,你可以在同一个应用程序数据库服务器上为每个环境运行多个应用程序数据库,但每个环境必须有自己的专用应用程序数据库。
维护
保持平稳运行。
Metabase 服务器维护
你无需做任何事情。它应该可以正常工作。
Metabase 应用程序数据库维护
所有数据库都需要维护才能获得最佳性能,PostgreSQL 和 MySQL 也不例外。遵循 PostgreSQL 的维护最佳实践 (https://postgresql.ac.cn/docs/current/maintenance.html) (尤其是备份
此应用程序数据库应
- 每天备份。
- 每周进行清理和分析。
此外,应定期归档和删除不再需要的卡片和仪表盘。
数据仓库服务器维护
数据仓库的维护取决于你正在使用的数据仓库。请参阅数据库的文档以获取指导。
负载测试示例
在这个简单的负载测试中,Metabase API 在 K6 上实现了以下指标
checks.........................: 100.00% ✓ 237963 ✗ 0
data_received..................: 16 GB 7.1 MB/s
data_sent......................: 119 MB 52 kB/s
http_req_blocked...............: avg=4.19µs min=559ns med=3.5µs max=37.63ms p(90)=5.9µs p(95)=7.2µs
http_req_connecting............: avg=211ns min=0s med=0s max=37.55ms p(90)=0s p(95)=0s
http_req_duration..............: avg=41ms min=1.21ms med=20.28ms max=8.1s p(90)=84.22ms p(95)=125.62ms
{ expected_response:true }...: avg=41ms min=1.21ms med=20.28ms max=8.1s p(90)=84.22ms p(95)=125.62ms
http_req_failed................: 0.00% ✓ 0 ✗ 259596
http_req_receiving.............: avg=12.02ms min=8.64µs med=57.34µs max=778.49ms p(90)=41.43ms p(95)=67.33ms
http_req_sending...............: avg=17.39µs min=3.32µs med=15.13µs max=5.86ms p(90)=26.11µs p(95)=32.59µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=28.96ms min=1.18ms med=14.86ms max=8.1s p(90)=61.91ms p(95)=84.26ms
http_reqs......................: 259596 113.584624/s
iteration_duration.............: avg=18.29s min=17.6s med=17.81s max=29s p(90)=19.85s p(95)=20.88s
iterations.....................: 7211 3.155128/s
vus............................: 1 min=1 max=100
vus_max........................: 100 min=100 max=100
作为背景,该测试在具有 16 个核心和 4GB RAM 的服务器上使用 Metabase v44.7 运行。它配置了环境变量 JAVA_TOOL_OPTIONS: -Xmx3584m -Xms2048m
。应用程序数据库是 Postgres 版本 15.2,具有 2 个核心和 4GB RAM。没有 HTTPS。
负载测试无法模拟真实生活中的使用情况。通常,人们在你的 Metabase 中的活动将生成不同的 API 调用模式。你还将在后台运行异步进程。如果 Metabase 缺少足够的 CPU 资源,它将对操作进行排队。如果队列溢出,Metabase 可能会崩溃并尝试恢复。在这种情况下,你需要分配更多核心。
异步进程
Metabase 将定期运行异步进程,这些进程将根据你的表上的表数量和列数量使用 CPU 和 RAM。
这些进程是
- 同步
- 扫描
- 指纹识别
- 字段值
- 模型缓存
- 问题元数据
如果你看到 Metabase 在某个时间段内使用了大量 CPU,请检查日志以查看 Metabase 是否正在运行这些进程中的任何一个。如果是这样,你可以安排这些任务在人们不使用你的 Metabase 时运行。
Metabase 会将每个这些任务分配给一个核心。如果你的服务器有四个核心,Metabase 将运行的最大异步进程数是三个,因为应该有一个核心可用于服务人们的请求(一个核心应该能够同时为大约 10 个使用 Metabase 的人提供请求服务)。
可观测性和一些需要关注的指标
Metabase 公开了一个指标端点,Prometheus 可以抓取该端点。理想情况下,你应该设置一些警报,以便在任何这些数字超过这些阈值之一时采取措施。
Metabase 应用程序
- API 响应时间
- CPU:最大 80%-90%
- RAM:最大 80%
Metabase 应用程序数据库
- CPU:最大 90%
- RAM:最大 80%
- 磁盘使用率:最大 80%。
- 磁盘 IOPS:检查你的磁盘的 IOPS 支持。如果你用于运行应用程序数据库的磁盘超过了磁盘声称支持的 IOPS,那么你的磁盘将对操作进行排队,这将影响性能。
何时增加连接池大小
默认情况下,Metabase 的连接池大小限制为 15 个连接。Metabase 将为每个连接的数据库管理一个池,包括应用程序数据库的一个池,每个池限制为 15 个连接。
为了处理更多人同时使用你的 Metabase,你可以使用 MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE
环境变量覆盖应用程序数据库的连接限制。如果你增加此限制,你可能需要为你的应用程序数据库提供更多 RAM,因此你应该监视你的应用程序数据库的 RAM 使用情况。如果数据库缺少可用 RAM,数据库将对连接进行排队,这意味着当 Metabase 等待 RAM 释放时,有些人会发现 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)对应用程序数据库的 schema 进行任何更改,因此您可以在次要版本之间无问题地升级和降级。
当升级到主要版本时(例如,从 1.50.9 到 1.51.3),您应该预计会有一些停机时间,因为 Metabase 可能需要处理应用程序数据库的 schema 更改。schema 更改所需的时间取决于您的应用程序数据库的大小。
下一步:在 Metabase 中管理用户
如何从管理数十个用户扩展到管理数千个用户。