适用于大数据的开源OLAP系统的比较:ClickHouse,Druid和Pinot

在这篇文章中,我想比较ClickHouse,Druid和Pinot这三个开放源数据存储,它们通过交互延迟对大量数据运行分析查询。

警告:这篇文章很大,您可能只想阅读最后的"摘要"部分。

信息来源

我从核心开发人员之一Alexey Zatelepin那里了解了ClickHouse的实现细节。 本文档页面的最后四个部分是英语提供的最好的材料,但是非常稀缺。

我是Druid的提交者,但是我对这个系统没有既得利益(实际上,我可能很快就会停止参与它的开发),因此读者可以期望我对Druid相当客观 。

我在这篇关于Pinot的文章中写的所有内容都是基于Pinot Wiki中的Architecture页面以及" Design Docs"部分中的其他Wiki页面,这些页面的最新更新于2017年6月,已经有半年多了。

这篇文章还评论了Alexey Zatelepin和Vitaliy Lyudvichenko(ClickHouse的开发人员),Gian Merlino(PMC成员和Druid的最活跃开发人员),Kishore Gopalakrishna(黑皮诺的建筑师)和Jean-FrançoisIm(黑皮诺的开发人员)。 感谢审稿人。




在选择大数据OLAP系统时,请不要比较它们在当前用例中的最佳状态。 目前,它们都非常次优。 比较您的组织可以使这些系统朝着使您的用例更优化的方向移动的速度。

由于其基本的架构相似性,ClickHouse,Druid和Pinot在效率和性能优化上具有大约相同的"极限"。 没有"魔术药"可以使这些系统中的任何一个都比其他系统快得多。 在当前状态下,系统在某些基准测试中的性能差异很大,因此请不要为之困惑。 例如 目前,Druid不像ClickHouse(请参见上文)那样很好地支持"主键排序",而ClickHouse不像Druid那样不支持倒排索引,这使得这些系统在特定工作负载方面处于优势。 如果您有意愿和能力,则可以在选定的系统中实施缺少的优化,而无需花费很多精力。

· 您的组织中的任何一个都应该具有能够阅读,理解和修改所选系统的源代码并具有执行此功能的工程师。 请注意,ClickHouse用C ++,Druid和Pinot用Java编写。

· 或者,您的组织应与提供所选系统支持的公司签订合同。 ClickHouse有Altinity,德鲁伊有Imply和Hortonworks。 目前没有针对Pinot的此类公司。

其他开发注意事项:

· Yandex的ClickHouse开发人员表示,他们将50%的时间用于构建公司内部所需的功能,而50%的时间用于"社区投票"次数最多的功能。 但是,要从中受益,您在ClickHouse中所需的功能应与社区中大多数其他人所需的功能匹配。

· Imply的Druid开发人员具有建立广泛适用的功能的动机,以最大程度地发展其未来业务。

· Druid的开发过程与Apache模型非常相似,多年来,它是由几家公司开发的,这些公司的优先级相差很大,而且没有一家公司占有主导地位。 ClickHouse和Pinot目前距离该州还很遥远,它们分别是分别由Yandex和LinkedIn开发的。 对德鲁伊的贡献以后被拒绝或撤销的可能性最小,因为它们与主要开发者的目标不一致。 德鲁伊没有"主要"开发商公司。

· Druid承诺支持"开发人员API",该API允许提供自定义列类型,聚合算法,"深度存储"选项等,并使它们与核心Druid的代码库保持独立。 Druid开发人员记录了此API,并跟踪其与先前版本的兼容性。 但是,该API尚未成熟,并且在每个Druid版本中都几乎被破坏了。 据我所知,ClickHouse和Pinot没有维护类似的API。

· 根据Github的说法,黑皮诺从事这项工作的人最多,去年似乎至少有10个人年在黑皮诺上进行了投资。 对于ClickHouse来说,这个数字可能是6;对于德鲁伊,这个数字大约是7。 这意味着从理论上讲,黑皮诺在主题系统中的进步最快。


系统之间的相似性

耦合数据和计算

