添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在一些大数据实时数据服务中,一般需要将多维度的业务数据及离线计算数据以准实时查询的方式提供给业务方使用。在存储系统的选择上,像Hive这种大数据存储系统又并不太适合进行实时数据查询,而传统MySQL这种关系型数据库在单表数据量庞大的情况下复杂条件查询的性能较低,因此针对此类实时大数据查询服务,一般会选择像HBase、Elasticsearch,以及Clickhouse这样的实时分布式存储系统。在一段时间以来,在以上三种存储系统的中,Elasticsearch以其优异的数据检索能力一直保持着比较高的市场占有率,但近年来它的江湖地位受到了后起之秀——Clickhouse的挑战。本文主要对比下Elasticsearch与Clickhouse的不同点及性能差异,以供大家参考。

Elasticsearch 是一个实时的分布式搜索分析引擎,它的底层是构建在Lucene之上的。简单来说是通过扩展Lucene的搜索能力,使其具有分布式的功能。ES通常会和其它两个开源组件logstash(日志采集)和Kibana(仪表盘)一起提供端到端的日志/搜索分析的功能,常常被简称为ELK。

Clickhouse是俄罗斯搜索巨头Yandex开发的面向列式存储的关系型数据库。ClickHouse是过去两年中OLAP领域中最热门的,并于2016年开源。ES是最为流行的大数据日志和搜索解决方案,但是近几年来,它的江湖地位受到了一些挑战,许多公司已经开始把自己的日志解决方案从ES迁移到了Clickhouse,这里就包括:携程,快手等公司。

架构和设计的对比

ES的底层是Lucenc,主要是要解决搜索的问题。搜索是大数据领域要解决的一个常见的问题,就是在海量的数据量要如何按照条件找到需要的数据。搜索的核心技术是倒排索引和布隆过滤器。ES通过分布式技术,利用分片与副本机制,直接解决了集群下搜索性能与高可用的问题。

ElasticSearch是为分布式设计的,有很好的扩展性,在一个典型的分布式配置中,每一个节点(node)可以配制成不同的角色,如下图所示:

  • Client Node,负责API和数据的访问的节点,不存储/处理数据

  • Data Node,负责数据的存储和索引

  • Master Node, 管理节点,负责Cluster中的节点的协调,不存储数据。

ClickHouse是基于MPP架构的分布式ROLAP(关系OLAP)分析引擎。每个节点都有同等的责任,并负责部分数据处理(不共享任何内容)。ClickHouse 是一个真正的列式数据库管理系统(DBMS)。在 ClickHouse 中,数据始终是按列存储的,包括矢量(向量或列块)执行的过程。让查询变得更快,最简单且有效的方法是减少数据扫描范围和数据传输时的大小,而列式存储和数据压缩就可以帮助实现上述两点。Clickhouse同时使用了日志合并树,稀疏索引和CPU功能(如SIMD单指令多数据)充分发挥了硬件优势,可实现高效的计算。Clickhouse 使用Zookeeper进行分布式节点之间的协调。

为了支持搜索,Clickhouse同样支持布隆过滤器。

查询对比实战

