如何在生产环境中运行 Metabase

如果你是自行托管Metabase,以下是一些基准和最佳实践。

本文描述了一个生产就绪的Metabase设置的外观,包括服务器大小、最佳实践和要避免的陷阱。本文面向有兴趣自行托管Metabase的人。如果您希望我们为您运行Metabase,请只需注册免费试用

Metabase JAR中包含的内容

为了便于理解,Metabase是一个网络应用程序。其后端是用Clojure编写的,其前端是用JavaScript、TypeScript和Clojurescript编写的,使用了React框架。

默认情况下,整个应用程序都是自包含的:后端和提供前端服务的网络服务器都包含在同一捆绑包中。该捆绑包是一个JAR文件,可以在安装了Java运行时环境的任何地方运行。

Metabase还提供了一个Docker容器,它打包了JRE和Metabase JAR(您也可以使用Podman运行)。

您只需要JAR和一个数据库

Metabase JAR running in a container, saving its application data in a Postgres database.

在生产环境中运行Metabase需要两样东西

  1. 要么是Metabase JAR,要么是Docker镜像。
  2. 一个专用的PostgreSQL数据库来存储Metabase的应用程序数据库

您也可以使用MySQL/MariaDB来存储Metabase的应用程序数据库,但只有当您对MySQL比对PostgreSQL更熟悉时才使用MySQL。

为什么你需要使用单独的应用程序数据库

Metabase将其所有实体(仪表板、问题、账户、配置)保存在其应用程序数据库中。

如果您坚持使用默认的基于文件的应用程序数据库,您的数据库最终将变得不可修复地损坏,您将不得不从头开始(在丢失所有工作:所有问题、仪表板等之后)。

所以,您要避免的一件事就是使用随Metabase JAR一起提供的默认应用程序数据库。这个嵌入式数据库仅适用于本地使用。我们将该嵌入式数据库作为一种派对礼物提供给那些只想在自己的机器上尝试Metabase的人。该嵌入式H2数据库还包含一些供人们玩耍的示例数据。它**不适用于生产环境**。

同样,如果您在容器中运行Metabase,每次容器被新版本替换时,您都将丢失所有工作。容器是为了短暂的,所以不要在容器中保留数据。

您可以通过使用专用PostgreSQL应用程序数据库来避免所有这些问题。

如果您已经开始了默认的H2数据库的使用

没关系。但您应该尽快迁移到生产数据库

Metabase应用程序和数据库服务器及其大小

我们建议您运行至少两个实例(理想情况下在同一网络)

您想在同一网络中运行这些实例的原因是为了减少Metabase(应用程序)从存储其应用程序数据的数据库获取响应所需的时间。Metabase的绝大多数操作都需要调用Metabase的API,该API使用应用程序数据库检索有关问题、仪表板、表元数据等信息。

Metabase应用程序服务器大小

对于每20个同时使用您的Metabase的人,Metabase将需要1个CPU和1GB的RAM。这些系统建议适用于您将Metabase作为JAR或作为Docker容器运行的情况。

Metabase应用程序数据库服务器大小

应用程序数据库可能是整个架构中最重要的组件:它是单一故障点,应用程序数据库返回查询到Metabase应用程序服务器越快,性能越好。作为起点,为运行应用程序数据库的服务器分配1个CPU核心和2GB的RAM。作为一般规则,对于每40个同时使用您的Metabase的人,PostgreSQL应用程序数据库将需要1个CPU核心和1GB的RAM。

每个Metabase环境都必须有其自己的专用应用程序数据库

我们所说的环境是指一个或多个Metabase JAR(或Docker镜像)和一个应用程序数据库。如果您正在运行多个环境,您可以在同一应用程序数据库服务器上运行多个应用程序数据库,每个环境一个,但每个环境都必须有其自己的专用应用程序数据库。

维护

保持一切顺利运行。

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

为了便于理解,测试在 Metabase v44.7 版本、16 核心和 4GB RAM 的服务器上运行。它配置了环境变量 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 将运行的最大异步进程数是三个,因为应该有一个核心用于服务人们的请求(一个核心应该能够服务大约 15 个同时使用 Metabase 的人的请求)。