从根本上讲,所有ClickHouse,Druid和Pinot都是相似的,因为它们在同一节点上存储数据并进行查询处理,这与去耦BigQuery体系结构不同。 最近,我描述了在德鲁伊(1,2)情况下耦合体系结构的一些固有问题。 目前没有与BigQuery等效的开源软件(也许是Drill?),我在此博客中探讨了构建此类开源系统的方法。

与大数据SQL系统的区别:索引和静态数据分发

主题系统的查询运行速度比SQL-on-Hadoop系列中的大数据处理系统Hive,Impala,Presto和Spark更快,即使后者访问以列格式存储的数据(如Parquet或Kudu)也是如此。 这是因为ClickHouse,Druid和Pinot

· 具有自己的格式来存储带索引的数据,并与查询处理引擎紧密集成。 Hadoop上的SQL系统通常与数据格式无关,因此在大数据后端的"侵入性"较小。

· 在节点之间相对"静态"地分配数据,并且分布式查询执行利用了这一知识。 另一方面,ClickHouse,Druid和Pinot不支持要求在节点之间移动大量数据的查询,例如 G。 在两个大表之间联接。

没有点更新和删除

从数据库的另一端来看,与诸如Kudu,InfluxDB和Vertica(?)之类的列存储系统相反,ClickHouse,Druid和Pinot不支持点更新和删除。 这使ClickHouse,Druid和Pinot能够进行更有效的列压缩和更积极的索引,这意味着更高的资源效率和更快的查询。

Yandex的ClickHouse开发人员的目标是将来支持更新和删除,但是我不确定这是否是真正的点查询或数据范围的更新和删除。

大数据样式提取

所有ClickHouse,Druid和Pinot都支持从Kafka接收流数据。 Druid和Pinot支持Lambda样式的流传输和同一数据的批量提取。 ClickHouse直接支持批量插入,因此不需要像Druid和Pinot那样的单独的批量摄取系统。 这篇文章下面将对此进行更详细的讨论。

大规模验证

这三个系统都得到了大规模验证:在Yandex.Metrica上有一个ClickHouse集群,大约有上万个CPU内核。 Metamarkets运行着类似规模的Druid集群。 LinkedIn上的单个黑皮诺集群拥有"数千台机器"。

不成熟

按照企业数据库标准,所有主题系统都非常不成熟。 (但是,可能不比一般的开源大数据系统还不成熟,但这是另一回事。)ClickHouse,Druid和Pinot到处都缺乏明显的优化和功能,并且到处都是bug(这里我不能百分百确定) 关于ClickHouse和Pinot,但没有理由认为它们比Druid更好。

这将我们带入下一个重要部分-

性能比较与制度选择

我经常在网上看到人们如何比较和选择大数据系统-他们获取数据样本,以某种方式将其吸收到评估的系统中,然后立即尝试衡量效率-它占用了多少内存或磁盘空间, 在不了解所评估系统内部的情况下,查询完成的速度如何。 然后,仅使用此类性能信息,有时还使用它们所需的功能列表以及当前比较的系统,他们会做出选择,或者更糟糕的是,决定从头开始编写自己的"更好"的系统。

我认为这种方法是错误的,至少在开源大数据OLAP系统中是如此。 设计通用的大数据OLAP系统,使其能够在大多数用例和功能(及其组合的强大功能!)中有效地工作,这个问题确实非常巨大-我估计这至少需要100个人年。 建立这样的系统。

ClickHouse,Druid和Pinot当前仅针对开发人员关心的特定用例进行了优化,并且几乎仅具有开发人员所需的功能。 如果您要部署其中一个系统的大型集群并关心效率,那么我保证您的用例将遇到其独特的瓶颈,主题OLAP系统的开发人员以前从未遇到过或没有遇到过 不在乎。 更不用说上述方法"将数据投入您所不了解的系统并衡量效率"很有可能会遇到一些主要瓶颈,而这些瓶颈可以通过更改某些配置或数据模式或以其他方式进行查询来解决 。

CloudFlare:ClickHouse与Druid

