一、问题描述

原来的日志系统使用的是ES作为底层存储,后来因为数据量大了之后,出现了写入存在阻塞和查询效率变低的问题。后来决定切换到Doris数据库。

Doris的优势根据公开资料来看,它在写入性能、查询效率和存储成本上,都优于ES。比如下面这个对比图:

但是真正上了生产环境之后才发现,各有各的坑。

首先我们遇到的问题就是默认情况下对中文日志的检索效果远远不如ES。具体比如说,搜索“预订下单接口”,搜索结果出来还出现了同时包含“预订”“下单”“接口”的日志信息,也就是说这一句话被分词后进行了分别匹配。比如说:

这个结果也被搜索了出来,这显然不是我们期望看到的结果。但是在ES上进行同样搜索的时候就不存在这个问题。

二、解决探索

从理论上分析导致这个搜索结果有两个原因:

  1. 是入库阶段对文本进行分词操作的时候,按照较细粒度的中文词拆分后入的库;
  2. 是在检索的时候是简单的按照是否包含词来判断匹配情况,而没有按照短语进行匹配。

针对第一个原因的探究,我们首先来看看Doris是如何分词入库的。

1.查看Doris官方文档我们得知,在表创建时,可以通过指定索引的倒排索引属性值,来对索引的分词和短语支持进行设置的,官方文档:倒排索引 - Apache Doris

其中最关键的就是parser、support_phrase、parser_mode三个参数。

2.查看我们现有的表结构可以获知目前我们的表是这么设置这些参数的:

CREATE TABLE `logs` (`alllogs` text NULL COMMENT '日志',INDEX idx_alllogs (`alllogs`) USING INVERTED PROPERTIES("support_phrase" = "false", "char_filter_pattern" = ".,", "parser" = "unicode", "lower_case" = "true", "char_filter_replacement" = " ", "char_filter_type" = "char_replace") COMMENT 'idx_alllogs'
) ENGINE=OLAP ......

parser:在这里的用处就是指定索引的分词器,这里我们原来设置的是unicode。

support_phrase:使用了false,也就是关闭了短语支持。同时parser_mode就没有必要设置了。

3.我们来看看parser的三个分词器english、chinese、unicode效果上有什么差异:

SELECT TOKENIZE('预订下单接口报错 at com.test.com.CheckOneTwo.doCheck', '"parser"="english"');
--运行结果:["at", "com", "test", "com", "checkonetwo", "docheck"]SELECT TOKENIZE('预订下单接口报错 at com.test.com.CheckOneTwo.doCheck', '"parser"="chinese"');
--运行结果:["预订", "下单", "接口", "报错", "com", "test", "com", "CheckOneTwo", "doCheck"]SELECT TOKENIZE('预订下单接口报错 at com.test.com.CheckOneTwo.doCheck', '"parser"="unicode"');
--运行结果:["预", "订", "下", "单", "接", "口", "报", "错", "com.test.com.checkonetwo.docheck"]

可以看到三种结果都各有各的问题:english直接忽略了中文,chinese虽然按中文词的粒度进行拆分但是又把包名进行了单次拆分,而unicode虽然把包名当成了整体但是却把中文拆成了单个字。

而如果我们在ES中使用IK分词器它的分词结果会是:

"预订","订下","订","下单","接口","报错","com.test.com.checkonetwo.docheck","com","test","com","checkonetwo","docheck"

显然从分词效果来看IK分词是最好的,但是遗憾的是Doris目前的版本并不支持IK分词(Doris官方计划2025年年内支持)。

仅仅基于目前的条件,parser设置为chinese或者unicode都可以。而对效果影响最大的应该是短语搜索的支持。

4.support_phrase设置为true之后,就支持短语搜索了,具体的修改过程如下:

SHOW INDEX FROM logs;
--查看表大小
SHOW DATA FROM logs;
--查看索引任务
show BUILD INDEX WHERE TableName="logs";--删除索引
ALTER TABLE logs DROP INDEX idx_alllogs;--尝试1:改为support_phrase=true, parser=chinese。
ALTER TABLE logs ADD INDEX idx_alllogs(`alllogs`) USING INVERTED PROPERTIES("support_phrase" = "true", "parser" = "chinese", "lower_case" = "true") COMMENT 'idx_alllogs';--尝试2:改为support_phrase=true, parser=unicode。
ALTER TABLE logs ADD INDEX idx_alllogs(`alllogs`) USING INVERTED PROPERTIES("support_phrase" = "true", "parser" = "unicode", "lower_case" = "true") COMMENT 'idx_alllogs';--重建索引
BUILD INDEX idx_alltext ON logs_message_crs;

这里我测试了support_phrase设置为true之后,分别设置chinese和unicode两个分词器的索引,观察了下存储代价。

logs表在support_phrase设置为false时,表大小3.9G。

改为support_phrase=true、 parser=chinese,表大小变为了8.9G。

改为support_phrase=true 、parser=unicode,表大小变为了8.0G。

