如何大规模运行 Metabase
将 Metabase 扩展到支持更多用户和数据库的最佳实践。
Metabase 是一款可扩展、久经考验的软件,被数万家公司用于提供高质量的自助分析。它通过水平扩展支持高可用性,并且开箱即用,效率很高:一台拥有 4GB RAM 的单核机器可以将 Metabase 扩展到支持数百个用户。

本文提供了关于如何在生产环境中随着用户和数据源数量的增加,保持 Metabase 顺畅运行的高层指导和最佳实践。每个数据系统都不同,因此我们只能从高层次讨论扩展策略,但您应该能够将这些策略应用到您的特定环境和使用场景中。
影响 Metabase 性能和可用性的因素
Metabase 在垂直和水平扩展方面都表现良好,但它只是您数据仓库的一个组成部分,您系统的整体性能将取决于您系统的构成和您的使用模式。影响您使用 Metabase 体验的主要因素包括
- 连接到 Metabase 的数据库数量。
- 每个数据库中的表数量。
- 数据仓库的效率。
- 仪表板中的问题数量。
例如,无论您运行多少个 Metabase 实例,如果一个问题需要运行一个您的数据库需要 30 分钟才能完成的查询:那就会花费 30 分钟。解决方案是重新评估您对该数据的需求(您是否每次都需要所有这些信息?)或找到提高数据库性能的方法,例如重新组织、索引或缓存您的数据。
数据库和表的数量也会影响客户端性能,但这仅在您管理数百个数据库和/或数千个表的大规模情况下才适用,因为元数据本身就可能查询量很大。为了在这种规模下保持平滑的性能,您可以 管理 Metabase 何时同步其元数据 与连接的数据库。
现在,让我们确保您的 Metabase 应用程序已得到充分优化以进行扩展。
垂直扩展
垂直扩展是一种“暴力”方法。为 Metabase 提供更多的 CPU 核心和内存,它将有更多的资源可用于其工作。如果您遇到与应用程序本身相关的性能问题(即与数据库的广度和大小无关),在更强大的机器上运行 Metabase 可以提高性能。
每 20 个并发用户,大约需要 1 个 CPU 核心和 1GB RAM
Metabase 开箱即用,效率很高。首先,一台单核机器和 2GB RAM 对于单用户或小型团队来说应该绰绰有余。
何时添加更多内存和 CPU 核心:如果您发现服务器始终使用当前资源(内存或计算)的 80% 以上。
Metabase 应用程序数据库的任何操作响应时间都应小于一秒(不包括 Metabase 连接到的数据仓库的响应时间)。
拥有 4-8GB 内存的机器应能处理数百个用户,如果需要,您可以增加 CPU 核心和内存量。
虽然增加 CPU 核心和内存可能有效,但通常最好使用水平扩展来支持更多用户。原因是每个 Metabase 实例都内置了数据库连接限制,以防止实例因请求而压垮您的数据仓库。您可以 增加实例可用的连接数,但我们仍然推荐使用多个实例。
水平扩展(推荐)
水平扩展不是增加运行 Metabase 的服务器大小,而是启动更多的服务器,每台服务器都运行 Metabase,并将它们连接到同一个应用程序数据库。这样,您可以结合使用多个 Metabase 实例和负载均衡器来将流量分发到这些实例。Metabase 开箱即支持水平扩展,因此您无需进行任何特殊配置即可运行多个 Metabase 实例。当 Metabase 服务器连接到现有的应用程序数据库时,它会识别自己是集群的一部分。
水平扩展的主要用例是提高可靠性(也称为“高可用性”),但水平扩展也可以提高多用户性能。当负载均衡时,高流量、CPU 密集型的 Metabase 实例在部分流量被导向其他实例时会表现更好(更快),因为 CPU 负载会在多台机器上分布。
Metabase 附带一个本地 H2 数据库 来存储您的应用程序数据(所有问题、仪表板、日志和其他 Metabase 数据),但在生产环境中运行时,您应该升级到一个关系数据库,例如运行在单独服务器上的 PostgreSQL。事实上,在水平扩展时,您必须使用运行在单独服务器上的关系数据库来存储您的应用程序数据。这样,所有 Metabase 实例都可以共享一个公共数据库。我们建议所有生产实例都使用独立的服务器上的外部数据库,即使您只运行一个 Metabase 实例,因此外部数据库并不是水平扩展的额外成本。
Metabase 使用外部 应用程序数据库 来存储用户会话数据,因此人们不必担心在 Metabase 实例出现故障时丢失保存的工作,管理员也不必处理配置粘性会话以确保用户连接到正确的 Metabase 实例。负载均衡器会将用户路由到可用的实例,以便他们可以继续工作。
利用基于时间的水平扩展
一些客户会根据一天中的时间调整 Metabase 实例的数量。例如,一些公司会在早上启动多个 Metabase 实例,以处理用户登录和运行晨报仪表板时产生的流量高峰,然后在下午(或晚上、周末)关闭这些实例以节省云支出。
对于像 Kubernetes 或 Google Cloud Platform 这样的环境,您需要参考各自系统的文档来设置类似的自动扩展规则。
简单的负载均衡
负载均衡器将流量分发到多个 Metabase 实例,以确保每个请求都获得最快的响应。如果一个 Metabase 实例暂时出现故障,负载均衡器会将请求路由到另一个可用的实例。
设置 Metabase 的负载均衡器很简单。Metabase 的 API 提供了一个健康检查端点 /api/health,负载均衡器可以调用该端点来确定 Metabase 实例是否正常运行并响应请求。如果实例健康,该端点将返回 HTTP 状态码 200 OK。否则,负载均衡器将知道将请求路由到另一个实例。
数据仓库调优
数据仓库的架构超出了本文的范围,但您应该知道,Metabase 中的查询速度仅限于数据库返回数据的速度。如果您提出的问题需要大量数据,而您的数据库检索这些数据需要很长时间,那么这些查询时间将影响您的体验,无论 Metabase 的速度有多快。
以下是一些改进数据仓库性能的方法
- 以一种预见人们将要提出的问题的方式来构建您的数据。 识别您的使用模式,并以一种易于返回组织中常见问题的结果的方式存储数据。编写 ETL 来创建新的表,将来自多个源的经常查询的数据整合在一起。
- 调优您的数据库。 阅读您的数据库文档,了解如何通过索引、缓存和其他优化来提高其性能。
- 过滤您的数据。鼓励人们在提问时过滤数据。他们还应该利用 Metabase 的数据探索工具(包括记录预览),以便只查询与他们要回答的问题相关的数据。
- 决定是使用数据库还是数据仓库。 人们通常使用 Metabase 入门,使用像 MySQL 或 PostgreSQL 这样的事务数据库。虽然这些数据库的扩展性很好,但它们通常没有针对 Metabase 将使用的分析查询进行优化。一旦达到一定规模,像
sum或max这样的操作可能会变慢。随着分析采用的增长,您可能会发现需要探索像 Amazon Redshift、Google BigQuery 或 Snowflake 这样的专用数据仓库。
Metabase 应用程序最佳实践
以下是一些充分利用您的 Metabase 应用程序的策略
- 仅请求您需要的数据.
- 使用托管关系数据库来存储您的 Metabase 应用程序数据.
- 缓存您的查询.
- 查找瓶颈.
- 增加到应用程序数据库的最大连接数.
- 增加到每个数据库的最大连接数.
- 仅在需要时与您的数据库同步.
- 升级到最新版本的 Metabase.
- 保持浏览器更新.
仅请求您需要的数据
如果人们运行大量返回大量记录的查询,Metabase 的速度快慢无关紧要:用户只能以数据仓库返回请求记录的速度获取数据。有时人们在仪表板上做得过多:当一个包含(例如)50 个问题的仪表板加载时,它会发送 50 个同时进行的请求来请求数据。根据数据库的大小,在这些记录返回之前可能需要很长时间。