为了对比ES和Clickhouse的基本查询能力的差异,我写了一些代码(https://github.com/gangtao/esvsch)来验证。这个测试的架构如下:

架构主要有四个部分组成:

  • ES stack ES stack有一个单节点的Elastic的容器和一个Kibana容器组成,Elastic是被测目标之一,Kibana作为验证和辅助工具。部署代码如下:

version: '3.7'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.4.0
    container_name: elasticsearch
    environment:
      - xpack.security.enabled=false
      - discovery.type=single-node
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    cap_add:
      - IPC_LOCK
    volumes:
      - elasticsearch-data:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
      - 9300:9300
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 4096M
        reservations:
          memory: 4096M
  kibana:
    container_name: kibana
    image: docker.elastic.co/kibana/kibana:7.4.0
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch
volumes:
  elasticsearch-data:
    driver: local
  • Clickhouse stack Clickhouse stack有一个单节点的Clickhouse服务容器和一个TabixUI作为Clickhouse的客户端。部署代码如下:

version: "3.7"
services:
  clickhouse:
    container_name: clickhouse
    image: yandex/clickhouse-server
    volumes:
      - ./data/config:/var/lib/clickhouse
    ports:
      - "8123:8123"
      - "9000:9000"
      - "9009:9009"
      - "9004:9004"
    ulimits:
      nproc: 65535
      nofile:
        soft: 262144
        hard: 262144
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "localhost:8123/ping"]
      interval: 30s
      timeout: 5s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 4096M
        reservations:
          memory: 4096M
  tabixui:
    container_name: tabixui
    image: spoonest/clickhouse-tabix-web-client
    environment:
      - CH_NAME=dev
      - CH_HOST=127.0.0.1:8123
      - CH_LOGIN=default
    ports:
      - "18080:80"
    depends_on:
      - clickhouse
    deploy:
      resources:
        limits:
          cpus: '0.1'
          memory: 128M
        reservations:
          memory: 128M
  • 数据导入 stack 数据导入部分使用了Vector.dev开发的vector,该工具和fluentd类似,都可以实现数据管道式的灵活的数据导入。

  • 测试控制 stack 测试控制我使用了Jupyter,使用了ES和Clickhouse的Python SDK来进行查询的测试。

用Docker compose启动ES和Clickhouse的stack后,我们需要导入数据,我们利用Vector的generator功能,生成syslog,并同时导入ES和Clickhouse,在这之前,我们需要在Clickhouse上创建表。ES的索引没有固定模式,所以不需要事先创建索引。

创建表的代码如下:

CREATE TABLE default.syslog(
    application String,
    hostname String,
    message String,
    mid String,
    pid String,
    priority Int16,
    raw String,
    timestamp DateTime('UTC'),
    version Int16
) ENGINE = MergeTree()
    PARTITION BY toYYYYMMDD(timestamp)
    ORDER BY timestamp
    TTL timestamp + toIntervalMonth(1);

创建好表之后,我们就可以启动vector,向两个stack写入数据了。vector的数据流水线的定义如下:

[sources.in]
  type = "generator"
  format = "syslog"
  interval = 0.01
  count = 100000
[transforms.clone_message]
  type = "add_fields"
  inputs = ["in"]
  fields.raw = "{{ message }}"
[transforms.parser]
  # General
  type = "regex_parser"
  inputs = ["clone_message"]
  field = "message" # optional, default
  patterns = ['^<(?P<priority>\d*)>(?P<version>\d) (?P<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z) (?P<hostname>\w+\.\w+) (?P<application>\w+) (?P<pid>\d+) (?P<mid>ID\d+) - (?P<message>.*)$']
[transforms.coercer]
  type = "coercer"
  inputs = ["parser"]
  types.timestamp = "timestamp"
  types.version = "int"
  types.priority = "int"
[sinks.out_console]
  # General
  type = "console"
  inputs = ["coercer"]
  target = "stdout"
  # Encoding
  encoding.codec = "json"
[sinks.out_clickhouse]
  host = "http://host.docker.internal:8123"
  inputs = ["coercer"]
  table = "syslog"
  type = "clickhouse"
  encoding.only_fields = ["application", "hostname", "message", "mid", "pid", "priority", "raw", "timestamp", "version"]
  encoding.timestamp_format = "unix"
[sinks.out_es]
  # General
  type = "elasticsearch"
  inputs = ["coercer"]
  compression = "none"
  endpoint = "http://host.docker.internal:9200"
  index = "syslog-%F"
  # Encoding
  # Healthcheck
  healthcheck.enabled = true

这里简单介绍一下这个流水线:

  • http://source.in 生成syslog的模拟数据,生成10w条,生成间隔和0.01秒

  • transforms.clone_message 把原始消息复制一份,这样抽取的信息同时可以保留原始消息

  • transforms.parser 使用正则表达式,按照syslog的定义,抽取出application,hostname,message ,mid ,pid ,priority ,timestamp ,version 这几个字段

  • transforms.coercer 数据类型转化

  • sinks.out_console 把生成的数据打印到控制台,供开发调试

  • sinks.out_clickhouse 把生成的数据发送到Clickhouse

  • sinks.out_es 把生成的数据发送到ES

