ClickHouse中的异步数据插入

简介: ClickHouse中的异步数据插入


介绍

ClickHouse 不仅被设计成快速查询,还适用于快速插入。ClickHouse 的表旨在每秒接收数百万行的插入,并存储大量数据(数百 PB)。高吞吐量的数据插入通常需要适当的客户端进行数据批处理。

在本文中,我们将描述高吞吐量下的另一种数据写入方式的机制:ClickHouse 异步数据插入将数据批处理的方式从客户端转移到服务器端,并支持客户端不适合批处理的场景。我们将深入了解异步插入,并使用模拟现实场景的示例应用来演示、基准测试和传统同步、异步插入方式的参数调优。


同步数据插入简介

对于MergeTree引擎系列中的传统插入,对于接收到插入的查询后,数据会以new data part的形式立即(同步地)写入到数据库存储中。下图说明了这一过程:

当 ClickHouse ① 接收到插入查询时,查询的数据 ② 会立即(同步地)以(至少)一个new data part(每个分区键)的形式写入到数据库存储中,之后, ③ ClickHouse 会确认插入查询的成功执行。

同时(以及以任何顺序),ClickHouse 还可以接收和执行其他插入查询(请参见图表中的 ④ 和 ⑤)。


为了实现最佳性能,数据需要进行批处理

在后台,为了逐步优化用于读取的数据,ClickHouse 不断地将data parts合并成较大的parts。合并过的parts会被标记为非活动状态,并最终在设定时长后(由old_parts_lifetime参数控制)被删除。创建和合并part需要消耗集群资源。为每个part创建和处理的文件,在宽格式中,每个表列都存储在单独的文件中。在复制模式中,会为每个part创建 ClickHouse Keeper 条目。此外,当写入新part时,数据会被排序和压缩。当parts合并时,需要对数据进行解压缩和合并排序。此外,在将合并的数据再次压缩并写入存储之前,还会应用特定于表引擎的优化。

用户应避免创建过多的小插入和过多小的parts。因为这会产生(1)在创建文件时的开销,(2)增加的写放大(导致更高的 CPU 和 I/O 使用率),以及(3)ClickHouse Keeper 请求的开销。这是因为在频繁小插入的情况下,由于高 CPU 和 I/O 使用率的开销,导致写入性能下降。留下较少的资源可用于查询和其他操作。

实际上,ClickHouse 实际上有内置保护机制(由参数parts_to_throw_insert控制),可以防止它花费太多资源来创建和合并parts:对于表 T 的插入查询,在 T 的单个分区上存在超过300个活动parts时,它将返回“Too many parts”的错误。为了防止发生这种情况,我们建议通过在客户端缓冲数据并将数据批量插入来发送少量但较大数据的插入,而不是许多小数据量的插入。理想情况下,每次插入至少有 1000 行或更多行。默认情况下,单个新part最多可以包含约 100 万行。如果单个插入查询包含超过 100 万行,ClickHouse 将为查询的数据创建多个new parts。

总体上,ClickHouse 能够通过传统的同步插入提供非常高的数据写入吞吐量。这也是用户特别选择 ClickHouse的原因之一。Uber 使用 ClickHouse 来每秒写入数百万条日志,Cloudflare 在 ClickHouse 中每秒存储 1100 万行,Zomato 每天可以写入多达 50 TB 的日志数据。

使用 ClickHouse 就像驾驶一辆高性能的一级方程式赛车 🏎。有大量的原始马力可用,您可以达到最高速度。但是,为了实现最佳性能,您需要在适当的时候换到足够高的档位,并相应地进行数据批处理。


有时客户端批处理是不可行的

有一些情况下,客户端批处理是不可行的。想象一下,有 100 多个或 1000 多个专用代理发送日志、指标、跟踪等的可观性用例,其中实时传输这些数据对于尽快检测到问题和异常至关重要。此外,在观察系统中可能会出现事件峰值,这可能导致在尝试在客户端缓冲可观性数据时出现大内存峰值和相关问题。


示例应用程序和基准测试设置

为了演示和基准测试一个不适合客户端批处理的场景,我们实现了一个名为 UpClick 的简单示例应用程序,用于监视 clickhouse.com(或任何其他网站)的全球延迟。以下图示描述了 UpClick 的架构:

我们使用了一个简单的serverless Google 云函数,每隔 n 秒( n 可配置)调度并执行一次,然后执行以下操作:


① 对 clickhouse.com 进行 ping(URL 可配置,并且可以轻松适应支持 URL 数组)

②通过 HTTP 接口将 ① 的结果与云函数的地理位置一起写入到 ClickHouse Cloud 服务中的目标表中


我们在基准测试中使用了一个具有6核24GiB的 ClickHouse Cloud 服务。该服务由 3 个2核8GiB的计算节点组成。

此外,我们 ③ 实现了一个实时的 Grafana 仪表板,每隔 n 秒更新一次,并在地理地图上显示了在欧洲、北美和亚洲的所有位置的过去 m 秒内的平均延迟,每个地理位置都部署了云函数。以下屏幕截图显示了欧洲的延迟情况:


在上面的仪表板截图中,通过颜色编码,我们可以看到访问 clickhouse.com 的延迟在荷兰和比利时低于(可配置的)指标,而在伦敦和赫尔辛基则高于此指标。

我们将使用 UpClick 应用程序来比较具有不同设置的同步和异步插入。

为了匹配实际的可观测性场景,我们使用一个负载生成器,可以创建和驱动任意数量的模拟云函数实例。通过这种方式,我们为基准测试运行创建和调度了 n 个云函数实例。每个实例每 m 秒执行一次。

在每次基准测试运行后,我们使用三个查询系统表的SQL进行监控(和可视化),以了解以下内容随时间变化情况:

  • 云函数目标表中活动parts的数量
  • 云函数目标表中所有parts(活动 + 非活动)的数量
  • ClickHouse Cloud 服务的 CPU 利用率

请注意,其中一些查询必须通过利用 clusterAllReplicas 表函数在具有特定名称的群集上执行。


同步插入基准测试

我们运行了以下参数的基准测试:

 

• 200 个 UpClick 云函数实例

• 每个云函数每 10 秒一次的调度/执行


实际上,每隔 10 秒就会向 ClickHouse 发送 200 次插入操作,导致 ClickHouse 每隔 10 秒创建 200 个新的数据分区。如果有 500 个云函数实例,ClickHouse 将每隔 10 秒创建 500 个新的数据分区,依此类推。这里可能会出现什么问题呢?

以下三个图表代表了基准测试运行期间目标表中活动parts的数量、所有parts(活动和非活动)的数量,以及 ClickHouse 集群的 CPU 利用率:

在基准测试开始后的 5 分钟内,活动parts的数量达到了上面提到的 Too many parts 错误的阈值,我们终止了基准测试。以每秒创建 200 个新的parts速度,ClickHouse 无法足够快地合并目标表的parts,以保持在 300 个活跃parts的阈值以下,防止自身陷入无法管理的局面。在 Too many parts 错误被触发时,云函数的表总共存在着近 30,000 个parts(活动和非活动)。请记住,合并过的parts会被标记为非活动,并在几分钟后删除。如上所述,创建和合并(过多的)parts需要消耗资源。我们试图让我们的方程式一号车 🏎 以最高速度行驶,但却选择了一个过低的档位,即通过频繁地发送非常小的插入操作。

请注意,对于我们的云函数来说,客户端批处理是不可行的设计模式。我们本可以使用聚合器(aggregator)或网关架构来批处理数据。然而,那会复杂化我们的架构并需要额外的第三方组件。幸运的是,ClickHouse 已经提供了我们问题的完美内置解决方案。


异步插入。


异步插入


描述


在传统的插入查询中,数据是同步插入到表中的:当ClickHouse 收到插入的query时,数据会立即写入到数据库存储中。

而在异步插入中,数据首先插入到缓冲区,然后稍后或异步地写入到数据库存储中。以下图表说明了这一点:

启用异步插入后,当 ClickHouse ① 接收到插入查询时,查询的数据首先被写入内存缓冲区中(②)。异步于 ①,只有在下一次刷缓冲区时(③),缓冲区的数据才会被排序并写入数据库存储中。请注意,在数据被刷到数据库存储之前,是搜索不到的;刷缓冲区是可配置的,我们稍后会展示一些示例。

在刷缓冲区之前,缓冲区会收集来自同一客户端或其他客户端的其他异步插入查询的数据。从缓冲区创建的parts可能包含来自多个异步插入查询的数据。总体上,这些机制将数据的批处理从客户端端转移到服务器端(ClickHouse 实例)。对于我们的 UpClick 用例来说非常适合。


可能会有多个parts