MarekVavruša的一个帖子说明了上述问题,其中一个例子是Cloudflare在ClickHouse和Druid之间的选择。 他们需要4个ClickHouse服务器(超过了9个),并估计类似的Druid部署将需要"数百个节点"。 尽管Marek承认这是不公平的比较,但是由于Druid缺乏"主键排序",他可能没有意识到仅通过在"摄取规范"中设置正确的尺寸顺序就可以在Druid中获得几乎相同的效果。 简便的数据准备:将Druid的__time列值截断为一些粗粒度,例如e。 G。 一个小时,如果某些查询需要更细的时间范围,则可以选择添加另一个长型列" precise_time"。 这是一种技巧,但是允许Druid在__time之前按某种维度对数据进行实际排序也很容易实现。

我不会质疑他们选择ClickHouse的最终决定,因为在大约10个节点的规模上,对于他们的用例,我还认为ClickHouse比Druid是更好的选择(我将在本文下面进行解释)。 但是他们得出的结论是,ClickHouse的效率(在基础设施成本方面)至少比Druid高出一个数量级,这完全是谬论。 实际上,在这里讨论的三个系统中,Druid提供了最多的功能来实现真正便宜的安装,请参阅下面的"在Druid中分层查询处理节点"。



ClickHouse和Druid / Pinot之间的区别

数据管理:Druid和Pinot

在Druid和Pinot中,每个"表"中的所有数据(无论这些系统用什么术语称呼)都被划分为指定数量的部分。 按照时间维度,通常还会将数据除以指定的时间间隔。 然后,将这些数据的各个部分分别"密封"到称为"段"的自包含实体中。 每个段包括表元数据,压缩的列数据和索引。

段被保留在"深度存储"(例如,HDFS)中,并且可以被加载到查询处理节点上,但是后者不负责段的持久性,因此可以相对自由地替换查询处理节点。 段并非严格地附加到某些节点,它们可以或多或少地加载到任何节点上。 特殊的专用服务器(在Druid中称为"协调器",在Pinot中称为"控制器",但在下面我将其统称为"主服务器")负责将分段分配给节点,并在节点之间移动分段 , 如果需要的话。 (这与我在本文中上面指出的观点并不矛盾,因为包括Druid和Pinot在内的所有三个主题系统在节点之间均具有"静态"数据分布,因为Druid(我想是Pinot)中的段载荷和运动是昂贵的 操作,而不是针对每个特定查询执行操作,通常仅每隔几分钟,几小时或几天执行一次。)

有关段的元数据直接在Druid中以及通过Pinot中的Helix框架保存在ZooKeeper中。 在Druid中,元数据也保留在SQL数据库中,本文下面的" Druid与Pinot之间的区别"部分对此进行了详细说明。

数据管理:ClickHouse

ClickHouse没有"细分",其中包含严格属于特定时间范围的数据。 没有数据的"深度存储",ClickHouse群集中的节点还负责查询处理以及存储在其上的数据的持久性/持久性。 因此,不需要像Amazon S3这样的HDFS设置或云数据存储。

ClickHouse具有分区表,由特定的节点集组成。 没有"中央权限"或元数据服务器。 在其中对某个表进行分区的所有节点都具有表元数据的完全相同的副本,包括存储该表分区的所有其他节点的地址。

分区表的元数据包括节点的"权重",用于分配新写入的数据,例如, G。 40%的数据应流向节点A,30%的数据流向节点B,30%的数据流向节点C。通常,数据在节点之间的分配应相等。 如上例所示,只有在将新节点添加到分区表中时才需要"倾斜",以便用某些数据更快地填充新节点。 这些"权重"的更新应由ClickHouse群集管理员手动完成,或者应在ClickHouse之上构建一个自动化系统。

数据管理:比较

在ClickHouse中,数据管理方法比在Druid和Pinot中更简单:不需要"深度存储",只需一种类型的节点,就不需要用于数据管理的专用服务器。 但是,当任何数据表变得如此之大以至于需要在数十个或更多节点之间进行分区时,ClickHouse的方法就变得有些问题了:查询放大因子变得与分区因子一样大,即使对于查询而言,其覆盖范围很小。 数据:

适用于大数据的开源OLAP系统的比较:ClickHouse,Druid和Pinot

