前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES VS CH,成本太高,效率太低?不存在的

ES VS CH,成本太高,效率太低?不存在的

原创
作者头像
点火三周
修改2020-12-08 14:22:18
7.8K0
修改2020-12-08 14:22:18
举报
文章被收录于专栏:Elastic Stack专栏Elastic Stack专栏

今天无意间一个客户问到CH和ES对比的问题。通常来说,ES并不是一个应该和CH进行横向比较的产品,ES是用综合数据库,一个大数据系统,一个搜索引擎,而CH是一个列式存储数据库的管理系统,两者最主要的使用场景并不特别重合。但因为ES出色的检索性能和丰富的数据分析能力,在数据分析产品预算有限的情况下,会有不少客户选择直接将ES用在OLAP分析的场景,而不是再额外部署一个OLAP系统,因此,自然免不了要被拿出来和CH作比较。

比较就比较吧,虽然在OLAP分析领域以列式存储库为主,ES并不是为这个场景而生的(You know, for search), 但综合各方面的能力之后,既然有很多用户选择使用ES作为OLAP分析工具,那我们就应该给大家以合适的指引。

特别是当互联网上出现如下这些描述不当的文章可能给人以误解时,我们有必要去做一些澄清。

文章原文我放在这,携程ClickHouse日志分析实践,分享实践是好的,但做产品比较以及下定论这种事,还是要严谨,要慎重。

这里我也不做一一的纠正,也不去做ES和CH的比较。我只是针对其中的一些表述,帮经常使用ES的同学来进行一些解惑

ES占用内存多?

ClickHouse相对ES占用更少的内存。 ES为了提高查询效率会将很多数据放在内存中,如:segment的索引数据、filter cache、field data cache、indexing buffer等;ES内存的使用量与索引量、数据量、写入量、查询量等成正比。删除(下线)索引、迁移索引或者扩容是应对ES内存问题的常用手段。但是删除(下线)索引导致用户希望保存更长时间数据的需求无法满足,而服务器扩容导致又了成本上升。 ClickHouse的内存消耗主要包括内存型的engine,数据索引,加载到内存中待计算的数据,搜索的结果等。在ClickHouse中日志的数据量和保存时间主要和磁盘有关。

我们可以看一下这里的描述,似乎侧面的意思同样的数据,ES的内存使用效率会更低?其实并不是。

  • 首先,ES是运行在JVM上的应用程序,而CH是C++编译的可运行程序,两者内存使用和管理的机制不同,不宜直接横向比较。(当然,看起来C++没有JVM的负担,貌似有丢丢优势,但如果垃圾回收没做好,也是有不能合理利用资源的可能的,这块水太深,不聊)
  • 其次,ES不是专门用于OLAP分析的列式库,整个ES节点上面运行了大量的额外功能去支持其他复杂的场景,并不是所有的资源都用于快速读/写,比如,ES对高并发的支持就比CH好很多ES也能做Schema On Read的运行时字段提取和操作。因此,在场景和功能特性不同的情况下,也不适宜做内存的比较
  • 再有,ES有大量的其他数据结构,比如倒排索引支持全文检索和模糊查询、BKD tree支持快速的range排序和地理位置边界查询,将这些数据加载到内存用于加速搜索无可厚非,最主要的是,这些数据是否生成,是否加载都是可控的,用户需要知道合理的数据建模,而不是让系统自动推测数据类型

就好比方说,比较BMW的混动7系和常规动力的丰田陆巡的油耗,得出结论BMW在省油方面做得比丰田强,看似结论成立,但实际上如果不考虑场景和用法,并没有多大的指导意义

Off-Heap

另外,这里说的内存到底是指的JVM使用的内存,还是把整个系统的内存都算到ES上面呢?如果大家了解过最新版本上的Off-Heap的特性,其实新版本的ES在内存使用上已经有很非常巨大的改进:

在这里插入图片描述
在这里插入图片描述

结合7版本最新的内存断路器,在最新版本上,已经很少听到用户反馈说 “ES中一个大查询导致OOM的问题”

因此,这里非常重要的一个点,要把ES升级到最新的版本

ES占用存储多?

在这里插入图片描述
在这里插入图片描述

熟悉ES的同学应该知道,ES提供了大量的选项可以控制生成数据的大小的,并且不同版本的ES性能和效率上也有不同,这里并没有给出ES具体的版本,也没有给出日志和mapping,所以很容易让人产生误导

ES指标型数据存储压缩

这里,我做了个测试,我用这样的一个数据集来测试:

在这里插入图片描述
在这里插入图片描述

原始数据1000多万行,1.4GB。

数据样本如下:

代码语言:txt
复制
{"geonameid": 2986043, "name": "Pic de Font Blanca", "latitude": 42.64991, "longitude": 1.53335, "country_code": "AD", "population": 0}
{"geonameid": 2994701, "name": "Roc Mélé", "latitude": 42.58765, "longitude": 1.74028, "country_code": "AD", "population": 0}
{"geonameid": 3007683, "name": "Pic des Langounelles", "latitude": 42.61203, "longitude": 1.47364, "country_code": "AD", "population": 0}
{"geonameid": 3017832, "name": "Pic de les Abelletes", "latitude": 42.52535, "longitude": 1.73343, "country_code": "AD", "population": 0}
{"geonameid": 3017833, "name": "Estany de les Abelletes", "latitude": 42.52915, "longitude": 1.73362, "country_code": "AD", "population": 0}
{"geonameid": 3023203, "name": "Port Vieux de la Coume d’Ose", "latitude": 42.62568, "longitude": 1.61823, "country_code": "AD", "population": 0}
{"geonameid": 3029315, "name": "Port de la Cabanette", "latitude": 42.6, "longitude": 1.73333, "country_code": "AD", "population": 0}
{"geonameid": 3034945, "name": "Port Dret", "latitude": 42.60172, "longitude": 1.45562, "country_code": "AD", "population": 0}
{"geonameid": 3038814, "name": "Costa de Xurius", "latitude": 42.50692, "longitude": 1.47569, "country_code": "AD", "population": 0}
{"geonameid": 3038815, "name": "Font de la Xona", "latitude": 42.55003, "longitude": 1.44986, "country_code": "AD", "population": 0}

这里需要指明的是,这个数据样本因为是geo name,因此每一个字段的值都不可能重复的,这个数据样本对于列式存储的来说,基本没有什么优化空间(因为列值全部不一样)。

使用如下mapping来构建ES的索引,0副本1分片:

代码语言:txt
复制
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 1

  },
  "mappings": {
      "dynamic": "strict",
      "properties": {
        "geonameid": {
          "type": "long"
        },
        "name": {
          "type": "text"
        },
        "latitude": {
          "type": "double"
        },
        "longitude": {
          "type": "double"
        },
        "country_code": {
          "type": "text"
        },
        "population": {
          "type": "long"
        }
      }
    }
}

最终生成的索引数据在1.6GB左右浮动,数据膨胀比例大概是1.2 (1.6G/1.4G),文件分布为:

在这里插入图片描述
在这里插入图片描述

以上是不做任何场景建模优化的数据。

如果我们只是做OLAP的数据统计分析,不做字段内的搜索,我们可以按照列式存储的场景来优化mapping:

  • "enabled": false, 不需要获取原值,只要排序和统计结果{ "settings": { "index.number_of_replicas": 0, "index.number_of_shards": 1 }, "mappings": { "dynamic": "strict", "_source": { "enabled": false }, "properties": { "geonameid": { "type": "keyword", "index": false }, "name": { "type": "keyword", "index": false }, "latitude": { "type": "double", "index": false }, "longitude": { "type": "double", "index": false }, "country_code": { "type": "keyword", "index": false }, "population": { "type": "long", "index": false } } } }最终生成的索引文件比较为:
  • "index": false, 不需要字段内检索,只要排序和统计结果
  • fdt, The stored fields for documents, 变小了
  • tim,tim,倒排索引,变小了
在这里插入图片描述
在这里插入图片描述

注意,因为cfs文件的存在(一个 "虚拟/组合 "文件,由所有其他索引文件组成,用于预防耗尽文件句柄,而特意合并的大文件) ,很难直观比较不同索引文件的变化,以下是针对cfs文件的介绍:

在这里插入图片描述
在这里插入图片描述

话归正题,现在的存储值由1.6G变为了1G,优化过后,膨胀比变为了0.7,因此,ES,并非那么的没有效率,只是看是否针对应用场景正确的配置了数据模型

我们在存储成本优先的情况下,甚至可以配置"index.codec": "best_compression", 获得更高的压缩比:

  • 约为0.6 (0.8 / 1.4 )
    在这里插入图片描述
    在这里插入图片描述
    要注意,这个场景里的值都是不一样的,因此,即便是CH也不会有太多的压缩空间,而携程帖子里的CDN日志等,可能有些字段会包含相同的信息,比如:某个字段的值都是AAAA,那这些字段就可以被列式存储有效压缩,这时如果ES设置了合理的字段,应该不会和CH差距特别的大。(区别肯定是有的,比如fdt等字段,要用于reindex等操作)

ES日志数据存储压缩

我们再来看看常规的日志,这是一个ES自身的GC日志,这里就有不少的重复值,比如5935,safepoint,gc

  • 日志有118428行,大小是12M
    在这里插入图片描述
    在这里插入图片描述
  • 我们可以快速的用新版的机器学习功能进行日志解析:
    在这里插入图片描述
    在这里插入图片描述
  • 它会生成建议的Grok模式,默认基本是字段都提取:
在这里插入图片描述
在这里插入图片描述
  • 然后摄入数据:
在这里插入图片描述
在这里插入图片描述
  • 生成的索引大小是6.5mb,在不做任何优化的情况下,压缩比率将近0.5,可见,文本类型比较多的索引,ES的压缩比率还要高一些
