clickhouse和elasticsearch(clickhouse与es索引比较)

作者:Renshua Clickhouse,阿里云数据库OLAP产品部,是俄罗斯搜索巨头Yandex开发的分析数据库。ClickHouse这两年在OLAP领域非常火,被国内互联网厂商广泛使用。Elasticsearch是一个接近实时的分布式搜索和分析引擎,其底层存储完全建立在Lucene之上。简单来说,Lucene通过扩展单机搜索能力,实现了分布式搜索和分析能力。Elasticsearch通常与其他两个开源组件Logstash(日志收集)和Kibana(仪表板)一起提供端到端的日志/搜索分析功能,通常简称为ELK。如今,很多用户在实际业务场景中经常面临ClickHouse和Elasticsearch的技术选择问题。用户对ClickHouse和Elasticsearch的内核知识了解不够,只能通过性能测试的方式来选择类型。本文旨在深入分析ClickHouse和Elasticsearch的内核架构,从原理上了解它们的优缺点。同时会附上一份涵盖多个场景的测试报告,供读者参考。
分布式架构Elasticsearch和ClickHouse都是支持分布式多计算机的数据产品。在这里,笔者首先要比较的是两者的区别。分布式架构的设计对产品的可用性和可扩展性有着非常重要的影响。在分布式架构上,要解决的核心问题包括:节点发现、元同步和副本数据同步。Elasticsearch作为一个老牌的开源产品,在这个领域已经比较成熟。原生节点发现和元同步协议给了用户非常好的易用性体验。Elasticsearch的元同步协议需要解决的问题其实和开源的Raft协议很像,只不过Raft在Elasticsearch诞生的时候还没有出现,所以我们要自己做一个。经过这么多年的打磨,Elasticsearch的元同步协议已经相当成熟。依托于此,Elasticsearch拥有非常易用的多角色划分、自动图式推理等功能。值得一提的是,Elasticsearch的多副本数据同步没有复用元同步协议,而是采用传统的主备同步机制,主节点负责同步到备用节点,这样会更简单高效。ClickHouse的分布式架构能力比较简单,这也是因为ClickHouse还是一个比较年轻的开源产品,还处于增加分布式可用性的阶段。ClickHouse引入了外部ZooKeeper集群来分发分布式DDL任务(节点元更改)、主备同步任务等操作。多副本之间数据运送的任务也是依赖于ZooKeeper集群,但是最终多副本之间的数据传输是通过Http协议点对点的数据复制,可以写多个副本,所以数据同步是完全多方向的。至于节点发现,ClickHouse目前没有这个能力,需要通过手动配置集群节点地址来解决。目前ClickHouse的脚手架式分布式架构导致其灵活部署能力和运维干预能力较强,对用户来说略显不太好用,用户门槛也比较高。但是从能力上限来说,ClickHouse的分布式部署可扩展性没有缺点,集群规模上限和Elasticsearch没有区别。ClickHouse架构扁平化,没有前端节点和后端节点,可以部署任意规模的集群。同时,ClickHouse对多副本功能有更细粒度的控制能力,可以在表级配置副本数量。同一个物理集群可以分成多个逻辑集群,每个逻辑机可以任意配置片数和副本数。
存储架构
写链路设计写吞吐量是大数据场景下的核心指标。用户对大数据产品的要求不仅仅是保存,更重要的是写得快。首先,本文介绍了Elasticsearch的实时写链接的设计:在Elasticsearch的每个分片中,写过程分为两部分,先写Lucene,再写TransLog。写请求到达Shard后,先写Lucene内存索引,趁数据还在内存,再写TransLog。写入传输日志后,将传输日志数据刷新到磁盘。成功写入磁盘后,请求将返回给用户。这里有几个关键点。第一,写Lucene放在最前面,主要是为了防止用户的写请求包含“非法”数据。第二,Lucene索引写出来之后,是不可搜索的。需要通过刷新把内存对象变成完整的段,然后再重新打开才可以搜索。该刷新时间间隔可以由用户设置。可见Lucene index不具备写实时可见性的能力,所以Elasticsearch是一个接近实时的系统。最后,经过很长一段时间,比如30元分钟后,Lucene会把内存中生成的新段刷新到磁盘。刷新后索引文件已经被持久化,历史TransLog就没用了,所以旧的TransLog会被清除。
Elasticsearch单条分片写链接
ClickHouse单碎片写链接
相比于Elasticsearch的写作环节,ClickHouse的写作模式更加“简单、直接”和极致。如上所述,Elasticsearch是一个接近实时的系统,内存存储引擎中新写入的数据需要定期刷新才能看到。而ClickHouse则干脆完全抛弃了内存存储引擎的功能,所有数据直接写入磁盘,也省去了传统的写重做日志的阶段。在极高写入吞吐量的场景下,Elasticsearch和ClickHouse都需要放弃一些写入的实时可见性,以提高吞吐量。但是,ClickHouse的主推是延迟向客户端批量写入数据。另外,对于多副本同步,Elasticsearch要求实时同步,即一个写请求必须写完多个副本才会返回,而ClickHouse依靠ZooKeeper进行异步磁盘文件同步(数据运送)。在实战中,ClickHouse的写吞吐量可以远远超过同规格的Elasticsearch。
Segment vs DataPartElasticsearch和ClickHouse在外观上有着相似的存储设计,但能力却大相径庭。Elasticsearch的磁盘文件是由段组成的,实际上是一个最小单位的Lucene索引。这里不讨论段内的存储格式。Segment会在后台异步合并,主要解决两个问题:1元)让二级索引更有序;密室逃脱:冠军联赛)来完成主键数据的更改。二级索引是一种“全局”有序索引,当所有数据都建立在一个索引中时,比建立在多个索引中时,查询速度更明显。Elasticsearch支持主键的删除和更新,通过Lucene索引的删除功能实现。更新操作将被转换为删除操作加写入操作。当Lucene索引的段中有多条被删除的记录时,系统需要通过段来合并这些记录。当多个段合并时,Lucene索引中存储的数据只显示append-only Kramp-Karrenbauer的合并。这样,次级索引的合并不需要被重新排序。与Elasticsearch中的Segment相比,ClickHouse存储中的最小单位是DataPart,批量写入的数据会落入一个DataPart中。DataPart中的数据存储处于完全有序的状态(根据表定义排序)。这种有序存储是默认的聚集索引,可用于加速数据扫描。ClickHouse也会异步合并DataPart,它的合并也是用来解决两个问题:1元)让数据存储更加有序;密室逃脱:冠军联赛)来完成主键数据的更改。DataPart在merge中存储数据时,表现出Kramp-Karrenbauer排序的方式,得到的DataPart仍然处于完全有序的状态。根据DataPart存储的完全有序设置,ClickHouse更新主键数据的方式与Elasticsearch完全不同。在更改主键时,Elasticsearch采用“先在Kramp-Karrenbauer中检查原记录生成新记录,然后在Kramp-Karrenbauer中删除原记录,在Kramp-Karrenbauer中写入新记录”的方法。这种方法完全限制了主键更新的效率,主键更新写的效率和只追加Kramp-Karrenbauer只写的效率有很大差别。但是,ClickHouse的主键更新是完全异步的,主键相同的多条记录异步合并时会产生最新的记录结果。这种异步批量主键更新方式比Elasticsearch更高效。最后,总结段和数据部分之间文件存储能力的差异。Segment是Lucene索引的存储格式,Lucene索引无疑是倒排文件中最好的存储。Lucene index还提供了行存储和列存储等不同格式的原始数据存储。Elasticsearch默认会将原始数据保存为两份,一份在行,一份在列。Elasticsearch会根据查询的模式选择合适的存储文件进行扫描。原生ClickHouse的DataPart中没有二级索引文件,数据完全存储在列中。ClickHouse实现的列的压缩比和扫描吞吐量是最好的。相对而言,Elasticsearch中的存储适中,成本至少翻倍。
再说说无Schemaless。说到Elasticsearch的特点,大家都会提到无模式这个词。Elasticsearch可以自动推断出写入数据的JSON Kramp-Karrenbauer shema,并根据写入数据的JSON Kramp-karren Bauer JSON-schema调整存储表的元结构,可以帮助用户省去很多建表和添加列的麻烦。但在笔者看来,Elasticsearch的这种能力其实叫做Auto Schema Impact更为贴切,这得益于Elasticsearch的分布式元同步能力。但是Elasticsearch的存储其实是需要schema的,甚至是强绑定schema的,因为是以二级索引为核心的存储。没有类型化字段,如何构建索引?真正的无模式应该是能够灵活高效地更改字段类型,同时确保查询性能不会显著下降。如今,用户想要改变Elasticsearch索引中的某个字段类型,方法只有一个:对整个数据进行重新索引。相比之下,ClickHouse的存储与schema的绑定不是很强,因为ClickHouse的分析能力是基于存储扫描的。它可以在数据扫描期间执行动态类型转换,也可以在数据部分合并时缓慢异步地调整字段类型。查询过程中字段类型变化所带来的开销是运行时添加cast运算符的开销,因此用户不会感觉到性能急剧下降。作者认为,无方案绝对不是弹性搜索的最大优势,而是它的弱点。至于自动模式推断,它对于小规模用户来说是一个非常友好的功能,但是它永远无法帮助用户创建具有最佳性能的模式。在大数据量的场景下,大家还是需要根据具体的查询需求来创建模式,所有的便利都是有代价的。
查询架构
计算引擎的作者在这里把ClickHouse和Elasticsearch放在一起谈计算引擎,因为Elasticsearch只是实现了一个通用的搜索引擎。但是搜索引擎能处理的查询复杂度是一定的,是有上限的。所有的搜索查询都可以在某些阶段后得到结果,但计算引擎不是。Elasticsearch也有SQL支持的插件,但是这个插件的实现逻辑是把简单的SQL查询翻译成一定的搜索模式。elastic search-SQL Kramp-karren Bauer SQL无法帮助搜索引擎没有支持的数据分析行为。另外,elastic search Kramp-karren Bauer SQL目前的翻译能力看起来也不是很完整和智能。为了获得最高的搜索性能,用户仍然需要尝试Elasticsearch的原生查询API。对于习惯使用SQL的用户来说,Elasticsearch的查询API是一个完全陌生的系统,复杂的查询非常难写。Elasticsearch的搜索引擎支持三种不同的搜索模式:query_and_fetch、query_then_fetch、dfs_query_then_fetch。第一种模式非常简单。每个分布式节点独立搜索,然后将获得的结果返回给客户端。第二种模式是每个分布式存储节点先搜索自己的TopN的记录Id和对应的分数,然后在查询请求节点聚集并重新排列得到最终的TopN结果,最后请求存储节点取详细数据。这里设计两轮请求的目的是尽量减少拉取细节的数量,也就是磁盘扫描的次数。最后一种方式是平衡各个存储节点的评分标准,先统计全局TF(词频)和DF(文档频),然后query_then_fetch。Elasticsearch的搜索引擎完全不具备数据库计算引擎的流处理能力,是完全的回合制请求Kramp-Karrenbauer响应数据处理。当用户需要返回大量数据时,查询很容易失败或者触发GC。一般来说,Elasticsearch的搜索引擎容量限制是两阶段查询,像多表关联这样的查询完全超过了它的容量限制。ClickHouse的计算引擎的特点是极度矢量化。完全由C template编写的矢量化函数和聚集算子,使其对聚集查询的处理性能达到极致。凭借存储的极致并行扫描能力,轻松运行满机资源。ClickHouse的计算引擎能力在分析和查询支持方面完全可以覆盖Elasticsearch的搜索引擎,一个拥有完整SQL能力的计算引擎可以让用户在数据分析方面更加灵活自由。
扫描数据ClickHouse是一个完全列式的存储和计算引擎,它以有序存储为核心。在查询扫描数据的过程中,首先根据存储排序、列块统计、分区键等信息推断出要扫描的列块,然后进行并行数据扫描,如表达式计算、聚合运算符等都在正则计算引擎中处理。从计算引擎到数据扫描,数据流都是基于列内存块的,是高度量化的。如前所述,Elasticsearch的数据扫描主要发生在查询和获取阶段。查询阶段主要扫描Lucene的索引文件获取查询命中的DocId,同时也扫描列出的文件进行聚合计算。在fetch阶段,我们主要检查Lucene index中的行文件,读取详细的结果。表达式计算和聚合计算都可以发生在两个阶段,它们的计算逻辑都是基于行为单元的。一般来说,Elasticsearch的数据扫描和计算没有矢量化能力,是基于二级索引的结果。当二级索引返回的命中行数特别大时(涉及大量数据分析查询),其搜索引擎会暴露出数据处理能力不足的缺点。
谈高并发。很多用户在谈论ClickHouse的时候,都会得到一个错误的形象。ClickHouse查询运行速度快,但是并发性不好。但这背后的原因其实是ClickHouse的并行性很牛逼,这是ClickHouse的一大强项。一个查询就能填满磁盘吞吐量,查询并行度完全独立于shard,可以随意调整。不可否认,处理并发请求的吞吐能力是衡量数据系统效率的最终指标。ClickHouse的架构没有天生的并发缺陷,但它是一个诚实坦率的男孩,要扫描的数据量和查询的计算复杂性就在这里。ClickHouse每次只做诚实的计算,机器的硬件容量决定了它的并发极限。ClickHouse的并发能力其实不错,认为它不能并发是错误的。只是默认情况下,ClickHouse的目标是保证单个查询的延迟足够低;在某些场景中,用户可以通过设置适当的系统参数来提高并发性,比如max_threads。另一方面,这也是为什么Elasticsearch的并发能力在某些场景下还是不错的。首先从缓存设计方面来说,Elasticsearch的缓存包括查询缓存、请求缓存、数据缓存和索引缓存。从查询结果到索引扫描结果的缓存加速是因为Elasticsearch认为其场景中存在热点数据,可能会重复查询。另一方面,ClickHouse只有一个用于IO的UnCompressedBlockCache和用于system的PageCache。为什么?ClickHouse是基于对查询场景的分析,数据和查询是多变的,查询结果等缓存不容易命中。因此,ClickHouse的做法是始终专注于磁盘数据,并具有良好的IO缓存能力。其次,回到数据扫描的粒度,Elasticsearch具有所有列的秒级索引能力。这些索引一般会预先预热并加载到内存中。即使在多变的查询条件下,索引查询结果的成本也很低,可以逐行读取数据来计算索引结果。而原生的ClickHouse不具备二次索引的能力,只能在多变的查询条件下对数据进行大量扫描以筛选出结果(阿里云ClickHouse已经具备二次索引的能力,解决了这个问题,性能水平与Elasticsearch相当。后续绩效评估会详细介绍)。但是Elasticsearch有二级索引,那么并发性会好吗?不完全是。当二级索引搜索得到的结果集非常大的时候,查询仍然会伴随着大量的IO扫描,高并发无从谈起,除非Elasticsearch的数据缓存足够大,能够将所有的原始数据加载到内存中。综上所述,Elasticsearch只能在全搜索场景下(过滤的记录数较少)和内存充足的运行环境下才能体现出并发的优势。但在分析场景下(过滤后记录更多),ClickHouse凭借其极致的列存储和向量化计算,会有更好的并发性能。两者的侧重点不同,ClickHouse的并发处理能力基于磁盘吞吐量,而Elasticsearch的并发处理能力基于内存缓存。ClickHouse更适合低成本、大容量的分析场景,可以充分利用磁盘的带宽容量。
性能测试在这一章中,笔者选取了用户业务中几个有代表性的数据场景,对Elasticsearch和ClickHouse做了全面多角度的性能测试报告。的特定测试集群环境如下:
点击之家
弹性搜索
节点数量
CPU: 8元核心内存:32GB存储:ESSD PL1 1500GB
CPU: 8元核心内存:32GB存储:ESSD PL1 1500GB

