我只用过 ES,没用过 Clickhouse。这里记录下我对 Clickhouse 一些调研,主要是通过对比 ES ,在这二者之间需要选型时我想了解的内容。
数据量方面
ClickHouse和ElasticSearch都可以处理PB级别的数据量。但是具体能处理多少数据并不仅取决于数据库本身,还需要考虑硬件、网络、查询负载等因素。
ClickHouse:ClickHouse设计用于在线分析处理(OLAP),它可以在实时查询大规模数据集时提供快速的结果。它的分布式系统架构使得它可以水平扩展来处理PB级别的数据。
ElasticSearch:ElasticSearch主要被用于全文搜索、日志和事件数据的实时分析。通过分片和副本的机制,ElasticSearch可以分布式处理大量数据。然而,虽然ElasticSearch理论上可以处理PB级别的数据,但是在实践中,由于资源和性能的限制,通常用来处理TB级别的数据。
炫杉:ElasticSearch 想接管的数据量越大,速度越快,所依赖的硬件成本就会越高。相对来说 ClickHouse 对硬件性能的利用会更好。
总的来说,如果你的数据量非常大(PB级别)并且需要进行复杂的实时分析查询,ClickHouse可能是更好的选择。而如果你的数据量较小(TB级别),或者你需要全文搜索和日志数据处理,ElasticSearch可能会更适合。
实时可查性
ClickHouse 是一个列式数据库,它的设计目标是快速处理大量数据,因此它的写入操作相对较慢,而查询操作却非常快。当新数据写入 ClickHouse 时,数据首先会写入到内存中的缓冲区,然后在一段时间后(或者当缓冲区满了之后)才会将这些数据刷新到磁盘。因此,新写入的数据在被刷新到磁盘之前是无法被查询到的,这就是 ClickHouse 的可查询性延迟。
炫杉补充:MySQL 是行式。ClickHouse 是列式。而 ES 是基于 Lucene ,使用了倒排索引。
具体的延迟时间取决于很多因素,比如你的硬件性能、系统负载、数据量等。在一般情况下,ClickHouse 的可查询性延迟可能会在几秒到几分钟之间。在大部分情况下,这个延迟是可以接受的,因为大规模的分析查询通常不需要实时性。
Elasticsearch 可以支持实时分析查询,但它的设计更侧重于文本搜索、日志数据处理和实时分析(例如,聚合和可视化)。Elasticsearch 的近实时性(near real-time)特性意味着在数据写入后一小段时间内(通常是一秒)数据就可以被查询到。
对于实时分析查询,Elasticsearch 提供了强大的聚合功能,可以进行复杂的实时分析和可视化。比如进行日志数据的实时分析,查看网站访问量的实时趋势等。
高可用
ElasticSearch 通过分片和副本机制实现了高可用性和容错性。ClickHouse 也支持数据复制和分片,但是配置相对复杂。
上手成本
ElasticSearch 需要一定的学习成本(Restful API 也还好)
ClickHouse 使用标准的 SQL 语句,使用起来比较简单。
关于 ES 的简单使用我有整理一些文章,可站内搜一下看。但更推荐你直接参考 ES 文档,或者根据你想实现的查询咨询 ChatGPt 来快速上手。
下面记录下 ClickHouse 的用法
ClickHouse 的简单使用
首先,你需要安装 ClickHouse。有多种安装方式,以下是在 Ubuntu 上的安装命令:
1 | # Update package list |
然后,你可以通过运行 clickhouse-client 命令进入 ClickHouse 的命令行客户端。
炫杉:安装比 ES 简单多了。
创建数据库
1 | CREATE DATABASE test; |
这个表用于存储网站访问记录,包含用户 ID、访问日期、用户所在国家、使用的浏览器和操作系统等信息。
果然是 MySQL
插入数据:
1 | INSERT INTO test.visits |
更新数据
首先,你需要先确保你的 ClickHouse 版本支持 ALTER TABLE UPDATE 语句(需要 19.7 及以上版本)。
然后,你可以这样进行更新:
1 | ALTER TABLE test.visits UPDATE browser = 'Firefox' WHERE id = 1; |
这个命令会将 id 为 1 的行的 browser 列的值更新为 ‘Firefox’。
请注意 ALTER TABLE UPDATE 操作在 ClickHouse 中并不是实时的,它只是标记了需要更新的数据。实际的更新操作会在后台异步进行,因此你可能需要等待一段时间才能在查询中看到更新的结果。
另外,如果你的数据表的引擎是 MergeTree 类型,你需要确保表的 ORDER BY 子句包含了 WHERE 子句中用到的所有列。在这个例子中,id 列应该包含在 ORDER BY 子句中。
说实话这段我没太看懂。
删除数据
1 | ALTER TABLE test.visits DELETE WHERE id = 1; |
这将会删除所有 id 为 1 的行。