作者介绍: 肖康,SelectDB 技能副总裁
导语
日志数据的处理与剖析是最典型的大数据剖析场景之一,曩昔业界以 Elasticsearch 和 Grafana Loki 为代表的两类架构难以一起统筹高吞吐实时写入、低本钱海量存储、实时文本检索的需求。Apache Doris 学习了信息检索的中心技能,在存储引擎上完成了面向 AP 场景优化的高功用倒排索引,关于字符串类型的全文检索和一般数值、日期等类型的等值、规模检索具有更高效的支撑,相较于 Elasticsearch 完成性价比 10 余倍的进步,以此为日志存储与剖析场景供给了更优的挑选。
日志数据剖析的需求与特色
日志数据在企业大数据中十分遍及,其体量往往在企业大数据体系中占据十分高的比重,包含服务器、数据库、网络设备、IoT 物联网设备产生的体系运维日志,与此一起还包含了用户行为埋点等事务日志。
日志数据关于保障体系稳定运转和事务开展至关重要:依据日志的监控告警能够发现体系运转危险,及时预警;在毛病排查进程中,实时日志检索能协助工程师快速定位到问题,尽快康复服务;日志报表能经过长前史核算发现潜在趋势。而用户埋点日志数据则是用户行为剖析以及智能推荐事务所依赖的决议计划根底,有助于用户需求洞察与体会优化以及后续的事务流程改善。
因为其在事务中能发挥的重要意义,因而构建一致的日志剖析渠道,供给对日志数据的存储、高效检索以及快速剖析才能,成为企业挖掘日志数据价值的要害一环。而日志数据和运用场景往往呈现如下的特色:
- 数据添加快:每一次用户操作、体系事情都会触发新的日志产生,很多企业每天新增日志到达几十甚至几百亿条,对日志渠道的写入吞吐要求很高;
- 数据总量大:因为自身事务和监管等需求,日志数据常常要存储较长的周期,因而累积的数据量常常到达几百 TB 甚至 PB 级,而较老的前史数据访问频率又比较低,面临沉重的存储本钱压力;
- 时效性要求高:在毛病排查等场景需求能快速查询到最新的日志,分钟级的数据推迟往往无法满意事务极高的时效性要求,因而需求完成日志数据的实时写入与实时查询。
这些日志数据和运用场景的特色,为承载存储和剖析需求的日志渠道提出了如下应战:
- 高吞吐实时写入:既需求确保日志流量的大规模写入,又要支撑低推迟可见;
- 低本钱大规模存储:既要存储很多的数据,又要下降存储本钱;
- 支撑文本检索的实时查询:既要能支撑日志文本的全文检索,又要做到实时查询呼应;
业界日志存储剖析处理方案
当前业界有两种比较典型的日志存储与剖析架构,别离是以 Elasticsearch 为代表的倒排索引检索架构以及以 Loki 为代表的轻量索引/无索引架构,假如咱们从实时写入吞吐、存储本钱、实时交互式查询功用等几方面进行比照,不难发现以下结论:
- 以 ES 为代表的倒排索引检索架构,支撑全文检索、查询功用好,因而在日志场景中被业界大规模运用,但其仍存在一些缺乏,包含实时写入吞吐低、耗费很多资源构建索引,且需求耗费巨大存储本钱;
- 以 Loki 为代表的轻量索引或无索引架构,实时写入吞吐高、存储本钱较低,可是检索功用慢、要害时分查询呼应跟不上,功用成为限制事务剖析的最大掣肘。
ES 在日志场景的优势在于全文检索才能,能快速从海量日志中检索出匹配要害字的日志,其底层中心技能是倒排索引(Inverted Index)。
倒排索引是一种用于快速查找文档中包含特定单词或短语的数据结构,最早运用于信息检索领域。如下图所示,在数据写入时,倒排索引能够将每一行文本进行分词,变成一个个词(Term),然后构建词(Term) -> 行号列表(Posting List) 的映射联系,将映射联系依照词进行排序存储。当需求查询某个词在哪些行呈现的时分,先在 词 -> 行号列表 的有序映射联系中查找词对应的行号列表,然后用行号列表中的行号去取出对应行的内容。这样的查询方法,能够防止遍历对每一行数据进行扫描和匹配,只需求访问包含查找词的行,在海量数据下功用有数量级的进步。
图:倒排索引原理暗示
倒排索引为 ES 带来快速检索才能的一起,也付出了写入速度吞吐低和存储空间占用高的价值——因为数据写入时倒排索引需求进行分词、词典排序、构建倒排表等 CPU 和内存密集型操作,导致写入吞吐大幅下降。而从存储本钱角度考虑,ES 会存储原始数据和倒排索引,为了加快剖析可能还需求额定存储一份列存数据,因而 3 份冗余也会导致更高的存储空间占用。
Loki 则放弃了倒排索引,虽然带来来写入吞吐和存储空间的优势,可是损失了日志检索的用户体会,在要害时刻不能发挥快速查日志的作用。本钱虽然有所下降,可是没有真实处理用户的问题。
更高性价比的日志存储剖析处理方案
从以上方案比照可知,以 Elasticsearch 为代表的倒排索引检索架构以及以 Loki 为代表的轻量索引/无索引架构无法一起统筹 高吞吐、低存储本钱和实时高功用的要求,只能在某一方面或某几方面做权衡取舍。假如在坚持倒排索引的文本检索功用优势的一起,大幅进步体系的写入速度与吞吐量并下降存储资源本钱,是否日志场景所面临的窘境就方便的处理呢?答案是必定的。
假如咱们希望运用 Apache Doris 来更优点理日志存储与剖析场景的痛点,其完成途径也十分清晰——在数据库内部添加倒排索引、以满意字符串类型的全文检索和一般数值/日期等类型的等值、规模检索,一起进一步优化倒排索引的查询功用、使其愈加符合日志数据剖析的场景需求。
在相同完成倒排索引的情况下,相较于 ES, Apache Doris 怎样做到更高的功用体现呢?或者说现有倒排索引的优化空间有哪些呢?
- ES 依据 Apache Lucene 构建倒排索引,Apache Lucene 自 2000 年开源至今已有超越 20 年的前史,规划之初首要面向信息检索领域、功用丰富且杂乱,而日志和大多数 OLAP 场景只需求其中心功用,包含分词、倒排表等,而相关度排序等并非强需求,因而存在进一步功用简化和功用进步的空间;
- ES 和 Apache Lucene 均选用 Java 完成,而 Apache Doris 存储引擎和履行引擎选用 C++ 开发并且完成了全面向量化,相关于 Java 完成具有更好的功用;
- 倒排索引并不能决定功用体现的全部,作为一个高功用、实时的 OLAP 数据库,Apache Doris 的列式存储引擎、MPP 散布式查询结构、向量化履行引擎以及智能 CBO 查询优化器,相较于 ES 更为高效。
经过在 Apache Doris 2.0.0 最新版别的探究与继续优化,在相同硬件配置和数据集的测验体现上,Apache Doris 在数据库内核完成高功用倒排索引后,相关于 ES 完成了日志数据写入速度进步 4 倍、存储空间下降 80%、查询功用进步 2 倍,再结合 Apache Doris 2.0.0 版别引进的冷热数据别离特性,全体性价比进步 10 倍以上!
接下来咱们进一步介绍规划与完成细节。
高功用倒排索引的规划与完成
业界各类体系为了支撑全文检索和任意列索引,往往有两种完成方法:一是经过外接索引体系来完成,原始数据存储在原体系中、索引存储在独立的索引体系中,两个体系经过数据的 ID 进行关联。数据写入时会同步写入到原体系和索引体系,索引体系构建索引后不存储完整数据只保留索引。查询时先从索引体系查出满意过滤条件的数据 ID 集合,然后用 ID 集合去原体系查原始数据。
这种架构的优势是完成简略,借力外部索引体系,对原有体系改动小。可是问题也很显着:
- 数据写入两个体系,反常有数据不一致的问题,也存在必定冗余存储;
- 查询需在两个体系进行网络交互有额定开支,数据量大时用 ID 集合去原体系查功用比较低;
- 保护两套体系的杂乱度高,将体系的杂乱性从开发测转移到运维测;
而另一种方法则是直接在体系中内置倒排索引,尽管技能难度更高,但功用更好、且无需花费额定的体系保护本钱,对用户愈加友爱,这也是 Apache Doris 所挑选的方法。
数据库内置倒排索引
在挑选了在数据库内核中内置倒排索引后,咱们需求进一步对 Apache Doris 索引结构进行剖析,判别能否经过在已有索引根底上进行拓展来完成。
Apache Doris 现有的索引存储在 Segment 文件的 Index Region 中,依照适用场景能够分为跳数索引和点查索引两类:
-
跳数索引:包含 ZoneMap 索引和 Bloom Filter 索引。
- ZoneMap 索引对每一个数据块和文件保存 Min/Max/isnull 等汇总信息,能够用于等值、规模查询的粗粒度过滤,只能排除不满意查询条件的数据块和文件,不能定位到行,也不支撑文本分词。
- BloomFilter 索引也是数据块和文件等级的索引,经过 Bloom Filter 判别某个值是否在数据块和文件中,相同不能定位到行、不支撑文本分词;
-
点查索引:包含 ShortKey 前缀排序索引和 Bitmap 索引。
- ShortKey 在排序的根底上,依据给定的前缀列完成快速查询数据的索引方法,能够对前缀索引的列进行等值、规模查询,但不支撑文本分词,别的因为数据要按前缀索引排序、因而一个表只允许一组前缀索引。
- Bitmap 索引记录数据值 -> 行号 Bitmap 的有序映射,是一种很根底的倒排索引,可是索引结构比较简略、查询功率不高、不支撑文本分词。
原有索引结构很难满意日志场景实时文本检索的需求,因而规划了全新的倒排索引。倒排索引在规划和完成上咱们采取了无侵入的方法、不改变 Segment 数据文件格局,而是添加了新的 Inverted Index File,逻辑上在 Table 的 Column 等级。具体流程如下:
- 数据写入和 Compaction 阶段:在写 Segment 文件的一起,同步写入一个 Inverted Index 文件,文件途径由 Segment ID + Index ID 决定。写入 Segment 的 Row 和 Index 中的 Doc 一一对应,因为同步次序写入,Segment 中的 Rowid 和 Index 中的 Docid 完全对应。
- 查询阶段:假如查询 Where 条件中有建了倒排索引的列,会主动去 Index 文件中查询,回来满意条件的 Docid List,将 Docid List 一一对应的转成 Rowid Bitmap,然后走 Doris 通用的 Rowid 过滤机制只读取满意条件的行,到达查询加快的作用。
图:Doris倒排索引架构图
这个规划的优点是已有的数据文件无需修改,能够做到兼容晋级,而且增减索引不影响数据文件和其他索引,用户增建索引没有担负。
通用倒排索引优化
C++和向量化完成
Apache Doris 运用 CLucene 作为底层的倒排索引库,CLucene 是一个用 C++ 完成的高功用、稳定的 Lucene 倒排索引库,它的功用比较完整,支撑分词和自定义分词算法,支撑全文检索查询和等值、规模查询。
Apache Doris 的存储模块和 CLucene 都用 C++ 完成,防止了Java Lucene 的 JVM GC 等开支,相同的核算 C++ 完成相关于 Java 功用优势显着,而且更利于做向量化加快。Doris 倒排索引进行了向量化优化,包含分词、倒排表构建、查询等,功用得到进一步进步。全体来看 Doris 的倒排索引写入速度能够超越单核 20MB/s,而 ES 的单核写入速度不到 5MB/s,有 4 倍的功用优势。
列式存储和紧缩
Lucene 本身是文档存储模型,主数据选用行存,而 Doris 中不同列的倒排索引是彼此独立的,因而倒排索引文件也选用列式存储,有利于向量化构建索引和进步紧缩率。
选用紧缩比高且速度快的 ZSTD,一般能够到达 5 ~10倍的紧缩比,与常用的GZIP紧缩比较有50%以上的空间节约且速度更快。
BKD 索引与 数值、日期类型 列优化
针对数值、日期类型的列,咱们还完成了 BKD 索引,能够对规模查询进步功用,存储空间也相关于转成定长字符串愈加高效,具有以下首要特性和优势:
- 高效规模查询:BKD 索引选用多维数据结构,为规模查询带来高功率。它能迅速定位数值或日期类型列中所需的数据规模,下降查询时间杂乱度。
- 存储空间优化:与其他索引方法比较,BKD 索引在存储空间运用上更高效。经过聚兼并紧缩相邻数据块,削减索引所需存储空间,下降存储本钱。
- 多维数据支撑:BKD 索引具有杰出扩展性,支撑多维数据类型,如地理坐标(GEO point)和规模(Range),使其在处理杂乱数据类型时具有高适应性。
此外,咱们在原有 BKD 索引才能根底上进行了进一步拓展:
- 优化低基数场景:针对数值散布会集、单个数值倒排列表较多的低基数场景,咱们调整了针对性的紧缩算法,下降很多倒排表解紧缩和反序列化所带来的CPU功用耗费。
- 预查询技能:针对查询成果射中数较高的场景,咱们选用预查询技能进行射中数预估。若射中数显著超越阈值,可越过索引查询,直接运用Doris在大数据量查询下的技能优势进行数据过滤。
面向 OLAP 的倒排索引优化
日志存储和剖析场景对检索的需求很简略,不需求特别杂乱的功用(比方相关性排序),更需求下降存储本钱和快速依照条件查出数据。因而,在面临海量数据的写入和查询时,Apache Doris 还针对 OLAP 数据库的特色优化了倒排索引的结构,使其愈加简洁高效。例如:
- 在写入流程确保不会多个线程写入一个索引,然后防止写入时多线程锁竞争的开支;
- 在存储结构上去掉了不必要的正排、norm 等文件,削减写入 IO 开支和存储空间占用;
- 查询进程中简化相关性打分和排序逻辑,下降不必要的开支,进步查询功用。
针对日志等数据有按时间分区、前史数据访问频度低的特色,依据独立的索引文件规划,Apache Doris 还将在后续的版别中供给更细粒度、更灵活的索引办理功用:
- 指定分区构建倒排索引,比方新增一个索引的时分指定最近7天的日志构建索引,前史数据不建索引
- 指定分区删去倒排索引,比方删去超越1个月的日志的索引,释放访问频度低的索引存储空间
功用测验
高功用是 Apache Doris 倒排索引规划和完成的首要起点,咱们经过公开的测验数据集别离与 ES 以及 Clickhouse 进行功用测验,测验作用如下:
vs Elasticsearch
咱们选用了 ES 官方的功用测验 Benchmark esrally 并运用其中的 HTTP Logs 日志,在相同的硬件资源、数据、测验Case 以及测验东西下,记录并比照各自的数据写入时间、吞吐以及查询推迟。
- 测验数据:esrally HTTP Logs track 中自带测验数据集,1998 年 World Cup HTTP Server Logs,未紧缩前 32G、共 2.47 亿行、单行平均长度 134 字节;
- 测验查询:esrally HTTP Logs 测验要害词检索、规模查询、聚合、排序等 11 个 Query,所有查询跑 100 次串行履行;
- 测验环境:3 台 16C 64G 云主机组成的集群。
在终究的测验成果中,Doris 写入速度是 ES 的 4.2 倍、到达 550 MB/s,写入后的数据紧缩比挨近 1:10、存储空间 节约 超 ****** 80%** ,查询耗时下降 57%、查询功用是 ES 的 2.3 倍。加上冷热数据别离下降冷数据存储本钱,全体相较 ES 完成 10倍以上的性价比进步。
vs Clickhouse
Clickhouse 近期的 v23.1 版别也引进了相似 Feature,将倒排索引作为实验性功用发布,因而咱们相同进行了跟 Clickhouse 倒排索引的功用比照。在本次测验中,咱们选用了 Clickhouse 官方 Inverted Index 介绍博客中运用的 Hacker News 样例数据以及查询 SQL ,相同坚持相同的物理资源、数据、测验 Case 以及测验东西。
(参阅文章:clickhouse.com/blog/clickh…)
- 测验数据:Hacker News 2873 万条数据,6.7G,Parquet 格局;
- 测验查询:3 个查询,别离查询 ‘clickhouse’、’olap’ OR ‘oltp’、’avx’ AND ‘sve’ 等要害字呈现的次数;
- 测验机器:1 台 16C 64G 云主机
在终究的测验成果中,3 个 SQL Apache Doris 的查询功用别离是 Clickhouse 的 4.7 倍、12.0 倍以及 18.5 倍,有显着的功用优势。
怎么运用
下面以一个 Hacker News 100 万条测验数据的示例展现 Doris 怎么运用倒排索引完成高效的日志剖析。
-
建表时指定索引
- INDEX idx_comment (
comment
) 指定对 comment 列建一个名为 idx_comment 的索引 - USING INVERTED 指定索引类型为倒排索引
- PROPERTIES(“parser” = “english”) 指定分词类型为英文分词
- INDEX idx_comment (
CREATE TABLE hackernews_1m
(
`id` BIGINT,
`deleted` TINYINT,
`type` String,
`author` String,
`timestamp` DateTimeV2,
`comment` String,
`dead` TINYINT,
`parent` BIGINT,
`poll` BIGINT,
`children` Array<BIGINT>,
`url` String,
`score` INT,
`title` String,
`parts` Array<INT>,
`descendants` INT,
INDEX idx_comment (`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'inverted index for comment'
)
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10
PROPERTIES ("replication_num" = "1");
注:关于已经存在的表,也能够经过 ADD INDEX idx_comment ON hackernews_1m(`comment`) USING INVERTED PROPERTIES("parser" = "english")
来添加索引。值得一提的是,和 Doris 原先存储在 Segment 数据文件中的智能索引和二级索引比较,添加倒排索引的进程只会读 comment 列构建新的倒排索引文件,不会读写原有的其他数据,功率有显着进步。
- 导入数据后查询,运用
MATCH_ALL
在 comment 这一列上匹配 OLAP 和 OLTP 两个词,和 LIKE 扫描硬匹配比较,查询功用有十余倍的进步。(这仅是 100 万条数据下的测验作用,而跟着数据量增大、功用进步越显着)
mysql> SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%';
+---------+
| count() |
+---------+
| 15 |
+---------+
1 row in set (0.13 sec)
mysql> SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP';
+---------+
| count() |
+---------+
| 15 |
+---------+
1 row in set (0.01 sec)
更多具体功用介绍和测验过程能够参阅Apache Doris 倒排索引官方文档 。
总结
经过内置高功用倒排索引,Apache Doris 关于字符串类型的全文检索和一般数值、日期等类型的等值、规模检索具有更高效的支撑,进一步进步了数据查询的功率和准确性,关于大规模日志数据查询剖析有了更好的功用体现,为需求检索才能的用户供给了更高性价比的挑选。
现在倒排索引已经支撑了 String、Int、Decimal、Datetime 等常用 Scalar 数据类型和 Array 数组类型,后续还会添加对 JSONB、Map 等杂乱数据类型的支撑。而 BKD 索引能够支撑多维度类型的索引,为未来 Doris 添加 GEO 地理位置数据类型和索引打下了根底。与此一起 Apache Doris 在半结构化数据剖析方面还有更多才能扩展,比方主动依据导入数据扩展表结构的 Dynamic Table、丰富的杂乱数据类型(Array、Map、Struct、JSONB)以及高功用字符串匹配算法等。
除倒排索引以外,Apache Doris 在 2.0.0 Alpha 版别中还完成了单节点数万 QPS 的高并发点查询才能、依据对象存储的冷热数据别离、依据价值模型的全新查询优化器以及 Pipeline 履行引擎等,欢迎大家下载体会。高并发点查询的具体介绍能够检查 SelectDB 技能团队过往发布的技能博客,其他功用的运用介绍请参阅社区官方文档,一起也敬请继续关注咱们后续发布的特性解读系列文章。
为了让用户能够体会社区开发的最新特性,一起确保最新功用能够收获到更广规模的运用反应,咱们建立了 2.0.0 版别的专项支撑群,欢迎广阔社区用户在运用最新版别进程中多多反应运用意见,协助 Apache Doris 继续改善,经过此处填写申请加入专项支撑群。