写点什么

Mac 下 Elasticsearch7.x 安装及 Springboot 集成

  • 2025-08-09
    吉林
  • 本文字数:7905 字

    阅读完需:约 26 分钟

Mac下Elasticsearch7.x安装及Springboot集成

一 简介

众所周知,检索是大模型 RAG 应用中的重要步骤。用户输入的问题,需要 rag 服务先使用检索模块检索到与问题最相关的知识,再进行筛选、排序、甄别、整理、总结,直到生成最终的回答。而检索结果直接关系到回答的质量。

尽管有了很多向量检索方案,但在实际应用中我们发现,基于向量的检索并不能完全取代关键词检索(尤其是在一些专业领域)。因此像 Elasticsearch 这类传统检索工具依然有很大的用武之地。本篇回顾一些 Es 安装和集成的基础知识,供大家尤其是初学者参考和从零开始搭建环境。

二 Elasticsearch 7.x 按照步骤及注意事项

2.1 安装

2.1.1 homebrew 安装

1. 安装 Homebrew(如果尚未安装)/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
2. 添加 Elastic 的 Homebrew Tapbrew tap elastic/tap
3. 安装 Elasticsearch 7.x(最新 7.17.x)brew install elastic/tap/elasticsearch-full@7
4. 启动 Elasticsearchbrew services start elastic/tap/elasticsearch-full@7
复制代码


2.1.2 下载压缩包安装

# 1. 下载 Elasticsearch 7.x(选择最新 7.17.x 版本)curl -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.13-darwin-x86_64.tar.gz
# 2. 解压文件tar -xzf elasticsearch-7.17.13-darwin-x86_64.tar.gzcd elasticsearch-7.17.13/
# 3. 启动 Elasticsearch(前台运行)./bin/elasticsearch
# 或者作为守护进程运行./bin/elasticsearch -d -p pid
复制代码

验证安装结果:


curl -X GET "http://localhost:9200"# 得到的输出如下{  "name" : "MacBook-Air.local",  "cluster_name" : "elasticsearch",  "cluster_uuid" : "GZx-tgLsRe61lUHb60J4qg",  "version" : {    "number" : "7.17.13",    "build_flavor" : "default",    "build_type" : "tar",    "build_hash" : "2b211dbb8bfdecaf7f5b44d356bdfe54b1050c13",    "build_date" : "2023-08-31T17:33:19.958690787Z",    "build_snapshot" : false,    "lucene_version" : "8.11.1",    "minimum_wire_compatibility_version" : "6.8.0",    "minimum_index_compatibility_version" : "6.0.0-beta1"  },  "tagline" : "You Know, for Search"}
复制代码


注意:按照上述方法安装,执行./bin/elasticsearch 启动服务时,可能会抱如下错误:

error updating geoip database [GeoLite2-ASN.mmdb]java.net.SocketTimeoutException: Connect timed out
复制代码

错误信息是 Elasticsearch 在启动时尝试下载 GeoIP 数据库(GeoLite2-ASN.mmdb)时连接超时。Elasticsearch 从 7.0 版本开始,内置了 GeoIP 下载功能,但可能由于网络问题(特别是国内访问 MaxMind 的数据库下载较慢)导致超时。

解决方法:

1. 手动下载并安装 GeoIP 数据库,操作步骤如下:

# 1. 停止 Elasticsearch(如果正在运行)ps aux | grep elasticsearch | grep -v grep | awk '{print $2}' | xargs kill -9
# 2. 手动下载数据库mkdir -p config/ingest-geoipcd config/ingest-geoipcurl -O https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-ASN.mmdbcurl -O https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdbcurl -O https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdbcd ../..
复制代码

注意:https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-ASN.mmdb这个源 git 地址也很可能无法下载,所以需要改为使用其他公开源的地址。例如 Cloudflare 镜像(本文采用,已验证)

# ASN 数据库curl -O https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/GeoLite2-ASN.mmdb
# City 数据库curl -O https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/GeoLite2-City.mmdb
# Country 数据库curl -O https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/GeoLite2-Country.mmdb
复制代码

或尝试其他源,例如阿里或华为云,也已验证可下载并且速度很快:

# 阿里云镜像curl -O https://mirrors.aliyun.com/elasticsearch/geoip/GeoLite2-ASN.mmdb
# 华为云镜像curl -O https://repo.huaweicloud.com/geoip/GeoLite2-ASN.mmdb
复制代码

2. 禁用 GeoIP 更新(临时解决方案)

编辑 config/elasticsearch.yml

# 禁用自动更新ingest.geoip.downloader.enabled: false
# 使用空数据库(避免错误)ingest.geoip.database_md5.ASN: "dummy"
复制代码

3. 增加超时时间

编辑 config/elasticsearch.yml

# 增加超时时间(单位:秒)ingest.geoip.downloader.timeout: 300
复制代码

2.1.3 其他常见问题

1. 内存不足错误

编辑 config/jvm.options

# 修改为适合您系统的值(推荐 1-2GB)-Xms1g-Xmx1g
复制代码

2. 文件描述符限制问题