运行Docker命令,执行该流水线:

docker run \
  -v $(mkfile_path)/vector.toml:/etc/vector/vector.toml:ro \
  -p 18383:8383 \
  timberio/vector:nightly-alpine

数据导入后,我们针对一下的查询来做一个对比。ES使用自己的查询语言来进行查询,Clickhouse支持SQL,我简单测试了一些常见的查询,并对它们的功能和性能做一些比较。

  • 返回所有的记录

> 基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。
> 项目地址:<https://github.com/YunaiV/onemall>
  "query":{
    "match_all":{}
# Clickhouse
"SELECT * FROM syslog"
  • 匹配单个字段

"query":{     "match":{       "hostname":"for.org" # Clickhouse "SELECT * FROM syslog WHERE hostname='for.org'"
  • 匹配多个字段

"query":{     "multi_match":{       "query":"up.com ahmadajmi",         "fields":[           "hostname",           "application" # Clickhouse、 "SELECT * FROM syslog WHERE hostname='for.org' OR application='ahmadajmi'"
  • 单词查找,查找包含特定单词的字段

"query":{     "term":{       "message":"pretty" # Clickhouse "SELECT * FROM syslog WHERE lowerUTF8(raw) LIKE '%pretty%'"
  • 范围查询, 查找版本大于2的记录

"query":{     "range":{       "version":{         "gte":2 # Clickhouse "SELECT * FROM syslog WHERE version >= 2"
  • 查找到存在某字段的记录 ES是文档类型的数据库,每一个文档的模式不固定,所以会存在某字段不存在的情况;而Clickhouse对应为字段为空值

"query":{     "exists":{       "field":"application" # Clickhouse "SELECT * FROM syslog WHERE application is not NULL"
  • 正则表达式查询,查询匹配某个正则表达式的数据

"query":{     "regexp":{       "hostname":{         "value":"up.*",           "flags":"ALL",             "max_determinized_states":10000,               "rewrite":"constant_score" # Clickhouse "SELECT * FROM syslog WHERE match(hostname, 'up.*')"
  • 聚合计数,统计某个字段出现的次数

"aggs":{     "version_count":{       "value_count":{         "field":"version" # Clickhouse "SELECT count(version) FROM syslog"
  • 聚合不重复的值,查找所有不重复的字段的个数

"aggs":{     "my-agg-name":{       "cardinality":{         "field":"priority" # Clickhouse "SELECT count(distinct(priority)) FROM syslog "

我用Python的SDK,对上述的查询在两个Stack上各跑10次,然后统计查询的性能结果。

我们画出出所有的查询的响应时间的分布:

总查询时间的对比如下:

通过测试数据我们可以看出Clickhouse在大部分的查询的性能上都明显要优于Elastic。在正则查询(Regex query)和单词查询(Term query)等搜索常见的场景下,也并不逊色。

在聚合场景下,Clickhouse表现异常优秀,充分发挥了列村引擎的优势。

注意,我的测试并没有任何优化,对于Clickhouse也没有打开布隆过滤器。可见Clickhouse确实是一款非常优秀的数据库,可以用于某些搜索的场景。当然ES还支持非常丰富的查询功能,这里只有一些非常基本的查询,有些查询可能存在无法用SQL表达的情况。

本文通过对于一些基本查询的测试,对比了Clickhouse 和Elasticsearch的功能和性能,测试结果表明,Clickhouse在这些基本场景表现非常优秀,性能优于ES,这也解释了为什么用很多的公司应从ES切换到Clickhouse之上。

—————END—————

来源:zhuanlan.zhihu.com/ p/353296392

原文链接: https://mp.weixin.qq.com/s?__biz=MzU3NDY4NzQwNQ==&mid=2247487171&idx=1&sn=6a98d343024aeb04d5c5048018bdb9b0&chksm=fd2fdf01ca58561782366b7067cc9963888a4a906379ed5dd5f4cf366f5dc9a0f0ba30b0c698&scene=126&&sessionid=0 ElasticSearch 6.3.1在多系统下的安装与启动 我第一次安装 ES 时候踩过不少坑(主要是Linux系统下), 所以今天把在windows和Linux下安装启动 ES 进行了总结(第一次写博客,排版别喷) 往下看完,不仅有windows还有Linux的(都是基于6.3.1版本,但是其他版本也部分适用) 一、Windows版本 ES 安装与启动 1.1 下载 ES 压缩包 ElasticSearch 分为Linux和Window版本,基于我们主要学习的是 ElasticSearch Java 客户端的使用,所以我们课程中使用的是先安装较为简便的Window版本,项目上线后, 公司 的运维人员会安装Linux版 本实例为博主原创,属于简单易上手并且能够拿来就用的SpringBoot ES 项目,全文使用的是 Elasticsearch Template进行开发。 本实例涵盖 ES 中的各类操作,如索引操作、CRUD操作、批处理、结果排序、分页查询、检索查询、关键字查询、高亮显示、逻辑查询、过滤查询、分组查询等等。并且已经过生产环境验证,各位可放心使用。如有不对之处欢迎在博客中留言交流。谢谢! 欢迎各位大神添加微信公众号:“愿为最亮星”,我们将在这一起探讨 Java 技术。 前段时间 公司 想尝试用 ES 来存一部分数据,以此缓解数据增长带来的对 数据库 的压力。 ES 的介绍很多地方都有,就不再写了。在研究了一段时间后,发现 ES 不适合做为数据存储使用,理由如下: mapping不可改,不能改index属性。 ES 中以定义的mapping不能修改名字和属性,无法修改名字勉强还能接受,但无法修改属性。官方文档中介绍了几种修改mapping的方法。一个是新建一个字段,程序中所有地方修 点击“开发者技术前线”,选择“星标????”在看|星标|留言, 真爱来源:京东技术(ID: jingdongjishu)京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部... 如果您只是使用 API 摄取数据并使用 kibana 进行搜索(Kibana 不支持 Zinc。Zinc 提供了自己的 UI),那么它可以 直接 替代 elasticsearch 。 为什么Zinc 唯一可行的搜索解决方案是 elasticsearch . 原文地址:https://pixeljets.com/blog/ clickhouse -vs- elasticsearch /原文作者:Anton Sidashin本文永久链接:https://... 远程日志是能切实提升程序员定位问题效率的工具,目前已经有成熟的方案 es elastic search,也就是elk。在实际使用的过程中,存储时间短,可能会丢少量条目消息的问题会出现,跟同事调研探讨以下解决方案。 问题:远程日志定位问题,有无更多方案 1.辅助以离线数仓 日志统一上报,落库kafka分流处理,一道进入elk,一道通过小时级别的 大数据 数仓,通过hive pr es to 对小时落库的hdsf数据大表做二次搜索,可以极大拉长可检索时间,简易检索的速度也很快,非常方便。缺点是定位时长需要等小时级别 前言文章内容输出来源:拉勾教育 Java 高薪训练营;NoSQL=Not Only SQL,支持类似SQL的功能, 与Relational Database相辅相成。其性能较高,不使用SQL意味着没有结构化的存储要求(SQL为结构化的查询语句),没有约束之后架构更加灵活。NoSQL 数据库 四大家族 列存储 Hbase,键值(Key-Value)存储 Redis,图像存储 Neo4j,文档存储 Mongo... Elasticsearch 简介 Elasticsearch 是一个实时 分布式 搜索和分析引擎。它让你以前所未有的速度处理 大数据 成为可能。 它用于全文搜索、结构化搜索、分析以及将这三者混合使用: 维基百科使用 Elasticsearch 提供全文搜索并高亮关键字,以及输入实时搜索(search-asyou-type)和搜索 纠错(did-you-mean)等搜索建议功能。 英国卫报使用 Elasticsearch 结合用户日志和社交网络数据提供给他们的编辑以实时的反馈,以便及时了 解公众对新发表的文章的回应。 Stack 点击上方“芋道源码”,选择“设为星标”管她前浪,还是后浪?能浪的浪,才是好浪!每天 10:33更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析 数据库 中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 E...