一文掌握ElastiscSearch
  ILwIY8Berufg 2023年11月02日 55 0

1.ElasticSearch 简介

ElasticSearch 是一款基于 Apache Lucene 构建的开源搜索引擎,它采用 Java 编写并使用 Lucene 构建索引、提供搜索功能。ElasticSearch 的目标是让全文搜索变 得简单,开发者可以通过它简单明了的 RestFul API 轻松地实现搜索功能,而不必去面对 Lucene 的复杂性。ES 能够轻松的进行大规模的横向扩展,以支撑 PB 级的结构化和非 结构化海量数据的处理。

简单来说,ElasticSearch 是一款基于 Lucene 的实时分布式搜索和分析引擎。 ElasticSearch 设计主要用于云计算中,能够达到实时搜索、稳定、可靠、快速,安 装使用也非常方便。

ES 的发展异常迅猛,下面是发展以及和 solr 简单的对比情况。

一文掌握ElastiscSearch_hadoop

官网地址https://www.elastic.co/

  • ES 和 SOLR 对比


SOLR

ElasticSearch

接口

类似 webservice 的接口

REST 风格的访问接口

分布式存储

solrCloud solr4.x 才支持

es 是为分布式而生的

支持的格式

xml json

json

  • ES 和 MySQL 的对比

MySQL

ElasticSearch

database(数据库)

index(索引库)

table(表)

type(类型)

row(行)

document(文档)

column(列)

field(字段)

2.REST 简介

REST 全称 Representational State Transfer。是一种软件的架构风格,而不 是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。 基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

其实说白了就是类似 HTTP 的访问,和 HTTP 非常的相似。

REST 操作:

  • GET:获取对象的当前状态;
  • PUT:改变对象的状态;
  • POST:创建对象;
  • DELETE:删除对象;
  • HEAD:获取头信息。

资源

一组资源的 URI,比如:http://example.com/res/

单个资源的 URI,比如:http://example.com/res/123

GET

列出 URI,以及该资源组中每个资源的详细信息(后者可选)

获取指定的资源的详细信息,格式可 以自选一个合适的网络媒体类型(比如:XML、JSON 等)

PUT

使用给定的一组资源替换当前整组资源

替换/创建指定的资源。并将其追加 到相应的资源组中。

POST

在本组资源中创建/追加一个新的资源。 该操作往往返回新的 URL

把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。

DELETE

删除整组资源

删除指定的元素

ES 内置的 REST 接口

URL

描述

/index/_search

搜索指定索引下的数据

/_aliases

获取或操作索引的别名

/index/

查看指定索引的详细信息

/index/type/

创建或操作类型

/index/_mapping

创建或操作 mapping

/index/_setting

创建或操作设置(number_of_shards 是不可更改的)

/index/_open

打开指定被关闭的索引

index/_close

关闭指定索引

index/_refresh

刷新索引(使新加内容对搜索可见,不保证数据被写入磁盘)

/index/flush

刷新索引(会触发 Lucene 提交)

3.ElasticSearch 的安装配置

ElasticSearch分布式集群搭建

4.CURL 简介

curl 是利用 URL 语法在命令行方式下工作的开源文件传输工具,使用 curl 可以简单 实现常见的 get/post 请求。简单的认为是可以在命令行下面访问 url 的一个工具。在 centos 的默认库里面是有 curl 工具的,如果没有请 yum 安装即可。

  • curl-
  • x 指定 http 的请求方法 有 HEAD GET POST PUT DELETE
  • -d 指定要传输的数据
  • -H 指定 http 请求头信息

ElasticSearch CRUL操作

5.ElasticSearch 版本控制

  • 普通关系型数据库使用的是(悲观并发控制(PCC))
    当我们在读取一个数据前先锁定这一行,然后确保只有读取到数据的这个线程可以修改这一行数据
  • ES 使用的是(乐观并发控制(OCC))
    ES 不会阻止某一数据的访问,然而,如果基础数据在我们读取和写入的间隔中发生了变化,更新就会失败,这时候就由程序来决定如何处理这个冲突。它可以 重新读取新数据来进行更新,又或者将这一情况直接反馈给用户。
  • ES 如何实现版本控制(使用 es 内部版本号)
  1. 首先得到需要修改的文档,获取版本(_version)号
curl -XGET http://hadoop01:9200/product/hadoop/1
  1. 再执行更新操作的时候把版本号传过去
    (覆盖)
curl -XPUT http://hadoop01:9200/product/1?version=1 -d '{"name":"hadoop","version":3}'

(部分更新)

curl -XPOST http://hadoop01:9200/product/1/_update?version=1 -d '{"doc":{"name":"apache hadoop","version":2.6.4}}'
  1. 如果传递的版本号和待更新的文档的版本号不一致,则会更新失败
  • ES 使用外部版本号实现版本控制
    如果你的数据库已经存在了版本号,或者是可以代表版本的时间戳。这时就可以在 es 的查询 url 后面添加 version_type=external 来使用这些号码。
    注意:版本号码必须要是大于 0 小于 9223372036854775807(java 中 long 的最大正值)的整数。
    es 在处理外部版本号的时候,它不再检查\_version 是否与请求中指定的数值是否相等,而是检查当前的_version 是否比指定的数值小,如果小,则请求成功。
    example:
curl -XPUT 'http://hadoop01:9200/product/20?version=10&version_type=external' -d '{"name": "flink"}'

注意:此处 url 前后的引号不能省略,否则执行的时候会报错

6.ElasticSearch 中的核心概念

  1. Cluster
    代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。ES的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看 ES 集群,在逻辑上是个整体,你与任何一个节点的通信和与整个 ES 集群通信是等价的。
    主节点的职责是负责管理集群状态,包括管理分片的状态和副本的状态,以及节点的发现和删除。
    只需要在同一个网段之内启动多个 ES 节点,就可以自动组成一个集群。
    默认情况下 ES 会自动发现同一网段内的节点,自动组成集群。
    集群的查看状态
    http://hadoop01:9200/_cluster/health?pretty
  2. shards
    代表索引分片,ES 可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上,构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
    可以在创建索引库的时候指定
curl -XPUT 'hadoop01:9200/test1/' -d '{"settings":{"number_of_shards":3}}'
  1. replicas
    代表索引副本,ES 可以给索引设置副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高 ES 的查询效率,ES 会自动对搜 索请求进行负载均衡。
    可以在创建索引库的时候指定
curl -XPUT 'hadoop01:9200/test2/'-d '{"settings":{"number_of_replicas":2}}'
  1. recovery
    代表数据恢复或者叫数据重新分布,ES 在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
  2. gateway
    代表 ES 索引的持久化存储方式,ES 默认是先把索引存放到内存中,当内存满了时再持久化到硬盘。当这个 ES 集群关闭在重新启动是就会从 gateway 中读取索引数据。Es支持多种类型的 gateway,有本地文件系统(默认),分布式文件系统,Hadoop 的 HDFS 和 amazon 的 s3 云存储服务。
  3. discovery.zen
    代表 ES 的自动发现节点机制,ES 是一个基于 p2p 的系统,它先通过广播寻找存在的 节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。
  • 如果是不同网段的节点如果组成 ES 集群
    禁用自动发现机制
discovery.zen.ping.multicast.enabled:false

设置新节点被启动时能够发现的注解列表

Discovery.zen.ping.unicast.hosts:["192.8.50.150", "192.8.53.124:9300"]
  1. Transport
    代表 ES 内部节点或集群与客户端的交互方式,默认内部是使用 tcp 协议进行交互,同时它支持 http 协议(json 格式)、thrift、servlet、memcached、zeroMQ 等传输协 议(通过插件方式集成)

7.ElasticSearch Java 客户端操作

ElasticSearch API使用

8.中文分词

ElasticSearch中文分词处理

9.并行过滤器

文档中 score(_score 字段是搜索结果)。score 是一个数字型的,是一种相对方法匹配查询文档结果。分数越高,搜索关键字与该文档相关性越高;越低,搜索关键字与该文 档相关性越低。

在 elasticsearch 中所有的搜索都会触发相关性分数计算。如果我们不使用相关性分数计算,那要使用另一种查询能力,构建过滤器。

过滤器是类似于查询的概念,除了得以优化,更快的执行速度的两个主要原因:

  • 过滤器不计算得分,所以他们比执行查询的速度
  • 过滤器可缓存在内存中,允许重复搜索

为了便于理解过滤器,先介绍过滤器搜索(like match_all, match, bool, etc.),可以与其他的普通查询搜索组合一个过滤器。 range filter,允许我们通过一个范围值来过滤文档 ,一般用于数字或日期过滤使用过滤器搜索返回 balances[ 20000,30000],即balance>=20000 && balance<=30000。

curl -XPOST 'hadoop01:9200/bank/_search?pretty' -d '{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}'

过滤查询包含 match_all查询(查询部分)和一系列过滤(过滤部分)。可以代替任何其他查询到查询部分以及其他过滤器过滤部分。在上述情况下,过滤器范围智能,因为文档落入 range 所有匹配“平等”,即比另一个更相关

一般情况,最明智的方式是决定是否使用 filter or query,就看你是否关心相关性分数。如果相关性不重要,那就使用 filter,否则就使用 query

queries and filters 很类似于关系型数据库中的 SELECT WHERE clause

10.执行聚合

聚合提供从你的数据中分组和提取统计能力。类似于关系型数据中的 SQL GROUP BY 和 SQL 聚合函数。在 ES,你有能力执行搜索返回命中结果,同时拆分命中结果,然后统一返回结果。当你使用简单的 API 运行搜索和多个聚合,然后返回所有结果避免网络带宽过 大的情况是高效的。

  • 根据 state 分组,降序统计 top 10 state
curl -XPOST 'hadoop01:9200/bank/_search?pretty' -d
'{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state"
      }
    }
  }

}' 类似于关系型数据库

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC;

size=0 不是展示搜索结果命中数,因为只是想要看聚合结果

  • 根据 state 计算账户平均 balance,降序统计 top 10 state
curl -XPOST 'hadoop01:9200/bank/_search?pretty' -d '{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {"field": "state"}
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}'

注意嵌套 average_balance 聚合 group_by_state 内聚合。这是一个常见的模式, 所有的聚合。您可以嵌套内聚合聚合任意提取旋转汇总时,你需要从你的数据。

  • 降序排序平均 balance
curl -XPOST 'hadoop01:9200/bank/_search?pretty' -d '{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state",
        "order": {
          "average_balance": "desc"
        }
      }
    },
    "aggs": {
      "average_balance": {
        "avg": {
          "field": "balance"
        }
      }
    }
  }
}'
  • 聚合年龄分区间(ages 20-29, 30-39 and 40-49),聚合性别,最后平均 balance 展示最终结果
curl -XPOST 'hadoop01:9200/bank/_search?pretty' -d '{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender"
          },
          "aggs": {
          "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}'

11.ElasticSearch 优化

  1. 关于创建
  • 调大系统的"最大打开文件数",建议 32K 甚至是 64K
    ulimit -a (查看)
    ulimit -n 32000(设置)
  • 修改配置文件调整 ES 的 JVM 内存大小
  1. 修改 bin/elasticsearch.in.sh 中 ES_MIN_MEM 和 ES_MAX_MEM 的大小,建议设置一样大,避免频繁的分配内存,根据服务器内存大小,一般分配 60%左右(默认 256M)
  2. 如果使用 searchwrapper 插件启动 es 的话则修改 bin/service/elasticsearch.conf(默认 1024M,2.x 以后不用考虑)
  • 设置 mlockall 来锁定进程的物理内存地址
  • 避免交换(swapped)来提高性能
  • 修改文件 conf/elasticsearch.yml中的bootstrap.mlockall: true

分片多的话,可以提升建立索引的能力,5-20 个比较合适。 如果分片数过少或过多,都会导致检索比较慢。分片数过多会导致检索时打开比较多的文件,另外也会导致多台服务器之间通讯。而分片数过少会导至单个分片索引过大,所以检索速度慢。建议单个分片最多存储 20G 左右的索引数据,所以,分片数量=数据总量/20G 副本多的话,可以提升搜索的能力,但是如果设置很多副本的话也会对服务器造成额外的压力,因为需要同步数据。所以建议设置 2-3 个即可。

要定时对索引进行优化,不然 segment 越多,查询的性能就越差

索引量不是很大的话情况下可以将 segment 设置为 1

curl -XPOST 'http://hadoop01:9200/crxy/_optimize?max_num_segments=1'

等于java代码

client.admin().indices().prepareOptimize("bigdata").setMaxNumSegments(1).get();
  1. 关于删除
    在 Lucene 中删除文档,数据不会马上在硬盘上除去,而是在 lucene 索引中产生一个.del 的文件,而在检索过程中这部分数据也会参与检索,lucene 在检索过程会判断是否删除了,如果删除了再过滤掉。这样也会降低检索效率。所以可以执行清除删除文档
curl -XPOST 'http://hadoop01:9200/bigdata/_optimize?only_expunge_deletes=true'

等于java代码

client.admin().indices().prepareOptimize("bigdata").setOnlyExpung eDeletes(true).get();

如果在项目开始的时候需要批量入库大量数据的话,建议将副本数设置为 0。因为 es 在索引数据的时候,如果有副本存在,数据也会马上同步到副本中,这样会对 es 增加压力。 待索引完成后将副本按需要改回来。这样可以提高索引效率。

  1. 关于配置
  • 去掉 mapping 中\_all 域,Index 中默认会有\_all 的域,(相当于 solr 配置文件中 的拷贝字段 text),这个会给查询带来方便,但是会增加索引时间和索引尺寸"_all":{"enabled":"false"}
  • log 输出的水平默认为 trace,即查询超过 500ms 即为慢查询,就要打印日志,造成 cpu 和 mem,io 负载很高。把 log 输出水平改为 info,可以减轻服务器的压力。 修改 ES_HOME/conf/logging.yaml文件,或者修改 ES_HOME/conf/elasticsearch.yaml
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
ILwIY8Berufg
最新推荐 更多

2024-05-31