# 临时增加限制sudo sysctl -w kern.maxfiles=65536sudo sysctl -w kern.maxfilesperproc=65536
# 永久设置(创建 /etc/sysctl.conf)kern.maxfiles=65536kern.maxfilesperproc=65536
复制代码

3. 无法绑定端口

检查端口是否被占用:

lsof -i :9200
复制代码


查到占用端口的进程后,kill {PID} 杀掉占用端口的进程,或修改 elasticsearch 的默认端口即可。

4. 权限问题

# 修改数据目录权限sudo chown -R $USER /usr/local/var/lib/elasticsearch/
复制代码

5、安装 Kibana(可选)及基础使用简介

# 使用 Homebrew 安装brew install elastic/tap/kibana-full
# 启动 Kibanabrew services start elastic/tap/kibana-full
复制代码

访问:http://localhost:5601 即可看到 es 的基础信息,并进行操作。例如根据提供的示例,添加示例数据:

添加完成后,可以在『view data』中查看 DashBoard。

es 中查看通过 kibana 添加的测试数据:

http://localhost:9200/cat/indices/kibana_sample_data*?v&s=index 可以查到如下三个 index 的数据信息:

也可以使用 Kibana → 左侧菜单 → Management → Dev Tools,在 Console 中执行查询:

// 查询电子商务数据(前10条)GET kibana_sample_data_ecommerce/_search{  "size": 10,  "query": {    "match_all": {}  }}
// 查询航班数据(按时间排序)GET kibana_sample_data_flights/_search{ "size": 5, "sort": [ { "timestamp": "desc" } ]}
// 查询日志数据(过滤错误日志)GET kibana_sample_data_logs/_search{ "query": { "match": { "event.severity": "error" } }}
复制代码

执行结果如下图所示:

更多 Kibana 的使用操作,如果感兴趣后续再做详细讲解,本篇不做展开。

6、卸载 Elasticsearch

# Homebrew 用户brew services stop elastic/tap/elasticsearch-fullbrew uninstall elastic/tap/elasticsearch-full
# 手动安装用户pkill -F pid # 停止进程rm -rf elasticsearch-7.17.13/
复制代码

7、版本兼容性说明

  • Elasticsearch 7.x 需要 Java 11 或更高版本

  • 使用 java -version 检查 Java 版本

  • 如果需要安装 Java: brew install openjdk@11


三 Springboot 集成 Elasticsearch 7.x

3.1 集成关键代码

1、新建 maven 工程

2、pom 文件引入依赖

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>
<groupId>com.flamingskys.learn.rag</groupId> <artifactId>db-apps</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging>
<properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <!-- 与 ES 7.x 兼容 --> </parent>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <!-- 确保使用 REST 客户端而非过时的 Transport 客户端 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.17.13</version> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies></project>
复制代码

3、实体类代码,这里定义商品的 id、名称、价格

package com.flamingskys.learn.rag.es.entity;
import lombok.Data;import org.springframework.data.annotation.Id;import org.springframework.data.elasticsearch.annotations.Document;import org.springframework.data.elasticsearch.annotations.Field;import org.springframework.data.elasticsearch.annotations.FieldType;
@Data@Document(indexName = "products")public class Product {
@Id private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart") private String name;
@Field(type = FieldType.Double) private Double price;
// 必须有默认构造函数 public Product() {}
public Product(String name, Double price) { this.name = name; this.price = price; }}
复制代码

4、Repository 定义

继承自 ElasticsearchRepository

package com.flamingskys.learn.rag.es.repository;
import com.flamingskys.learn.rag.es.entity.Product;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;import java.util.List;
public interface ProductRepository extends ElasticsearchRepository<Product, String> { List<Product> findByName(String name); Page<Product> findByName(String name, Pageable pageable); List<Product> findByPriceBetween(Double minPrice, Double maxPrice);}
复制代码

5、Service 定义:

import com.flamingskys.learn.rag.es.entity.Product;import com.flamingskys.learn.rag.es.repository.ProductRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.stereotype.Service;
@Servicepublic class ProductService {
private final ProductRepository productRepository;
@Autowired public ProductService(ProductRepository productRepository) { this.productRepository = productRepository; }
public Product saveProduct(Product product) { return productRepository.save(product); }
public Page<Product> searchProducts(String query, Pageable pageable) { return productRepository.findByName(query, pageable); }
public void deleteProduct(String id) { productRepository.deleteById(id); }}
复制代码

6、Controller:3 个接口:创建索引、检索、删除

import com.flamingskys.learn.rag.es.service.ProductService;import com.flamingskys.learn.rag.es.entity.Product;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.web.bind.annotation.*;
@RestController@RequestMapping("/api/products")public class ProductController {
private final ProductService productService;
@Autowired public ProductController(ProductService productService) { this.productService = productService; }
@PostMapping("/create") public Product createProduct(@RequestBody Product product) { return productService.saveProduct(product); }
@GetMapping("/search") public Page<Product> searchProducts( @RequestParam String query, Pageable pageable) { return productService.searchProducts(query, pageable); }
@DeleteMapping("/{id}") public void deleteProduct(@PathVariable String id) { productService.deleteProduct(id); }}
复制代码