异步插入缓冲区中的行可能包含几个不同的分区键值,因此在刷缓冲区期间,ClickHouse 会为缓冲区中包含的不同分区键值,创建(至少)一个新的data part。此外,对于没有分区键的表,根据在缓冲区中收集的行数,缓冲区刷新可能会导致多个parts。


可能会有多个缓冲区


每个插入查询的形状(插入查询的语法,不包括值子句/数据)和setting都将有一个缓冲区。在多节点集群(例如 ClickHouse Cloud)上,每个节点将有自己的缓冲区。以下图表说明了这一点:

查询 ①、② 和 ③(以及 ④)具有相同的目标表 T,但不同的语法形状。查询 ③ 和 ④ 具有相同的形状,但不同的设置。查询 ⑤ 具有不同的形状,因为它的目标是表 T2。因此,所有 5 个查询都将有一个单独的异步插入缓冲区。当查询通过分布式表(自管理集群)或load balancer(ClickHouse Cloud)对多节点集群进行定位时,缓冲区将分别对应每个节点。

每个设置的缓冲区可以为同一表的不同数据提供不同的刷新时间。在我们的 UpClick 示例应用中,可能有一些需要在近实时内进行监控的重要站点(使用较低的 async_insert_busy_timeout_ms 设置),以及可以以更高时间粒度刷新不太重要的站点(使用较高的 async_insert_busy_timeout_ms 设置),从而减少此数据的资源使用。


插入是幂等的


对于 MergeTree 引擎系列的表,默认情况下,ClickHouse 将自动去重异步插入。这使得异步插入是幂等的,因此在以下情况下具有容错性:

  1. 如果节点在缓冲区刷新之前因某种原因崩溃,插入将超时(或得到更具体的错误),并且不会得到确认。
  2. 如果数据被刷新,但由于网络中断,确认不能返回给查询的发送者,发送者将获得超时或网络错误。

从客户端的角度来看,很难区分 1 和 2。然而,在这两种情况下,未确认的插入操作可以立即重试。只要以相同的数据按相同的顺序重试插入,如果(未确认的)原始数据插入成功,ClickHouse 将自动忽略重试的异步插入。


缓冲区刷新期间可能会出现插入错误


当刷缓冲区时,可能会发生插入错误:即使是使用异步插入,也可能会出现 Too many parts 错误。例如,使用不当的分区键。或者在缓冲区刷新时,执行缓冲区刷新的群集节点在某个特定时间点存在一些运行问题。此外,在缓冲区刷新时,异步插入查询的数据只会在将缓冲区刷新时解析并对目标表结构进行验证。如果由于解析或类型错误,某些行值无法插入,该查询的任何数据都不会被刷到存储(其他查询的数据刷新不受此影响)。ClickHouse 将把缓冲区刷新期间的插入错误编写详细的错误消息记录到日志文件和系统表中。稍后我们将讨论客户端如何处理此类错误。


异步插入 vs. 缓冲区表


通过buffer表引擎,ClickHouse 提供了一种类似于异步插入的数据插入机制。缓冲区表将接收的数据缓冲在主内存中,并定期将其刷新到目标表中。尽管如此,缓冲区表与异步插入之间存在重大差异:

  • 必须显式地创建buffer表(在集群上的每个节点),并将其连接到目标表。异步插入可以通过参数async_insert简单地进行设置。
  • 插入查询需要明确地针对buffer表,而不是真正的目标表。而在异步插入中则不需要。
  • 当目标表的 DDL 更改时,buffer表也需要进行 DDL 更改。而在异步插入中则不需要。
  • buffer表中的数据会在节点崩溃时丢失,类似于异步插入的“发射并忘记”模式。而在异步插入默认模式下,这种情况并不会发生。
  • 如上所述,异步插入为每个插入查询形状和setting提供了一个缓冲区,即使所有插入查询都针对同一表。为同一表中的不同数据启用细粒度数据刷新策略。buffer表是没有这种机制的。

总体而言,与buffer表相比,从客户端的角度来看,异步插入的缓冲机制是完全透明且完全由 ClickHouse 管理的。异步插入可以被视为缓冲区表的继任者。


支持的接口和客户端


异步插入支持 HTTP 和TCP协议,和一些流行的客户端,如 Go 客户端在开启查询设置、用户设置或连接设置级别上支持异步插入,或直接支持异步插入。


配置返回行为

