Elasticsearch学习笔记

 一、什么是elasticsearch?
 
  Elasticsearch是一个基于Lucene作为底层引擎实现的分布式近实时搜索引擎,简称ES,直接翻译为中文为:弹性搜索
  Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库Apache Lucene。(elastic:有弹性的,灵活的)
  Elasticsearch以文档的形式存储数据,通常是JSON格式数据,每个文档拥有键和值,比数据表的行更为灵活       
  Elasticsearch常见的用法是索引大规模的数据,这样可以运行全文搜索和实时数据统计,可以将Elasticsearch当做一个NoSQL的数据存储,其会自动将数据划分为分片,在集群中的服务器上做负载均衡。这使得动态添加和移除服务器变得很容易。分片也可以复制,使得集群具有容错性。                           
  
 
  Lucene
    Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。
 
 
  Elasticsearch与Lecene:
    Elasticsearch使用Java编写,内部使用Lucene做索引与搜索。简单来说,就是对Lucene 做了一层封装,它提供了一套简单一致的 RESTful API 来帮助我们实现存储和检索。
    在Lecene的基础之上,elasticsearch添加了自己的高级功能,从缓存到实时性分析
  
 
  Elasticsearch适用场景
    ①:从海量数据中检索出少量数据
      如商品搜索、视频搜索、音乐搜索、论坛帖子
    ②:对指标进行统计计算
    ③:利用Kibana/Grafana等工具进行可视化分析 
      如日志检索
 
  Elasticsearch不适用场景
    ①:拉取大量原始数据
      ES 是个搜索引擎并不擅长作为数据库使用,适合实时搜索计算得到少量结果,拉取或更新大量原始数据会非常慢
    ②:经常对数据进行UPDATE/DELETE
    ③:作为数据仓库进行永久存储数据
    ④:写入实时性要求非常高(<1s)的场景
 
 
 
 二、安装运行
 
  1、Elasticsearch
    ①:安装Java JRE,并配置JAVA_HOME系统环境变量
    ③:解压
    ④:启动运行

      Run bin/elasticsearch (or bin\elasticsearch.bat on Windows)

    ⑤:访问

      Run curl http://localhost:9200/ (or Invoke-RestMethod http://localhost:9200 with PowerShell)

      出现以下信息表明成功安装:

