Elasticsearch:使用新的 wildcard 字段更快地在字符串中查找字符串 - 7.9 新功能_elasticsearch wildcard-程序员宅基地

技术标签: Elastic  Elasticsearch  elasticsearch  大数据  

在 Elasticsearch 7.9 中,我们将引入一种新的 “wildcard” 字段类型,该字段类型经过优化,可在字符串值中快速查找模式。这种新的字段类型采用了一种全新的方式来索引字符串数据,从而解决了在日志安全性数据中高效索引和搜索的最佳实践。根据你现有的字段用法,通配符可以提供:

  • 更简单的搜索表达式(无需将 AND /单词/短语组合在一起)
  • 更简单的索引编制(无需定义分析器选择)
  • 不再有的缺失值
  • 更快的搜索
  • 更少的磁盘使用

这种新数据类型最令人兴奋的功能是简化了部分匹配。使用通配符,你不再需要担心文本模式在字符串中的位置。只需使用常规查询语法进行搜索,Elasticsearch 就会在字符串中的任何位置找到所有匹配项。没错,我们完成了所有这些操作,而无需您更改查询语法。

当涉及字符串值的部分匹配时,通配符数据类型解决了安全性领域中那些人指出的问题,但在可观察性及其他方面具有应用程序(如下所述)。尤其是,希望搜索计算机生成的日志的用户应发现此新字段类型比现有选项更自然。

在此博客中,我们将介绍如何做到这一点,以及如何从通配符字段中获得最大收益。让我们来看看。

索引字符串的现有选项

直到7.9,在搜索字符串时,Elasticsearch 大致提供了两种选择:

  • text fields
  • keyword fields

文本字段将字符串 “tokenize” 为多个 token,每个token 通常代表单词。搜索 quick foxes 的搜索者因此可以匹配谈论 quick brown fox 的文章。

keyword 字段通常用于较短的结构化内容,例如国家/地区代码,无需分析即可将其编入索引作为单个 token。然后,分析师可以使用这些数据,比如,运用 aggregation 可视化受欢迎的度假胜地等。

如果没有用户明确的映射选择,Elasticsearch 的默认索引模板假定 JSON 文档中显示的字符串值应同时索引为 text 字段和 keyword 字段。目的是,如果字符串表示应该被切成多个单词 token 以进行搜索的散文,或者当被用于 “热门目的地” 条形图中展示时应作为单个结构化值(例如城市名称 “New York”)。

文字和关键字字段不足时

对于 text 或 keyword 字段效果不佳的字符串内容,我们不必走得太远。 Elasticsearch 自己的日志文件产生的消息不能很好地适合任一类别。让我们检查一下原因。

每个 Elasticsearch 日志文件条目都遵循记录事件的经典最低要求- timestamp 和 message。记录的 message 用于以半结构形式描述各种事件,例如:

  • 正在创建或删除的索引
  • 服务器加入或离开集群
  • 资源压力警告
  • 具有长堆栈跟踪的详细错误消息

上面是一个已记录事件的示例。上面高亮显示的是我想搜索以查找类似记录错误的消息部分。那将是在文本编辑器中的简单 Cmd / Ctrl-F 键按下,但是使用 Elasticsearch 并不是那么简单。请记住,Elasticsearch 是很容扩展的,因此 Ctrl-F 非常适合小的文本文件,但不适用于TB级数量的日志。需要某种索引才能快速搜索。

将消息记录为 text 字段

如果我们将消息内容索引为 text 字段,则最终用户将立即遇到翻译问题。选定的子字符串是“ NodeNotConnectedException:[54b_data_2]”,但关键的问题是 “索引中该如何表示”?

  • 是半个 token 吗?
  • 一个 token?
  • 一个半 token?
  • 二个?两个半? ...

之所以会出现这个谜,是因为与英语文本(例如 “quick brown fox”)不同,我们不知道单词在日志消息中的开头或结尾的位置,例如上面显示的堆栈跟踪。这不是人类自然会讲的语言,因此很容易意外地仅选择单词的一部分。

match 查询可以帮助用户规避必须知道选择中的:or [ or _ 字符是单词标记的一部分还是仅用于拆分单词。但是,match 查询将无助于知道我们选择的开始或结束是否会裁剪掉完整的 token。如果分析器的选择保留 Java 包名中的逗点 .,我们将不得不使用昂贵的通配符搜索 *NodeNotConnectedException 或向后退选择以添加前面的 org.elasticsearch.transport. 到我们的 “match” 查询中的字符中。

即使对于有经验的 Elasticsearch 开发人员,构造一个尊重 tokenization 策略的查询也是一个巨大的挑战。

将消息记录为 keyword 字段

keyword 字段对于如何存储索引内容的奥秘要少得多,它是一个字符串,我们可以使用单个正则表达式或通配符表达式来匹配字段值内的任意片段(例如我们的搜索字符串)。

为用户简化了搜索,但是执行过程存在两个主要问题:

  • 搜索速度
  • 缺失数据

如果像我们的搜索一样,我们正在字符串中间搜索某些东西并且有许多唯一值,则搜索速度会非常慢。尽管关键字字段已建立索引,但这是一个错误的数据结构。一个例子就是研究人员尝试在词典中查找所有带有 “oo” 的单词。他们必须扫描从 A 到 Z 的每一页上的每个单词,才能找到 “afoot” 到 “zoo” 的值。从本质上讲,keyword 字段与每个唯一值有关,而索引对于加快此过程没有任何帮助。使事情变得更加困难的是,如果日志消息像 Elasticsearch 产生的那样包含诸如时间和内存大小等变量,则日志消息通常会产生许多唯一的字符串值。

keyword 字段的另一个大问题是它不能处理很长的字段。默认的字符串映射将忽略长度超过256个字符的字符串,并从索引术语列表中静默删除值。 Elasticsearch 的大多数日志文件消息都超过了此限制。

即使你确实提高了 Elasticsearch 限制,也不能超过单个 token 的 32k 硬 Lucene 限制,并且 Elasticsearch 当然会记录一些超出此限制的消息。

这对于我们的日志记录来说是一个盲点,这是不希望的,在某些安全情况下是不可接受的。

引入新的 wildcard 字段

为了解决这些问题,我们有一个新的 wildcard 字段,该字段擅长在任意字符串值的中间查找任何模式。

  • 与 text 字段不同,它不会将字符串视为由标点符号分隔的单词的集合。
  • 与 keyword 字段不同,它可以快速地搜索许多唯一值,并且没有大小限制。

这个是怎么工作的呢?

详细的模式匹配操作(例如通配符或正则表达式)在大型数据集上运行可能会非常昂贵。加快这些操作的关键是限制应用这些详细比较的数据量。

新的 wildcard 字段使用以下两种数据结构以这种方式自动加速通配符和正则表达式搜索:

  • 字符串中所有3个字符序列的  n-gram 索引
  • 完整原始文档值的 “二进制 doc value” 存储

基于来自搜索字符串的匹配 n-gram 片段,第一种结构用于提供候选对象的快速但粗略的缩小。

第二个数据结构用于通过自动查询验证由 n-gram 语法匹配产生的匹配候选。

wildcard 例子

安全分析人员可能会对查找黑客可能提到 “shell” 一词的任何日志消息感兴趣。 给定通配符查询 “*shell*”,通配符字段会自动将此搜索字符串拆分为3个字符的 n-gram,从而创建与 Lucene 查询等效的内容:

she AND ell

这样可以减少我们需要考虑的文档数量,但可能会产生一些误报-例如 包含字符串的文档:

/Users/Me/Documents/Fell walking trip with Sheila.docx

显然,搜索字符串越长,产生的误报就越少。 例如,搜索 “* powershell.exe*” 将产生更具选择性的 n-gram 查询

pow AND wer AND rsh AND hel AND l.e AND exe

消除任何误报是必不可少的完成阶段,因此 wildcar 字段将对由粗糙的 n-gram 查询产生的所有匹配项进行此检查。 这是通过从 Lucene 二进制 doc value 存储中检索完整的原始值,并对完整值运行通配符或 regexp 模式来完成的。

Regexp 例子

正则表达式更为复杂,并且可以包含值路径的选择,例如 此搜索对 DLL 或 EXE 文件的引用:

.*\.(dll|exe)

为了加速这种查询,将表达式解析为使用布尔逻辑排列的 n-gram 语法:

(.dl AND ll_) OR (.ex AND xe_)

请注意,在此示例中,_ 字符用于显示在何处添加了不可打印的字符以标记索引字符串的结尾。

正则表达式及区分大小写

我们知道安全分析师已经调整了他们的 Elasticsearch 正则表达式搜索以使用混合大小写表达式,例如在搜索对 cmd.exe 的引用时无论他们将写哪种大小写:

[Cc][Mm][Dd].[Ee][Xx][Ee]

wildcard 字段可识别这些混合大小写的表达式,并且将优化上述表达式的粗略查询,使其等效于此 Lucene 查询:

cmd AND d.e AND exe

(请注意,用于加速查询的 n-gram 索引始终为小写)。

在索引字段中使用 wildcard 字段的内容时,在 keyword 字段上使用这些大小写混合的现有安全规则应运行得更快。

但是,这些表达式看起来仍然很难看,很难编写,因此在将来的 Elasticsearch 版本中,我们还希望在 regexp 查询中引入区分大小写的标志,可以将其设置为 “false” 以使查询不区分大小写。 从本质上来说,它将搜索 abc 搜索 [Aa] [Bb] [Cc],而无需用户写所有这些方括号。 最终结果将是更简单,更快速的规则。

与 keyword 字段比较

keyword 字段的一个主要目标是在可行的情况下替代 keyword 字段。 我们一直努力确保它对所有查询类型产生相同的结果-尽管有时 wildcard 会更快,有时会更慢。 该表应有助于比较两个字段:

  1. 从32个压缩块中检索 doc value 时速度稍慢
  2. 有点慢,因为与 n-gram 的近似匹配需要验证
  3. keyword 字段仅访问每个唯一值一次,而 wildcard 字段则评估每个值的发音
  4. 如果启用了 “allow expensive queries” 设置
  5. 它取决于通用前缀-keyword 字段具有基于通用前缀的压缩,而 wildcard 字段则是整值 LZ4 压缩
  6. 内容会有所不同,但测试索引网站日志需要499秒,而 keyword 是365秒

下一步是什么

为了使搜索和分析应用程序可以考虑到越来越多的字段类型列表,从而简化了工作,我们简化了索引描述字段功能 API 中字段的方式。功能上与关键字字段等效的物理字段(例如 wildcard 和 constant_keyword)现在将自己描述为属于 keyword 家族。引入类型意味着将来可以进行其他字段类型分组,并且可以采用它们,而下游客户端应用程序无需了解新的物理字段类型。只要它们的行为与同一家族的其他成员相同,就可以在不更改客户端应用程序的情况下使用它们。

弹性通用模式(ECS)为流行的数据字段定义了标准化的索引映射。

在7.9中,尚未将 ECS 更新为使用 wildcard 字段,但是在将来,我们可以期望将几个高基数 keyword 字段切换为使用通配符字段。发生这种情况时,客户端应用程序通常不需要因此而进行任何更改,而应受益于更快的搜索。

听起来不错,代价是什么呢?

像往常一样,答案是“取决于”。 存储成本主要取决于字段数据的重复级别。 对于大多数唯一值,存储成本实际上可以比使用 keyword 字段的存储成本低。 这是因为我们增加了 Lucene 来压缩用于访问原始内容的二进制 doc value 存储。

我们测试了一个包含200万个 Weblog 记录的示例数据集,其中文件中的每一行都被索引为一个字段中包含的单个值。 使用关键字字段的索引为 310MB,但由于压缩,使用新通配符字段的等效索引为 227MB。 不可否认,时间戳有助于确保每个文档的值都是唯一的,但是URL,IP地址和用户代理的组合也可以导致许多唯一的字符串。

摘要备忘单-我什么时候应该使用通配符字段?

我们认识到以上所有内容都需要考虑很多,因此下面给出了适合使用通配符字段的粗略指南。

动手实践

讲了这么多,那么我们该如何使用这个 wildcard 的新数据类型呢?接下来,我们使用一个例子来进行展示。打开我们的 Kibana (记得安装 Elastic Stack 7.9),并打入如下的命令:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_wildcard": {
        "type": "wildcard"
      }
    }
  }
}

在上面,我们定义了一个叫做 my_wildcard 的字段。它的数据类型是 wildcard。接着我们创建如下的文档:

PUT my-index-000001/_doc/1
{
  "my_wildcard" : "This string can be quite lengthy"
}

我们使用如下的方法来进行搜索:

GET my-index-000001/_search
{
  "query": {
    "wildcard": {
      "my_wildcard": "*quite*lengthy"
    }
  }
}

上面的搜索显示的结果是:

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.8610575,
    "hits" : [
      {
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 3.8610575,
        "_source" : {
          "my_wildcard" : "This string can be quite lengthy"
        }
      }
    ]
  }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/UbuntuTouch/article/details/108120879

智能推荐

获取大于等于一个整数的最小2次幂算法(HashMap#tableSizeFor)_整数 最小的2的几次方-程序员宅基地

文章浏览阅读2w次,点赞51次,收藏33次。一、需求给定一个整数,返回大于等于该整数的最小2次幂(2的乘方)。例: 输入 输出 -1 1 1 1 3 4 9 16 15 16二、分析当遇到这个需求的时候,我们可能会很容易想到一个"笨"办法:..._整数 最小的2的几次方

Linux 中 ss 命令的使用实例_ss@,,x,, 0-程序员宅基地

文章浏览阅读865次。选项,以防止命令将 IP 地址解析为主机名。如果只想在命令的输出中显示 unix套接字 连接,可以使用。不带任何选项,用来显示已建立连接的所有套接字的列表。如果只想在命令的输出中显示 tcp 连接,可以使用。如果只想在命令的输出中显示 udp 连接,可以使用。如果不想将ip地址解析为主机名称,可以使用。如果要取消命令输出中的标题行,可以使用。如果只想显示被侦听的套接字,可以使用。如果只想显示ipv4侦听的,可以使用。如果只想显示ipv6侦听的,可以使用。_ss@,,x,, 0

conda activate qiuqiu出现不存在activate_commandnotfounderror: 'activate-程序员宅基地

文章浏览阅读568次。CommandNotFoundError: 'activate'_commandnotfounderror: 'activate

Kafka 实战 - Windows10安装Kafka_win10安装部署kafka-程序员宅基地

文章浏览阅读426次,点赞10次,收藏19次。完成以上步骤后,您已在 Windows 10 上成功安装并验证了 Apache Kafka。在生产环境中,通常会将 Kafka 与外部 ZooKeeper 集群配合使用,并考虑配置安全、监控、持久化存储等高级特性。在生产者窗口中输入一些文本消息,然后按 Enter 发送。ZooKeeper 会在新窗口中运行。在另一个命令提示符窗口中,同样切换到 Kafka 的。Kafka 服务器将在新窗口中运行。在新的命令提示符窗口中,切换到 Kafka 的。,应显示已安装的 Java 版本信息。_win10安装部署kafka

【愚公系列】2023年12月 WEBGL专题-缓冲区对象_js 缓冲数据 new float32array-程序员宅基地

文章浏览阅读1.4w次。缓冲区对象(Buffer Object)是在OpenGL中用于存储和管理数据的一种机制。缓冲区对象可以存储各种类型的数据,例如顶点、纹理坐标、颜色等。在渲染过程中,缓冲区对象中存储的数据可以被复制到渲染管线的不同阶段中,例如顶点着色器、几何着色器和片段着色器等,以完成渲染操作。相比传统的CPU访问内存,缓冲区对象的数据存储和管理更加高效,能够提高OpenGL应用的性能表现。_js 缓冲数据 new float32array

四、数学建模之图与网络模型_图论与网络优化数学建模-程序员宅基地

文章浏览阅读912次。(1)图(Graph):图是数学和计算机科学中的一个抽象概念,它由一组节点(顶点)和连接这些节点的边组成。图可以是有向的(有方向的,边有箭头表示方向)或无向的(没有方向的,边没有箭头表示方向)。图用于表示各种关系,如社交网络、电路、地图、组织结构等。(2)网络(Network):网络是一个更广泛的概念,可以包括各种不同类型的连接元素,不仅仅是图中的节点和边。网络可以包括节点、边、连接线、路由器、服务器、通信协议等多种组成部分。网络的概念在各个领域都有应用,包括计算机网络、社交网络、电力网络、交通网络等。_图论与网络优化数学建模

随便推点

android 加载布局状态封装_adnroid加载数据转圈封装全屏转圈封装-程序员宅基地

文章浏览阅读1.5k次。我们经常会碰见 正在加载中,加载出错, “暂无商品”等一系列的相似的布局,因为我们有很多请求网络数据的页面,我们不可能每一个页面都写几个“正在加载中”等布局吧,这时候将这些状态的布局封装在一起就很有必要了。我们可以将这些封装为一个自定布局,然后每次操作该自定义类的方法就行了。 首先一般来说,从服务器拉去数据之前都是“正在加载”页面, 加载成功之后“正在加载”页面消失,展示数据;如果加载失败,就展示_adnroid加载数据转圈封装全屏转圈封装

阿里云服务器(Alibaba Cloud Linux 3)安装部署Mysql8-程序员宅基地

文章浏览阅读1.6k次,点赞23次,收藏29次。PS: 如果执行sudo grep 'temporary password' /var/log/mysqld.log 后没有报错,也没有任何结果显示,说明默认密码为空,可以直接进行下一步(后面设置密码时直接填写新密码就行)。3.(可选)当操作系统为Alibaba Cloud Linux 3时,执行如下命令,安装MySQL所需的库文件。下面示例中,将创建新的MySQL账号,用于远程访问MySQL。2.依次运行以下命令,创建远程登录MySQL的账号,并允许远程主机使用该账号访问MySQL。_alibaba cloud linux 3

excel离散度图表怎么算_excel离散数据表格-Excel 离散程度分析图表如何做-程序员宅基地

文章浏览阅读7.8k次。EXCEL中数据如何做离散性分析纠错。离散不是均值抄AVEDEV……=AVEDEV(A1:A100)算出来的是A1:A100的平均数。离散是指各项目间指标袭的离散均值(各数值的波动情况),数值较低表明项目间各指标波动幅百度小,数值高表明波动幅度较大。可以用excel中的离散公式为STDEV.P(即各指标平均离散)算出最终度离散度。excel表格函数求一组离散型数据,例如,几组C25的...用exc..._excel数据分析离散

学生时期学习资源同步-JavaSE理论知识-程序员宅基地

文章浏览阅读406次,点赞7次,收藏8次。i < 5){ //第3行。int count;System.out.println ("危险!System.out.println(”真”);System.out.println(”假”);System.out.print(“姓名:”);System.out.println("无匹配");System.out.println ("安全");

linux 性能测试磁盘状态监测:iostat监控学习,包含/proc/diskstats、/proc/stat简单了解-程序员宅基地

文章浏览阅读3.6k次。背景测试到性能、压力时,经常需要查看磁盘、网络、内存、cpu的性能值这里简单介绍下各个指标的含义一般磁盘比较关注的就是磁盘的iops,读写速度以及%util(看磁盘是否忙碌)CPU一般比较关注,idle 空闲,有时候也查看wait (如果wait特别大往往是io这边已经达到了瓶颈)iostatiostat uses the files below to create ..._/proc/diskstat

glReadPixels读取保存图片全黑_glreadpixels 全黑-程序员宅基地

文章浏览阅读2.4k次。问题:在Android上使用 glReadPixel 读取当前渲染数据,在若干机型(华为P9以及魅族某魅蓝手机)上读取数据失败,glGetError()没有抓到错误,但是获取到的数据有误,如果将获取到的数据保存成为图片,得到的图片为黑色。解决方法:glReadPixels实际上是从缓冲区中读取数据,如果使用了双缓冲区,则默认是从正在显示的缓冲(即前缓冲)中读取,而绘制工作是默认绘制到后缓..._glreadpixels 全黑