Elasticsearch的理解与使用

        在大数据与云计算时代,“高效检索” 与 “实时分析” 成为业务突破的关键能力。Elasticsearch(简称 ES)作为一款开源分布式搜索与分析引擎,凭借其低延迟、高可扩、强灵活的特性,已成为日志分析、全文检索、业务监控等场景的 “标配工具”。本文将从 ES 的核心本质出发,深入剖析其架构原理,再通过完整的 Java 代码实现核心功能,帮助开发者从 “认知” 到 “落地” 全面掌握 ES。

一、Elasticsearch 本质认知:它到底是什么?

1. 定位与核心价值

ES 并非传统数据库,而是一款 **“搜索 + 分析” 一体化引擎 **,核心解决 “从海量非结构化 / 半结构化数据中快速找到目标信息” 的问题。与传统数据库(如 MySQL)相比,其优势体现在:

  • 全文检索能力:支持中文、英文等多语言分词,可实现模糊匹配、短语搜索、权重排序(如 “搜索‘苹果手机’时,优先展示销量高的商品”)。
  • 分布式天然适配:数据自动分片存储,集群可轻松扩展至数百节点,承载 PB 级数据。
  • 实时性:数据写入后秒级可检索,延迟通常低于 100ms,满足日志监控、实时推荐等场景。
  • 多维度分析:无需依赖 Hadoop 等工具,通过聚合功能即可实现 “按地区统计订单量”“计算商品价格分布” 等分析需求。

2. 核心概念与传统数据库对比

ES 的术语体系是理解其设计思想的关键,通过与 MySQL 类比可快速掌握:

Elasticsearch 概念

传统数据库(MySQL)

核心作用

Index(索引)

数据库(Database)

存储一类结构相似的数据(如 “商品索引”“用户日志索引”),索引名需小写,无特殊字符

Document(文档)

数据行(Row)

索引的最小数据单元,以 JSON 格式存储(如{"id":"1001","name":"iPhone 15","price":7999})

Field(字段)

数据列(Column)

文档的属性(如 “name”“price”),支持多种类型(text、keyword、integer、date 等)

Mapping(映射)

表结构(Schema)

定义字段的类型、分词器、是否可搜索等规则(如 “将‘name’设为 text 类型,使用 IK 分词器”)

Shard(分片)

无直接对应

将索引拆分后的小分片,分布式存储在不同节点,实现水平扩展(解决单节点存储上限问题)

Replica(副本)

主从复制(Slave)

分片的备份,用于高可用(分片故障时自动切换)和读写分离(副本承担读请求)

注意:ES 7.x 后已废弃Type(类型)(原对应 MySQL 的 Table),原因是 “同一索引下不同 Type 的字段可能冲突,导致分片存储效率低下”,建议通过不同索引区分数据类型(如 “商品索引” 和 “订单索引” 分开创建)。

二、Elasticsearch 架构原理:分布式背后的逻辑

ES 的强大源于其分布式架构设计,理解底层逻辑能帮助开发者在实际项目中避免 “踩坑”(如分片数量不合理导致性能瓶颈)。

1. 集群的核心组成:节点(Node)

一个 ES 集群由多个节点组成,每个节点是一台运行 ES 服务的服务器,按功能可分为 4 类:

  • Master 节点:集群 “管理者”,负责创建索引、分片分配、节点加入 / 退出等管理操作,不承担数据存储和查询压力。建议部署 3 个节点(避免单点故障,通过选举机制实现高可用)。
  • Data 节点:集群 “数据载体”,负责数据的存储(分片)、索引写入和查询请求处理。根据数据量和查询压力横向扩展(如 “从 3 个 Data 节点扩展到 5 个,提升查询吞吐量”)。
  • Coordinating 节点:“请求入口”,接收客户端请求后,将请求分发到相关 Data 节点,汇总结果后返回给客户端。可由 Master 或 Data 节点兼任,高并发场景建议单独部署。
  • Ingest 节点:数据 “预处理管道”,负责数据写入前的清洗(如 “过滤日志中的敏感字段”“将日期格式从‘yyyy-MM-dd’转为‘timestamp’”)。

