使用ElasticSearch完成对文件名的搜索(包含ELK在Linux下的安装)

本篇文章包含以下内容:

  1. ES的介绍
  2. ELK在Linux系统下的部署以及各种坑
  3. ES在项目中的使用

思维导图:

1、背景

使用 elasticsearch,以下简称es 的几个原因如下

  • 关系型数据库在进行模糊(%关键字%)搜索的时候,会全表扫描,查询非常慢
  • 关系型数据库在关键字搜索时,并不支持全文分词搜索,比如用户本打算搜索:公众号-111,却手误:公号-111,es 可以根据分词的结果搜索出想要的结果。
  • 在数据分析、日志分析上用到 es

2、es 基本概念

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。Elasticsearch 在 Apache Lucene 的基础上开发而成,由 Elasticsearch N.V.(即现在的 Elastic)于 2010 年首次发布。

Elasticsearch 是文件存储,Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档,用 JSON 作为文档序列化的格式,比如下面这条用户数据:

{
    "name":"name",
    "sex":0,
    "age":21
}

3、es 优势

  • 分布式:横向可扩展性,增加服务器可直接配置在集群中
  • 高可用:提供了复制功能,具有容错机制,能自动发现新的或失败的节点,重组和重新平衡节点数据
  • 实时性:数据进入 es,可达到近实时搜索
  • Restful api:json 格式的 RESTful 风格
  • 全文检索:基于 lucene 的强大的全文检索能力

4、在linux系统中部署es

1、下载对应版本的es,这里下载了8.1.2

https://www.elastic.co/cn/downloads/past-releases/elasticsearch-8-1-2

2、下载完成后,复制到服务器,解压到合适的位置

此处我解压到了/root/docker/elasticsearch文件夹下

tar -zxvf elasticsearch-8.1.2-linux-x86_64.tar.gz -C /root/docker/elasticsearch/

注:超级天坑,解压到上面的文件夹后怎么都找不到es自带的jdk,无法启动,把es解压到/usr/local后就可以了。然后跳过第三步都可以启动。

3、解决es强依赖jdk问题

由于es和jdk是一个强依赖的关系,所以当我们在新版本的ElasticSearch压缩包中包含有自带的jdk,但是当我们的Linux中已经安装了jdk之后,就会发现启动es的时候优先去找的是Linux中已经装好的jdk,此时如果jdk的版本不一致,就会造成jdk不能正常运行。

注:如果Linux服务本来没有配置jdk,则会直接使用es目录下默认的jdk,反而不会报错。

  • 进入bin目录cd /root/docker/elasticsearch/elasticsearch-8.1.2/bin
  • 修改elasticsearch配置,将以下代码加入到文件开头vim ./elasticsearch
############## 添加配置解决jdk版本问题 ##############
# 将jdk修改为es中自带jdk的配置目录
export JAVA_HOME=/root/docker/elasticsearch/elasticsearch-8.1.2/jdk
export PATH=$JAVA_HOME/bin:$PATH

if [ -x "$JAVA_HOME/bin/java" ]; then
        JAVA="/root/docker/elasticsearch/elasticsearch-8.1.2/jdk/bin/java"
else
        JAVA=`which java`
fi

4、解决内存不足问题

进入config文件夹开始配置,使用vim编辑jvm.options:

默认配置如下:
##-Xms4g
##-Xmx4g
默认的配置占用内存太多了,调小一些:
-Xms256m
-Xmx256m

/root/docker/elasticsearch/elasticsearch-8.1.2/

5、创建专用用户启动ES

root用户不能直接启动Elasticsearch,所以需要创建一个专用用户,来启动ES

  • 创建用户

useradd user-es

#设置密码
sudo passwd user-es
root
root
  • 创建所属组:

chown user-es:user-es -R /root/docker/elasticsearch/elasticsearch-8.1.2

  • 切换到user-es用户

su user-es

  • 进入bin目录

cd /root/docker/elasticsearch/elasticsearch-8.1.2/bin 疑似记录错误?/usr/local/elasticsearch-8.1.2/bin/

  • 启动elasticsearch

./elasticsearch

  • 后台启动启动elasticsearch

