作者:肖康,SelectDB 技术 副总裁 、Apache Doris Committer
日志数据是企业大数据体系中重要的组成部分之一,这些数据记录了网络设备、操作系统以及应用程序的详细历史行为,蕴含了丰富的信息价值,在可观测性、网络安全、业务分析等关键业务领域发挥着重要作用,可帮助企业更好了解系统及业务运行情况,及时发现及解决问题,以保障系统安全稳定运行。具体而言,日志数据可以通过以下方式为企业带来价值:
日志数据本质是一系列系统事件的有序记录,其生成方式和使用场景决定了具备以下几个特点:
为了应对以上需求、发挥出日志数据的更高价值,业界对于日志场景有不少解决方案,而以 Elasticsearch 为核心的 ELK 体系则是其中典型代表。在此我们以 Elasticsearch 为例,来分享基于 Elasticsearch 的日志系统架构是如何面临挑战。
基于 Elasticsearch 的日志系统典型架构如上图所示,整个系统分为下面几个模块:
基于 Elasticsearch 的日志系统架构具有较好的实时日志检索能力,然而该系统在实际应用中也存在一些痛点,如写入吞吐低、存储成本高、不支持复杂查询等问题。
Elasticsearch 的 Index Mapping 定义了数据的 Schema,包括字段的名字、数据类型、是否建索引等。
Elasticsearch 的 Dynamic Mapping 可以根据写入的 JSON 数据自动增加 Mapping 中的字段,对日志数据的Schema Free 提供了一定程度的支持,但是也存在明显不足:
Elasticsearch 开发的 ES DSL(Domain Specific Language,特定领域语言)与大多数工程师、数据分析师熟悉的技术栈差异比较大,这为用户设置了较高的学习和使用门槛,并需要学习大量的多新的概念和语法,即使学会之后还需要经常查阅手册才能写出正确的 DSL 语句。同时,Elasticsearch 生态自成体系、比较封闭,与其他系统如 BI 工具等打通比较困难。更重要的是,Elasticsearch 分析能力较弱,只支持简单的单表分析,不支持多表 JOIN、子查询、视图等复杂分析,无法满足企业日志分析需求。
基于 Elasticsearch 的日志系统使用成本较高也是一个被用户长期诟病的问题,成本主要来源于两个方面:
而随着数据和集群规模增长, Elasticsearch 集群还面临一些稳定性问题:
从以上方案对可知,基于 Elasticsearch 的日志系统架构在应用中无法同时兼顾高吞吐、低存储成本和实时高性能的要求,且不支持复杂查询。那么是否有其他方案可以较好的平衡成本与性能,且能提供更好的分析能力呢?答案是有的。
立志于通过一个系统解决多个场景的数据分析问题、降低复杂技术展带来的运维和使用成本,为了更加契合日志数据分析的场景需求,Apache Doris 在 2.0 版本中引入了多项功能优化:例如支持原生的半结构数据类型,优化了 Text 匹配速度和文本算法,从而提升了日志数据导入和查询的性能;增加了倒排索引、以满足字符串类型的全文检索和普通数值/日期等类型的等值、范围检索。最终通过 Benchmark 测试和实际应用验证表明, 基于 Apache Doris 构建的新一代日志分析系统相较于 Elasticsearch 具有最高 10 倍的性价比提升。
基于 Apache Doris 的日志系统典型架构如下图所示,相较于 Elasticsearch 整个系统架构更加开放:
除此之外,基于 Apache Doris 的日志系统还具备以下几个重要的优势:
为了更好的适应 Text、JSON 格式日志 Schema Free 的特点,Apache Doris 在这两个方面进行了增强:
提供丰富的数据类型:优化已有 Text 的数据类型,通过向量化技术提升字符串查找、正则匹配的性能,通过这些优化实现性能提升 2-10倍;增加 JSON 数据类型,在数据写入对 JSON字符串进行解析并存储成紧凑高效的二进制格式,可使得查询性能提升 4 倍;增加 Array Map 复杂数据类型,将原本使用字符串拼接的复杂类型结构化,进一步提升了存储压缩率和查询性能。
支持 Schema Evolution:与 Elasticsearch 不同的是,Apache Doris 支持根据业务需要对 Schema 进行调整,包括按需在线增减字段、增减索引、更改字段数据类型等。
-- 增加列,毫秒级返回,立即生效
ALTER TABLE lineitem ADD COLUMN l_new_column INT;
-- 增加倒排索引,毫秒级返回,新写入数据自动生成索引
ALTER TABLE table_name ADD INDEX index_name(column_name) USING INVERTED;
-- 历史partition可以按需BUILD INDEX,后台增量生成索引
BUILD INDEX index_name ON table_name PARTITIONS(partition_name1, partition_name2);
Apache Doris 支持标准 SQL、兼容 MySQL 协议和语法,因此基于 Doris 的日志系统能够使用 SQL 进行日志分析,这使得日志系统具备以下优势:
经过 Benchmark 测试及生产验证,基于 Apache Doris 高性能基础引擎针对日志场景进行优化后,日志系统性价比相对于 Elasticsearch 具有 5-10 倍的提升。
我们在 Elasticsearch 提供的官方性能 Benchmark Rally 的 HTTP Logs 测试集上进行了对比测试。如下图可知,Doris 写入速度是 Elasticsearch 的 5 倍,存储空间减少了 80%,达到 550 MB/s,写入后的数据压缩比接近 1:10、存储空间节省超 80% ,查询耗时下降 57%、查询性能是 Elasticsearch 的 2.3 倍。加上冷热数据分离降低冷数据存储成本,整体相较 Elasticsearch 实现 10 倍以上的性价比提升。
在用户实际场景的验证中,Doris 也表现出了超出预期的性价比优势。例如,某游戏公司最初使用的是 Elasticsearch,通过标准的 ELK 进行日志分析,使用成本非常高。由于存储成本过高,使得该公司在日志数据的合理存储和高效分析受到了很大的限制,无法满足业务需求。而在使用 Doris 搭建日志系统后,所需存储空间仅是 Elasticsearch 的 1/6,极大的降低了存储成本。同时 Doris 的高性能和优秀的分析能力,也使得该公司能够更高效灵活的处理日志数据,并提供更好的业务支持。此外,某安全公司利用 Doris 提供的倒排索引构建了日志分析系统,仅使用原来 1/5 的服务器,承载了 30 万每秒的写入流量,导入及查询速度更快。Doris 的引入,不仅降低了该公司运营成本,也极大的提升了分析的效率及系统稳定性,为业务提供了强有力的支持
下面为大家介绍基于 Apache Doris 构建新一代日志系统的实践步骤。
首先需要在 Apache Doris 官网:https://doris.apache.org/zh-CN/download 下载 2.0 及以上版本;下载完成后参考部署文档进行集群部署:https://doris.apache.org/zh-CN/docs/dev/install/standard-deployment
参考下面的例子建表,关键点如下:
CREATE DATABASE log_db;
USE log_db;
CREATE RESOURCE "log_s3"
PROPERTIES
(
"type" = "s3",
"s3.endpoint" = "your_endpoint_url",
"s3.region" = "your_region",
"s3.bucket" = "your_bucket",
"s3.root.path" = "your_path",
"s3.access_key" = "your_ak",
"s3.secret_key" = "your_sk"
);
CREATE STORAGE POLICY log_policy_1day
PROPERTIES(
"storage_resource" = "log_s3",
"cooldown_ttl" = "86400"
);
CREATE TABLE log_table
(
`ts` DATETIMEV2,
`clientip` VARCHAR(20),
`request` TEXT,
`status` INT,
`size` INT,
INDEX idx_size (`size`) USING INVERTED,
INDEX idx_status (`status`) USING INVERTED,
INDEX idx_clientip (`clientip`) USING INVERTED,
INDEX idx_request (`request`) USING INVERTED PROPERTIES("parser" = "english")
)
ENGINE = OLAP
DUPLICATE KEY(`ts`)
PARTITION BY RANGE(`ts`) ()
DISTRIBUTED BY RANDOM BUCKETS AUTO
PROPERTIES (
"replication_num" = "1",
"storage_policy" = "log_policy_1day",
"deprecated_dynamic_schema" = "true",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-3",
"dynamic_partition.end" = "7",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "AUTO",
"dynamic_partition.replication_num" = "1"
);
Apache Doris 支持多种数据导入方式,对于实时日志数据,推荐 3 种导入方式:
将 JSON 格式的日志写入 Kafka 消息队列,创建 Kafka Routine Load,让 Doris 从 Kafka 中主动拉取数据。示例如下,其中 property.*
配置是非必须的:
-- 准备好kafka集群和topic log _topic
-- 创建routine load,从kafka log _topic将数据导入log_table表
CREATE ROUTINE LOAD load_log_kafka ON log_db.log_table
COLUMNS(ts, clientip, request, status, size)
PROPERTIES (
"max_batch_interval" = "10",
"max_batch_rows" = "1000000",
"max_batch_size" = "109715200",
"strict_mode" = "false",
"format" = "json"
)
FROM KAFKA (
"kafka_broker_list" = "host:port",
"kafka_topic" = "log _topic",
"property.group.id" = "your_group_id",
"property.security.protocol"="SASL_PLAINTEXT",
"property.sasl.mechanism"="GSSAPI",
"property.sasl.kerberos.service.name"="kafka",
"property.sasl.kerberos.keytab"="/path/to/xxx.keytab",
"property.sasl.kerberos.principal"="[email protected]"
);
创建好 Routine Load 后,可以通过 SHOW ROUTINE LOAD
查看运行状态。更多使用说明请参考 https://doris.apache.org/zh-CN/docs/dev/data-operate/import/import-way/routine-load-manual。
配置 Logstash 的 HTTP Output,将数据通过 HTTP Stream Load 发送到 Doris。
lo``gstash.yml
配置 Batch 攒批条数和时间,用于提升数据写入性能pipeline.batch.size: 100000
pipeline.batch.delay: 10000
testlog.conf
日志采集配置文件中增加一个 HTTP Output、URL 配置 Doris 的 Stream Load 地址。 http basic auth
,用命令 echo -n 'username:password' | base64 来
计算。load_to_single_tablet
参数能够减少导入的小文件。output {
http {
follow_redirects => true
keepalive => false
http_method => "put"
url => "http://172.21.0.5:8640/api/logdb/logtable/_stream_load"
headers => [
"format", "json",
"strip_outer_array", "true",
"load_to_single_tablet", "true",
"Authorization", "Basic cm9vdDo=",
"Expect", "100-continue"
]
format => "json_batch"
}
}
参考下面的方式通过 Http Stream Load 接口导入数据到 Doris,关键点如下:
basic auth
进行 HTTP 鉴权,用命令echo -n 'username:password' | base64
来计算http header "format:json"
,指定数据格式为 JSONhttp header "read_json_by_line:true"
,指定每行一个 JSONhttp header "load_to_single_tablet:true"
,指定一次写入一个分桶curl \
--location-trusted \
-u username:password \
-H "format:json" \
-H "read_json_by_line:true" \
-H "load_to_single_tablet:true" \
-T logfile.json \
http://fe_host:fe_http_port/api/log_db/log_table/_stream_load
Doris 支持标准 SQL,可以通过 MySQL客 户端或者通过 JDBC 等方式连接到集群,然后执行 SQL 进行查询。
mysql -h fe_host -P fe_mysql_port -u root -Dlog_db
下面是日志分析场景中,常见的几种查询。
SELECT * FROM log_table ORDER BY ts DESC LIMIT 10;
SELECT * FROM log_table WHERE clientip = '8.8.8.8' ORDER BY ts DESC LIMIT 10;
SELECT * FROM log_table WHERE request MATCH_ANY 'error 404' ORDER BY ts DESC LIMIT 10;
SELECT * FROM log_table WHERE request MATCH_ALL 'image faq' ORDER BY ts DESC LIMIT 10;
Apache Doris 针对日志场景进行了多项优化,最终达到存储空间节省超 80% 、写入速度是 Elasticsearch 的 5倍、查询性能是 Elasticsearch 的 2.3 倍。在冷热数据分层功能加持下,整体相较 Elasticsearch 实现 10 倍以上的性价比提升。这些都表明,Apache Doris 已经足够支撑各企业构建新一代日志系统。
后续倒排索引还会增加对 JSON、Map 等复杂数据类型的支持。而 BKD 索引可以支持多维度类型的索引,为未来 Doris 增加 GEO 地理位置数据类型和索引打下了基础。与此同时 Apache Doris 在半结构化数据分析方面还有更多能力扩展,比如丰富的复杂数据类型(Array、Map、Struct、JSON)以及高性能字符串匹配算法等,这些更显将满足更加丰富的日志应用场景。
最后,如果该文章所述符合您的使用场景,欢迎大家下载 Apache Doris 2.0 版本进行测试使用,为用户提供全面的技术支持和服务~
填写问卷,加入专项支持群