7、配置类,从 application.yml 中读取 es 相关配置信息:

import org.elasticsearch.client.RestHighLevelClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.elasticsearch.client.ClientConfiguration;import org.springframework.data.elasticsearch.client.RestClients;import org.springframework.data.elasticsearch.core.ElasticsearchOperations;import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;import java.net.URI;import java.util.List;import java.util.stream.Collectors;
@Configurationpublic class ElasticsearchConfig {
private final ElasticsearchProperties elasticsearchProperties;
@Autowired public ElasticsearchConfig(ElasticsearchProperties elasticsearchProperties) { this.elasticsearchProperties = elasticsearchProperties; }
@Bean public RestHighLevelClient elasticsearchClient() { // 将 URI 转换为 host:port 格式 List<String> hostsAndPorts = elasticsearchProperties.getUris().stream() .map(uri -> { URI parsed = URI.create(uri); return parsed.getHost() + ":" + parsed.getPort(); }) .collect(Collectors.toList());
ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo(hostsAndPorts.toArray(new String[0]))// .withBasicAuth(elasticsearchProperties.getUsername(), elasticsearchProperties.getPassword()) .withConnectTimeout(elasticsearchProperties.getConnectionTimeout()) .withSocketTimeout(elasticsearchProperties.getSocketTimeout()) .build();
return RestClients.create(clientConfiguration).rest(); }
@Bean public ElasticsearchOperations elasticsearchTemplate() { return new ElasticsearchRestTemplate(elasticsearchClient()); }}
复制代码

8、启动类

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplicationpublic class ElasticsearchApplication {
public static void main(String[] args) { SpringApplication.run(ElasticsearchApplication.class, args); }}
复制代码

9、application.yml

spring:  elasticsearch:    rest:      uris: http://localhost:9200      # 如果启用了安全认证(ES 8.x默认启用)      # username: elastic      # password: yourpassword
# 连接池配置 connection-timeout: 5s read-timeout: 30s
# 可选:禁用不需要的ES功能xpack: ml: enabled: false security: enabled: false
复制代码

完整工程代码,可查看 https://gitee.com/flamingskyline/rag.git并获取。

3.2 常见问题处理

3.2.1 源发行版本 11

运行工程时,一直提示 java: 警告: 源发行版 11 需要目标发行版 11 导致无法运行,

已完成设置项目 SDK、设置模块语言级别、并在 pom.xml 的<properties>增加如下配置后运行还是没有生效:

<java.version>11</java.version><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target>
复制代码

在命令行执行 mvn clean compile 清理并重新编译时,出现了错误信息:[ERROR] 源发行版 11 与 --enable-preview 一起使用时无效

排查 pom.xml 配置,确实在<build>标签中设置了<compilerArgs>--enable-preview</compilerArgs>


移除<jvmArguments>--enable-previews</> 后 错误消除。

3.2.2 ik 分词器

es 服务已启动,但启动 springboot 工程时报错,且信息如下:

Caused by: org.springframework.data.elasticsearch.RestStatusException: Elasticsearch exception [type=illegal_argument_exception, reason=Custom Analyzer [ik_max_word] failed to find tokenizer under name [ik_max_word]];nested exception is ElasticsearchStatusException[Elasticsearch exception [type=illegal_argument_exception, reason=Custom Analyzer [ik_max_word] failed to find tokenizer under name [ik_max_word]]]
复制代码

Elasticsearch 无法找到名为 ik_max_word 的分词器,是因为 IK 分词器插件未正确安装或配置导致。

安装方法:

https://release.infinilabs.com/analysis-ik/stable/ 中,下载 elasticsearch-analysis-ik-7.17.13.zip,解压到本地 es 下的 plugins ik 目录下,例如: /Users/{这里是你的真实目录}/develop/middlewire/elasticsearch-7.17.13/plugins/ik。 解压后包含以下文件:


安装完成后,重启 es 服务。

3.2.3 启动时无法加载机器学习(ML)所需的本地库

按照 ik 后重启 es 报错,且错误信息如下:

uncaught exception in thread [main] ElasticsearchException[Failure running machine learning native code. This could be due to running on an unsupported OS or distribution, missing OS libraries, or a problem with the temp directory. To bypass this problem by running Elasticsearch without machine learning functionality set [xpack.ml.enabled: false].]
复制代码

是无法加载机器学习本地库导致。由于暂时没有使用到,所以使用提供的参考处理方法,禁用机器学习功能(推荐用于非生产环境)。

vi config/elasticsearch.yml

在配置中增加以下两个配置:

# 禁用 ML 功能xpack.ml.enabled: false
# 同时禁用安全模块(如不需要)xpack.security.enabled: false
复制代码

保存并再次重启 es,启动正常。


发布于: 刚刚阅读数: 5
用户头像

磨炼中成长,痛苦中前行 2017-10-22 加入

微信公众号【程序员架构进阶】。多年项目实践,架构设计经验。曲折中向前,分享经验和教训

评论

发布
暂无评论
Mac下Elasticsearch7.x安装及Springboot集成_elasticsearch_程序员架构进阶_InfoQ写作社区