./elasticsearch -d

关闭es:

ps -ef | grep ela

kill <进程id>

6、启动ElasticSearch报错:error updating geoip database

解决方案:

在elasticsearch.yml中添加如下配置:

ingest.geoip.downloader.enabled: false
1

关闭geoip数据库的更新

7、修改elastic用户登录密码

在elasticsearch根目录下,输入:

./bin/elasticsearch-reset-password --username elastic -i

然后输入新的密码elastic。

于是原来的

elastic

0KskxivpPR-lGMsNZ-Ii

变成了

elastic

elastic

8、重新启动步骤

进入/usr/local/elasticsearch-8.1.2/bin/ 文件夹 !!!

切换user-es用户

杀死现有进程

ps -ef | grep ela

kill <进程id>

后台启动启动elasticsearch,进入bin目录

./elasticsearch -d

9、文件描述符限制太低(max file descriptors [65535] for elasticsearch process is too low)

elasticsearch安装后启动时候,遇到此问题

问题翻译过来就是:elasticsearch用户拥有的可创建文件描述的权限太低,至少需要65536;

解决办法:

#切换到root用户修改

vim /etc/security/limits.conf

在最后面追加下面内容

*** hard nofile 65536

*** soft nofile 65536

*** 是启动ES的用户

使用sysctl -p刷新配置文件

切换用户使用 ulimit -Hn 查看当前值 是65535就成功

10、虚拟内存区域限制太低问题(vm.max_map_count [65530] is too low,crease to at 262144)

elasticsearch用户拥有的内存权限太小,至少需要262144,解决办法:

在 /etc/sysctl.conf 文件最后添加如下内容,即可永久修改

  • 切换到root用户

执行命令:su root

  • 执行命令

vim /etc/sysctl.conf

  • 添加如下内容

vm.max_map_count=262144

  • 保存退出,刷新配置文件

sysctl -p

  • 切换user-es用户,继续启动

su user-es

  • 启动es服务

./bin/elasticsearch -d

11、开放http访问

使用vim编辑config目录下的elasticsearch.yml文件

将xpack.security.enabled: true

和xpack.security.transport.ssl: enabled: true

修改为false

network.host: 0.0.0.0
http.port: 9200


ingest.geoip.downloader.enabled: false

# Enable security features
xpack.security.enabled: false

xpack.security.enrollment.enabled: true

# Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents
xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12

# Enable encryption and mutual authentication between cluster nodes
xpack.security.transport.ssl:
  enabled: false
  verification_mode: certificate
  keystore.path: certs/transport.p12
  truststore.path: certs/transport.p12

5、安装kibana

1、下载与es版本相同的kibana的tar.gz

https://www.elastic.co/downloads/past-releases#kibana

2、解压到自己需要的目录

此处我解压到了es的同级目录:

tar -zxvf kibana-8.1.2-linux-x86_64.tar.gz -C /usr/local/

3、权限配置: 设置对安装目录下文件的拥有权限:

chown -R user-es:user-es kibana-8.1.2

4、修改配置:

vim /usr/local/kibana-8.1.2/config/kibana.yml 

通过指令打开kibana的yml文件,修改以下配置

#修改主机地址设为本地,设置本机可以访问
server.host: "0.0.0.0"
#配置ES的IP地址,有需要可修改
#elasticsearch.hosts: ["http://localhost:9200"]

5、启动命令(要提前启动ES):

切换到user-es用户,进入kibana的bin目录

./kibana

后台启动
nohup ./kibana & 

6、地址栏访问 服务器地址:5601

http://172.18.22.129:5601

kibana初始化与Es链接SSl的token 有效期30分钟 过期使用.\elasticsearch-create-enrollment-token -s kibana 再次创建

将生成的token 复制进来

点击Configure Elastic等待片刻

进入页面

输入elasticSearch的账号密码登录

elastic

elastic

7、汉化

在config/kibana.yml中添加下行重启即可

i18n.locale: "zh-CN"

8、停止命令、后台启动

切换到user-es用户

nohup ./kibana & 
或者
nohup ./kibana >/dev/null &

