elasticsearch入门(一)

前言

elasticSearch入门-ES入门 - wangssd - 博客园

Elasticsearch倒排索引结构 - 废物大师兄 - 博客园

倒排索引为什么叫倒排(转自知乎)

渣翻译的例子之一。

英文原名Inverted index,大概因为 Invert 有颠倒的意思,就被翻译成了倒排。

但是倒排这个名称很容易让人理解为从A-Z颠倒成Z-A。

个人认为翻译成转置索引可能比较合适。

一个未经处理的数据库中,一般是以文档ID作为索引,以文档内容作为记录。

而Inverted index 指的是将单词或记录作为索引,将文档ID作为记录,这样便可以方便地通过单词或记录查找到其所在的文档。


作者:知乎用户
链接:https://www.zhihu.com/question/23202010/answer/23901671
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一、了解elasticsearch

1.1 elasticsearch简介

        Elasticsearch 是由Apache开源的一个兼有搜索引擎和NoSQL数据库功能的系统,其特点主要如下:

  • 基于Java/Lucene构建,支持全文搜索、结构化搜索
  • 低延迟,支持实时搜索
  • 分布式部署,可横向集群扩展
  • 支持百万级数据
  • 支持多条件复杂查询,如聚合查询
  • 高可用性,数据可以进行切片备份
  • 支持Restful风格的api调用

1.2 elasticsearch应用场景

        ES作为全文检索的搜索引擎,在以下几个方面都存在着相应的应用:

  • 监控。针对日志类数据进行存储、分析、可视化。针对日志数据,ES给出了ELK的解决方案。其中logstash采集日志,ES进行复杂的数据分析,kibana进行可视化展示。
  • 电商网站。用于商品信息检索
  • Json文档数据库。用于存放json格式的文档
  • 维基百科。提供全文搜索并高亮关键字

1.3 elasticsearch核心概念

下面分别介绍ES中的核心概念词:

  • 集群(Cluster): 包含一个或多个具有相同 cluster.name 的节点。
  • 节点(node): 是一个逻辑上独立的服务,可以存储数据,并参与集群的索引和搜索功能, 每个节点都有其唯一的名字,集群通过节点名称进行管理和通信。节点可以充当一个或多个角色。ES集群中的每个节点都会存储集群状态,知道索引内各分片所在的节点位置。
  • 主节点(master node):主要负责集群方面的操作,比如节点的加入和退出、索引的创建和删除、分片被分配到哪个节点、节点状态监测。
  • 数据节点(Data Node):存储文档数据的节点,执行文档数据的查询和写入等操作。
  • 协调节点(Coordinate Node):客户端请求可以发送到集群的任何节点,集群中的每个节点都知道所有文档的位置。接收到客户端请求的节点自动变为协调节点,进行请求的转发,并整合数据返回给客户端。比如创建索引的请求,就转发到主节点。
  •  映射(Mapping): mapping是对索引库中的索引字段及其数据类型进行定义,类似于关系型数据库中的表结构。ES默认动态创建索引和索引类型的mapping,这就像是关系型数据库中无需定义表结构,更不用指定字段的数据类型。也可以手动指定mapping类型。mapping机制可以自动检测数据的结构和类型,创建索引并使数据可搜索。
  • 分片(shard):索引数据量很大,超过硬件存放单个文件的限制,就会影响查询请求的速度,Es引入了分片技术。一个分片本身就是一个完成的搜索引擎,文档存储在分片中,而分片会被分配到集群中的各个节点中,随着集群的扩大和缩小,ES会自动的将分片在节点之间进行迁移,以保证集群能保持平衡。一个索引中含有shard的数量,默认值为5,在索引创建后这个值是不能被更改的。
  • 副本(replica):切片(shard)的冗余备份,每个切片默认的副本数为1。副本数可以随时进行调整。
  • 索引(Index): 索引与关系型数据库实例(Database)相当。索引只是一个逻辑命名空间。ES可以把索引数据存放到服务器中,也可以sharding(分片)后存储到多台服务器上。每个索引有一个或多个分片,每个分片可以有多个副本。
  • 文档类型(Type):相当于数据库中的table概念。每个文档在ElasticSearch中都必须设定它的类型。文档类型使得同一个索引中在存储结构不同文档时,只需要依据文档类型就可以找到对应的参数映射(Mapping)信息,方便文档的存取。
  • 文档(Document) :相当于数据库中的row, 是可以被索引的基本单位。其可以理解为关系型数据库中表的一行数据记录。每个文档由多个字段(field)组成,区别于关系型数据库的是,ES是一个非结构化的数据库,每个文档可以有不同的字段,并且有一个唯一标识。

ES和关系型数据库概念对比如下: 

