0%

Elasticsearch 二次评分(Rescore):优化顶部结果相关性

在 Elasticsearch 中,当基础查询返回的顶部文档相关性不够理想时,可通过二次评分(Rescore) 机制对前 N 个文档重新计算得分,进一步优化排序。这种方式既能保证查询效率(仅处理顶部文档),又能提升关键结果的准确性,适用于需要精细调整排序的场景(如搜索引擎结果页 Top 10 优化)。

二次评分的核心原理

二次评分的工作流程如下:

  1. 基础查询:执行初始查询(如 matchbool),获取匹配文档并按得分排序。
  2. 筛选顶部文档:从每个分片的结果中选取前 window_size 个文档(默认取 from + size 个)。
  3. 重新评分:对这些顶部文档应用二次评分查询(如 function_scorescript_score),计算新得分。
  4. 合并结果:根据配置的评分模式(如求和、相乘)合并原始得分与二次评分,得到最终排序。

基础语法与示例

基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET index/_search
{
"query": { // 1. 基础查询
"match": { "title": "elasticsearch" }
},
"rescore": { // 2. 二次评分配置
"window_size": 50, // 每个分片取前50个文档进行二次评分
"query": {
"rescore_query": { // 二次评分查询
"function_score": {
"script_score": {
"script": "doc['publishTime'].value / 1000000" // 以发布时间作为加分项
}
}
},
"query_weight": 0.8, // 原始得分权重
"rescore_query_weight": 0.2 // 二次评分权重
}
},
"size": 10 // 最终返回10条结果
}

得分计算逻辑

最终得分由原始查询得分和二次评分按权重合并:

阅读全文 »

Elasticsearch 中的查询(Query)与过滤(Filter):核心区别与应用场景

在 Elasticsearch 中,查询(Query)和过滤(Filter)是两种核心的数据筛选机制,虽然都能实现结果筛选,但在用途、性能和实现方式上有本质区别。理解二者的差异是优化查询性能和相关性的关键。

核心区别

维度 查询(Query) 过滤(Filter)
核心目标 筛选匹配的文档,并计算相关性得分(_score) 仅筛选匹配的文档,不计算得分
性能特点 消耗 CPU 资源(需计算得分),无缓存 不消耗额外 CPU,结果可被缓存(Filter Cache)
适用场景 全文检索、相关性排序(如 “搜索关键词”) 精确匹配、范围筛选(如 “价格> 100”“状态 = 激活”)

查询(Query):注重相关性

查询操作不仅会筛选出符合条件的文档,还会根据文档与查询条件的匹配程度计算相关性得分_score),得分越高,文档与查询的相关性越强。

常用查询类型

  • 全文查询matchmatch_phrase(用于文本字段,会分词)。
  • 术语查询termterms(用于精确匹配,如关键词、数字)。
  • 复合查询booldis_max(组合多个查询条件)。

示例:匹配 “elasticsearch 教程” 并计算得分

1
2
3
4
5
6
7
8
GET books/_search
{
"query": {
"match": {
"title": "elasticsearch 教程" // 全文匹配,计算得分
}
}
}
阅读全文 »

接口幂等性设计:确保重复请求安全处理的完整方案

接口幂等性是分布式系统设计中的关键特性,指多次执行相同请求时,系统最终状态与执行一次相同。这一特性可有效避免因网络重试、用户误操作等导致的数据重复或状态异常。本文将分析重复请求的成因,并提供从前端到后端的完整解决方案。

重复请求的常见场景

重复请求的产生可能源于客户端、网络或服务端,典型场景包括:

  1. 客户端操作失误
    • 用户快速点击提交按钮;
    • 刷新页面、使用后退 / 前进按钮重复提交表单;
    • 浏览器历史记录重复提交。
  2. 网络与重试机制
    • 网络延迟导致客户端未收到响应,触发重试;
    • 分布式系统中的请求重试机制(如 Feign 重试、消息队列重试)。
  3. 系统设计缺陷
    • 前端未禁用重复提交;
    • 后端未处理重复请求,导致重复写入数据库。

接口幂等性解决方案

确保幂等性需从前端防重后端校验两方面入手,形成多层防护。

1. 前端防重:减少重复请求产生

前端是防止重复请求的第一道防线,通过限制用户操作和请求发送,从源头减少重复请求。

(1)禁用提交按钮

点击提交后立即禁用按钮,防止短时间内重复点击:

阅读全文 »

Elasticsearch Java API 全解析:从 TransportClient 到 RestHighLevelClient

Elasticsearch 提供了多种 Java API 用于与集群交互,其中 TransportClient(已过时)和 RestHighLevelClient(推荐)是最常用的两种。本文详细讲解这两种客户端的使用方法,包括索引管理、文档操作、查询等核心功能。

TransportClient(过时,了解即可)

TransportClient 基于 TCP 协议与 Elasticsearch 集群通信,在 Elasticsearch 7.0 后被标记为过时,8.0 完全移除。但部分旧系统仍在使用,此处简要介绍其核心用法。

依赖配置

1
2
3
4
5
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.4.0</version> <!-- 需与 Elasticsearch 版本匹配 -->
</dependency>

客户端初始化

1
2
3
4
5
6
7
8
9
10
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import java.net.InetAddress;

// 创建客户端(连接到本地 9300 端口,Transport 协议默认端口)
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getLocalHost(), 9300
));

核心操作示例

(1)索引管理
阅读全文 »

Elasticsearch 脑裂问题:原理、成因与解决方案

在 Elasticsearch 集群中,脑裂(Split Brain) 是一种严重的集群异常状态,指集群中同时存在多个主节点(Master),导致数据分片分配、请求路由混乱,最终引发数据不一致。本文详细解析脑裂的成因、检测方法及根治方案。

什么是脑裂?

Elasticsearch 集群依赖单一主节点(Master)维护集群状态(如分片分配、节点信息)。正常情况下,主节点由候选主节点(Master Eligible Node)选举产生,且集群中始终只有一个主节点。

脑裂发生时
由于网络分区或节点通信中断,集群被分割成多个独立子集群。每个子集群都认为原主节点已宕机,从而各自选举出新的主节点。此时,集群中出现多个主节点,各自维护一套集群状态,导致:

  • 数据写入分散在不同子集群,无法同步。
  • 搜索请求命中不同主节点时,返回结果不一致。
  • 分片分配混乱,可能出现重复或丢失。

脑裂的常见成因

网络问题(最主要原因)

  • 网络延迟 / 分区:集群节点间网络不稳定(如交换机故障、防火墙拦截),导致部分节点无法与主节点通信。
  • 网络超时:节点间心跳检测(Ping)超时,误认为主节点宕机。

节点负载过高

  • 若主节点同时承担数据存储和计算任务(即既是 Master 又是 Data Node),当流量激增时,主节点可能因 CPU / 内存耗尽而 “假死”(无法响应心跳)。
  • 其他节点长时间未收到主节点响应,判定主节点宕机,触发新主节点选举。
阅读全文 »