日志分析场景作者在日志分析场景中选取了两个有代表性的查询场景进行对比测试,结果如下。从结果分析来看,两种场景下ClickHouse和Elasicsearch之间的性能差距随着where条件筛选出的记录数量的增加而增大。在数据量更大的trace_log场景下,两者的性能差距一目了然。请点击“链接”下载完整版的Elasticsearch和ClickHouse的建表声明和查询。
Access_log(数据量197921836)ClickHouse中的ClickHouse建表语句如下:
创建表access _ log _ local on cluster default(` SQL ` String,` schema` String,` type` String,` access_ip` String,` conn_id` UInt32,` process _ id ` uint 32,` accept_time` UInt64,` _date` DateTime,` total_time` UInt32,` succeed` String,` inst _ name ` String)ENGINE=merge tree()PARTITION BY toymmdd(_ date)ORDER BY(logic _ ins _ id,accept _ time);在集群上创建表access _ log默认值为access_log_local引擎=Distributed(default,default,access _ log _ local,rand());注:*左右滑动阅览点击之家中的查询语句如下:
– Q1select _date,accept_time,access_ip,type,total_time,concat(toString(total_time),’ ms’) as total_time_ms,sql,schema,succeed,process_id,inst _ name from access _ log where _ date=’ 2020-12-27 00:38:31 ‘ and _ date=’ 2020-12-28 00:3836031 ‘ and logic _ date当总时间=100时一当总计_时间100和总时间=500时2当总计_时间500和总时间=1000时3当总计_时间1000和总时间=3000时四当总计_时间3000和总时间=10000时5当total_time 10000和总时间=30000时6否则七以重新排序结束,当总时间=100时为0 ~100毫秒,当总时间=500时为100毫秒~ 500毫秒,当总时间=1000时为500毫秒~ 500毫秒,当总时间=3000时为500毫秒~ 1秒,当总时间=3000时为一秒~3秒,当总时间=10000时为3秒~10秒以上作为标签结束, 当总时间=100时为”0~100″当总时间=100且总时间=500时为”100~500″当总时间=1000时为”500~1000″当总时间=1000且总时间=3000时为”1000~3000″当总时间=3000且总时间=10000时为” 3000 ~ 1000 “-Q3 select to start of minute(_ date)为时间,计数()为访问日志中的值其中logic _ ins _ id=500152868 and accept _ time=1609087111000 and accept _ time=1609000711000 group by time order by time; -Q4 select count(*)as c from(select _ date,accept_time,access_ip,type,total_time,concat(toString(total_time),’ ms’) as total_time_ms,sql,schema,succeed,process_id,inst_name from access_log其中logic _ ins _ id=501422856 and _ date=’ 2020-12-27 003:38:31 ‘ and _ date=’ 2020-10注:*左右滑动阅览性能对比如下:
跟踪日志(数据量569816761)点击之家中的建表语句如下:
在群集默认情况下创建表trace _ local(` service name ` low cardinality(String),` host` LowCardinality(String),` ip` String,` spanName` String,` spanId` String,` duration` Int64,` rpcType` Int32,` startTime` Int64,` traceId` String,` tags.k` Array(String),` tags.v` Array(String),` events` String,KEY trace _ idx traceId TYPE range)ENGINE=merge tree()PARTITION BY int在集群上创建表跟踪默认值为trace_local engine=Distributed(default,default,trace _ local,rand());注:*左右滑动阅览点击之家中的查询语句如下:
-Q1 select * from traceprefheretraceid=’ CCC 6084420 b 76183 ‘其中开始时间1597968000300000和开始时间1598054399099000设置max _ threads=1;- Q2select count(*) count,spanName作为名称从跟踪,其中服务名=’柯南-迪恩-用户-周期’和开始时间1597968000300000和开始时间1598054399099000分组按spanNameorder按desc计数限制1000;-Q3选择主机作为名称,count(*)从跟踪计数,其中服务名=’ Conan-dean-user-period ‘和开始时间1597968000300000和开始时间1598054399099000按主机分组;- Q4select count(*) count,tags.k作为跟踪数组连接标记。k其中服务名=’柯南-迪恩-用户-周期’和开始时间1597968000300000和开始时间1598054399099000分组按标签。k;- Q5select count(*) spancount,sum(duration) as sumDuration,intDiv(startTime,1440000000)as timeself from trace其中service name=’ Conan-dean-user-period ‘和start time 1597968000300000和start time 159805439099000 group by time sel;- Q6select count(*) spanCount,countIf(duration=1000000),countIf(duration 1000000),countIf(duration 3000000)from trace where service name=’ Conan-dean-user-period ‘和开始时间159796800030000和startTime 1598054399099000-Q7选择主机,start time,traceId,spanName,duration,tags.k,tags。vfrom trace其中服务名=’ Conan-dean-user-period ‘和开始时间1597968000300000和开始时间1598054399099000限制100000;注:*左右滑动阅览性能对比如下:
官方准时测试集准时测试集是点击之家官网上推荐的一个分析型查询基准,为了更加公证公开地对比点击之家和弹性搜索在分析查询上的性能差异。作者也引入了这个数据集进行测试比对,结果如下所示,点击之家在纯分析型查询场景下具有巨大性能优势弹性搜索和点击之家完整版建表语句和查询下载请点击「链接」 。
用户画像场景(数据量262933269)用户画像场景也是用户比较难选择使用弹性搜索还是点击之家的一个典型场景,该场景的具体特点是超大宽表,大批量更新写入,查询返回的数据量大,筛选条件复杂多变。用户在使用弹性搜索时遇到的难点问题主要有两个:数据写不进去,导入慢;数据拉不出来,返回大规模明细数据非常慢。针对这个场景,作者根据真实用户的业务场景,嘲笑了一张接近150列的大宽表进行相关的查询测试,具体的查询如下所示,每条查询返回的结果集在10万到100万行级别弹性搜索和点击之家完整版建表语句和查询下载请点击「链接」 。
点击之家中的查询语句如下:
-Q1从person _ tag中选择user _ id,其中模拟3d _ like 8和模拟3d _消费_内容_cnt 8和mock _ 10 _ day _ product _ avg _ AMT 1设置append _ squashing _ after _ filter=1;-Q2 select user _ id from person _ tag其中mock _ 7 _ day _ receive _ CNT 8和like _ fitness=1和mock 14d _ share _ CNT 8设置append _ squashing _ after _ filter=1;-Q3 select user _ id from person _ tag where home _ perfer _ mock _ score 8和mock7d_access_homepage_cnt 8设置append _ squashing _ after _ filter=1;-Q4 select user _ id from person _ tag其中is _ send _ register _ coupon 8和模拟1d_like 8设置append _ squashing _ after _ filter=1;-q5 select user _ id from person _ tag其中like _ sports=1且like _ 3c=1且sex=1且like _ dance=1且mock 1d _ share _ CNT 6设置append _ squashing _ after _ filter=1;-q6 select user _ id from person _ tag其中mock 14d _ access _ home page _ CNT 8和like _ anime=1设置append _ squashing _ after _ filter=1;- Q7select user_id,offline_ver,is_visitor,mock1d_comment_like,reg_days,mock14d_share_cnt,mock _ 30 _ order _ avg _ delivery _ time _ CNT,mock7d_comment_cnt,performance_rate,mock3d_valid_user_follow_cnt,mock30d_consume_content_cnt,like_cnt,like_photo,ls90_day_access_days,mock3d_release_trend_cnt,mock14d_access_homepage_range注:*左右滑动阅览查询性能结果对比如下,可以看出弹性搜索在扫描导出大量结果数据的场景下,性能非常大,返回的结果集越大越慢,其中Q5是查询命中结果集很小的对比案例5 .
二级索引点查场景(数据量1000000000)在分析查询业务场景中,用户难免会有几个明细点查案件,例如根据日志traceId查询明细信息。开源点击之家因为没有二级索引能力,在遇到这种情况时,查询性能对比弹性搜索完全落后。阿里云点击之家自研了二级索引能力,补齐了这方面的短板,作者在这里专门加了一个二级索引点查的场景来进行性能对比测试弹性搜索和点击之家完整版建表语句和查询下载请点击「链接」 。点击之家中的建表语句如下:
创建表point _ search _ test _ local on cluster default(` PRI _ KEY ‘ String、` SED _ KEY` String、` INT _ 0` UInt32、` INT _ 1` UInt32、` INT _ 3` UInt32、` INT _ 4` UInt32、` LONG _ 0` UInt64、` LONG _ 1` UInt64、` LONG _ 2` UInt64、` LONG _ 3` UInt64、` LONG _ 4` UInt64、` STR _ 0` String、` STR _ 64在集群上创建表点_搜索_测试默认值为point_search_test_local engine=Distributed(default,默认,point _ search _ test _ local,rand());注:*左右滑动阅览点击之家中的查询模板语句如下:
select * from point_search_test其中SED _ KEY=’ XXX ‘ settings max _ threads=1;注:*左右滑动浏览的最终查询性能对比如下。阿里云ClickHouse拥有二级索引能力后,其点击搜索能力不弱于Elasticsearch,在存储原生二级索引能力上有着极致的表现。(ClickHouse二级指数Kramp-Karrenbauer云数据库Clickhouse Kramp-Karrenbauer阿里云)
数据导入性能对比上面列出的所有数据集,笔者通过导入ESSD本地文件,对Elasticsearch和ClickHouse的导入性能进行了测试和对比。ClickHouse可以直接使用Clickhouse Kramp-Karrenbauer客户端读取各种格式的本地文件并导入,而Elasticsearch配置Logstash任务。具体耗时结果如下:
结论Elasticsearch在全搜索场景(过滤的记录数较少的场景)下效果最好,在内存丰富的运行环境下能表现出优秀的并发查询能力。但在大规模数据的分析场景下(过滤后记录较多的地方),ClickHouse凭借其极致的列存储和向量化计算,会有更好的并发性能,查询支持完备性也更好。ClickHouse的并发处理能力是基于磁盘吞吐量的,而Elasticsearch的并发处理能力是基于内存缓存的,这使得两者的成本区间相差很大。ClickHouse更适合低成本、大容量的数据分析场景,可以充分利用磁盘带宽。在数据导入和存储成本上,ClickHouse占有绝对优势。
#阿里云# #数据库#

其他教程

蛇的尾巴发出的声音有什么作用(为什么响尾蛇的尾巴会发声)

2022-8-18 17:23:40

其他教程

喀秋莎的射速(喀秋莎射程最远是多少)

2022-8-18 17:25:46

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索