可见短语支持让表空间几乎大了一倍。根据我们生产环境同样数据与ES的横向对比得出一个结论:要Doris实现与ES同样的中文搜索效果,可能在存储空间大小上Doris并无优势。

接下来我们针对上面的第二个原因进行探究,也就是查询需要使用短语查询。

查询的时候有四种查法。

1. LIKE:跟MySQL差不多,如果使用LIKE "%keyword%"进行匹配,大部分时候是用不到索引的,会进行全表扫描,查询效率极低,所以不推荐。

2.MATCH_ANY:"keyword1 keyword2",多个搜索关键字时,只要包含其中任意一个就会命中。值得注意的是如果keyword是多个中文短语,那么会被拆成词语后进行匹配。比如说“预定信息  错误异常”,会把只包含“预定”的记录也会匹配出来。也就是这里并没有用上短语匹配。

3.MATCH_ALL:"keyword1 keyword2",多个搜索关键字时,包含全部关键字才会命中。同样值得注意的是是如果keyword是多个中文短语,那么会被拆成词语后进行匹配。比如说“预定信息  错误异常”,它会把同时包含“预定” “信息” “错误” “异常”的匹配出来,是拆分后进行匹配的。同样也没有用上短语匹配。

4.MATCH_PHRASE:这个才是我们需要用到的短语匹配的能力。当我们需要MATCH_PHRASE "预定订单错误"时,他会把"预定订单错误"当成一个短语整体进行匹配,而不是拆分成单个词进行匹配。但是这里又有一个新的问题需要注意,就是多个关键词匹配的问题,如果我们需要搜索同时包含“预定信息  错误异常”的日志,那么使用MATCH_PHRASE "预定信息  错误异常"将无法得到我们想要的结果,因为它会把"预定信息  错误异常"当成一个整体,而不是以空格为切分。那多个关键字如何匹配呢,其中一个简单的办法就是使用多个MATCH_PHRASE进行匹配,比如说:MATCH_PHRASE "预定信息" AND MATCH_PHRASE "错误异常",这样就能达到预期的效果。

三、结论

好了,以上就是整个调优和分析的过程,总结一下如何解决Doris的中文检索效果,有如下几个关键点:

1.打开support_phrase=true,使其索引支持短语检索。但是要注意这里将会带来额外的存储开销。

2.parser设置为chinese或者unicode,使其支持中文分词。

3.使用MATCH_PHRASE进行短语匹配。

希望上面的内容对你有所帮助,如果你还遇到其他问题,欢饮留言区讨论。

参考材料:为什么 Apache Doris 是比 Elasticsearch 更好的实时分析替代方案?-腾讯云开发者社区-腾讯云

Doris如何做到将查询性能提升100倍 - 墨天轮

Doris 超全索引实战教程 - 墨天轮

深入剖析 Doris 倒排索引(上):原理与应用全解析​_doris 分词器-CSDN博客

倒排索引 - Apache Doris

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/91165.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/91165.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/91165.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CDN怎么加速跟防御网站攻击呢?

**CDN(内容分发网络)**通过分布式架构和智能路由技术,不仅可以加速网站内容访问,还能有效防御多种网络攻击(如DDoS、SQL注入等)。以下是 CDN 如何实现加速和防御的详细解析:1. CDN 如何加速网站…

【Linux】批量处理多个用户的 sudo 权限问题

要批量处理多个用户的 sudo 权限问题,有以下几种高效方法: 方法一:通过用户组批量授权(推荐) 这是最安全便捷的方式,只需将用户加入已有 sudo 权限组(如 wheel 或 sudo):…

云原生MySQL Operator开发实战(五):扩展与生态系统集成

引言 在前四篇文章中,我们构建了一个功能完备的MySQL Operator,涵盖了从基础架构到生产部署的全过程。本文将作为本系列的收官之作,重点探讨Operator的扩展能力和与云原生生态系统的深度集成,包括自定义插件系统、与CI/CD流水线的集成、服务网格支持以及与云服务的无缝对接…

【MySQL】数据库的简单介绍

1.数据库是什么简单来说,数据库是用于存储数据和管理数据的软件。数据库可以提供远程服务,通过远程连接来使用数据库,因此数据库也被称为数据库服务器!2.为什么要使用数据库存储数据用文件就可以了,为什么还要弄一个数…

uniapp,uview icon加载太慢了,老是显示叉叉,将远程加载改到本地加载。

处理方式:将远程字体文件下载到本地进行加载。app.vue。font-face {font-family: uicon-iconfont;src: url(./static/fonts/font_2225171_8kdcwk4po24.ttf) format(truetype);font-weight: normal;font-style: normal;}下载文件:从node_modules找文件u-i…

Python爬虫01_Requests第一血获取响应数据

引入requests包,发起请求并获取响应数据。 import requestsif __name__ "__main__":#step 1:指定urlurl http://www.7k7k.com/#step 2:发起请求,get方法会返回一个响应对象response requests.get(url)#step 3&#x…