您可以选择异步插入查询何时返回给查询的发送者以及何时插入的确认操作发生。通过 wait_for_async_insert 设置进行配置:

  • 默认的返回行为是,在下一次缓冲区刷新发生并插入的数据位于存储上后,插入查询才会返回给发送者。
  • 或者,通过将设置设置为 0,插入查询将在数据刚刚插入到缓冲区后立即返回。

我们称之为“点火并忘记”模式。

这两种模式都有相当显著的优缺点。因此,我们将在下面的两节中详细讨论这两种模式。


默认的返回行为


描述


以下图表描绘了异步插入的默认返回行为(wait_for_async_insert = 1 ):

当 ClickHouse ① 接收到插入查询时,查询的数据首先被写入内存缓冲区中(②)。当 ③ 发生下一次缓冲区刷新时,缓冲区的数据被排序并作为一个或多个data parts写入数据库存储中。在缓冲区刷新之前,其他插入查询的数据可以在缓冲区中被收集。仅在下一次常规的缓冲区刷新发生后,来自 ① 的插入查询将返回给发送者,并附带插入的确认。换句话说,发送插入查询的客户端端调用会在下一次缓冲区刷新发生时被阻塞。因此,上述图表中的 3 个插入不可能来自同一个单线程的插入循环,而是来自不同的多线程并行插入循环或不同的并行客户端/程序。


优势


这种模式的优势在于持久性保证 + 易于识别失败的批次:

  1. 持久性保证:当客户端获得插入的确认时,数据保证已写入数据库存储(并可以通过查询进行搜索)。
  2. 返回插入错误:当在缓冲区刷新期间发生插入错误时,查询的发送者会收到详细的错误消息,而不是确认。因为 ClickHouse 在缓冲区刷新之前一直等待返回插入的确认。
  3. 易于识别失败的数据集:如上所述,插入错误会及时返回,因此很容易识别无法插入的数据集。


劣势


这种模式的缺点在于,在使用单线程插入循环进行数据写入的情况下,可能会在某些场景中产生反压(back pressure):

  1. 获取下一个数据批次
  2. 发送带有数据的插入查询到 ClickHouse;现在调用会被阻塞,直到下一次缓冲区刷新发生
  3. 接收插入成功的确认
  4. 转到 1

在这种情况下,通过适当地对数据进行客户端批处理并使用多线程并行插入循环,可以增加写入吞吐量。


基准测试


我们进行了两个基准测试。


基准测试 1:

• 200 个 UpClick 云函数实例

• 每个云函数每 10 秒一次调度/执行

• 1 秒的缓冲区刷新时间


基准测试 2:

500 个 UpClick 云函数实例

• 每个云函数每 10 秒一次调度/执行

• 1 秒的缓冲区刷新时间


我们对这两个基准测试运行了以下异步插入设置:

async_insert = 1

② wait_for_async_insert = 1

③ async_insert_busy_timeout_ms = 1000

④ async_insert_max_data_size = 1_000_000

⑤ async_insert_max_query_number = 450


① 启用异步插入。通过 ②,我们设置了上述异步插入的默认返回行为。我们配置了缓冲区应该在每秒刷新一次,或者如果 ④ 数据达到 1 MB,或者如果 ⑤ 收集了来自 450 个插入查询的数据。无论发生什么情况,都会触发下一次缓冲区刷新。在 ClickHouse 中,②、③、④、⑤ 都是默认值(OSS 中 ③ 的默认值为 200 ,在 ClickHouse Cloud 中为 1000 )。

以下三个图表显示了云函数基准测试的第一个小时内活动parts的数量、云函数目标表中所有parts(活动和非活动parts)的数量,以及 ClickHouse 集群的 CPU 利用率:

您可以看到,不管我们运行了多少个云函数实例(200 个或 500 个,甚至更多的情况,如 1000 个等等),活动parts的数量都保持稳定在 8 个以下。而云函数目标表中所有parts(活动和非活动parts)的数量在运行了多少个云函数实例(200 个或 500 个)时都保持稳定在 1300 个以下。

