Elasticsearch
Elasticsearch(简称ES)是一个可分布式的实时搜索和分析引擎,一个建立在全文搜索引擎,一个建立在全文搜索引擎Apache Lucence基础上的搜索引擎,它不仅可以进行全文搜素,还可以进行以下工作:
分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。实时分析的分布式搜索引擎。可以扩展到上百台服务器,处理PB级别的结构化或非及结构化数据提供了rest api的操作接口,开箱即用。
存储单位:
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024MB
1PB=1024TB
1EB=1024PB
1ZB=1024EB
1YB=1024ZB
基本概念:
Elasticsearch是面向文档型数据库,一个条数据在这里就是一个文档
1、索引(index):索引是具有相似特性的文档集合。例如,可以为客户数据提供索引,为产品目录建立另一个索引。索引由名称(必须全部小写)标识,该名称用于在对其中的文档执行索引,搜索,更新和删除操作时引用索引。在单个群集中,你可以定义尽可能多的索引。
2、文档:elasticsearch文档是一个存储在索引中的Json文档。每个文档都有一个类型和对应的id,这是唯一的。如:
{
“_index”:“packtpub”,
"_type:“elk”,
“_id”:“1”,
“_version”:1,
“found”:true,
“_source”:true,
book_name:“learning elk”,
book_author:”鲁迅” //单位是字段
}
}
3、字段(Field)文档内的一个基本单位,键值对形式(book_name:”learning elk”)
4、类型(Type)类型是index下的一个逻辑分类。比如weather这个index里,可以按照城市分组,也可以按照气候类型分组,这种分组就叫做类型。
5、映射(Mapping):映射用于映射文档的每个field及其对应的数据类型,例如字符串,整数,浮点数,双精度数,日期等。
6、分片shard:单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多的数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。
primary shard:主分片
rdplica shard:复制分片
7、分词:把一段文本中的词按一定规则进行切分。
8、主分片(primary shard)与复制分片(replica shard)复制分片通常驻留在一个不同的节点上,而不是主碎片,在故障转移和负载平衡的情况下,可以满足多个请求。
9、集群(Clutser):集群是存储索引数据的节点集合。elasticsearch提供了水平的可伸缩性用以存储集群中的数据。每个集群都由一个集群名称来表示,不同的节点指明集群名称链接在一起。
10、节点(Node):节点是一个单独运行的elasticsearch实例,它属于一个集群。默认情况下。elasticsearch中的每个节点都加入名为“elasticsearch”的集群。每个节点都可以在elasticsearch中使用自己的elasticsearch.yml,他们可以对内存和资源分配有不同的设置。
ES 集群
集群分类:
1、数据节点(Data Node):数据节点索引文档并对索引文档执行搜索,建议添加更多数据的节点,以提高性能或扩展集群。通过在elasticsearch中设置这些属性,可以使节点成为一个数据节点。elasticsearch.yml 配置node.master = flase node.data = true
2、管理节点(Master Node):主节点负责集群的管理。对于大型集群,建议由三个专用的主节点(一个主节点和两个备份节点),它们只作为主节点,不存储索引或执行搜索。在elasticsearch.yml配置声明节点为主节点:node
.matser = true node.data = true
3、路由节点:亦称负载均衡节点(Routing Node or load balancer node)这些节点不扮演主节点或数据节点的角色,但只执行负载平衡或为搜索请求路由,或将文档编入适当的节点。这对于高容量搜索或索引操作非常有用。node.master = false node.data = flase
4、提取节点(ingest节点):可以创建多个预处理管道,用以修改传入文档。
Zendiscovery通信(发现机制):
ES进程会绑定在自己的回环地址上,然后扫描本机的9300-9305号端口,尝试跟其他主机上相同端口的es进程进行通信,然后自动形成一个集群,如果改了监听地址为非回环地址,ES按照配置文件里指定的地址或自动扫描当前网段的其他节点,自动跟着它节点上的ES Node进行通信。
Master选举:
说明:下边的判断框(是否为本地节点),是说master是否为自己,如果master不是自己,则发送加入集群的请求,如果master是本机,等待加入的节点数量达到规定数量足以完成选举,选举完成以后宣布自己是master,发布cluster state。要说明的是,当临时master选举出来的时候是选举master的第一步,master是集群概念,所以要等待其他节点加入进来才算是真正意义的master。
脑裂:
因为网络或其他故障,导致一个集群被划分成了两伙或多方势力。这群伙都有多个node以及一个master,那么原来的集群就出现了多个matser。master主宰了集群状态的维护以及shard的分配,因此如果有多个master,可能会导致数据被破坏。
容错机制
状态 意义
green 所有主分片和从分片都可用
yellow 所有主分片可用,但存在不可用的从分片
red 存在不可用的主分片
宕机瞬间
master node 宕机的一瞬间,该节点的primary shard(主分片)就没有了,此时状态就不是active.status。那么集群中就不是所有的主分片都是active了。
容错步骤一:
master选举,es自动选举出两一个node称为master,承担起master的责任。
容错步骤二:
新master将丢失的主分片的某个复制分片提升为主分片。
此时cluster status(集群状态) 会变成yellow,因为所有的主分片都变成了activ status了,但是少了一个复制分片。
容错步骤三:
重启node,新的master会将缺失的副本都copy一份到该节点。而且该节点会使用之前已有的分片数据,只是同步一下宕机的修改,cluster status(集群状态)变成green。
构建Elasticsearch实验步骤如下:
实验环境:Centos7.3操作系统,实验需要三台虚拟机
实验步骤:
分布式的实时搜索和分析引擎
(1)首先三台虚拟机安装Elasticsearch
三台服务器:
[root@localhost yfr]# systemctl stop firewalld 关闭防火墙
[root@localhost yfr]# setenforce 0 关闭沙盒
[root@localhost yfr]# mkdir -p /es/{data,log} 创建属主目录
[root@localhost yfr]# groupadd es 创建用户组
[root@localhost yfr]# useradd es -g es 创建用户
[root@localhost yfr]# chown -R es:es /es/ 设置属主属组
[root@localhost yfr]# vim /etc/hosts 本地hosts文件添加
192.168.0.10 es1
192.168.0.20 es2
192.168.0.30 es3
进行软限制,限制最大打开文件数量为819200:
[root@localhost yfr]# echo ‘* soft nofile 819200’ >> /etc/security/limits.conf
进行硬限制,限制最大打开文件数量为819200:
[root@localhost yfr]# echo ‘* hard nofile 819200’ >> /etc/security/limits.conf
进行软限制,限制用户可用进程数为2048:
[root@localhost yfr]# echo ‘* soft nproc 2048’ >> /etc/security/limits.conf
进行硬限制,限制用户的可用进程数为4096:
[root@localhost yfr]# echo ‘* hard nproc 4096’ >> /etc/security/limits.conf
[root@localhost yfr]# echo ‘vm.max_map_count=655360’ >> /etc/sysctl.conf 设置最大线程数
[root@localhost yfr]# sysctl -p 加载sysctl的内容
vm.max_map_count = 655360
配置Java环境变量:
[root@localhost yfr]# tar xf jdk-8u201-linux-x64.tar.gz -C /usr/local/ 解压jdk包
[root@localhost yfr]# vim /etc/profile 进入环境变量配置文件
export JAVA_HOME=/usr/local/jdk1.8.0_201/
export JRE_HOME=/usr/local/jdk1.8.0_201/jre
export CLASSPATH=
J
A
V
A
H
O
M
E
/
l
i
b
/
t
o
o
l
s
.
j
a
r
:
JAVA_HOME/lib/tools.jar:
JAVAHOME/lib/tools.jar:JAVA_HOME/lib/dt.jar
export PATH=
J
A
V
A
H
O
M
E
/
b
i
n
:
JAVA_HOME/bin:
JAVAHOME/bin:JRE_HOME/bin:$PATH
[root@localhost yfr]# . /etc/profile 执行环境变量的改变
安装并且配置Elasticearch:
[root@localhost yfr]# tar zxf elasticsearch-6.3.2.tar.gz 解压Elasticearch包
[root@localhost yfr]# mv elasticsearch-6.3.2 /usr/local/es 移动到指定目录
[root@localhost yfr]# chown -R es.es /usr/local/es 设置属主属组
[root@localhost yfr]# vim /usr/local/es/config/elasticsearch.yml 修改配置文件
cluster.name: yunan-cluster 集群名字,17行,去掉注释
node.name: es1 节点名称,23行,去掉注释
node.master: true 节点资格,增加
node.data: true 是否可存放数据,增加
path.data: /es/data 指定数据文件存放目录,35行,去掉注释
path.logs: /es/log 指定日志文件目录,39行,去掉注释
network.host: 192.168.0.10 指定本节点IP,57行,去掉注释
http.port: 9200 ES默认监听端口,61行,去掉注释
transport.tcp.port:9300 集群节点进行通信的端口,增加
discovery.zen.ping.unicast.hosts: [“192.168.0.10:9300”, “192.168.0.20:9300”,“192.168.0.30:9300”] 指定节点范围,71行,去掉注释
discovery.zen.minimum_master_nodes: 2 选举条件,达到最小2个,即可选择master,去掉注释,75行,去掉注释
discovery.zen.ping_timeout: 120s 增加,ping所有的节点,检查是否有es进程,时间长一点,防止脑裂的超时时间
client.transport.ping_timeout: 60s 增加,客户端连接ES服务通信时的超时时间
gateway.recover_after_nodes: 3 节点到达三个开启复制,85行,去掉注释
gateway.recover_after_time: 5m 增加,五分钟后,检测节点,开启数据复制(如果上面一条不满足)
gateway.recover_after_data_nodes: 2 增加,达到两个节点就开始数据复制(如果上面两个条件都不满足),不满足的情况超时。
注意:分别到57行和23行改变名字改变每台机不同的本机节点的IP地址
[root@localhost ~]# su es 切换用户
[es@localhost root]$ /usr/local/es/bin/elasticsearch 启动Elasticsearch
…等待选举出主节点
开启一个终端:
查看群集当前状态信息:
[root@localhost ~]# curl -XGET ‘http://192.168.0.10:9200/_cluster/health?pretty’
{
“cluster_name” : “yunan-cluster”,
“status” : “green”,
“timed_out” : false,
“number_of_nodes” : 3,
“number_of_data_nodes” : 3,
“active_primary_shards” : 0,
“active_shards” : 0,
“relocating_shards” : 0,
“initializing_shards” : 0,
“unassigned_shards” : 0,
“delayed_unassigned_shards” : 0,
“number_of_pending_tasks” : 0,
“number_of_in_flight_fetch” : 0,
“task_max_waiting_in_queue_millis” : 0,
“active_shards_percent_as_number” : 100.0
}
查看当前master节点信息:
[root@localhost ~]# curl -XGET ‘http://192.168.0.10:9200/_cat/master?pretty’
IpInLcqHQMGYbZwZZwzWIw 192.168.0.20 192.168.0.20 es2
查看所有节点信息:
[root@localhost ~]# curl -XGET ‘http://192.168.0.10:9200/_cat/nodes’
192.168.0.10 12 93 18 0.40 0.63 0.66 mdi - es1
192.168.0.30 13 93 9 0.19 0.57 0.59 mdi - es3
192.168.0.20 11 93 12 0.18 0.59 0.65 mdi * es2
(2)创建索引并且增加内容,安装分词器
[root@localhost ~]# curl -XPUT http://192.168.0.10:9200/yunan 创建索引
{“acknowledged”:true,“shards_acknowledged”:true,“index”:“yunan”}
[root@localhost ~]# curl -XPOST “http://192.168.0.10:9200/yunan/fulltext/_mapping” -H ‘Content-Type:application/json’ -d’
{
“properties”:{
“content”:{
“type”:“text”,
“analyzer”:“ik_max_word”,
“search_analyzer”:“ik_max_word”
}
}
}’
[root@localhost ~]# curl -XPOST “http://192.168.0.10:9200/yunan/fulltext/1” -H ‘Content-Type:application/json’ -d’{“content”:“卡路里我的天敌,燃烧我的卡路里”}’
{"_index":“yunan”,"_type":“fulltext”,"_id":“1”,"_version":1,“result”:“created”,"_shards":{“total”:2,“successful”:2,“failed”:0},"_seq_no":0,"_primary_term":1} 添加内容
[root@localhost ~]# curl -XPOST “http://192.168.0.10:9200/yunan/fulltext/1” -H ‘Content-Type:application/json’ -d’ 查看刚刚添加的
{
“query” : {“match”: {“content”:“卡路里”}},
“highlight”: {
“pre_tags” : ["",""],
“post_tags”: [""],
“fields”: {
“content” : {}
}
}
}’
{"_index":“yunan”,"_type":“fulltext”,"_id":“1”,"_version":2,“result”:“updated”,"_shards":{“total”:2,“successful”:2,“failed”:0},"_seq_no":1,"_primary_term":1}
停掉三台服务器
[root@localhost ~]# tar xf node-v10.6.0-linux-x64.tar.gz 解压包
[root@localhost ~]# mv node-v10.6.0-linux-x64 /usr/local/node 移动到指定目录
[root@localhost ~]# vim /etc/profile 修改环境变量配置文件
export NODE_HOME=/usr/local/node
export PATH=
N
O
D
E
H
O
M
E
/
b
i
n
:
NODE_HOME/bin:
NODEHOME/bin:JAVA_HOME/bin:
J
R
E
H
O
M
E
/
b
i
n
:
JRE_HOME/bin:
JREHOME/bin:JRE_HOME=/bin:$PATH
[root@localhost ~]# . /etc/profile 重载环境变量
[root@localhost ~]# unzip elasticsearch-head-master.zip 解压包
[root@localhost ~]# mv elasticsearch-head-master /usr/local/es-head 移动到指定目录
[root@localhost ~]# cd /usr/local/es-head/
使用es-head的代码进行:
[root@localhost es-head]# npm install -g grunt–registry=https://registry.npm.taobao.org
/usr/local/node/bin/grunt -> /usr/local/node/lib/node_modules/grunt/bin/grunt
- grunt@1.0.4
added 97 packages from 63 contributors in 14.851s
[root@localhost es-head]# npm install -g cnpm --registry=https://registry.npm.taobao.org
/usr/local/node/bin/cnpm -> /usr/local/node/lib/node_modules/cnpm/bin/cnpm
- cnpm@6.1.1
added 681 packages from 942 contributors in 20.673s
[root@localhost es-head]# cnpm install
[root@localhost es-head]# vim Gruntfile.js 修改配置文件
connect: {
server: {
options: {
hostname:0.0.0.0,
port: 9100,
base: ‘.’,
keepalive: true
}
}
}
[root@localhost es-head]# vim /usr/local/es/config/elasticsearch.yml 末尾添加
http.cors.enabled: true
http.cors.allow-origin: “*”
再次启动三台ES服务器:
[root@localhost ~]# su es
[es@localhost root]$ /usr/local/es/bin/elasticsearch
…选举中
开启第二个终端:
[root@localhost ~]# cd /usr/local/es-head/
[root@localhost es-head]# . /etc/profile
[root@localhost es-head]# grunt server
浏览器访问,并且验证
其中带有星星的是主节点
Elasticsearch常用命令:
1、查看所有可查看项:
[root@localhost ~]# curl http://192.168.64.3:9200/_cat
2、显示详细信息:
[root@localhost ~]# curl http://192.168.64.3:9200/_cat/master?v
id host ip node
dXu8pHDvSNOO-o1g6kVPiw 192.168.64.3 192.168.64.3 es1
3、输出可以显示的列?v:
[root@localhost ~]# curl http://192.168.64.3:9200/_cat/master?help
id | | node id
host | h | host name
ip | | ip address
node | n | node name
4、指定输出的列?h:
[root@localhost ~]# curl http://192.168.64.3:9200/_cat/master?h=ip,node
192.168.64.3 es1
5、查看所有索引:
[root@localhost ~]# curl http://192.168.64.3:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open yunan _d59yemZQc2lgPUDArdZJg 5 1 1 0 8.3kb 4.1kb
6、创建索引:
[root@localhost ~]# curl -XPUT http://192.168.1.139:9200/kgctest1?pretty
{
“acknowledged” : true,
“shards_acknowledged” : true,
“index” : “yunantest1”
}
7、关闭索引:
[root@localhost ~]# curl -XPOST http://192.168.1.139:9200/yunantest1/_close?pretty
{
“acknowledged” : true
}
8、开启索引:
[root@localhost ~]# curl -XPOST http://192.168.1.139:9200/yunantest1/_open?pretty
{
“acknowledged” : true,
“shards_acknowledged” : true
}
9、删除索引:
[root@localhost ~]# curl -XDELETE http://192.168.1.139:9200/yunantest1?pretty
{
“acknowledged” : true
}
10、插入数据:
[root@localhost ~]# curl -XPUT http://192.168.1.139:9200/kgctest1/fulltext/1?pretty -H ‘Content-Type: application/json’ -d’
{
“name”: “tiechuiguniang”
}’
{
“_index” : “kgctest1”,
“_type” : “fulltext”,
“_id” : “1”,
“_version” : 1,
“result” : “created”,
“_shards” : {
“total” : 2,
“successful” : 2,
“failed” : 0
},
“_seq_no” : 0,
“_primary_term” : 1
}
11、取出数据:
[root@localhost ~]# curl -XGET ‘http://192.168.1.139:9200/kgctest1/fulltext/1?pretty’
{
“_index” : “kgctest1”,
“_type” : “fulltext”,
“_id” : “1”,
“_version” : 1,
“found” : true,
“_source” : {
“name” : “tiechuiguniang”
}
}
12、 更新文档(数据):
[root@localhost ~]# curl -XPOST ‘http://192.168.1.139:9200/kgctest1/fulltext/1_update?pretty’ -H ‘Content-Type: application/json’ -d’
{
“doc”:{“name”:“wangtiechui”}
}’
{
“_index” : “kgctest1”,
“_type” : “fulltext”,
“_id” : “1_update”,
“_version” : 1,
“result” : “created”,
“_shards” : {
“total” : 2,
“successful” : 2,
“failed” : 0
},
“_seq_no” : 0,
“_primary_term” : 1
}
13、删除文档:
[root@localhost ~]# curl -XDELETE ‘http://192.168.1.139:9200/kgctest1/fulltext/1?pretty’
{
“_index” : “kgctest1”,
“_type” : “fulltext”,
“_id” : “1”,
“_version” : 2,
“result” : “deleted”,
“_shards” : {
“total” : 2,
“successful” : 2,
“failed” : 0
},
“_seq_no” : 1,
“_primary_term” : 1
}
14、查看莫格索引下的所有文档:
[root@localhost ~]# curl -XPOST ‘http://192.168.1.139:9200/kgctest1/fulltext/_search?pretty’ -H ‘Content-Type: application/json’ -d’
{
“query”: {“match_all”:{}}
}’
{
“took” : 748,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 1.0,
“hits” : [
{
“_index” : “kgctest1”,
“_type” : “fulltext”,
“_id” : “1_update”,
“_score” : 1.0,
“_source” : {
“doc” : {
“name” : “wangtiechui”
}
}
}
]
}
}
15、查询符合条件的文档:
[root@localhost ~]# curl -XPOST ‘http://192.168.1.139:9200/kgctest1/fulltext/_search?pretty’ -H ‘Content-Type: application/json’ -d’
{
“query”: {“match”:{“name”:“wangtiechui”}}
}’
{
“took” : 152,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 0,
“max_score” : null,
“hits” : [ ]
}
}
16、清除内存中的缓存clear:
[root@localhost ~]# curl -XPOST ‘http://192.168.1.139:9200/kgctest1/_cache/clear?pretty’ -H ‘Content-Type: application/json’
{
“_shards” : {
“total” : 10,
“successful” : 10,
“failed” : 0
}
}
17、flush(强制刷新数据到磁盘):
[root@localhost ~]# curl -XPOST ‘http://192.168.1.139:9200/kgctest1/_flush?pretty’ -H ‘Content-Type: application/json’
{
“_shards” : {
“total” : 10,
“successful” : 10,
“failed” : 0
}
}
refresh:立即实现数据从内存到磁盘的缓存过程,从而使文档可以被立即搜索到
[root@localhost ~]# curl -XPOST ‘http://192.168.1.139:9200/kgctest1/_refresh?pretty’ -H ‘Content-Type: application/json’
{
“_shards” : {
“total” : 10,
“successful” : 10,
“failed” : 0
}
}
FLUSH和REFRESH的区别:
当一个文档进入ES的初期, 文档是被存储到内存里的,默认经过1s之后, 会被写入文件系统缓存,这样该文档就可以被搜索到了,注意,此时该索引数据被没有最终写入到磁盘上。如果你对这1s的时间间隔还不满意, 调用_refresh就可以立即实现内存->文件系统缓存, 从而使文档可以立即被搜索到。 ES为了数据的安全, 在接受写入的文档的时候, 在写入内存buffer的同时, 会写一份translog日志,从而在出现程序故障/磁盘异常时, 保证数据的完整和安全。flush会触发lucene commit,并清空translog日志文件。 translog的flush是ES在后台自动执行的,默认情况下ES每隔5s会去检测要不要flush translog,默认条件是:每 30 分钟主动进行一次 flush,或者当 translog 文件大小大于 512MB主动进行一次 flush