> Data distribution tradeoff in ClickHouse

在上图中给出的示例中,表数据分布在Druid或Pinot中的三个节点之间,但是查询少量数据间隔通常只会命中两个节点(除非该间隔跨越了段间隔边界)。 在ClickHouse中,如果表在三个节点之间进行分区,则任何查询都需要命中三个节点。 在此示例中,这似乎并没有太大的区别,但是可以想象节点数为100,而分区因子仍可以是e。 G。 10德鲁伊或黑皮诺。

为了缓解此问题,实际上,Yandex上最大的ClickHouse群集(数百个节点)被分成许多"子群集",每个群集包含几十个节点。 该ClickHouse集群用于支持网站分析,并且每个数据点都有"网站ID"维度。 每个网站ID都严格分配给特定的子集群,该网站ID的所有数据都存放在该子集群中。 该ClickHouse群集之上有一些业务逻辑层,可在数据提取和查询方面管理此类数据分离。 值得庆幸的是,在用例中,很少有查询可以跨多个网站ID来访问数据,而且这些查询并非来自服务客户,因此它们没有严格的实时SLA。

ClickHouse方法的另一个缺点是,当群集快速增长时,如果没有人工手动更改分区表中的"节点权重",数据就不会自动重新平衡。

Druid中的查询处理节点分层

具有段的数据管理"很容易推理"。 段可以相对容易地在节点之间移动。 这两个因素帮助Druid实现了查询处理节点的"分层":将旧数据自动移动到磁盘相对较大但内存和CPU较少的服务器上,从而可以显着降低运行大型Druid集群的成本, 减慢对旧数据的查询。

与"扁平"集群相比,该功能可使Metamarkets每月节省数十万美元的Druid基础设施支出。

适用于大数据的开源OLAP系统的比较:ClickHouse,Druid和Pinot

> Tiering of query processing nodes in Druid

据我所知,ClickHouse和Pinot还没有类似的功能,它们群集中的所有节点都应该是相同的。

由于Pinot的体系结构与Druid的体系非常相似,因此我认为在Pinot中引入类似的功能并不难。 在ClickHouse中执行此操作可能会比较困难,因为段的概念对于实现此类功能确实很有帮助,但是仍然可以实现。

数据复制:Druid和Pinot

德鲁伊和黑皮诺的复制单位是单个段。 段在"深层存储"层(例如,HDFS中的三个副本,或者在云blob存储(例如Amazon S3)中透明完成)和查询处理层中复制:通常在Druid和Pinot中,每个段 在两个不同的节点上加载。 如果复制因子低于指定级别,则"主"服务器将监视每个段的复制级别并在某个服务器上加载一个段。 G。 如果某个节点无响应。

数据复制:ClickHouse

ClickHouse中的复制单元是服务器上的表分区,即 e。 来自某个表的所有数据,存储在服务器上。 与分区类似,ClickHouse中的复制是"静态且特定的",而不是"云样式",即 e。 多台服务器知道它们是彼此的副本(对于某些特定表;对于其他表,复制配置可能不同)。 复制可提供持久性和查询可用性。 当某个节点上的磁盘损坏时,数据也不会丢失,因为它也存储在其他节点上。 当某个节点暂时关闭时,查询可以路由到副本。

在Yandex上最大的ClickHouse集群中,不同数据中心中有两组相等的节点,并且它们是成对的。 在每一对中,节点是彼此的副本(即使用两个的复制因子)并且位于不同的数据中心中。

ClickHouse依赖ZooKeeper进行复制管理,但是不需要ZooKeeper。 这意味着单节点ClickHouse部署不需要ZooKeeper。

数据提取:Druid和Pinot

在Druid和Pinot中,查询处理节点专门用于加载段并向段中的数据提供查询,但不累积新数据并产生新段。

当可以延迟一个小时或更长时间来更新表时,将使用批处理引擎(例如Hadoop或Spark)创建分段。 Druid和Pinot都对Hadoop提供了"一流"的现成支持。 Spark中有一个用于Druid索引的第三方插件,但目前尚不支持。 据我所知,Pinot甚至没有对Spark的这种支持。 e。 您应该自己做出贡献:了解Pinot接口和代码,编写一些Java或Scala代码。 但这并不难。 (更新:Slack的Ananth PackkilDurai现在正在为黑皮诺的Spark提供支持。)