ES

关系型数据库

索引(Index)

数据库(DataBase)

类型(Type)

表(Table)

映射(mapping)

表结构(Schema)

文档(Document)

行(Row)

字段(Field)

列(Column)

反向索引

正向索引

DSL查询

SQL查询

1.4 ES架构 

1.4.1整体架构

下面将由下到上的对ES整体架构图中的各个部分进行介绍:

  • 最底层的Gateway部分是ES的数据持久化,ES中的数据可以存储在本地,也可以通过分片的形式进行集群存储,还可以使用hadoop的hdfs分布式文件系统和亚马逊的s3来进行分布式存储。
  • Distributed Lucence Directory:顾名思义,指的是每个索引下切片的Lucence目录
  • ES中间的三个模块分别为索引模块、搜索模块、映射模块,这三个模块构成了ES的整个工作流程。
  • Discovery:发现,指的是集群的发现机制。当集群中有节点进入和离开,会对一个分片进行重新的分片。发现机制通过zen组件的形式或通过插件EC2来进行实现。
  • Scripting:顾名思义,指的是脚本。ES支持的脚本语言包括mvel、js、python、etc等
  • 3rd Plugins:代表第三方插件
  • Transport:表示集群间的信息交互,传输协议包括Thrift、Memcached、Http等
  • JMX:监控
  • Restful style API:Restful风格的API操作
  • Java(Netty):ES的编程框架

 1.4.2集群架构

        集群架构图主要展示了3个节点组成的集群。其中P0、P1、P2表示一个索引的三个切片,R0、R1、R2表示上述三个切片对应的副本,可以看到每个切片和其对应的副本都存储在不同的节点上,这样保证了当其中某一个节点挂掉后,索引的数据不会丢失,仍可以从切片的副本中进行读取,保证整个系统的高可用性。通过每个客户端都能通过ES集群中的任一节点来查询数据。 

1.5 ES原理

1.5.1 Lucence存储和检索

        这部分主要对Lucence的存储和查询过程进行简要的描述。针对Lucence的存储和查询过程如下图所示:

存储过程:

  1. 存储文档经过词法分析得到一系列的词(Term)
  2. 通过一系列词来创建形成词典和反向索引表
  3. 将索引进行存储并写入硬盘。

查询过程:

  1. 用户输入查询语句。
  2. 对查询语句经过词法分析得到一系列词(Term) 。
  3. 通过语法分析得到一个查询树。
  4. 通过索引存储将索引读入到内存。
  5. 利用查询树搜索索引,从而得到每个词(Term) 的文档链表,对文档链表进行交、差、并得到结果文档。
  6. 将搜索到的结果文档对查询的相关性进行排序。
  7. 返回查询结果给用户。

1.5.2 ES写数据

        ES写数据包含两种情况,分别为写入一个新的文档和在原有文档的基础上进行数据的追加(覆盖原有的文档)。两者基本上没有什么区别,后者是把原来的文档进行删除,再重新写入。

ES写数据流程:

  1. 客户端选择一个ES节点发送写请求,ES节点接收请求变为协调节点。
  2. 协调节点判断写请求中如果没有指定文档id,则自动生成一个doc_id。协调节点对doc_id进行哈希取值,判断出文档应存储在哪个切片中。协调节点找到存储切片的对应节点位置,将请求转发给对应的node节点。
  3. Node节点的primary shard处理请求,并将数据同步到replica shard
  4. 协调节点发现所有的primary shard和所有的replica shard都处理完之后,就返回结果给客户端。

ES写数据底层原理:

  1. 数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到操作系统缓存(os cache),生成新的segment。(os cache 中存储的数据能被搜索到)
  2. 写入 os cache 中的translog数据,默认每隔 5 秒刷一次到磁盘中去,如果translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。

 1.5.3 ES读数据

        ES读数据是通过doc_id来进行查询,先根据doc_id判断出文档存储在哪个切片上,再从切片上把数据读取过来。

ES读数据流程:

  1. 客户端给任意一个节点发送请求,该节点变为协调节点
  2. 协调节点根据doc_id,进行哈希取值,判断出文档存储在哪个切片上。
  3. 协调节点将请求转发到对应的节点上,然后使用随机轮询算法(round-robin),在切片和副本切片中随机选择一个,以使读请求负载均衡
  4. 接收请求的节点返回文档数据给协调节点,协调节点再返回数据给客户端。

1.5.4 ES检索关键词

ES检索关键词流程:

ES检索关键词是ES最常使用的做法,通过关键词,将包含关键词的文档全部搜索出来。

  1. 客户端向任意一个节点发送请求,该节点变为协调节点
  2.  协调节点将搜索请求转到所有的shard上
  3. 每个shard将自身的检索结果(搜索到的doc_id和分数),返回给协调节点。
  4. 协调节点根据检索结果进行相关性排序,产出最终的结果。再把doc_id发送给各个节点,拉取文档数据,最终返回给客户端。

