大规模使用 Metabase
为支持更多用户和数据库而扩展 Metabase 的最佳实践。
Metabase 是一款可扩展、经过实战考验的软件,被成千上万的公司用于提供高质量的自助式分析。它通过横向扩展支持高可用性,并且开箱即用效率很高:一个配备 4 GB RAM 的单核机器可以将 Metabase 扩展到数百个用户。
本文提供了关于如何在用户和数据源数量增加的情况下,保持 Metabase 在生产环境中平稳运行的高级指导和最佳实践。每个数据系统都不同,因此我们只能从高层次讨论扩展策略,但您应该能够将这些策略应用到您的特定环境和使用情况。
影响 Metabase 性能和可用性的因素
Metabase 在垂直和水平方向上都具有良好的可扩展性,但它只是您的数据仓库的一个组成部分,您系统的整体性能将取决于系统的构成和使用模式。影响您使用 Metabase 体验的主要因素包括
- 连接到 Metabase 的数据库数量。
- 每个数据库中的表数量。
- 您的数据仓库的效率。
- 仪表板中的问题数量。
例如,如果您的问题需要运行一个数据库需要 30 分钟才能完成的查询,那么您运行多少个 Metabase 实例都无关紧要:它仍然需要 30 分钟。解决方案是重新评估您对该数据的需求(您每次真的需要所有这些信息吗?)或寻找提高数据库性能的方法,例如重组、索引或缓存您的数据。
数据库和表的数量也会影响客户端性能,但这仅限于大规模情况,即您管理着数百个数据库和/或数千个表,因为元数据本身就很多,需要查询。为了即使在此规模下也能保持平稳的性能,您可以管理 Metabase 与您连接的数据库同步其元数据的时间。
现在,让我们确保您的 Metabase 应用程序经过良好调整以进行扩展。
垂直扩展
垂直扩展是一种暴力方法。为 Metabase 提供更多的核心和内存,它将拥有更多可用资源来完成其工作。如果您遇到与应用程序本身相关的性能问题(即与您的数据库的广度和规模无关的问题),在更强大的机器上运行 Metabase 可以提高性能。
每 20 个并发用户大约需要 1 个 CPU 核心和 1GB 内存
Metabase 开箱即用效率很高。首先,一台配备 2 GB RAM 的单核机器对于单个用户或小型团队来说应该绰绰有余。
何时增加更多内存和核心:如果您发现服务器持续使用其当前资源(内存或计算)的 80% 以上。
Metabase 应用程序数据库的任何操作(不包括连接到 Metabase 的数据仓库的响应时间)响应时间应小于一秒。
配备 4-8 GB RAM 的机器应能处理数百个用户,如果需要,您可以增加核心数和内存大小。
虽然增加更多的核心和内存可能有效,但通常最好使用水平扩展来支持更多用户。原因是每个 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 的数据探索工具(包括记录预览),以便只查询与他们试图回答的问题相关的数据。
- 决定是使用数据库还是数据仓库。人们通常使用事务型数据库(如 MySQL 或 PostgreSQL)开始使用 Metabase。虽然这些数据库的扩展性很好,但它们通常没有针对 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 将向人们显示结果的时间戳,如果他们想重新运行查询,他们可以手动刷新问题的结果。缓存适用于不经常更新的结果。
寻找瓶颈
专业版和企业版计划提供使用情况分析,供您监控应用程序的使用情况和性能。例如,您可以查看提出了多少问题,由谁提出,以及问题运行了多长时间,这有助于识别任何需要注意的瓶颈。
增加到应用程序数据库的最大连接数
到 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/HTTP/2 提供 Metabase 服务
通过 HTTPS over HTTP/2 提供 Metabase 实例服务可以提高性能,因为 HTTP/1.1 上的浏览器可以将每个域的连接限制在大约 6 个并发连接,而 HTTP/2 则在单个连接上进行多路复用。更多可用的连接并不能解决慢速数据库或线程耗尽的过载 Metabase 实例问题,但您至少会知道您的浏览器没有限制您的连接。
保持浏览器最新
Metabase 是一个网络应用程序,可以受益于最新版本的浏览器,例如 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 讨论论坛并搜索您的问题。如果您找不到解决方案,请自行提交问题。