当应该实时更新表时,Druid和Pinot都引入了"实时节点"的概念,该概念可做三件事:接受来自Kafka的新数据(Druid也支持其他来源),查询最近的数据,以及 在后台创建细分,然后将其推送到"深度存储"。

数据提取:ClickHouse

ClickHouse无需准备严格包含所有数据(属于特定时间间隔)的"段",因此可以简化数据提取架构。 ClickHouse不需要像Hadoop这样的批处理引擎,也不需要"实时"节点。 常规ClickHouse节点(用于存储数据并为其提供查询)与之相同,它们直接接受批处理数据写入。

如果表已分区,则接受批量写入的节点(例如1万行)将根据分区表本身中所有节点的"权重"来分配数据(请参见上方的"数据管理:ClickHouse"部分)。

单批写入的行形成一个小的"集合"。 集立即转换为列格式。 每个ClickHouse节点上都有一个后台进程,该进程将行集合并为较大的行集。 ClickHouse的文档在很大程度上将此原则称为" MergeTree",并强调了它与日志结构的合并树的相似之处,尽管IMO有点令人困惑,因为数据不是以树的形式组织的,而是采用扁平列格式。

数据提取:比较

Druid和Pinot的数据摄取"繁重":它包含几种不同的服务,而管理是一项负担。

尽管有一个警告,但ClickHouse中的数据提取要简单得多(以更复杂的历史数据管理为代价-参见上文):您应该能够在ClickHouse本身前面"批量"处理数据。 开箱即用的功能是自动获取和批处理来自Kafka的数据,但是如果您有不同的实时数据源,包括从Kafka替代的排队基础架构,流处理引擎到简单的HTTP端点,则需要 创建中间批处理服务,或直接向ClickHouse提供代码。

查询执行

Druid和Pinot具有称为"代理"的专用节点层,它们接受对系统的所有查询。 它们基于从段到加载段的节点的映射,确定应向哪些"历史"查询处理节点发出子查询。 代理将此映射信息保留在内存中。 代理节点将下游子查询发送到查询处理节点,当这些子查询的结果返回时,代理将它们合并,并将最终的合并结果返回给用户。

我只能推测为什么在设计Druid和Pinot时决定提取另一种类型的节点。 但是现在看来,这是必不可少的,因为随着群集中的段总数超过一千万,段到节点的映射信息需要GB的内存。 在所有查询处理节点上分配这么多的内存太浪费了。 因此,这是Druid和Pinot的"分段"数据管理架构所带来的另一个缺点。

在ClickHouse中,通常不需要为"查询代理"指定单独的节点集。 ClickHouse中有一种特殊的临时"分布式"表类型,可以在任何节点上进行设置,并且对该表的查询可以完成在Druid和Pinot中负责"代理"节点的工作。 通常,此类临时表是在参与分区表的每个节点上建立的,因此,实际上,每个节点都可以作为对ClickHouse集群进行查询的"入口点"。 该节点将向其他分区发出必要的子查询,处理该查询本身的一部分,并将其与其他分区的部分结果合并。

当一个节点(ClickHouse中的一个处理节点,或Druid和Pinot中的"代理"节点)向其他节点发出子查询,并且单个或几个子查询由于某种原因而失败时,ClickHouse和Pinot会正确处理此情况: 合并所有成功子查询的结果,并且仍将部分结果返回给用户。 现在,德鲁伊非常缺乏此功能:如果任何子查询失败,那么整个查询也会失败。

ClickHouse与Druid或Pinot:结论

Druid和Pinot中数据管理的"分段"方法与ClickHouse中较简单的数据管理方法定义了系统的许多其他方面。 但是,重要的是,这种差异对潜在的压缩效率(尽管目前这三个系统中的压缩情况目前都是令人沮丧的)或查询处理速度几乎没有影响。

