暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

重学ElasticSearch (ES) 系列(一):核心概念及安装

一叶扁舟 2022-04-05
2556

【系列文章】
重学ElasticSearch (ES) 系列(二):搜索外相关操作(集群、索引、文档)
重学ElasticSearch (ES) 系列(三):深入数据搜索
重学ElasticSearch (ES) 系列(四):ELK搭建SpringBoot日志实时分析系统
重学ElasticSearch (ES) 系列(五):常见面试题

目录

一、概述

1.1、什么是ES

一个开源的高扩展分布式全文检索引擎,可近乎实时的存储、检索数据,可扩展性强,可处理PB级别的数据。

通过简单的Restful API, 来隐藏Luncee的复杂性,从而让全文搜索变得简单

1.2、倒排索引

1.2.1、什么是倒排索引

倒排索引是一种数据结构

Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。

1、把每个文档拆分为独立的词

2、创建一个包含所有且不重复的词条列表

3、记录每个词条出现在哪些文档中

倒排索引.png

这样,搜索linux,就能快速定位到3、4文档

1.2.2、倒排索引的核心组成

倒排索引包含2个部分:单词字典、倒排列表

  • 单词字典(Term Dictionary)

    单词字典记录所有文档的单词和倒排列表的关联关系

    单词字典一般比较大,可以通过B+树或哈希拉链表实现,以满足高性能的插入和查询

  • 倒排列表(Posting List)

    倒排列表由索引项组成

    • 索引项
      • 文档id
      • 词频TF:该单词在文档中出现的次数,用于相关性评分
      • 位置:单词在文档中的分词位置,用于语句搜索
      • 偏移:记录单词的在文档中的起始和结束位置,用于高亮显示
    image.png

1.3、核心概念

1、es提供了分布式集群(Cluster)的方式,保证高可用
2、多个节点(Node)组成一个集群
3、一个节点中分布着多个索引(index)/索引的一部分(分片Shard)
4、节点间多个分片组成一个index

image.png

Near Realtime(近实时)

Elasticsearch是一个近乎实时的搜索平台,这意味着从索引文档到可搜索文档之间只有一个轻微的延迟(通常是一秒钟)。

Cluster(集群)

群集是一个或多个节点的集合,它们一起保存整个数据,并提供跨所有节点的联合索引和搜索功能。每个群集都有自己的唯一群集名称,节点通过名称加入群集。

Node(节点)

节点是指属于集群的单个Elasticsearch实例,存储数据并参与集群的索引和搜索功能。可以将节点配置为按集群名称加入特定集群,默认情况下,每个节点都设置为加入一个名为elasticsearch的群集。

1.2.4、Index(索引)

索引是一些具有相似特征的文档集合,类似于MySql中数据库的概念。但是在Elasticsearch 6.0.0及更高的版本中,一个index只能包含一个type,其实也类似于一个Index就是一个表。

Type(类型)

类型是索引的逻辑类别分区,通常,为具有一组公共字段的文档类型,类似MySql中表的概念。注意:在Elasticsearch 6.0.0及更高的版本中,一个索引只能包含一个类型。

Document(文档)

文档是可被索引的基本信息单位,以JSON形式表示,类似于MySql中行记录的概念。

Shards(分片)

当索引存储大量数据时,可能会超出单个节点的硬件限制,为了解决这个问题,Elasticsearch提供了将索引细分为分片的概念。分片机制赋予了索引水平扩容的能力、并允许跨分片分发和并行化操作,从而提高性能和吞吐量。

  • 主分片
    主分片用于解决数据水平扩展问题。通过主分片,可以将数据分布到集群内的不同节点上。主分片在创建索引时指定,后续不允许修改

在可能出现故障的网络环境中,需要有一个故障切换机制,Elasticsearch提供了将索引的分片复制为一个或多个副本的功能,副本在某些节点失效的情况下提供高可用性。

  • 副本分片(Replicas)
    副本分片用于解决数据高可用问题。是主分片的拷贝。副本分片数可以动态调整。

二、安装

2.1、Linux下安装

2.1.1、安装ElasticSearch

官方下载地址

  • 下载解压

    tar -zxvf elasticsearch-7.16.2.tar.gz
  • 修改配置文件

    cd elasticsearch-7.16.2/config vi elasticsearch.yml
    # ---------------------------------- Cluster ----------------------------------- # 集群名称,默认是elasticsearch cluster.name: my-elasticsearch # ------------------------------------ Node ------------------------------------ node.name: node-1 cluster.initial_master_nodes: ["node-1"] # ----------------------------------- Paths ------------------------------------ path.data: /path/to/data path.logs: /path/to/logs # ---------------------------------- Network ----------------------------------- # 为es设置ip绑定,默认是127.0.0.1,也就是默认只能通过127.0.0.1 或者localhost才能访问,也可配置0.0.0.0全部可以访问 network.host: 192.168.0.1 # 为es设置自定义端口,默认是9200 http.port: 9200
  • 创建用户及设置文件权限

    # 创建用户和组 groupadd esuser useradd -g esuser esuser # 设置密码 passwd esuser # 设置文件权限 chown -R esuser:esuser /elasticsearch-7.16.2
  • 启动

    su - esuser cd /elasticsearch-7.16.2/bin ./elasticsearch -d
  • 关闭

    ps -ef|grep elasticsearch kill -9 pid

2.1.2、安装kibana

官方下载链接

  • 解压

    tar -zxvf kibana-7.16.2-linux-x86_64.tar.gz
  • 修改配置

    cd kibana-7.16.2-linux-x86_64/config vi kibana.yml
    server.port: 5601 server.host: "192.168.1.23" elasticsearch.hosts: ["http://192.168.111.133:9200"] elasticsearch.username: "kibana_system" elasticsearch.password: "elastic" il18n.locale: zh-CN
  • 修改权限

    # 设置文件权限 chown -R esuser:esuser /kibana-7.16.2-linux-x86_64
  • 启动

    cd /kibana-7.16.2-linux-x86_64/bin ./kibana &

2.2、Docker安装

2.2.1、安装Elasticsearch

  • 拉取镜像

    docker pull elasticsearch:7.16.2
  • 创建持久化文件

    mkdir -p /root/elasticsearch/config mkdir -p /root/elasticsearch/data # 赋予权限 chmod 777 /root/elasticsearch/data
  • 初始化配置

    echo "http.host: 0.0.0.0" >> elasticsearch/config/elasticsearch.yml
  • 启动镜像

    docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -v /root/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /root/elasticsearch/data:/usr/share/elasticsearch/data -v /root/elasticsearch/plugins:/usr/share/elasticsearch/plugins -d elasticsearch:7.16.2
    • p: 端口映射
    • -e: 单点模式启动
    • -v: 目录挂载
    • -d: 后台运行
  • 测试访问

    localhost:9200

    { "name" : "1915d6ba7ccb", "cluster_name" : "elasticsearch", "cluster_uuid" : "E017hynLQvi28mpqUmU00w", "version" : { "number" : "7.16.2", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f", "build_date" : "2020-03-26T06:34:37.794943Z", "build_snapshot" : false, "lucene_version" : "8.4.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }

2.2.2、安装kibana

kibana 是 Elasticsearch 的最佳拍档

用于Query DSL的编写,也可以做各式各样的数据报表

  • 拉取镜像

    docker pull kibana:7.16.2
    
  • 配置文件

    mkdir kibana
    vi kibana.yml
    
    server.host: 0.0.0.0 elasticsearch.hosts: http://localhost:9200
  • 启动

    docker run --name kibana -v /Users/yangmeng/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml -p 5601:5601 -d kibana:7.16.2 
    
    • 若遇到该容器已经存在,rm掉,重现启动即可

      docker rm a71a11a3a30fd6bfc
      
  • 访问

    localhost:5601 【Kibana server is not ready yet】

  • 排错

    按照以上做法,访问localhost:5601会报错 【Kibana server is not ready yet】

    原因是:1、ElasticSearch和kibana版本不匹配

    ​ 2、kibana.yml错误

    • 更改kibana.yml

      server.host: 0.0.0.0 elasticsearch.hosts: http://192.168.0.102:9200
    • 重启kibana

      docker restart 80118c57cabc
      

kibana.png

三、分词

3.1、概述

ES 中处理分词的部分被称作分词器,英文是Analyzer,它决定了分词的规则。ES 自带了很多默认的分词器,比如StandardKeywordWhitespace等等,默认是 Standard

当我们在读时或者写时分词时,均可以指定要使用的分词器。

分词倒排索引

  • 分词原理

    分词器的组成如下:

    • Character Filters:针对原始文本进行处理,比如去除html标签
    • Tokenizer:将原始文本按照一定规则切分为单词
    • Token Filters:针对Tokenizer处理的单词进行再加工,比如转小写、删除或增新等处理
  • 分词器种类

    • 默认分词器:standard

      POST _analyze { "analyzer": "standard", "text": "往事知多少" }
    • 停用词分词器:stop

      POST _analyze { "analyzer": "stop", "text": ["The 2 QUICK Brown Foxes jumped over the lazy dog's bone."] }
    • 中文分词器:ik分词器

      POST _analyze { "analyzer": "ik_smart", "text": "春花秋月何时" } POST _analyze { "analyzer": "ik_max_word", "text": "往事知多少" }

3.2、写入时分词

当创建文档时,ES会进行分词,用于倒排索引,存储在服务器磁盘中

  • 默认写入时分词

    写入时,分词默认使用的是Standard。会将中文分成单个字当索引

    PUT mapping_test { "mappings": { "properties": { "title": { "type": "text" } } } }
  • 指定分词器

    写入时,也可以指定分词器

    PUT mapping_test { "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_max_word" } } } }

3.3、搜索时分词

用户搜索时,也会对搜索词进行分词,存储在内存中(查询结束则消失)

  • 默认分词器

    读时分词器默认与写时分词器默认保持一致(读写采用一致的分词器,才能尽最大可能保证分词的结果是可以匹配的。)

  • 指定分词器

    ES 允许也读时分词器单独设置

    POST test/_search { "query":{ "match":{ "msg":{ "query": "eating", "analyzer": "english" } } } }

3.4、IK分词器

对中文的分词进行了优化

3.4.1、安装IK分词器插件

进入ElasticSearch容器,安装插件,重启容器

需要跟ElasticSearch相同版本

IK分词器各个版本

image.png

// 进入容器 docker exec -it es /bin/bash // 下载相同版本的ik插件 elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.16.2/elasticsearch-analysis-ik-7.16.2.zip // 重启容器 docker restart es

3.4.2、使用

3.4.2.1、测试分词效果

一个中文分词器插件,提供了两个分词算法:ik_smart:最小切分、ik_max_word:最小粒度划分

GET _analyze { "analyzer": "ik_smart", "text": "春花秋月何时了" } GET _analyze { "analyzer": "ik_max_word", "text": "春花秋月何时了" }

ik分词.png

# 补充:curl携带body发送请求测试ik分词器 curl -X POST \ 'http://127.0.0.1:9200/_analyze?pretty=true' \ -H 'Content-Type: application/json' \ -d '{"text":"我们是软件工程师","tokenizer":"ik_smart"}'

3.4.2.1、自定义扩展词

  • 修改配置文件IKAnalyzer.cfg.xml

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict">myself.dic</entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords"></entry> <!--用户可以在这里配置远程扩展字典 --> <!--<entry key="remote_ext_dict">http://localhost/es_new_word.txt</entry>--> <!--用户可以在这里配置远程扩展停止词字典--> <!-- <entry key="remote_ext_stopwords">words_location</entry> --> </properties>
  • 编写自定义dic(myself.dic)

    春花秋
    

3.4.3、实操

3.4.3.1、与默认分词器对比

【默认分词器】

存入时:把华夏拆分为"华" “夏”

搜索时:把华为云拆分为"华" “为” “云”

因此,把华夏也匹配到了

image.png

【ik分词器】

存入时:把华夏拆分为"华夏"

搜索时:把华为云拆分为"华为" “云”

因此,不会把华夏匹配进去

image.png

3.4.3.2、使用ik分词器分词

  • 创建索引

    【注意】一定要在创建索引时指定ik分词器,才会生效

    # 【一定要在创建索引时指定ik分词器,才会生效】 PUT /yang9 { "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_max_word" } } } }
  • 存入数据

    PUT /yang9/_doc/1 { "title": "华为云数据库代理正式商用", "analyzer": "ik_max_word" # 可以省略,默认跟索引设置的分词器一致 } PUT /yang9/_doc/2 { "title": "华夏", "analyzer": "ik_max_word" # 可以省略,默认跟索引设置的分词器一致 }
  • 搜索数据

    POST /yang9/_search { "query": { "match": { "title": { "query": "华为", "analyzer": "ik_max_word" # 可以省略,默认跟存入数据分词器一致 } } } }
最后修改时间:2022-11-04 23:26:44
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论