2. 分片机制:分布式存储的核心

ES 通过分片(Shard) 实现数据的分布式存储,分为 “主分片” 和 “副本分片”:

  • 主分片(Primary Shard):索引创建时指定的分片数量(一旦创建不可修改),用于数据写入和核心查询(如 “创建商品索引时,设置 3 个主分片”)。
  • 副本分片(Replica Shard):主分片的备份,数量可动态调整(如 “为 3 个主分片各创建 1 个副本,共 6 个分片”),与主分片不在同一节点(避免节点宕机导致数据丢失)。

分片分配示例

3 个 Data 节点,创建 “商品索引”(3 个主分片,1 个副本),最终分片分布如下:

  • 节点 1:主分片 P0、副本分片 R1
  • 节点 2:主分片 P1、副本分片 R2
  • 节点 3:主分片 P2、副本分片 R0

此时:

  • 写入数据:客户端请求先到 Coordinating 节点,根据文档 ID 哈希值路由到对应主分片(如 “文档 ID=1001” 路由到 P0),写入成功后同步到副本 R0。
  • 查询数据:Coordinating 节点将请求分发到主分片或副本分片(如 “查询‘iPhone 15’时,同时查询 P0、P1、P2 的副本,并行返回结果”),提升读性能。

3. 数据写入与检索流程

(1)数据写入流程(以 “新增商品文档” 为例)
  • 客户端通过 Java 代码(High Level REST Client)向 Coordinating 节点发送写入请求。
  • Coordinating 节点计算文档 ID 的哈希值,确定应写入的主分片(如 P0)。
  • 主分片 P0 验证文档格式(是否符合 Mapping 规则,如 “price” 是否为数值类型),写入数据并生成倒排索引(全文检索的核心结构,后文详解)。
  • 主分片 P0 将数据同步到副本分片 R0。
  • 副本 R0 同步完成后,主分片 P0 向 Coordinating 节点返回 “写入成功”,最终反馈给客户端。
(2)数据检索流程(以 “搜索‘苹果手机’为例)
  • 客户端发送查询请求到 Coordinating 节点。
  • Coordinating 节点将查询请求分发到所有主分片 / 副本分片(如 P0、P1、P2 及其副本)。
  • 各分片执行查询,返回匹配的文档 ID 和相关性得分(Score,根据 “关键词出现频率”“文档热度” 等计算)。
  • Coordinating 节点汇总所有分片的结果,按得分排序,取前 N 条(如前 20 条),再向对应分片请求完整文档数据。
  • 分片返回完整文档,Coordinating 节点整理结果并返回给客户端。

4. 全文检索核心:倒排索引

ES 之所以能实现高效全文检索,核心在于倒排索引(Inverted Index) 结构,与传统数据库的 “正排索引”(按文档 ID 存储数据)相反:

  • 正排索引:文档 ID → 文档内容(如 “文档 1001 → 我买了一部苹果手机”),适合按 ID 查询,但无法快速匹配 “包含‘手机’的文档”。
  • 倒排索引:关键词 → 包含该关键词的文档 ID 列表(如 “手机 → 文档 1001、文档 1003、文档 1005”),直接通过关键词定位文档,检索效率提升 10 倍以上。

倒排索引的构成

  • 词典(Dictionary):存储所有去重后的关键词(如 “苹果”“手机”“华为”),通常以 B + 树结构存储,便于快速查找。
  • postings 列表(Postings List):记录每个关键词对应的文档 ID、出现位置(如 “‘手机’在文档 1001 的第 3 个字符处出现”)、出现频率(如 “‘手机’在文档 1001 中出现 2 次”),用于计算文档与查询的相关性(Score)。

三、Elasticsearch 核心功能 Java 实战

        ES 官方提供多种客户端(如 Transport Client、High Level REST Client),其中High Level REST Client(7.x + 推荐) 基于 HTTP 协议,支持所有 ES 功能,且与 ES 版本兼容性好。以下实战基于 ES 7.17.0 版本,通过 Java 代码实现全文搜索、聚合分析、数据同步、集群监控等核心功能。

1. 环境准备

(1)Maven 依赖配置