但这并非全部。Metabase 不会因为您在仪表板中添加更多问题而减慢速度。如果您的查询不提取大量数据,或者您的数据仓库可以在一秒内返回结果,50 个问题将快速加载。
但总的来说,鼓励人们保持仪表板的重点。仪表板旨在讲述您的数据故事,您可以用几个问题(甚至一个问题)来讲述一个好故事。利用 Metabase 的数据探索工具来了解您的数据(例如,预览表格记录的功能),以便您只关注回答问题所需的记录。
因此,请确保每个问题都对完成仪表板是必需的,并且在查询时间或空间数据时要格外小心,因为您可以通过将问题限制在较短的时间范围或较小的区域来过滤掉大量不必要的数据。

使用托管关系数据库来存储您的 Metabase 应用程序数据
应用程序数据库存储您的所有问题、仪表板、集合、权限以及与 Metabase 应用程序相关的其他数据。您可以使用关系数据库(如 PostgreSQL 或 MySQL)来管理您的应用程序数据库,但我们推荐使用托管解决方案,如 AWS RDS。RDS 将自动进行备份,并使您可以轻松地根据需要调整存储和计算资源,从而减轻您的负担。
缓存您的查询
您可以 配置缓存 来存储最近提出的问题的结果,这样就不需要重新计算。Metabase 会向用户显示结果的时间戳,如果他们想重新运行查询,可以手动刷新问题结果。缓存适用于不经常更新的结果。