Linux定时器和时间管理源码相关总结

基础可参考: Linux内核定时器相关内容总结-CSDN博客 定时器来源 定时器也是来源于芯片的硬件定时器,属于内部外设,有些可能也会用外部定时器,不管咋样,都属于芯片外设,既然是外设,那么我们也要编…

JDK17 新特性跟学梳理

JDK17 新特性跟学梳理JDK17 背景介绍一、JDK 17对Switch语句的增强二、字符串拼接三、强制转换四、密封类Sealed Classes五、Record类六、优化空指针异常信息七、ZGC垃圾收集器八、JVM常量API九、重写Socket底层API十、JDK飞行记录事件流十一、EdDSA签名算法十二、隐藏类十三、…

ESP8266 AT 固件

ESP-12E 是一种常见的 ESP8266 模块,通常带有 4MB(32Mbit)闪存,非常适合刷写 最新版 AT 固件。 ✅ 适用于 ESP‑12E 的 AT 固件推荐 固件来源固件版本特点Espressif 官方v2.2.1.0 (ESP8266 IDF AT)官方最新版,基于 RT…

Node.js(三)之Express

Express 目录 Express 九、初识Express 9.1 Express简介 1. 什么是 Express 2. 进一步理解Express 3. Express能做什么 9.2 Express的基本使用 1. 安装 2. 创建基本的Web服务器 3. 监听GET请求 4. 监听POST请求 5. 把内容响应给客户端 6. 获取URL中携带的查询参数…

IKAnalyzer分词插件使用方法

前言 随着越来越多的大数据网站崛起,特别是一些私人网站都提供了站内搜索,有些人会用elastsearch来实现站内搜索的目的,但是一些小站并没有那么大的数据提供搜索,在安装一个 elastsearch 服务未免有点浪费? 因此&#…

ESB 在零售,物流,制造,保险,医疗行业的应用方式

企业服务总线(Enterprise Service Bus, ESB)是一种基于中间件的集成模式,用于实现不同系统之间的集成与通信。ESB通过标准化接口、消息路由、协议转换和数据转换等功能,帮助企业实现系统间的无缝对接,提高业务敏捷性。…

vcsa6.7-重置root密码

客户反馈vc无法登录了,登录环境一看,报错如下首先想到是证书到期了,浏览器确认,确实是证书到期了准备ssh登录才发现root密码忘记了,那就先重置root密码,1、登录esxi主机找到vcsa6.7机器关机做快照2、开机到…

C++ 赋值与交换法则

在C中,赋值与交换法则(Assignment and Swap Idiom)通常指的是在实现类的赋值操作符(operator)时,结合拷贝构造和交换操作来确保强异常安全保证(Strong Exception Safety Guarantee)的…

Ambari中文汉化

Ambari-ZH 当前Ambari的汉化版本为2.7.4,汉化采用对该版本的ambari源码直接修改的方式进行,如有翻译不当之处,请批评指正 一、使用方法如下: 方式一:直接下载 下载地址:https://github.com/ukayunnuo/Ambari-2.7.x-zh/releases/download/…

表格之固定列和表头

说明 利用粘性定位实现 列固定 td.fixed {position: sticky;left: 0;z-index: 5;/* 最好指定背景&#xff0c;否则滑动时会显示下面的列 */background-color: #f8f9fa; }表头固定 <head><style>.table-container {position: relative;display: flex;overflow: hidd…

React 图标库发布到 npm 仓库

将搭建的 React 图标库发布到 npm 仓库需要经过一系列步骤&#xff0c;包括配置 package.json、构建代码、注册 npm 账号、测试和发布。以下是详细流程&#xff1a; 1. 准备工作 (1) 确保项目结构完整 图标库的典型结构&#xff08;以 Rollup 构建为例&#xff09;&#xff1…

Java学习第八十四部分——HttpClient

目录 一、前言介绍 二、主要特点 三、功能用法 四、应用场景 五、最佳实践 六、总结归纳 一、前言介绍 HttpClient 是一个用于发送 HTTP 请求和接收 HTTP 响应的客户端库&#xff0c;广泛应用于 Web 开发、API 调用、微服务通信等场景。 二、主要特点 支持多种HTTP方…

学习笔记-中华心法问答系统的性能提升

1.简介本周主要任务是自行查找文献&#xff0c;针对源代码进行性能提升&#xff0c;主要包括三个方面&#xff1a;预处理&#xff1a;分词、关键词提取、词向量生成&#xff1b;文本分析&#xff1a;从多个关键词的词向量&#xff0c;如何到一句话的语义理解&#xff1b;问题分…

Python爬虫03_Requests破解百度翻译

爬取百度翻译页面信息 以POST方法发送JSON数据&#xff0c;爬取响应信息&#xff0c;并且需要对响应信息对象类型进行区分。 import requests import json#1.指定url post_url https://fanyi.baidu.com/sug#2.进行UA封装 headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; …