1.5.5 ES删数据

删除数据底层原理:

删除操作,是在commit 的时候会生成一个.del文件,里面将doc标识为deleted状态,搜索的时候根据.del文件就知道这个 doc 是否被删除了。

二、elasticsearch的搭建

2.1 安装

安装配置:
  • 新版本要求至少jdk1.8以上。
  • 支持tarziprpm等多种安装方式。
    windows下开发建议使用ZIP安装方式。
  • 支持docker方式安装(详细参见:https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html

 下载ES:Elasticsearch 6.2.1:https://www.elastic.co/downloads/past-releases

解压elasticsearch-6.2.1.zip:

  • bin:脚本目录,包括:启动、停止等可执行脚本
  • confifig:配置文件目录
  • data:索引目录,存放索引文件的地方
  • logs:日志目录
  • modules:模块目录,包括了es的功能模块
  • plugins :插件目录,es支持插件机制

2.2 配置文件 

2.2.1 三个配置文件

ES 的配置文件的地址根据安装形式的不同而不同:
  • 使用ziptar安装,配置文件的地址在安装目录的confifig下。
  • 使用RPM安装,配置文件在/etc/elasticsearch下。
  • 使用MSI安装,配置文件的地址在安装目录的confifig下,并且会自动将confifig目录地址写入环境变量 ES_PATH_CONF。
本教程使用的 zip 包安装,配置文件在 ES 安装目录的 confifig 下。
配置文件如下:
  • elasticsearch.yml 用于配置Elasticsearch运行参数
  • jvm.options 用于配置Elasticsearch JVM设置
  • log4j2.properties用于配置Elasticsearch日志

2.2.2 elasticsearch.yml

配置格式是 YAML ,可以采用如下两种方式:
  • 方式1:层次方式
path: data: /var/lib/elasticsearch
logs: /var/log/elasticsearch
  • 方式2:属性方式
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
本项目采用方式 2 ,例子如下:
cluster.name: xuecheng 
node.name: xc_node_1 
network.host: 0.0.0.0 
http.port: 9200 
transport.tcp.port: 9300 
node.master: true node.data: true 
#discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301", "0.0.0.0:9302"] discovery.zen.minimum_master_nodes: 1
 
bootstrap.memory_lock: false 
node.max_local_storage_nodes: 1 
path.data: D:\ElasticSearch\elasticsearch‐6.2.1\data 
path.logs: D:\ElasticSearch\elasticsearch‐6.2.1\logs 
http.cors.enabled: true 
http.cors.allow‐origin: /.*/
注意 path.data path.logs 路径配置正确。
常用的配置项如下:
  • cluster.name:
    配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称。
  • node.name:
    节点名,通常一台物理服务器就是一个节点,es会默认随机指定一个名字,建议指定一个有意义的名称,方便管 理一个或多个节点组成一个cluster集群,集群是一个逻辑的概念,节点是物理概念,后边章节会详细介绍。
  • path.conf:
    设置配置文件的存储路径,tarzip包安装默认在es根目录下的confifig文件夹,rpm安装默认在/etc/

elasticsearch path.data:
设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径, 用逗号隔开。

path.logs:
设置日志文件的存储路径,默认是es根目录下的logs文件夹

  • path.plugins:
    设置插件的存放路径,默认是es根目录下的plugins文件夹
  • bootstrap.memory_lock:true
    设置为 true 可以锁住 ES 使用的内存,避免内存与 swap 分区交换数据。
  • network.host:
    设置绑定主机的 ip 地址,设置为 0.0.0.0 表示绑定任何 ip ,允许外网访问,生产环境建议设置为具体 的ip
  • http.port: 9200
    设置对外服务的 http 端口,默认为 9200
  • transport.tcp.port: 9300
    集群结点之间通信端口
  • node.master:
    指定该节点是否有资格被选举成为 master 结点,默认是 true ,如果原来的 master 宕机会重新选举新的master。
  • node.data: 指定该节点是否存储索引数据,默认为true 
  • discovery.zen.ping.unicast.hosts: ["host1:port", "host2:port", "..."]
    设置集群中 master 节点的初始列表。
  • discovery.zen.ping.timeout: 3s
    设置 ES 自动发现节点连接超时的时间,默认为 3 秒,如果网络延迟高可设置
  • discovery.zen.minimum_master_nodes:
    主结点数量的最少值 , 此值的公式为:
    (master_eligible_nodes / 2) + 1 ,比如:有 3 个符合要求的主结点,那么这
    里要设置为 2
  • node.max_local_storage_nodes: 
    单机允许的最大存储结点数,通常单机启动一个结点建议设置为1,开发环境如果单机启动多个节点可设置大于1.

2.2.3 jvm.options

设置最小及最大的 JVM 堆内存大小:
jvm.options 中设置 -Xms -Xmx
  • 两个值设置为相等
  • 将 Xmx 设置为不超过物理内存的一半

2.2.4 log4j2.properties

日志文件设置, ES 使用 log4j ,注意日志级别的配置。

2.2.5 系统配置

linux 上根据系统资源情况,可将每个进程最多允许打开的文件数设置大些。
su limit -n 查询当前文件数
使用命令设置 limit:
先切换到 root ,设置完成再切回 elasticsearch 用户。
sudo su
ulimit ‐n 65536 
su elasticsearch
也可通过下边的方式修改文件进行持久设置:
/etc/security/limits.conf
将下边的行加入此文件:
elasticsearch ‐ nofile 65536

2.3.我的集群配置

我在window系统本地采用了集群的方式。下面贴上我的配置:

es1:elasticsearch.yml:

#集群名称,保证唯一
cluster.name: my-elasticsearch
#节点名称,必须不一样
node.name: node-1
#必须为本机的IP地址
network.host: 127.0.0.1
#服务端口号,在同一机器下必须不一样
http.port: 9201
#集群间通信端口号,在同一机器下必须不一样
transport.tcp.port: 9301
#设置集群自动发现机器IP集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
#是否支持跨域,默认为false
http.cors.enabled: true
#当设置允许跨域,默认为*,表示支持所有域名
http.cors.allow-origin: "*"

es2:elasticsearch.yml:

#集群名称,保证唯一
cluster.name: my-elasticsearch
#节点名称,必须不一样
node.name: node-2
#必须为本机的IP地址
network.host: 127.0.0.1
#服务端口号,在同一机器下必须不一样
http.port: 9202
#集群间通信端口号,在同一机器下必须不一样
transport.tcp.port: 9302
#设置集群自动发现机器IP集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
#是否支持跨域,默认为false
http.cors.enabled: true
#当设置允许跨域,默认为*,表示支持所有域名
http.cors.allow-origin: "*"

es3:elasticsearch.yml:

#集群名称,保证唯一
cluster.name: my-elasticsearch
#节点名称,必须不一样
node.name: node-3
#必须为本机的IP地址
network.host: 127.0.0.1
#服务端口号,在同一机器下必须不一样
http.port: 9203
#集群间通信端口号,在同一机器下必须不一样
transport.tcp.port: 9303
#设置集群自动发现机器IP集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
#是否支持跨域,默认为false
http.cors.enabled: true
#当设置允许跨域,默认为*,表示支持所有域名
http.cors.allow-origin: "*"

2.3 启动ES(集群)

进入集群每个节点的 bin 目录,在 cmd 下运行: elasticsearch.bat

浏览器输入:http://localhost:9201/ 

显示结果如下(配置不同内容则不同)说明 ES 启动成功:
{
  "name" : "node-1",
  "cluster_name" : "my-elasticsearch",
  "cluster_uuid" : "U08xs9UMSHqmxzWmFD04Vg",
  "version" : {
    "number" : "6.5.1",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "8c58350",
    "build_date" : "2018-11-16T02:22:42.182257Z",
    "build_snapshot" : false,
    "lucene_version" : "7.5.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

2.4 head插件安装

head 插件是 ES 的一个可视化管理插件,用来监视 ES 的状态,并通过 head 客户端和 ES 服务进行交互,比如创建映射、创建索引等,head 的项目地址在 https://github.com/mobz/elasticsearch-head
ES6.0 开始, head 插件支持使得 node.js 运行。
1 、安装 node.js
2 、下载 head 并运行
git clone git://github.com/mobz/elasticsearch-head.git cd elasticsearch-head npm install npm run start open
HTTP ://本地主机: 9100 /
3 、运行

 打开浏览器调试工具发现报错:

Origin null is not allowed by Access-Control-Allow-Origin.

原因是: head 插件作为客户端要连接 ES 服务(localhost:9200),此时存在跨域问题, elasticsearch 默认不允许跨 域访问。
解决方案:
设置 elasticsearch 允许跨域访问。
confifig/elasticsearch.yml 后面增加以下参数:
# 开启 cors 跨域访问支持,默认为 false http.cors.enabled: true # 跨域访问允许的域名地址,(允许所有域名 ) 以上使 用正则 http.cors.allow-origin: /.*/
注意:将 confifig/elasticsearch.yml 另存为 utf-8 编码格式。
成功连接 ES:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值