查找瓶颈
Pro 和 Enterprise 套餐 提供 使用情况分析,供您监控应用程序的使用情况和性能。例如,您可以查看有多少问题被提出,由谁提出,以及问题运行了多长时间,这有助于识别需要关注的瓶颈。

增加到应用程序数据库的最大连接数
Metabase 应用程序数据库的最大连接数由 MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE 环境变量指定,该变量当前默认为 15。如果您的使用量经常耗尽所有这些连接,通过增加最大连接数可以提高性能。或者,您可以通过水平扩展来增加连接数(例如,如果您添加一个额外的 Metabase 实例,您就相当于增加了 15 个到应用程序数据库的连接)。
您可以通过 查看日志 来检查连接数,并查找类似 ... App DB connections: 12/15 的行。在该示例中,Metabase 使用了 15 个可用应用程序数据库连接中的 12 个。
增加到每个数据库的最大连接数
同样,单个 Metabase 实例到每个数据库的默认最大连接数为 15。这意味着每个数据库 15 个连接,所以如果您将 Metabase 连接到两个数据库,您将最多有 30 个连接。
您可以更改 MB_JDBC_DATA_WAREHOUSE_MAX_CONNECTION_POOL_SIZE 环境变量来增加到每个数据库的最大连接数。与应用程序数据库连接一样,您也可以通过水平扩展来增加连接数。每个额外的 Metabase 实例将增加 15 个最大连接数(或您设置的任何最大值)。欲了解更多信息,请参阅我们的 环境变量文档。
仅在需要时与您的数据库同步
默认情况下,Metabase 每小时执行一次轻量级同步。同步不会复制您的任何数据。Metabase 仅检查以确保其应用程序数据库中维护的表、列和行列表与您的数据库中的表、列和行保持最新。
您可以 设置这些同步的时间和频率。对于大型数据库,您可以考虑限制 Metabase 执行同步的次数,并将同步限制在非高峰时段,尤其是在您不经常向数据库添加新表的情况下。

升级到最新版本的 Metabase
如果您还没有这样做,我们建议您 升级到最新版本的 Metabase,以获得最新的性能改进。
通过 HTTPS over HTTP/2 提供 Metabase
通过 HTTPS over HTTP/2 提供 Metabase 实例可以提高性能,因为 HTTP/1.1 浏览器对每个域的连接数限制约为 6 个,而 HTTP/2 则通过单个连接进行多路复用。更多可用连接无法解决数据库缓慢或 Metabase 实例线程耗尽的问题,但至少您知道您的浏览器没有限制您的连接。
保持浏览器更新
Metabase 是一个 Web 应用程序,可以受益于最新版本的浏览器,例如 Firefox、Chrome、Edge 和 Safari。
支持的部署
有许多方法可以设置 Metabase,我们最喜欢的一些包括
- AWS Elastic Beanstalk:请查看我们关于 在 Elastic Beanstalk 上设置 Metabase 的指南。我们使用 Elastic Beanstalk 来托管我们的内部 Metabase 应用程序。
- Docker:请参阅 在 Docker 上运行 Metabase。
Google Cloud Platform、Microsoft Azure、Digital Ocean 和其他云提供商为托管您的 Metabase 应用程序提供了其他很棒的选择。
托管 Metabase
如果您不想处理 Metabase 应用程序的维护和支持,Metabase 提供了一个 托管解决方案。您仍然需要确保您的数据源性能良好,但您不必再管理 Metabase 应用程序的运行了。
获取帮助
如果您仍有疑问,很可能有人已经问过同样的问题。请查看 Metabase 讨论论坛 并搜索您遇到的问题。如果您找不到解决方案,可以提出您自己的问题。