ClickHouse与传统的RDMBS类似。 G。 PostgreSQL。 特别是,ClickHouse可以仅部署在单个服务器上。 如果预计的部署规模很小,则e。 G。 不超过100个用于查询处理的CPU内核和1 TB数据的数量,我想说ClickHouse相对于Druid和Pinot具有显着优势,因为它简单易用,不需要其他类型的节点,例如" master", "实时提取节点","经纪人"。 在此领域,ClickHouse与InfluxDB竞争而不是与Druid或Pinot竞争。

Druid和Pinot类似于大数据系统,例如HBase。 不取决于它们的性能特征,而是取决于对ZooKeeper的依赖性,对持久性复制存储(例如HDFS)的依赖性,对单个节点故障的恢复能力的关注以及不需要常规人员关注的自主工作和数据管理。

对于广泛的应用程序,ClickHouse或Druid或Pinot都不是明显的赢家。 首先,我建议考虑能够理解的系统源代码,修复错误,添加功能等。"性能比较和系统选择"部分将对此进行更多讨论。

其次,您可以查看下表。 该表中的每个单元格都描述了某个应用程序的属性,这使ClickHouse或Druid / Pinot可能是更好的选择。 行没有按其重要性排序。 每行的相对重要性对于不同的应用程序是不同的,但是如果您的应用程序由表中一列的许多属性来描述,而由另一列的无或几个属性来描述,则很可能应该从列标题中选择相应的系统 。

注意:以上两个属性都不意味着您必须使用相应的系统,或者必须避免使用其他系统。 例如,如果您预测的集群很大,那并不意味着您应该只考虑Druid或Pinot,而不要考虑ClickHouse。 相反,这意味着Druid或Pinot可能会成为更好的解决方案,但是在某些应用中,即使对于大型集群,ClickHouse最终也可能是更理想的选择,即使对于大型集群也是如此。

Druid与Pinot的区别

正如我在上面多次提到的,Druid和Pinot具有非常相似的体系结构。 在一个系统中存在着几个相当大的功能,而在另一个系统中则没有,还有一些区域,其中一个系统比另一个系统前进得远得多。 但是,我要提到的所有这些内容都可以通过合理的努力在另一个系统中复制。

Druid和Pinot之间只有一个区别,那就是太大了,无法在可预见的将来消除-这是"主"节点中的细分管理的实现。 而且,这两种系统的开发人员可能都不想这样做,因为两者的方法各有利弊,并不是说一个人总比别人好。

Druid中的细分管理

Druid(和Pinot中都不是)中的"主"节点不负责集群中数据段的元数据的持久性以及段与加载这些段的查询处理节点之间的当前映射。 此信息保留在ZooKeeper中。 但是,Druid还将这些信息保存在SQL数据库中,应该提供该信息以设置Druid集群。 我不能说为什么最初做出这个决定,但是目前它提供了以下好处:

· 较少的数据存储在ZooKeeper中。 ZooKeeper中仅保留有关从段ID到加载该段的查询处理节点列表的映射的最少信息。 剩下的扩展元数据(例如细分的大小,数据中的维度和指标列表等)仅存储在SQL数据库中。

· 如果由于数据段太旧而将其从集群中逐出(这是时间序列数据库的常见功能,所有ClickHouse,Druid和Pinot都具有),则将它们从查询处理节点上卸载,并从ZooKeeper中删除有关它们的元数据 ,但不是来自"深度存储"和SQL数据库。 只要不从这些地方手动删除它们,就可以快速"恢复"真正的旧数据,以防某些报告或调查需要该数据。

· 最初这不太可能是一个意图,但是现在Druid中有计划使对ZooKeeper的依赖成为可选。 目前,ZooKeeper用于三种不同的事物:段管理,服务发现和属性存储,例如。 G。 用于实时数据摄取管理。 服务发现和属性存储功能可以由Consul提供。 细分管理可以通过HTTP公告和命令来实现,而ZooKeeper的持久性功能已由SQL数据库"备份",则部分启用了细分管理。