在这里插入图片描述
在这里插入图片描述
  • 我们可以对同一个数据做优化,我们不提取字段,全部保存在message当中,把index: false配置一下,可以看到索引大小缩小为3.3mb,几乎是原始数据的1/4
在这里插入图片描述
在这里插入图片描述

因此,如果我们愿意,我们可以有不同的方式来平衡存储成本和查询性能

ES Schema On Read

通过上面提到的方式,我们几乎只存储原始数据的情况下,可以大幅压缩生成索引的大小(原数据的1/4)。特别是面对一些不是特别频繁做查询和分析的场景,我们先把日志采集到ES,留待将来分析,在将来需要时,动态提取字段,再进行分析

通过这种方式,我们可以:

  • 大幅减少存储成本
  • 提高数据摄入速度
  • 更加灵活的分析数据
在这里插入图片描述
在这里插入图片描述

以下是即将发布的新的runtime类型:

在这里插入图片描述
在这里插入图片描述

Searchable Snapshot

另外一个和存储大小,成本有关的特性是ES上的新的Searchable Snapshot,通过该功能,我们可以:

  • 节省一半Cold层的成本
  • 以对象存储的成本,存储历史数据,并且可以检索
    在这里插入图片描述
    在这里插入图片描述
    也就是说,新的ES架构,可以以低得多的成本,支撑海量数据的存储和查询
    在这里插入图片描述
    在这里插入图片描述

ES的读写速度

我非常的好奇这里的查询场景,ClickHouse经过优化后耗时29.5s,这已经是一个比较不能接受的值了。但上面说,ES直接查不出来,这里,我看到了挺多的问题。因为本身Netflow的日志格式并不复杂,在运维场景下,即便数据量很大,也不应该查不出来

在这里插入图片描述
在这里插入图片描述

首先,第一个问题是不合理的ES使用: ES使用的是40核256G的服务器,一台服务器部署一个ES实例,单服务器数据量3T左右,熟悉ES的同学都知道,JVM的内存是有限制的,31G再往上就效率非常低了,在这个例子里面,如果这么大的一台服务器,只给JVM分配了31G内存,然后剩下的内存空载在那不让ES使用,想查得快也很难,通常这样配置的服务器,我们会在上面安装4个ES的节点。在这样的配置上说ES的成本高,性能低,是非常不合理的。

在这里插入图片描述
在这里插入图片描述

可以看到的公开压测数据如下:(注意,这里没有针对列式存储场景的优化,同样生成倒排索引)

在这里插入图片描述
在这里插入图片描述

其次,还是ES版本问题,ES的新版本本身就比老版本在一些指标、日志场景上快了几倍到上百倍不等,在一个“错误”的配置上去,再使用老版本的ES去比较CH的话,得出来的结论可能没那么有意义

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ES慢速查询的能力

其实现在各个大数据系统,没有范式革命的产品,有的就是在资源、性能、成本、规模上的互有取舍。有时,我们不一定强调快,能在更大的数据集上运行查询也是一个能力,通过ES最新的async search功能,结合searchable snapshot,ES集群可以对数十PB存在在对象存储上的数据进行检索,单次运行默认可以查询5天之久,因此,单纯比较某些场景查得快不一定能满足所有的需求,比如全量的数据审计。

在这里插入图片描述
在这里插入图片描述

ES的运维管理

这里不说太多,可能还是因为版本太低的原因

在这里插入图片描述
在这里插入图片描述

ES ILM和data stream

没有了解过新版本上的ILM和data stream功能的可以了解下,ES的新版本一直在持续优化数据治理的能力,并简化操作。通过ILM,我们可以自动化的实现数据的迁移,而通过data stream,我们可以更轻松的管理数据流,而不是一个个的索引

ES SQL

在这里插入图片描述
在这里插入图片描述

总结

这篇文章并非打算引战ES和CH社区。全文我几乎没有比较过ES和CH,这里,重申一下

这里的重点是:

  1. ES是一个综合数据库和大数据产品,整个Elasitc Stack有:
    • 数据摄入层 (beats, logstash)
    • 有数据规范(ECS)
    • 有机器学习功能
    • 有数据展示层 (kibana)
    • 有解决方案

因此,在做产品或者架构比较的时候,应该把ES看做是一个平台,而不是单一用途的产品,这样会有助于降低成本,提升投资回报率

  1. ES的产品一直在快速的迭代和更新,希望大家能够多了解新版本上的特性,这非常有助于成本的优化,性能的提升和运维的简化
  2. 当数据量过多,集群过多的时候,对ES的运维管理力不从心,可以联系一下售后和咨询,帮忙解决问题,毕竟直接替换产品,重入新坑,成本过高

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ES占用内存多?
    • Off-Heap
    • ES占用存储多?
      • ES指标型数据存储压缩
        • ES日志数据存储压缩
          • ES Schema On Read
            • Searchable Snapshot
            • ES的读写速度
              • ES慢速查询的能力
              • ES的运维管理
                • ES ILM和data stream
                  • ES SQL
                  • 总结
                  相关产品与服务
                  Elasticsearch Service
                  腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档