在pom.xml中引入 ES 客户端及相关依赖(版本需与 ES 集群一致):

<dependencies><!-- Elasticsearch High Level REST Client --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.17.0</version></dependency><!-- Elasticsearch 核心依赖 --><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.17.0</version></dependency><!-- JSON 解析(用于文档序列化/反序列化) --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.32</version></dependency><!-- 日志依赖(用于调试) --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.36</version><scope>test</scope></dependency></dependencies>
(2)ES 客户端初始化(单例模式)

客户端创建成本较高,建议通过单例模式复用,避免频繁创建销毁连接:

import org.apache.http.HttpHost;import org.apache.http.auth.AuthScope;import org.apache.http.auth.UsernamePasswordCredentials;import org.apache.http.client.CredentialsProvider;import org.apache.http.impl.client.BasicCredentialsProvider;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import java.io.IOException;/*** ES客户端工具类(单例模式)*/public class EsClientUtils {// 单例客户端实例private static RestHighLevelClient client;// ES集群节点(多个节点用逗号分隔)private static final String ES_NODES = "192.168.1.100:9200,192.168.1.101:9200";// ES账号密码(若未开启认证,可删除相关代码)private static final String USERNAME = "elastic";private static final String PASSWORD = "123456";// 私有构造器(防止外部实例化)private EsClientUtils() {}/*** 获取ES客户端实例*/public static RestHighLevelClient getClient() {if (client == null) {synchronized (EsClientUtils.class) {if (client == null) {// 1. 解析ES节点String[] nodes = ES_NODES.split(",");HttpHost[] httpHosts = new HttpHost[nodes.length];for (int i = 0; i < nodes.length; i++) {String[] hostPort = nodes[i].split(":");httpHosts[i] = new HttpHost(hostPort[0], Integer.parseInt(hostPort[1]), "http");}
// 2. 配置账号密码认证(若未开启认证,可省略)CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(USERNAME, PASSWORD));// 3. 构建客户端client = new RestHighLevelClient(RestClient.builder(httpHosts).setHttpClientConfigCallback(httpClientBuilder ->httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)));}}}return client;}/*** 关闭客户端*/public static void closeClient() throws IOException {if (client != null) {client.close();}}}

2. 索引与映射操作(基础必备)

在写入数据前,需先创建索引并定义映射(类似 MySQL 中 “先建表,再插入数据”)。以下代码实现 “创建商品索引(product)”,并定义字段映射规则:

import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;import org.elasticsearch.client.RequestOptions;import org.elasticsearch.client.RestHighLevelClient;import org.elasticsearch.common.settings.Settings;import org.elasticsearch.common.xcontent.XContentBuilder;import org.elasticsearch.common.xcontent.json.JsonXContent;import java.io.IOException;/*** 索引与映射操作示例*/public class EsIndexDemo {// 索引名称private static final String INDEX_NAME = "product";/*** 创建索引并定义映射* 需求:* 1. 主分片数3,副本数1(适合3个Data节点的集群)* 2. 字段映射:* - id:keyword类型(不分词,用于精确匹配)* - name:text类型(分词,使用IK中文分词器)* - brand:keyword类型(不分词,用于分组统计)* - price:double类型(用于范围查询、排序)* - sales:integer类型(用于排序、聚合)* - create_time:date类型(用于时间范围查询)*/public static void createIndexWithMapping() throws IOException {RestHighLevelClient client = EsClientUtils.getClient();// 1. 构建创建索引请求CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);// 2. 设置索引参数(分片、副本等)request.settings(Settings.builder().put("number_of_shards", 3) // 主分片数.put("number_of_replicas", 1) // 副本数.put("refresh_interval", "1s") // 刷新间隔(数据写入后1秒可检索));// 3. 定义映射规则XContentBuilder mappingBuilder = JsonXContent.contentBuilder();mappingBuilder.startObject().startObject("properties")// id字段:keyword类型(不分词).startObject("id").field("type", "keyword").endObject()// name字段:text类型,使用IK分词器(需提前在ES安装IK插件).startObject("name").field("</doubaocanvas>

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

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

相关文章

利用FFmpeg自动批量处理m4s文件

缓存了一些视频m4s文件&#xff0c;只能用指定的软件打开&#xff0c;网上查了一下&#xff0c;需要去掉m4s文件开头的9个0&#xff0c;还要用FFmpeg将两个文件合并成一个文件。 经仔细研究缓存目录和其中文件&#xff0c;发现以下特点&#xff1a;“缓存目录”中有很多“数字文…

MLLM学习~M3-Agent Prompt学习

Prompt “输入→处理→输出→评估” 全流程 Prompt 并非孤立存在&#xff0c;形成了完整的视频理解链路&#xff1a; 视频原始数据&#xff08;语音 / 图像&#xff09;→ 模块 1&#xff08;提取语音 绑定人物 ID&#xff09;→ 模块 2&#xff08;生成情景记忆描述&#xff…

Ubuntu 20.04安装显卡驱动、CUDA、Miniconda和Pytorch(2025.06最新)-Ubuntu从零搭建深度学习环境

文章目录一、安装显卡驱动1.1 查看显卡型号1.2 根据显卡型号选择驱动1.3 获取下载链接1.4 查看下载的显卡驱动安装文件1.5 更新软件列表和安装必要软件、依赖1.6 卸载原有驱动1.7 禁用默认驱动1.8 安装lightdm显示管理器1.9 停止显示服务器1.10 在文本界面中&#xff0c;禁用X-…

PyCharm 连接 AutoDL 远程服务器

实验室的电脑性能不行了&#xff0c;所以想着租一台服务器&#xff0c;然后还想使用PyCharm在本地编程&#xff0c;因此就查找相关资料&#xff0c;这里记录一下配置过程&#xff0c;方便以后查阅。 PyCharm 连接 AutoDL 远程服务器PyCharm 连接服务器上传数据集到服务器运行代…

Spark广播变量HttpBroadcast和TorrentBroadcast对比

HttpBroadcast会在driver端的BlockManager里面存储广播变量对象&#xff0c;并且将该广播变量序列化写入文件中去。所有获取广播数据请求都在driver端&#xff0c;所以存在单点故障和网络IO性能问题。 TorrentBroadcast会在driver端的BlockManager里面存储广播变量对象&#xf…

新手向:C语言、Java、Python 的选择与未来指南

语言即工具&#xff0c;选对方向比埋头苦学更重要你好&#xff0c;编程世界的新朋友&#xff01;当你第一次踏入代码的宇宙&#xff0c;面对形形色色的编程语言&#xff0c;是否感到眼花缭乱&#xff1f;今天我们就来聊聊最主流的三种编程语言——C语言、Java 和 Python——它们…

收集飞花令碎片——C语言关键字typedef

在C语言的指针章节中&#xff0c;我们讲到函数指针模块 在函数指针中&#xff0c;有一个重要的关键字&#xff1a;typedef typedef关键字作用基本语法重难点&#xff1a;对数组指针与函数指针的重命名数组指针重命名一维数组指针重命名遍历二维数组函数指针重命名作用 typedef是…

基于Spring Boot的家政服务管理系统+论文示例参考

1.项目介绍 系统角色&#xff1a;管理员、家政服务、服务人员功能模块&#xff1a;用户管理、服务人员、服务类型、家政服务、服务预约、接单信息、服务记录、评价信息、反馈投诉等技术选型&#xff1a;SpringBoot&#xff0c;Vue等测试环境&#xff1a;idea2024&#xff0c;jd…

AI助力HTML5基础快速入门:从零开始理解网页结构

前言 作为一名前端开发初学者&#xff0c;理解HTML的基本结构是你踏入Web开发世界的第一步。HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础&#xff0c;就像盖房子需要先搭建好框架一样&#xff0c;学习HTML就是学习如何构建网页的基本骨架。今天&#xff0c;我…

实现调用libchdb.a静态连接库中的未公开导出函数

前文写了调用libchdb.so动态连接库中的未公开导出函数的方法&#xff0c;不久前chdb发布了3.6版&#xff0c;其中提供了静态链接库。 尝试编译一个不依赖庞大动态连接库libchdb.so的程序&#xff0c;获得了成功&#xff0c;以下是操作步骤。 1.下载chdb静态连接库 wget https:…

HTTPS 端口号详解 443 端口作用、iOS 抓包方法、常见 HTTPS 抓包工具与网络调试实践

在现代互联网中&#xff0c;几乎所有移动应用和网站都使用 HTTPS 协议 来保障数据安全。而 HTTPS 的默认端口就是 443。相比 HTTP 的 80 端口&#xff0c;443 不仅增加了 SSL/TLS 加密&#xff0c;还涉及到证书验证和加密握手&#xff0c;这使得开发者在进行 HTTPS 抓包 时面临…

【Python系列PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘pyqt5’问题

【Python系列PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘pyqt5’问题 摘要 在日常Python开发中&#xff0c;使用PyCharm控制台执行pip install时经常会遇到ModuleNotFoundError: No module named pyqt5等类似报错。这类报错不仅…

“可信资产IPO +数链金融RWA” 链改2.0六方共识(深圳)

“可信资产IPO 数链金融RWA”链改2.0六方共识【2025年8月30日 深圳】全球数链金融的建设者、创新者与决策者&#xff1a;我们——来自“生态、项目、资金、合规、技术、行业”六方领域的实践者&#xff0c;在链改1.0的基础上于深圳达成链改2.0时代核心共识&#xff1a;以“可信…

华为云 GaussDB:金融级高可用数据库,为核心业务保驾护航

一、文档概述在数字化浪潮席卷全球的当下&#xff0c;数据已成为企业发展的核心战略资产&#xff0c;而数据库作为数据存储、管理与交互的核心载体&#xff0c;其稳定性、可靠性与安全性直接决定了企业业务的连续性与竞争力。尤其在对数据准确性、业务连续性要求近乎苛刻的金融…

Docker快速入门手册

文章目录一、安装验证是否安装成功二、Docker命令镜像容器数据卷管理网络模式三、Dockerfile推送至镜像仓库阿里云ECI弹性容器部署阿里云Serverless应用引擎SAE部署阿里云FC函数部署容器四、Docker Compose::: tip 简介Docker是一种开源的应用容器引擎&#xff0c;让开发者能够…

Golang并发编程及其高级特性

并发编程模型 线程模型&#xff1a;Go的GoroutineGoroutine&#xff08;M:N 模型&#xff09; package mainimport ("fmt""runtime""sync""time" )func main() {// 查看当前机器的逻辑CPU核心数&#xff0c;决定Go运行时使用多少OS线程…

弧形导轨如何提升新能源汽车的能效和续航里程?

弧形导轨在新能源汽车中的应用主要集中在电池生产线和自动化装配线等领域&#xff0c;通过提高生产效率和精度&#xff0c;间接提升新能源汽车的能效和续航里程。高精度装配&#xff1a;在新能源汽车的电池生产线中&#xff0c;弧形导轨用于高精度的自动化装配设备&#xff0c;…

考研择校考虑因素和备考流程

考研择校一、选择专业二、选择学校三、考研计划安排一、选择专业 1、了解自己的未来工作规划&#xff08;这里肯定没有啥规划&#xff09;&#xff1b; 2、连接考研的相关几个专业哪个好就业&#xff08;公务员和找工作&#xff09;&#xff1b; 3、知乎、小红书、deepseek都可…

1.13 Memory Profiler Package - Unity Objects(unity对象页签)

1.Unity Objects(Unity对象页签)简介 2.界面功能参数1.Unity Objects(Unity对象页签)简介 Unity Objects用于快速定位unity对象内存占用的类型和具体实例a.查找内存占用最大的资源, 判断这些资源是否可以压缩或延迟加载b.查找重复加载的资源c.查看运行时创建但是没有释放的资源…

Android真机-安装Reqable证书-抓SSL包

使用Reqable的自动安装系统证书无法正常抓包&#xff0c;所以就有了这篇文章超简单的安装方式 - 记得确保手机已拥有root权限一、从Reqable导出公钥证书无需使用OpenSSL 将 .pem 文件转换为 .0 格式注意是 .0 格式的这个证书二、推送证书到手机adb root adb remount adb push 证…