将SQL数据库作为依赖项的弊端是更大的操作负担,尤其是在组织中尚未建立某些SQL数据库的情况下。 Druid支持MySQL和PostgreSQL,Microsoft SQL Server有一个社区扩展。 同样,当Druid部署在云中时,可以使用方便的托管RDBMS服务,例如Amazon RDS。

Pinot的细分市场管理

与Druid本身实现所有段管理逻辑并仅依赖Curator与ZooKeeper进行通信不同,Pinot将大部分段和集群管理逻辑委托给Helix框架。 一方面,我可以想象它为Pinot开发人员提供了一种专注于其系统其他部分的杠杆。 与在Druid中实现的逻辑相比,Helix的bug可能更少,这是因为在不同的条件下对它进行了测试,并且可能将更多的时间投入到Helix开发中。

另一方面,Helix的"框架界限"可能会限制Pinot。 螺旋线,进而是Pinot,可能永远永远依赖ZooKeeper。


现在,我将列举Druid与黑皮诺之间更浅的区别。 这里的"浅"是指如果有人愿意的话,有一条清晰的途径可以在缺少这些功能的系统中复制这些功能。

黑皮诺的"谓词下推"

如果在摄取期间通过某些维键在Kafka中对数据进行了分区,则Pinot会生成包含有关该分区的信息的段,然后在执行带有该维谓词的查询时,代理节点会预先过滤段,这样有时段会少得多 因此,查询处理节点需要命中。

此功能对于某些应用程序的性能很重要。

当前,如果在Hadoop中创建了段,但在实时摄取期间创建段时尚不支持,Druid支持基于密钥的分区。 德鲁伊目前尚未对经纪人实施"谓词下推"。

"可插拔"Druid和自以为是的Pinot

由于Druid由许多组织使用和开发,因此随着时间的流逝,它几乎为每个专用部件或"服务"获得了几个可交换选项的支持:

· HDFS或Cassandra或Amazon S3或Google Cloud Storage或Azure Blob存储等作为"深度存储";

· Kafka或RabbitMQ,Samza或Flink或Spark,Storm等(通过宁静)作为实时数据提取源;

· Druid本身,或Graphite,Ambari或StatsD或Kafka,作为Druid群集(度量标准)遥测的接收器。

由于Pinot几乎都是在LinkedIn上专门开发的,并且要满足LinkedIn的需求,因此,它通常不能为用户提供太多选择:HDFS或Amazon S3必须用作深度存储,而只有Kafka才能进行实时数据提取。 但是,如果有人需要,我可以想象不难为Pinot中的任何服务引入对多个可插拔选项的支持。 自Uber和Slack开始使用黑皮诺以来,这种情况可能很快就会改变。

在Pinot中更好地优化了数据格式和查询执行引擎

也就是说,Druid目前尚不具备Pinot分段格式的以下功能:

· 在Druid中以位粒度和字节粒度压缩索引列。

· 每一列的倒排索引都是可选的,在Druid中这是必填项,有时不需要,并且占用大量空间。 Uber观察到的Druid和Pinot之间在空间消耗上的差异可能是由于这一点。

· 每段记录数值列中的最小值和最大值。

· 开箱即用的数据排序支持。 如上文" CloudFlare:ClickHouse与Druid"部分中所述,在Druid中只能通过手动方式和破解方式实现。 数据排序意味着更好的压缩,因此Pinot的这一功能是Uber观察到的Druid和Pinot之间的空间消耗(和查询性能!)差异的另一个可能原因。

· 与Druid相比,用于多值列的某种更优化的格式。

所有这些事情都可以在Druid中实现。 而且,尽管Pinot的格式在目前比Druid的格式上有了更好的优化,但距离真正的优化还差很远。 例如,Pinot(以及Druid)仅使用通用压缩(例如Zstd),而尚未实现Gorilla论文中的任何压缩思想。

关于查询执行,不幸的是,Uber主要使用计数(*)查询来比较Druid和Pinot(1、2)的性能,因为目前这只是Druid中的哑线性扫描,尽管用a代替它真的很容易。 正确的O(1)实现。 这是"黑匣子"比较毫无意义的说明,本文上面的"关于性能比较和系统选择"部分对此进行了介绍。