这就是使用异步插入进行 UpClick 云函数的优势所在。无论我们运行多少个云函数实例 - 200 个、500 个,甚至 1000 个以上 - ClickHouse 都会对从云函数接收的数据进行批处理,并每秒创建一个新的数据分区。因为我们将 async_insert_busy_timeout_ms 设置为 1000 。我们在足够高的挡位上以足够高的速度驾驶着我们的 F1 赛车🏎,从而最大程度地减少了用于数据写入的 I/O 和 CPU 周期。正如您所看到的,与此前在本文中所做的传统同步插入基准测试相比,两个基准测试运行的 CPU 利用率要低得多。使用 500 个并行客户端运行的基准测试的 CPU 利用率高于使用 200 个并行客户端运行的基准测试的 CPU 利用率。对于具有 500 个客户端的情况,当每秒刷新一次时,缓冲区包含更多数据。并且在缓冲区刷新期间创建新的parts和较大的parts合并时,ClickHouse 需要花费更多的 CPU 周期来对数据进行排序和压缩。

请注意, async_insert_max_data_size async_insert_max_query_number 可能会在不到一秒的时间内触发缓冲区刷新,尤其是在大量的云函数或客户端的情况下。您可以将这两个参数设置更高的值,以确保仅时间参数触发缓冲区刷新,从而牺牲以暂时性更高的主内存使用量为代价。


发射并忘记(Fire-and-forget )返回行为


描述


以下图表说明了异步插入的可选发射并忘记返回行为(wait_for_async_insert = 0 ):

当 ClickHouse ① 接收到插入查询时,查询的数据首先被写入内存缓冲区中(②)。之后,③ 插入查询将返回确认给发送者。在下一次常规缓冲区刷新发生时,缓冲区的数据将被排序并作为一个或多个data parts写入数据库存储中。在缓冲区刷新之前,其他插入查询的数据可以在缓冲区中被收集。


优势

这种模式的优势在于使用单线程插入循环的客户端可以实现非常高的数据写入吞吐量(并且集群资源利用率最小):



劣势


然而,这种模式也带来了劣势:

  1. 没有持久性保证

即使客户端获得已插入的确认,也不一定意味着查询的数据已经或将被写入数据库存储。插入错误可能会在缓冲区刷新期间发生。并且在下一次常规内存缓冲区刷新之前,ClickHouse 节点崩溃或关闭时可能会发生数据丢失。更糟糕的是,这可能是沉默的数据丢失,因为客户端很难找出这些异常事件,因为最初的插入已经成功确认到缓冲区中。对于 ClickHouse 节点的正常关闭,有一个系统命令可以刷新所有异步插入缓冲区。此外,有一个服务端参数决定是否在正常关闭时自动刷新异步插入缓冲区。

  1. 插入错误不会返回

当在缓冲区刷新期间发生插入错误时,缓冲区中的原始插入仍然返回客户端写入成功的确认。客户端只能通过检查日志文件和系统表来事后发现这些插入错误。在第二篇文章中,我们将提供相关指导。

  1. 很难定位失败的数据集

在前面提到的沉默插入错误的情况下,识别此类失败的数据集是棘手且复杂的。ClickHouse 目前并没有在任何地方记录这些失败的数据集。为了识别事后无法插入的数据集,可以为发射并忘记模式中失败的异步插入设置一个死信队列。

通常来说,发射并忘记模式下的异步插入,只适用于可以接受数据丢失的情况。


基准测试

我们进行了两个基准测试。


基准测试 1:


500 个 UpClick 云函数实例

• 每个云函数每 10 秒一次调度/执行

• 5 秒的缓冲区刷新时间


基准测试 2:


500 个 UpClick 云函数实例

• 每个云函数每 10 秒一次调度/执行

• 30 秒的缓冲区刷新时间


我们对这两个基准测试运行了以下异步插入设置:


① async_insert = 1

② wait_for_async_insert = 0

③ async_insert_busy_timeout_ms = 5000(基准测试 1)

  async_insert_busy_timeout_ms = 30_000(基准测试 2)

④ async_insert_max_data_size = 100_000_000

⑤ async_insert_max_query_number = 450_000


① 启用异步插入。通过 ②,我们启用了上述异步插入的发射并忘记返回行为。缓冲区应在基准测试 1 中每 5 秒刷新一次,在基准测试 2 中每 30 秒刷新一次。请记住,仅在缓冲区被刷新到数据库存储的data parts之后,数据才能查询到。通过 ④ 和 ⑤,我们将另外两个缓冲区刷新阈值设置为较高的值,以确保只有时间设置 ③ 触发缓冲区刷新。

以下三个图表显示了云函数基准测试的第一个小时内活动parts的数量、云函数目标表中所有parts(活动和非活动parts)的数量,以及 ClickHouse 集群的 CPU 利用率:

无论基准测试运行了多少次,活动parts的数量都保持稳定在 7 个以下。所有parts(活动和非活动parts)在缓冲区刷新频率降低 6 倍时会减少约 6 倍。与在本文前面所做的默认异步插入返回行为的基准测试运行中每秒刷新一次缓冲区相比,只有每 5 或 30 秒刷新一次缓冲区时,CPU 利用率会降低。然而,这两个基准测试运行的 CPU 利用率非常相似。当缓冲区每 30 秒刷新一次时,ClickHouse 会创建更少但更大的分区,从而增加排序和压缩数据的 CPU 资源需求。


总结

在本篇博文中,我们探讨了 ClickHouse 异步数据插入的机制。我们讨论了在高写入吞吐量场景中,传统的同步插入需要适当的客户端数据批处理。相比之下,通过将数据批处理从客户端转移到服务器端,异步插入会自动保持parts创建的频率,从而支持不适合客户端批处理的场景。我们使用了一个示例应用程序来演示了基准测试和调整传统同步插入和异步插入下的不同参数设置。希望您可以学到新的方法来加速您的 ClickHouse使用场景。



相关文章
|
2月前
|
存储 SQL 关系型数据库
ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计
ClickHouse的核心架构包括执行过程和数据存储两部分。执行过程涉及Parser与Interpreter解析SQL,通过Column、DataType、Block、Functions和Storage模块处理数据。Column是内存中列的表示,Field处理单个值,DataType负责序列化和反序列化,Block是内存中表的子集,Block Streams处理数据流。Storage代表表,使用不同的引擎如StorageMergeTree。数据存储基于分片和副本,1个分片由多个副本组成,每个节点只能拥有1个分片。
89 0
ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计
|
2月前
|
分布式计算 DataWorks 调度
DataWorks报错问题之dataworks同步clickhouse数据报错如何解决
DataWorks是阿里云提供的一站式大数据开发与管理平台,支持数据集成、数据开发、数据治理等功能;在本汇总中,我们梳理了DataWorks产品在使用过程中经常遇到的问题及解答,以助用户在数据处理和分析工作中提高效率,降低难度。
|
7月前
|
存储 SQL 编解码
如何在ClickHouse中处理时序数据
ClickHouse具有强大的工具,可以高效地存储和处理时序数据,并可用于简单的解决方案和数据发掘,以及支持PB级的实时分析应用。
|
8月前
|
SQL 关系型数据库 MySQL
ClickHouse同步MySQL数据
ClickHouse同步MySQL数据
252 0
|
存储 索引
67.【clickhouse】ClickHouse从入门到放弃-对于分区、索引、标记和压缩数据的协同总结
【clickhouse】ClickHouse从入门到放弃-对于分区、索引、标记和压缩数据的协同总结
67.【clickhouse】ClickHouse从入门到放弃-对于分区、索引、标记和压缩数据的协同总结
|
存储 缓存 数据库
66.【clickhouse】ClickHouse从入门到放弃-数据标记
【clickhouse】ClickHouse从入门到放弃-数据标记
66.【clickhouse】ClickHouse从入门到放弃-数据标记
|
存储 算法 数据库
62.【clickhouse】ClickHouse从入门到放弃-数据分区
【clickhouse】ClickHouse从入门到放弃-数据分区
62.【clickhouse】ClickHouse从入门到放弃-数据分区
|
存储 Serverless
ClickHouse 数据基本类型
ClickHouse 数据基本类型
351 0
ClickHouse 数据基本类型
clickhouse数据文件目录移动到新目录并建立软连接
原目录:/var/lib/clickhouse目标目录:/test/clickhouse 1、复制数据cp /var/lib/clickhouse/data -r ...
3416 0
|
网络协议 数据可视化 Ubuntu
使用 Apache Superset 可视化 ClickHouse 数据
Apache Superset是一个强大的BI工具,它提供了查看和探索数据的方法。它在 ClickHouse 用户中也越来越受欢迎。 我们将介绍安装 Superset 的 2 种方法,然后展示如何从 Superset 连接到您的第一个 ClickHouse 数据库。代码示例基于 Ubuntu 18.04、Superset 1.1.0 和 clickhouse-sqlalchemy 0.1.6。
733 0
使用 Apache Superset 可视化 ClickHouse 数据

热门文章

最新文章