可观测性和需要关注的指标

理想情况下,您应该设置一些警报,以便在这些数字超过这些阈值之一时采取行动。

Metabase 应用程序

  • API 响应时间
  • CPU:80%-90% 最大
  • RAM:80% 最大

Metabase 应用程序数据库

  • CPU:90% 最大
  • RAM:80% 最大
  • 磁盘使用率:80% 最大。
  • 磁盘 IOPS:检查您的磁盘 IOPS 支持情况。如果您用于运行应用程序数据库的磁盘超过了磁盘声称支持的 IOPS,那么您的磁盘将排队操作,这将影响性能。

何时增加连接池大小

默认情况下,Metabase 的连接池大小为 15 个连接。要处理更多同时使用 Metabase 的人,您可以使用环境变量 MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE 设置更高的值。但更多的连接将需要在应用程序数据库中更多的 RAM,因此您需要监控 RAM 使用情况。如果数据库缺乏空闲 RAM,数据库将尝试排队连接,并且有些人会发现 Metabase 在等待 RAM 释放时无响应。

Metabase 只使用它在任何给定时间需要的连接。但某些请求可以占用许多这些连接。例如,如果有人加载了一个包含 20 张卡片的大纲,Metabase 将使用其 15 个可用的连接来检索结果,并在连接可用时加载剩余的五张卡片。

使用负载均衡器

A Metabase setup with a load balancer.

一个好的架构实践是在 Metabase 上使用负载均衡器,即使您只有一个服务器在运行,并且没有进行横向扩展。稍后部署负载均衡器可能会更难实现,负载均衡器还可以执行 TLS 终止(即加密和解密 HTTP 流量)、WAF(Web 应用程序防火墙)、重定向和其他常见任务。

请参阅 简单的负载均衡

日志

Metabase会生成应用程序日志,您应该保留这些日志。这些日志对于调试和审计都很有用。请查看我们关于日志配置的文档。

如果您还在Metabase之上部署了负载均衡器或反向代理,我们建议您将这些日志保存到日志聚合器中。这些日志将帮助您识别模式并在需要时进行调查。

Metabase通过HTTPS

您可以在不使用负载均衡器或反向代理的情况下,通过HTTPS来提供服务Metabase。

请注意,如果您使用同一服务器同时运行Metabase和TLS终止(即HTTPS),Metabase将失去在加密/解密流量上花费的有价值的CPU资源。因此,您可能想要使用负载均衡器

要避免的陷阱

从他人的经验中学习。

我们建议您避免声称自动扩展的服务

根据我们的经验,许多声称自动扩展的服务并不神奇。我们反而建议您实施一些可观察性指标,并对其进行监控,然后根据这些观察结果进行必要的扩展更改,因为随着您的公司发展,您的Metabase使用量也会增长。

避免在未使用时关闭服务器的服务

如果您必须使用自动扩展服务,请避免任何在未使用时定期关闭服务器的服务。

原因有两方面

  1. 异步进程。Metabase运行一些异步进程,例如获取您的表的元数据、刷新模型或获取过滤器值。如果这些进程不能运行,人们将看不到Metabase提供的许多功能。
  2. 启动时间。下一次登录到您的应用程序的人将遭受巨大的性能损失,因为服务器需要从完全冷启动中启动。

在云提供商上运行的问题

请注意:许多云服务提供商将在共享基础设施上托管您。在这种情况下,租户共享对CPU的访问权。多租户服务器可能更便宜,并且只要您的CPU使用率保持在100%以下,它们可以提供良好的性能。如果您的Metabase服务器在一段时间内使用了100%的CPU,服务提供商可能会限制您分配的CPU的性能,并且您的性能将显著下降。相同的限制也可能发生在共享基础设施中的磁盘IOPS上。

下一节:Metabase中的人员管理

如何从管理数十个用户发展到数千个用户。

下一篇文章