我认为,Uber观察到的GROUP BY查询性能的差异应归因于Druid的细分市场中缺乏数据排序,如本节上文所述。

Druid拥有更智能的细分分配(平衡)算法

Pinot的算法是将段分配给当前加载的总段数最少的查询处理节点。 Druid的算法更加复杂,它考虑了每个细分的表格和时间,并应用了一个复杂的公式来计算最终得分,通过该公式对查询处理节点进行排名,以选择最佳的节点来分配新的细分。 该算法使Metamarkets的生产查询速度提高了30–40%。 然而,在Metamarkets,我们仍然对这种算法不满意,请参阅本文中的"历史节点性能的巨大差异"部分。

我不知道LinkedIn在Pinot中使用如此简单的分段平衡算法的效果如何,但如果他们需要时间来改进其算法,可能会有巨大的收获等待着他们。

Pinot在查询执行路径上更具容错能力

正如我在上面的"查询执行"部分中提到的那样,当"代理"节点向其他节点进行子查询,而某些子查询失败时,Pinot会合并所有成功的子查询的结果,并且仍将部分结果返回给用户。

德鲁伊目前尚未实现此功能。

Druid中的查询处理节点分层

请参阅本文上方的同名部分。 Druid允许为较旧和较新的数据提取查询处理节点的"层",并且较旧数据的节点具有较低的" CPU,RAM资源/已加载段数"比率,从而可以在访问时以较小的基础架构开销换取较低的查询性能 旧数据。

据我所知,Druid目前没有类似的功能。



摘要

ClickHouse,Druid和Pinot具有根本上相似的架构,它们在通用大数据处理框架(例如Impala,Presto,Spark和列式数据库)之间具有独特的优势,并适当支持唯一主键,点更新和删除(例如InfluxDB)。

由于它们的架构相似,ClickHouse,Druid和Pinot具有近似相同的"优化限制"。 但是到目前为止,这三个系统都还不成熟,距离该限制还很遥远。 仅需花费几个月的工程师工作,就可以对其中任何一个系统(当应用于特定用例时)大幅度提高效率。 我不建议您完全比较主题系统的性能,不要选择您可以理解和修改的源代码,或者要投资的源代码。

在这三个系统中,ClickHouse与Druid和Pinot略有不同,而后两个几乎相同,但它们几乎是完全独立于同一系统的两个独立开发的实现。

ClickHouse更类似于PostgreSQL之类的"传统"数据库。 ClickHouse的单节点安装是可能的。 在小规模(少于1 TB的内存,少于100个CPU内核)上,如果您仍然想与它们进行比较,则ClickHouse比Druid或Pinot更有趣,因为ClickHouse更简单并且移动部件和服务更少。 我要说的是,它在这种规模上与InfluxDB或Prometheus竞争,而不是与Druid或Pinot竞争。

Druid和Pinot更类似于Hadoop生态系统中的其他大数据系统。 它们即使在非常大的规模(超过500个节点)中仍保留"自动驾驶"属性,而ClickHouse需要专业SRE的大量关注。 此外,与ClickHouse相比,Druid和Pinot更适合优化大型集群的基础架构成本,并且更适合云环境。

Druid和Pinot之间唯一的可持续区别是Pinot依赖Helix框架,并将继续依赖ZooKeeper,而Druid可以摆脱对ZooKeeper的依赖。 另一方面,Druid的安装将继续取决于某些SQL数据库的存在。

目前,黑皮诺比德鲁伊的优化效果更好。 (但是请在上面再次阅读-"我不建议您完全比较主题系统的性能",以及帖子中的相应部分。)

Druid和Pinot的体系结构几乎完全相同,而ClickHouse则与它们略有不同。 我将首先将ClickHouse的架构与"通用" Druid / Pinot架构进行比较,然后讨论Druid与Pinot之间的较小差异。


(本文翻译自Roman Leventov的文章《Comparison of the Open Source OLAP Systems for Big Data: ClickHouse, Druid, and Pinot》,参考:https://medium.com/@leventov/comparison-of-the-open-source-olap-systems-for-big-data-clickhouse-druid-and-pinot-8e042a5ed1c7)


分享到:


相關文章: