Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475作者:https://blog.csdn.net/w1570631036/p/16028174.html
目录
SearchType搜索入口:3.1 query阶段3.2 Fetch阶段3.2.1 FetchSearchPhase(对应上面的1)3.2.2 ExpandSearchPhase(对应上图的2)4.1 执行query、fetch流程
本文基于elasticsearch8.1。在es搜索中,经常会使用索引+星号,采用时间戳来进行搜索,比如aaaa-*在es中是怎么处理这类请求的呢?是对匹配的进行搜索呢还是仅仅根据时间找出索引,然后才遍历索引进行搜索。在了解其原理前先了解一些基本知识。
SearchType
QUERY_THEN_FETCH(默认):第一步,先向所有的shard发出请求,各分片只返回排序和排名相关的信息(注意,不包括文档document),然后按照各分片返回的分数进行重新排序和排名,取前size个文档。然后进行第二步,去相关的shard取document。这种方式返回的document与用户要求的size是相等的。
DFS_QUERY_THEN_FETCH:比第1种方式多了一个初始化散发(initial scatter)步骤。
为了能够深刻了解es的搜索过程,首先创建3个索引,每个索引指定一天的一条记录。
POST aaaa-16/_doc
{
"@timestamp": "2022-02-16T16:21:15.000Z",
"word":"16"
}
POST aaaa-17/_doc
{
"@timestamp": "2022-02-17T16:21:15.000Z",
"word":"17"
}
POST aaaa-18/_doc
{
"@timestamp": "2022-02-18T16:21:15.000Z",
"word":"18"
}
即可在kibana上看到3条数据
此时,假设我们用一个索引+星号来搜索,es内部的搜索是怎么样的呢?
GET aaaa*/_search
{
"query": {
"range": {
"@timestamp": {
"gte": "2022-02-18T10:21:15.000Z",
"lte": "2022-02-18T17:21:15.000Z"
}
}
}
}
正好命中一条记录返回。
{
"took" : 2,
"timed\_out" : false,
"\_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max\_score" : 1.0,
"hits" : [
{
"\_index" : "aaaa-18",
"\_id" : "0zB2O38BoMIMP8QzHgdq",
"\_score" : 1.0,
"\_source" : {
"@timestamp" : "2022-02-18T16:21:15.000Z",
"word" : "18"
}
}
]
}
}
一、es的分布式搜索过程
一个搜索请求必须询问请求的索引中所有分片的某个副本来进行匹配。假设一个索引有5个主分片,每个主分片有1个副分片,共10个分片,一次搜索请求会由5个分片来共同完成,它们可能是主分片,也可能是副分片。也就是说,一次搜索请求只会命中所有分片副本中的一个。当搜索任务执行在分布式系统上时,整体流程如下图所示。图片来源Elasitcsearch源码解析与优化实战
搜索入口:
整个http请求的入口,主要使用的是Netty4HttpRequestHandler。
@ChannelHandler.Sharable
class Netty4HttpRequestHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpPipelinedRequest httpRequest) {
final Netty4HttpChannel channel = ctx.channel().attr(Netty4HttpServerTransport.HTTP\_CHANNEL\_KEY).get();
boolean success = false;
try {
serverTransport.incomingRequest(ht