- 查看进程号 jps 或者 ps -ef|grep kibana  或者 ps -ef|grep 5601
- 杀死进程 kill -9 进程号

netstat -tunlp | grep 5601   // 可用

21811就是进程号

9、修改es为http访问后,kibana无法访问的问题

编辑kibana.yml文件,将https改为http。重启kibana即可。

2024-9-23更新:修改es地址从172.17.0.1集群网段修改为为localhost

6、安装ik分词器

1、下载与es版本相同的ik压缩包 elasticsearch-analysis-ik-8.1.2.zip

https://github.com/infinilabs/analysis-ik/releases

2、上传并解压

在elasticsearch-8.1.2/plugins目录下创建ik分词器文件夹(文件夹名称一定要为ik,不然启动elasticsearch报错)

在plugins目录创建文件夹命令如下:

mkdir ik

再将ik安装包传输到ik文件夹中解压,或直接解压后再上传:

tar -zxvf analysis-ik-8.1.2.tar.gz

上传完毕后重启es即可使用,使用示例

POST _analyze
{
  "analyzer":"ik_smart",
  "text": ["我是中国人!"]
}
POST _analyze
{
  "analyzer":"ik_max_word",
  "text": ["我是中国人!"]
}

ik分词器不会跟ElasticSearch标准分词器一样只会把每个汉字拆分为单独一个词项,而是会根据分词类型(ik_smart,ik_max_word)把汉字拆分为不同词项,而且ik_smart拆分颗粒度比较粗糙,ik_max_word拆分颗粒度比较细致。

在建索引的时候使用 ik_max_word 分词器,这样分的词可以更细。

在搜索的时候使用 ik_smart 分词器,这样在搜索的时候分的词粒度更粗,只用查更少的词,能提高效率。

  • ik分词器支持扩展词典
  • IK分词器支持热词更新

7、在项目使用ElasticSearch

导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.1.2</version>
</dependency>

nacos中的配置

# elasticsearch配置        
elasticsearch:
  host: localhost
  port: 9200
  scheme: http  

ElasticSearchConfig.java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import org.elasticsearch.client.RestClient;
import org.apache.http.HttpHost;


@Configuration
public class ElasticSearchConfig {
    @Value("${elasticsearch.host}")
    private String host;

    @Value("${elasticsearch.port}")
    private int port;

    @Value("${elasticsearch.scheme}")
    private String scheme;
    @Bean
    public ElasticsearchClient elasticsearchClient() {
        RestClient client = RestClient.builder(new HttpHost(host, port, scheme)).build();
        ElasticsearchTransport transport = new RestClientTransport(client, new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }
}

FileSearch.java

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class FileSearch {
    private String indexName;
    private String userFileId;
    private String fileId;
    private String fileName;
    private String content;
    private String fileUrl;
    private Long fileSize;
    private Integer storageType;
    private String identifier;
    private Long userId;
    private String filePath;
    private String extendName;
    private Integer isDir;
    private String uploadTime;
    private Integer deleteFlag;
    private String deleteTime;
    private String deleteBatchNum;
}

然后在文件上传和删除的时候更新ES的索引即可。

public void uploadESByUserFileId(String userFileId) {
    exec.execute(()->{
        try {

            Map<String, Object> param = new HashMap<>();
            param.put("userFileId", userFileId);
            List<UserFile> userfileResult = userFileMapper.selectByMap(param);
            if (userfileResult != null && userfileResult.size() > 0) {
                FileSearch fileSearch = new FileSearch();
                BeanUtil.copyProperties(userfileResult.get(0), fileSearch);
elasticsearchClient.index(i -> i.index("filesearch").id(fileSearch.getUserFileId()).document(fileSearch));
            }
        } catch (Exception e) {
            log.debug("ES更新操作失败,请检查配置");
        }
    });


}

public void deleteESByUserFileId(String userFileId) {
    exec.execute(() -> {
        try {
            elasticsearchClient.delete(d -> d
                    .index("filesearch")
                    .id(userFileId));
        } catch (Exception e) {
            log.debug("ES删除操作失败,请检查配置");
        }
    });


}
点赞

当前页面评论已关闭。

隐藏
变装