{
  "name" : "yangyongjiedeiMac.local",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "GIPKGMkiSVOQ25vMW-oLpw",
  "version" : {
    "number" : "7.16.2",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "2b937c44140b6559905130a8650c64dbd0879cfb",
    "build_date" : "2021-12-18T19:42:46.604893745Z",
    "build_snapshot" : false,
    "lucene_version" : "8.10.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

 

  2、Kibana 

    Kibana 是一个开源的分析和可视化平台,Kibana 提供搜索、查看和与存储在 Elasticsearch 索引中的数据进行交互的功能。开发者或运维人员可以轻松地执行高级数据分析,并在各种图表、表格和地图中可视化数据

    ①:下载Kibana https://www.elastic.co/cn/downloads/kibana

    ②:配置Kibana(默认elasticsearch.hosts: ["http://localhost:9200"])

      Open config/kibana.yml in an editor.

      Set elasticsearch.hosts to point at your Elasticsearch instance.

        默认情况下,Kibana 会连接运行在 localhost 上的 Elasticsearch 实例。如果需要连接不同的 Elasticsearch实例,可以修改 kibana.yml 配置文件中的 Elasticsearch URL 配置项并重启 Kibana

        如:elasticsearch.hosts: ["http://localhost:9200"]

    ③:运行

      Run bin/kibana (or bin\kibana.bat on Windows)

    ④:访问

      Point your browser at http://localhost:5601

 

    

        

    

 

 三、Elasticsearch核心概念

  对比关系型数据库:

 关系型数据库 Elasticsearch 
 数据库(database)  索引(indices)
 表(tables)  类型(types)
 行(rows)  文档(documents)
 字段(columns)  fields
 Schema  Mapping
 SQL  DSL

        elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)

    注意:Type是个不合理的设计,ES6.x中一个 Index 中只能有一个 Type,ES7.x开始正式弃用

 

  逻辑设计:

    用于索引和搜索的基本单位是文档,可以将其认为是关系数据库中的一行。

    文档以类型来分组,类型包含若干文档,类似表格包含若干行。

    索引是更大的容器,一个或多个类型存在于同一索引中,即一个索引中包含多个类型。

       当我们索引一篇文档时,可以通过这样的一个顺序找到 它: 索引 ▷ 类型 ▷ 文档ID ,通过这个组合我们就能索引到某个具体的文档。注意 : ID不必是整数,实际上它是个字符串,并没有限制。

   

    文档(Document)

      Index 中的一条数据/记录被称为一份 Document 文档,是一个可被索引(动词)的基础信息单元。文档以JSON格式来表

      Elasticsearch是面向文档的,这意味着索引和搜索数据的最小单位是文档。

      Elasticsearch中文档的几个重要属性:

        ①:一篇文档通常是数据的JSON表示

        ②:它是自我包含的,一篇文档同时包含字段和对应的值,也就是同时包含 key:value

        ③:它可以是层次型的,一个文档中包含子文档

        ④:灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在 elasticsearch 中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段

        ⑤:Elasticsearch中的文档是无模式的,也就是说并非所有的文档都需要拥有相同的字段,它们不受限于同一模式。可以随意添加和忽略字段,但是每个字段的类型确实很重要,因为Elasticsearch保存字段和类型之间的映射和其他设置。

    

    类型(Type)

      类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。类型中对于字段的定义称为映射

      在不同的类型中,最好放入不同结构(模式)的文档。

      ES6.x中一个 Index 中只能有一个 Type,ES7.x开始正式弃用

    索引(Index)

      索引是映射类型的容器。一个Elasticsearch非常像关系型世界中的数据库,是独立的大量文档集合。

      每个索引存储在磁盘上的同组文件中;索引存储了所有映射类型的字段,还有一些设置。

    倒序索引

      Elasticsearch使用的是一种称为倒序索引的结构,底层采用Lecene倒序索引。

      这种结构适用于快速的全文搜索(ES在不扫描所有文档的情况下,就能检索哪些文档包含特定的词条),一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。

      倒序索引存储是每个词,和包含它的文档列表。由于不是根据文档来确定关键词,而是根据关键词来确定包含它的文档,因此称为倒序索引。

    Field/Mapping 字段和映射:

      一份文档中可以有多个字段,和其他非关系型数据库类似,以 k/v 结构的 JSON 格式存储。一个字段对应着一种映射,即数据的类型。多数情况下一个字段的Mapping一旦确定就无法更改

       映射是用于定义ES对索引中字段的存储类型、分词方式和是否存储等信息,就像数据库中的schema,描述了文档可能具有的字段或属性、每个字段的数据类型

      只不过关系型数据库建表时必须指定字段类型,而 ES 对于字段类型可以不指定然后动态对字段类型猜测,也可以在创建索引时具体指定字段的类型。

      对字段类型根据数据格式自动识别的映射称之为动态映射(Dynamic Mapping),我们创建索引时具体定义字段类型的映射称之为静态映射或显示映射(Explicit Mapping)

 

 

  物理设计:

     Elasticsearch在后台把每个索引划分成多个分片,每份分片可以在集群中的不同服务器间迁移。

    通常,应用程序无需关心这些,因为无论Elasticsearch是单台还是多台服务器,应用和Elasticsearch的交互基本保持不变。

 

     分片(Shards)和副本(Replicas)

      分片是为了解决分布式存储大规模数据的问题,将Index中的数据切成若干个分片,存储到不同的Data Node节点上

      Elasticsearch索引创建的时候,默认情况下,每个索引由5个主分片组成,每个主分片又有一个副本分片(副本分片是主分片的完整副本,副本分片用于搜索)。

      副本分片是主分片的拷贝,主分片和其副本分片通常位于不同的节点上。实现高可用,并在一定程度上提高搜索吞吐量。

      主分片和副本分片需要保持数据的同步。数据同步使得副本分片可以服务于搜索请求,并在原有主分片无法访问时自动升级为主分片。

      技术上而言,一份分片是一个目录中的文件,Lecene用这些文件存储索引数据。一份分片是一个Lucene索引,所以一个ElasticSearch索引由多个Lucene索引组成。

      分片也是Elasticsearch将数据从一个节点迁移到另一个节点的最小单位。

      默认情况下,Elasticsearch中的每个索引分配5个主分片和1个副本。这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片(每个主分片有一个副本分片),这样每个索引总共就有10个分片

PUT /myIndex  
{  
   "settings" : {  
      "number_of_shards" : 5,  
      "number_of_replicas" : 1  
   }  
} 

      主分片和对应的副本分片是不会在同一个节点上的,所以副本分片数的最大值是 N-1(其中 N 为节点数)

      分片总结:

      ①:将数据分片是为了提高可处理数据的容量和易于进行水平扩展,为分片做副本是为了提高集群的稳定性和提高并发量

      ②:副本是乘法,越多消耗越大,但也越保险。分片是除法,分片越多,单分片数据就越少也越分散

      ③:副本越多,集群的可用性就越高,但是由于每个分片都相当于一个Lucene的索引文件,会占用一定的文件句柄,内存及CPU。并且分片间的数据同步也会占用一定的网络带宽,所以索引的分片数和副本数也不是越多越好。

 

 

    节点

      一个节点是一个Elasticsearch的实例。在服务器上启动Elasticsearch之后,就拥有了一个节点。

 

    集群

      多个Elasticsearch节点组成一个Elasticsearch集群。

      每一个运行实例称为一个 Node 节点,每一个运行实例既可以在同一机器上(一机多实例),也可以在不同的机器上

      默认情况下,可以连接集群中的任一节点并访问完整的数据集,就好像集群中只有单独的一个节点。

      集群中的节点之间必须保证能够快速的通信。

 

    当索引一篇文档时发生了什么?

      ①:根据文档ID的散列值确定一个主分片(目标分片),接受请求的节点将文档转发到该主分片所在的节点

      ②:然后文档被发送到该主分片的所有副本分片中进行索引(主副分片数据需要及时同步,副本分片服务于搜索请求)

      ③:在所有可用的副本分片中完成文档的索引后,索引命令就会成功返回。

    搜索索引时发生了什么?

      ①:接受请求的节点,将请求转发到一组(一个或多个)包含所有数据的分片(ElasticSearch使用round-robin的轮询机制选择可用的分片,可以是主分片或副本分片,并将请求转发过去)

      ②:聚集一组中分片的结果,然后返回给客户端 

    Elasticsearch中一篇文档的URI:

      http://localhost:9200/index_name/type_name/doc_id

 

 

 四、与Elasticsearch交互

  Elasticsearch提供了多种交互使用方式,包括Java API和RESTful API 。

 

 

五、Elasticsearch数据类型和映射

  文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html#_core_datatypes

  每个字段都有一个字段数据类型或字段类型。此类型指示字段包含的数据类型(例如字符串或布尔值)及其预期用途。例如,您可以将字符串索引到文本和关键字字段。但是,文本字段值会被分析用于全文搜索,而关键字字符串则保留原样用于过滤和排序

常见类型 说明
text 全文搜索字符串,分词
keyword 用于精确字符串匹配(term)和聚合,不分词
date、date_nanos 格式化为日期或数字日期的字符串
byte, short, integer, long 整数类型
float,double,half_float 浮点数类型

  常见的映射:

  • 字符串: text(分词), keyword(不分词)
    • text会对字符串进行字词的拆分;
      • 使用text类型的字段,在索引到ES时,会使用分词器对字符串进行分词处理,将字符串拆分成一个个字词,每个字词作为一个term,可用来关键字匹配和全文搜索。
    • keyword不进行拆分,将整个字符串作为一个长term,只能按照其确切值进行搜索
  • 数值型: long, integer, byte, double, float, half_float, scaled_float
  • 日期: date
  • 布尔: boolean
  • 二进制: binary
  • 范围类型: integer_range, float_range, long_range, double_range, date_range
  • IP 类型: ip
  • 地理位置: geo_point, geo_shape

同时 ES 具有Dynamic Mapping 的特性,即使没有对字段指定映射,会自动猜测该字段的映射,默认映射规则如下:

JSON datatype Elasticsearch datatype
Null 不会映射字段
true or false boolean
浮点型数字 Float float
整型数字 Integer long
JSON对象 Object
数组 数组中第一个非空值的类型
String 如果满足日期类型的格式,映射为日期类型
如果满足数字型的格式,映射为long或者float
如果就是字符串,会映射为一个text类型和一个keyword类型

    

 

 

 

六、为Elasticsearch设置最低安全性

  需启用Elasticsearch安全功能,然后为内置用户创建密码

 

  启用Elasticsearch安全功能

    当您使用基本许可证时,默认禁用 Elasticsearch 安全功能。启用 Elasticsearch 安全功能会启用基本身份验证,以便您可以使用用户名和密码身份验证运行本地集群

    1、在集群中的每个节点上,停止 Kibana 和 Elasticsearch(如果它们正在运行)

    2、在集群中的每个节点上,将xpack.security.enabled设置添加到$ES_PATH_CONF/elasticsearch.yml文件并将值设置为true:xpack.security.enabled: true

    3、如果您的集群只有一个节点,请discovery.type在 $ES_PATH_CONF/elasticsearch.yml文件中添加设置并将值设置为single-node. 此设置可确保您的节点不会无意中连接到可能在您的网络上运行的其他集群

      discovery.type: single-node

 

  为内置用户创建密码

    要与集群通信,您必须为内置用户配置用户名。除非您启用匿名访问,否则所有不包含用户名和密码的请求都会被拒绝

    1、在集群中的每个节点上,启动Elasticsearch

    2、在另一个终端窗口中,通过运行elasticsearch-setup-passwords程序设置内置用户的密码。

      ①:./bin/elasticsearch-setup-passwords interactive

      ②:根据提示输入密码,建议使用字母+数字组合

    3、保存自己设置的密码(为elastic用户设置密码后,您将无法再次运行该elasticsearch-setup-passwords命令)

    4、或者 ./bin/elasticsearch-setup-passwords auto 随机生成密码,并输出到控制台

    密码涉及的用户:elastic,apm_system,kibana,kibana_system,logstash_system,beats_system,remote_monitoring_user

 

  配置Kibana以使用密码连接到Elasticsearch

    启用 Elasticsearch 安全功能后,用户必须使用有效的用户名和密码登录 Kibana。

    您将配置 Kibana 以使用kibana_system您之前创建的内置用户和密码。Kibana 执行一些需要kibana_system用户使用的后台任务

    1、将elasticsearch.username设置添加到KIB_PATH_CONF/kibana.yml 文件并将值设置为kibana_system用户:elasticsearch.username: "kibana_system"

    2、在安装 Kibana 的目录中,运行以下命令来创建 Kibana 密钥库并添加安全设置:

      ①、创建Kibana密钥库:./bin/kibana-keystore create

      ②、将kibana_system用户的密码添加到 Kibana 密钥库:./bin/kibana-keystore add elasticsearch.password

        出现提示时,输入kibana_system用户的密码。

     3、重启Kibana:./bin/kibana

     4、以elastic用户身份登录 Kibana 。使用此超级用户帐户来 管理空间、创建新用户和分配角色。如果您在本地运行 Kibana,请转到http://localhost:5601查看登录页面

 

 

 

七、Elasticsearch快的原因

  1、内存读取

    Elasticsearch是基于Lucene, 而Lucene被设计为可以利用操作系统底层机制来缓存内存数据结构,换句话说Elasticsearch是依赖于操作系统底层的 Filesystem Cache,

    查询时,操作系统会将磁盘文件里的数据自动缓存到 Filesystem Cache 里面去,因此要求Elasticsearch性能足够高,那么就需要服务器的提供的足够内存给Filesystem Cache 覆盖存储的数据

  2、多种索引

    倒序索引

    doc values    

      doc values是列式存储的正排索引,通过docID可以快速读取到该doc的特定字段的值,列式存储存储对于聚合计算有非常高的性能

  3、集群分片

      Elasticsearch可以简单、快速利用多节点服务器形成集群,以此分摊服务器的执行压力。

      此外数据可以进行分片存储,搜索时并发到不同服务器上的主分片进行搜索

 

 

 

 八、Elasticsearch配置

  ①、elasticsearch.yml 中指定集群的名称——这是Elasticserch具体选型所在的主要配置文件

  ②、logging.yml中编辑日志选项——日志配置文件包括log4j的日志选项,Elasticsearch使用log4j来记录日志

  ③、在环境变量或者elasticsearch.sh中调整内存设置——这个文件用于配制Elasticsearch所运行的Java虚拟机

 

 

 

 

附录:

   Elasticsearch官方中文文档:https://www.elastic.co/guide/cn/elasticsearch/guide/2.x/index.html

   Elastic 中国社区官方博客:https://elasticstack.blog.csdn.net/?type=blog

 

 

END.

 
posted @ 2019-12-26 18:23  杨岂  阅读(212)  评论(0编辑  收藏  举报