如何消化每天 150 亿条日志,让大查询保持在 1 秒内

作者:微信小助手

发布时间:2023-10-07T17:55:34

该数据仓库用例与规模有关。用户是中国联通,全球最大的电信服务提供商之一。使用 Apache Doris 在数十台机器上部署多个 PB 级集群,以支持 30 多个业务线每日添加的 150 亿条日志。如此庞大的日志分析系统是网络安全管理的一部分。出于实时监控、威胁追踪和警报的需求,用户需要一个能够自动收集、存储、分析和可视化日志和事件记录的日志分析系统。

从架构的角度来看,系统应该能够对各种格式的日志进行实时分析,当然还要具有可扩展性,以支持庞大且不断扩大的数据规模。本文关于用户的日志处理架构是什么样的,以及如何实现稳定的数据摄取、低成本存储和快速查询。
系统架构

这是用户的数据管道。日志被收集到数据仓库中,并经过多层处理。

  • ODS:来自所有来源的原始日志和警报都收集到 Apache Kafka 中。同时,它们的副本将存储在HDFS中以供数据验证或重放。

  • DWD:这是事实表所在的位置。Apache Flink 对数据进行清理、标准化、回填和去标识化,并将其写回 Kafka。这些事实表也将被放入 Apache Doris 中,以便 Doris 跟踪某个项目或用于仪表板和报告。由于日志不反对重复,因此事实表将按照Apache Doris 的Duplicate Key 模型进行排列。

  • DWS:该层聚合来自DWD的数据,为查询和分析奠定基础。

  • ADS:在这一层中,Apache Doris 使用其 Aggregate Key 模型自动聚合数据,并使用Unique Key 模型自动更新数架构 2.0 是从架构 1.0 发展而来的,由 ClickHouse 和 Apache Hive 支持。这种转变出于用户对实时数据处理和多表连接查询的需求。根据使用 ClickHouse 的经验,用户发现对并发和多表联接的支持不足,表现为仪表板频繁超时和分布式联接中的OOM 错误。

现在让我们看看用户使用架构2.0在数据摄取、存储和查询方面的实践。

真实案例练习

每天稳定摄取 150 亿条日志

用户的业务每天会产生 150 亿条日志。快速稳定地摄取如此大的数据量是一个现实问题。对于 Apache Doris,推荐的方法是使用 Flink-Doris-Connector。它是由 Apache Doris 社区开发的,用于大规模数据写入。该组件需要简单的配置。实现了Stream Load,可以达到每秒200,000~300,000条日志的写入速度,而且不中断数据分析工作负载。
得到的一个经验是,在使用Flink进行高频写入时,需要根据自己的情况找到合适的参数配置,避免数据版本积累。针对这种情况用户做了以下优化:
  • Flink Checkpoint:将检查点间隔从 15 秒增加到 60 秒,以减少写入频率和单位时间内 Doris 处理的事务数量。这样可以缓解数据写入压力,避免生成过多的数据版本。

  • 数据预聚合:对于ID相同但来自不同表的数据,Flink会根据主键ID进行预聚合并创建扁平表,以避免多源数据写入造成过多的资源消耗。

  • Doris Compaction:这里的技巧包括找到正确的Doris后端(BE)参数来分配适量的CPU资源进行数据压缩,设置适当数量的数据分区、桶和副本(过多的数据片会带来巨大的开销),并设置 max_tablet_version_num 以避免版本累积。

这些措施共同确保了数据日常摄取的稳定性。过程中用户见证了Doris后端的稳定性能和较低的压缩分数。此外,Flink 中的数据预处理与Doris 中的Unique Key 模型相结合,来保证更快的数据更新。

存储策略可降低成本 50%
日志的大小和生成率也给存储带来了压力。海量的日志数据中,只有一部分具有较高的信息价值,因此应差异化存储。用户采用三种存储策略来降低成本。
  • ZSTD(ZStandard)压缩算法:对于大于1TB的表,在建表时指定压缩方式为“ZSTD”,将实现10:1的压缩比。
  • 冷热数据分层存储:这是Doris新特性支持的。用户设置 7 天的数据“冷却”期。这意味着过去7天的数据(即热点数据)将存储在SSD中。随着时间的推移,热数据“冷却”(超过 7 天),它会自动转移到成本较低的HDD。随着数据变得更加“冷”,它将被转移到对象存储,以大大降低存储成本。另外,在对象存储中,数据将仅存储一份而不是三份。这进一步降低了成本和冗余存储带来的管理费用。
  • 不同数据分区的差异化副本数:用户按时间范围对数据进行分区。原则是为较新的数据分区提供更多的副本,为旧的数据分区提供更少的副本。在他们的应用中,过去 3 个月的数据被频繁访问,因此他们为此分区有 2 个副本。3~6个月前的数据有两个副本,6个月前的数据有一个副本。
通过这三种策略,用户的存储成本降低了 50%。
根据数据大小差异化查询策略

有些日志必须立即追踪定位,例如异常事件或故障的日志。为了保证这些查询的实时响应,用户针对不同的数据大小有不同的查询策略:

  • 小于100G:利用Doris的动态分区功能。小表将按日期分区,大表将按小时分区。这样可以避免数据倾斜。为了进一步确保分区内数据的平衡,使用snowflake ID 作为分桶字段。还设置了20天的起始偏移量,这意味着最近20天的数据将被保留。通过这种方式,找到了数据积压和分析需求之间的平衡点。

  • 100G~1T:这些表有其物化视图,是存储在Doris中的预先计算的结果集。因此,对这些表的查询速度更快而且资源消耗更少。Doris中物化视图的DDL语法与PostgreSQL、Oracle中的相同。

  • 超过100T:这些表被放入Apache Doris的Aggregate Key模型中并进行预聚合。这样就可以在1~2s内完成20亿条日志记录的查询。

这些策略缩短了查询的响应时间。例如,以前对特定数据项的查询需要几分钟,但现在可以在毫秒内完成。对于百亿条数据的大表,不同维度的查询都可以在几秒钟内完成。
正在进行的计划

用户正在 Apache Doris 中使用新添加的倒排索引进行测试。旨在加速字符串的全文搜索以及数字和日期时间的等价和范围查询。用户还对 Doris 中的自动分桶逻辑提供了宝贵的反馈:目前,Doris 根据前一个分区的数据大小来决定一个分区的分桶数量。问题在于,用户大部分新数据都是在白天输入,晚上则很少。因此,Doris 为夜间数据创建了太多的存储桶,但在白天创建的存储桶却太少,这与用户所需要的正好相反。用户希望增加一个新的自动分桶逻辑,参考前一天的数据大小和分布来决定分桶数量。我们正在致力于此优化。

原文作者:ApacheDoris