暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

从ELK到Clickhouse

小数据自留地 2023-04-19
2025

作为一名运维开发工程师,从17年开始就基于ELK打造我们的日志系统,去年随着部门业务的扩展,我们将使用了多年的ELK 6升级到了ELK 8, 并大规模扩容了我们的集群。另一方面作为一名大数据运维开发,我们也在构建基于Clickhouse的实时数仓,在加强我们CK的开发和运维能力的同时,我们关注到了很多国内的互联网大厂都提到了将基于ELK的日志系统迁移到Clickhouse,今年初开始我们也进行这方面的探索。

互联网大厂的相关方案


为什么要从ELK 转向Clickhouse, 各个互联网大厂的文章都有阐述,都是大同小异,ES自身在集群到达一定的规模后开始遇到瓶颈,Clickhouse自身优秀的数据压缩和查询性能。 大家在打造ELK日志体系的时候,架构基本都比较类似, 但从ELK体系迁移到Clickhouse, 不仅仅是将日志存储从ELasticSearch替换到Clickhouse,更是需要重新打造围绕ES的Logstash,Kibana等的整个日志平台,各个互联网大厂的平替方案更是百花齐放,这里我们收集了一下网上的公开方案:

  • 携程作为ES方面的重度用户,我曾经看过多篇关于ES的技术分享,从ES到CK,我最早关注到也是携程的这篇  《携程日志系统治理演进之路》https://zhuanlan.zhihu.com/p/598729102  携程这边仍然是第一步将数据写入Kafka,然后基于携程自己开源的GoHangout(类Logstash)将数据写入CK。

  • B站的 《B站基于Clickhouse的下一代日志体系建设实践》  https://zhuanlan.zhihu.com/p/565030219, B站的方案整体来说还是比较复杂,自研的东西非常多,我们能够直接借鉴的东西不多,B站的方案中提到了OpenTelemetry Logging ,这个是我们值得关注的一个方向,未来进一步规范我们的日志输出。

  • 唯品会的 《相比ES,ClickHouse简直不要太香!》  https://blog.csdn.net/qq_42046105/article/details/124957826, 这篇文章值得我们参考的东西很多, 唯品会也是将数据先写入Kafka,用Flink从Kafka写到CK, 在数据存储方面,使用ssd_to_hdd,实现冷热数据的分

  • 使用 ClickHouse 构建通用日志系统》   https://zhuanlan.zhihu.com/p/554103626  这篇文章覆盖的面很广,也值得反复去看看。

  • 石墨文档的 《墨文档日志架构http://clickvisual.gocn.vip/clickvisual/05arch/graphite-document-logging-architecture.html#_1-%E8%83%8C%E6%99%AF  石墨文档不仅介绍了他们的日志架构,同时还开源了他们的ClickVisual的日志查询平台,我们最后落地的方案也最类似石墨的架构。

我们按之前ELK方案的Filebeat ->Logstash -> ElasticSearch - > Kibana ,一步步来拆分各个大厂提供的的替代方案:

  • Filebeat:应用日志收集到Kafka端,这一段每家的方案不尽相同,但是基本仍然可以延续使用之前ELK的那一套。

  • Logstash:从Kafka写入日志到CK这一部分,这里就是百花齐放,携程采用的GoHangout, B站的Log-Ingester,唯品会采用Flink, 石墨文档的CK Kafka Engine。 

  • Elasticsearch: 对应CK中的建表,存储等,各个文章也提出了不同的方式和优化方案一开始看的是云里雾里,这个只有逐步进行实战了之后再进行反复优化。

  • Kibana:  ELK 体系中的Kibana非常好用的,尤其是对非开发的业务人员也非常友好,各个大厂也都是以Kibana作为范本进行自研的替代方案,这也是我们这样的小团队从ES转换到CK的最大难点。现在唯一看到的开源的是石墨文档的ClickVisual, 我们打算下一步就开始试用。


小数据团队的从ES到CK演进

因为缺乏比较好的Kibana平替产品,我们团队并没有以数据查询作为切入点,而是先开发基于日志的告警,这样直接在Grafana写SQL就可以了,并不需要将CK暴露给开发和业务同学用于日志查询。我们来逐步拆解一下我们自己的演进方案:

  • Filebeat:和前面提到的各个互联网大厂一样,我们仍然是首先将日志输出到Kafka,这一块我们仍然维持之前试用的Filebeat。

  • Logstash + Elasticsearch :从Kafka写入日志到CK这一部分,最初我们采用了和唯品会类似的方案,通过Flink写入CK,但是我们因为我们在Flink这方面的开发资源比较有限,Flink开发和运维都还处于探索期,也遇到了一些问题,最终我们决定将有限的Flink资源投入到更加复杂的实时数仓的的数据处理任务。针对通用日志的数据同步,因为不需要做数据解析,我们希望实现的是基于配置实现,通用和稳定的数据同步方案。经过初步调研和测试后,现阶段我们采用和石墨文档相同的的基于CK Kafka Engine的方案:


首先在CK中建一个Kafka Engine 表

    CREATE TABLE LOG.log_queue
    (
    `log` String
    )
    ENGINE = Kafka
    SETTINGS kafka_broker_list = 'kafka1:9092'
     kafka_topic_list = 'app, wechat',
    kafka_group_name = 'ck-log',
     kafka_format = 'JSONAsString';

    再建一个MergeTree表用来落地日志数据

      CREATE TABLE LOG.rawlog
      (
          `tags` Array(String),
          `message` String CODEC(ZSTD(1)),
          `hostname` String,
          `logfile_path` String,
          `log_time` DateTime DEFAULT now(),
           INDEX message message TYPE tokenbf_v1(307202, 0) GRANULARITY 1
      )
      ENGINE = MergeTree
      PARTITION BY (toDate(log_time), tags)
      ORDER BY (tags, log_time)
      TTL log_time + toIntervalDay(30)
      SETTINGS index_granularity = 8192;

      CK的建表我们吸取了大家分享的一些经验,使用ZSTD压缩数据,tokenbf_v1优化message的查询,最后通过物化视图来将Kafka表中的数据落地:

        CREATE MATERIALIZED VIEW LOG.mv_rawlog TO LOG.rawlog
        (
        `tags` Array(String),
        `message` String,
        `hostname` String,
        `logfile_path` String,
        `log_time` DateTime
        ) AS
        SELECT
        JSONExtractString(log, 'tags') AS tags,
        JSONExtractString(log, 'message') AS message,
        JSONExtractString(JSONExtractString(log, 'host'), 'name') AS hostname,
        JSONExtractString(JSONExtractString(JSONExtractString(log, 'log'), 'file'), 'path') AS logfile_path,
        now() AS log_time
        FROM LOG.log_queue

        针对个别需要特殊解析的日志,我们直接采用了CK物化引擎进行处理,充分利用CK强大的函数以及它对json解析特别友好的特性。

        小结

        现阶段我们在生产环境实现了ELK和CK的双跑,现在CK的日志系统还是局限在日志的监控和告警,下一步我们准备开始试用ClickVisual,将CK日志平台投入到搜索场景进行实战和优化

        文章转载自小数据自留地,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论