Elasticsearch使用说明
文章目录
一、基本概念
1> 集群和节点
一个es集群是由一个或多和es节点组成的集合
每一个集群都有一个名字, 如之前的wali
每个节点都有自己的名字, 如之前的master, slave1, slave2
节点是可以存储数据, 参与索引数据等的独立服务
2> 索引(类似于数据库里面的database)
索引是含有相同属性的文档集合
索引在es中是通过一个名字来识别的, 必须是英文字母小写, 且不含中划线
3> 类型(相当于sql中的table)
一个索引可以定义一个或多个类型, 文档必须属于一个类型
4> 文档(相当于sql中的一行记录)
文档是可以被索引的基本数据单位
5> 分片
每个索引都有多个分片, 每个分片都是一个luncene索引
分片的好处: 分摊索引的搜索压力, 分片还支持水平的拓展和拆分以及分布式的操作, 可以提高搜索和其他处理的效率
6> 备份
拷贝一个分片就完成了分片的备份
备份的好处: 当主分片失败或者挂掉, 备份就可以代替分片进行操作, 进而提高了es的可用性, 备份的分片还可以进行搜索操作, 以分摊搜索的压力.
ES在创建索引时, 默认创建5个分片, 一份备份, 可以修改, 分片的数量只能在创建索引的时候指定, 索引创建后就不能修改分片的数量了, 而备份是可以动态修改的
1.1 ES的基本用法
ES以RESTFul风格来命名API的, 其API的基本格式如下
http://:/<索引>/<类型>/<文档id>
ES的动作是以http方法来决定的: 常用的http方法: GET/PUT/POST/DELETE
Eg1, 创建索引, 结合head插件创建索引的实例
返回”概览”查看创建情况
创建索引分为: 结构化创建与非结构化创建
查看索引是否是结构化的方法
Mappings是结构化的一个关键词, 其后内容是空的, 说明这个索引是一个非结构化的索引
创建结构化索引的方法
点击head插件的”复合查询”
验证json后, 提交请求,
返回head插件”概览查看”
Head插件中编写json发送请求比较复杂, 可以使用postman或者是fiddler等工具进行请求的发送
请求数据的json格式
{
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 1
},
“mappings”: {
“man”: {
“properties”: {
“name”: {
“type”: “text”
},
“country”: {
“type”: “keyword”
},
“age”: {
“type”: “integer”
},
“date”: {
“type”: “date”,
“format”: “yyyy-MM-dd HH:mm:ss||yyyy:MM:dd||epoch_millis”
}
}
},
“woman”: {}
}
}
1.1.1、 数据插入
文档id, 唯一索引值, 指向文档数据
1.1.1.1 指定文档id插入
使用http中的put方法,
插入时输入的ip地址, 如http://192.168.253.129:9200/people/man/1
请求参数依次为:索引名称/类型名称/文档id
请求参数
{
“name”: “瓦力”,
“country”: “China”,
“age”: 30,
“date”: “1987-03-07 12:12:12”
}
Head插件中”数据浏览”
1.1.1.2 自动产生文档id插入
使用http中的post方法,
插入时输入的ip地址, 如http://192.168.253.129:9200/people/man
请求参数
{
“name”: “超重瓦力”,
“country”: “China”,
“age”: 40,
“date”: “1977-03-07 12:12:12”
}
响应结果
1.1.2、 修改文档数据
1.1.2.1 直接修改文档
http方法: post方法
请求地址: http://192.168.253.129:9200/people/man/1/_update
关键词: _update, doc
请求参数
{
“doc”: {
“name”: “谁是瓦力”
}
}
“doc”为关键字, 要修改的文档放在doc中, 实例修改了type为people索引下man中id为1 的name属性
返回的结果
可以在head插件中”数据浏览”中验证修改结果
1.1.2.2 脚本修改文档
通过脚本修改的api格式与直接修改的是一致的
http方法: post方法
请求地址: http://192.168.253.129:9200/people/man/1/_update
请求参数
{
“script”: {
“lang”: “painless”,
“inline”: “ctx._source.age += 30”
}
}
关键字”script”: 标志以脚本的方式修改文档
“lang”: 表示以何种脚本语言进行修改, “painless”表示以es内置的脚本语言进行修改. 此外es还支持多种脚本语言, 如Python, js等等
“inline”:指定脚本内容 “ctx”代表es上下文, _source 代表文档
可以在head插件中”数据浏览”检查修改数据
此外还有其他的参数设置方式, 例如将参数放到外面
{
“script”: {
“lang”: “painless”,
“inline”: “ctx._source.name = params.name; ctx._source.age = params.age”,
“params”: {
“age”: 30,
“name”: “谁是瓦力”
}
}
}
1.2.1.3、删除
1.1.3.1 删除文档
http方法: delete
请求路径http://192.168.253.129:9200/people/man/1
1.1.3.2 删除索引
\1. 可以通过head插件进行删除
\2. 通过api删除
Http方法: delete
链接地址: http://192.168.253.129:9200/book
分类: ElasticSearch
二、ES为什么要实现集群
在单台ES服务器节点上,随着业务量的发展索引文件慢慢增多,会影响到效率和内存存储问题等。
如果使用ES集群,会将单台服务器节点的索引文件使用分片技术,分布式的存放在多个不同的物理机器上,从而可以实现高可用、容错性等。
2.1、什么是分片技术
将数据拆分成多台节点进行存放。
2.2、ES是如何解决高并发
ES是一个分布式全文检索框架,隐藏了复杂的处理机制,内部使用 分片机制、集群发现、分片负载均衡请求路由。
Shards 分片:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
Replicas分片:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
es核心存放的是索引。
2.3、ES集群核心原理分析
1、每个索引会被分成多个分片shards进行存储,默认创建索引是分配5个分片进行存储,每个分片都会分布式部署在多个不同的节点上进行部署,该分片成为primary shards 主分片。
查看索引分片信息
http://192.168.0.110:9200/myindex/_settings
结果为:
{
"myindex":{
"settings":{
"index":{
"creation_date":"1559964953858",
"number_of_shards":"5", //主分片
"number_of_replicas":"1", //副分片
"uuid":"PPLrlfo6Re2z6KMrVfaMWg",
"version":{
"created":"6040399"
},
"provided_name":"myindex"
}
}
}
}
在ES 中每一个主的分片都有一个对应的副分片,这里总共由10分片。
注意:索引的主分片数量定义好后,不能被修改。主分片数量一旦定义好之后就不能修改,但是副分片的数量是可以修改的。
2、每一个主分片为了实现高可用,都会有自己对应的备分片,主分片对应的备分片不能存放同一台服务器上,主分片可以和其他备分片存放在同一个node节点上。
单台 ES 服务器中是没有副分片的。
2.4、documnet routing(数据路由)
当客户端发起创建document的时候,es需要确定这个document放在该index哪个shard上。这个过程就是数据路由。
路由算法:shard = hash(routing) % number_of_primary_shards
如果number_of_primary_shards在查询的时候取余发生的变化,无法获取到该数据
2.5、ES是相关名词
Cluster:代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。
Shards:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。 replicas:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
Recovery:代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
2.6、ES集群环境搭建
服务集群配置
修改配置文件
目录:/usr/local/es/elasticsearch-6.4.3/config
vi elasticsearch.yml
cluster.name: myes ###保证三台服务器节点集群名称相同
node.name: node-1 #### 每个节点名称不一样 其他两台为node-1 ,node-2
network.host: 192.168.212.110 #### 实际服务器ip地址
discovery.zen.ping.unicast.hosts: [“192.168.0.105”, “192.168.0.108”,“192.168.212.110”]##多个服务集群ip
discovery.zen.minimum_master_nodes: 1
关闭防火墙 systemctl stop firewalld.service
默认底层开启9300 集群
验证集群****效果
http://192.168.0.110:9200/_cat/nodes?pretty
注意克隆data文件会导致数据不同步
报该错误解决办法
failed to send join request to master
因为克隆导致data文件也克隆呢,直接清除每台服务器data文件,data目录:/usr/local/es/elasticsearch-6.4.3/data 。
效果如下,第一张图是添加索引,第二张是查询索引。注意它们的 ip 不一致,这样说明集群环境搭建成功了。
2.7、重点:
文档:用来存储每个类型的数据
索引:用来存储数据的地方
分片:把各种 [索引] 存储在分片上,分片储存在物理磁盘上,每一个分片就是一个lucene的实例, 有主分片和副分片之分
主分片/副分片:起初,elasticsearch服务运行之后,通常第一步把数据存到主分片上,每一个主分片可以复制成一个或者多个副分片
节点:一个节点 包含多个分片,这些分片可以是手动指定放到哪个节点,或者 elastic自动分配到节点中,每运行一个elsaticsearch的服务,就相当于一个节点
集群:一个集群包含多个节点,把所有不同的服务器上或者同个服务器上 运行的所有elsaticsearch服务的节点集中一块 对外提供服务。
按顺序来说:集群 > 节点 > 分片 > 索引
2.8、意义:
elasticsearch天生是一个分布式的,一个节点换了,可自动选择主节点,自动复制主分片数据 备份
数据分析-如聚合搜索(如分组group by)
关键词高亮
全文搜索
分词查询
使搜索更加简单
三、集群搭建,集群控制(个人采用方案)
系统开启一些配置
The vm.max_map_count
setting should be set permanently in /etc/sysctl.conf:
$ grep vm.max_map_count /etc/sysctl.conf
vm.max_map_count=262144
docker-compose搭建elasticsearch集群,同时部署Kibana,elasticsearch-head
docker-compose.yml 文件配置如下
version: '3'
networks:
esnet:
driver: bridge
services:
es01:
image: elasticsearch:7.2.0
container_name: es1
restart: always
environment:
- TZ="Asia/Shanghai"
- cluster.name=docker-cluster
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- node.name=node0
- node.master=true
- node.data=true
- bootstrap.memory_lock=true
- search.max_buckets=100000000
- http.cors.enabled=true
- http.cors.allow-origin=*
- cluster.initial_master_nodes=node0
- "discovery.zen.ping.unicast.hosts=es01,es02,es03"
- "discovery.zen.minimum_master_nodes=2"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./es010086/data:/usr/share/elasticsearch/data
- ./es0100086/logs:/usr/share/elasticsearch/logs
ports:
- 9200:9200
networks:
- esnet
es02:
image: elasticsearch:7.2.0
container_name: es2
restart: always
environment:
- TZ="Asia/Shanghai"
- cluster.name=docker-cluster
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- node.name=node1
- node.master=true
- node.data=true
- bootstrap.memory_lock=true
- search.max_buckets=100000000
- http.cors.enabled=true
- http.cors.allow-origin=*
- cluster.initial_master_nodes=node0
- "discovery.zen.ping.unicast.hosts=es01,es02,es03"
- "discovery.zen.minimum_master_nodes=2"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./es020086/data:/usr/share/elasticsearch/data
- ./es020086/logs:/usr/share/elasticsearch/logs
ports:
- 9201:9200
- 9301:9300
networks:
- esnet
es03:
image: elasticsearch:7.2.0
container_name: es3
restart: always
environment:
- TZ="Asia/Shanghai"
- cluster.name=docker-cluster
- node.name=node2
- node.master=true
- node.data=true
- bootstrap.memory_lock=true
- search.max_buckets=100000000
- http.cors.enabled=true
- http.cors.allow-origin=*
- cluster.initial_master_nodes=node0
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- "discovery.zen.ping.unicast.hosts=es01,es02,es03"
- "discovery.zen.minimum_master_nodes=2"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./es030086/data:/usr/share/elasticsearch/data
- ./es030086/logs:/usr/share/elasticsearch/logs
ports:
- 9202:9200
- 9302:9300
networks:
- esnet
kibana:
image: kibana:7.2.0
container_name: kibana
restart: always
environment:
- TZ="Asia/Shanghai"
ports:
- 5601:5601
volumes:
- ./kibana.yml:/usr/share/kibana/config/kibana.yml:rw
depends_on:
- es01
networks:
- esnet
eshead:
image: mobz/elasticsearch-head:5
container_name: eshead
networks:
- esnet
ports:
- 9110:9100
kibana.yml 文件配置如下
kibana.yml 文件配置如下
server.name: kibana
server.host: "0"
#此处为es的master地址
elasticsearch.hosts: [ "http://192.167.175.122:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
部署容器时可能遇到的问题
1.es节点挂载目录的权限不够造成容器启动失败,可以执行命令chmod 777 XXX赋予文件权限
2.es需要的内存不够可能造成容器未正常启动,可以编辑文件vim /etc/sysctl.conf,在末尾添加vm.max_map_count=262144,最后需要执行命令sysctl -p使配置生效
四、可视化工具介绍
一直以来都对查询ES数据的麻烦头痛不已,一直没有找可视化工具来使用,一方面是因为是在这之前没有很迫切的需要,另一方面请“原谅我这一生放纵不羁爱自由”,言归正传,介绍两个可视化工具。
一、elasticsearch-head
界面比较老了,但是很简洁
1、下载地址 :https://github.com/mobz/elasticsearch-head 如果很慢的话,可以复制链接用迅雷下载。也可以 点击用百度网盘下载
2、要使用这个插件需要安装nodejs,grunt。
a)安装nodejs,并配置环境变量。 百度即可(安装路径最好不要带中文)
b)安装grunt,在node安装后目录下,使用命令:npm install -g grunt-cli 安装接口, 安装完成后grunt -version查看,出现版本信息即可。
3、开始安装head插件
a)将下载好的zip包解压(目录不要带中文),
b)dos窗口进入解压后目录elasticsearch-head-master, 执行命令: npm install;
c)在此目录下执行命令:npm start,启动插件
浏览器访问http://localhost:9100,将IP替换为安装es的服务器连接即可
二、elasticHD
界面还是不错的, 看着是现代化UI该有的界面
1、下载地址:https://github.com/360EntSecGroup-Skylar/ElasticHD/releases 选择自己系统对应版本下载。点击百度网盘下载
2、解压之后,cd 到安装目录 执行dos命令:ElasticHD -p 127.0.0.1:9800,即可。
五、网上配置过程:
https://www.elastic.co/guide/en/elasticsearch/reference/5.6/docker.html
https://blog.csdn.net/sinat_31908303/article/details/80496349
六、各种报错
elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root
ES不能能使用root用户直接运行,必须使用普通用户运行。
解决办法:添加用户,ES安装目录的所有者。
adduser 用户名
chown -R 用户名:用户组名 目录路径
Exception in thread "main" java.nio.file.AccessDeniedException: /opt/app/elasticsearch-6.6.0/config/jvm.options
使用的用户对安装目录的文件没有权限造成的,(可能是当前登录的用户没有权限,也可能是在更改安装目录的所有者的时候没有递归安装)
解决办法:
切换用户在启动es,如果报同样错误,使用chown -R 用户名:用户组名 目录路径更改文件所有者。
[WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [es1] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: Unable to access ‘path.data’ (/var/es/dat)
因为不是root用户,在配置文件的时候。数据目录和日志目录等不能应该放在用户家目录下,防止因为该用户不能在所设置的目录下创建文件而引起报错。
[unknown] unable to install syscall filter:
java.lang.UnsupportedOperationException: seccomp unavailable: CONFIG_SECCOMP not compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed
Centos6不支持SecComp,而高版本ES在5.X之后默认bootstrap.system_call_filter为true进行检测,所以导致检测失败,失败后直接导致ES不能启动
解决办法(两种):
1.可以把Centos内核升级到Centos7。
2.修改配置文件,关闭ES启动时候的安全检测。具体elasticsearch.yml中配置
Centos6不支持SecComp,而高版本ES在5.X之后默认bootstrap.system_call_filter为true进行检测,所以导致检测失败,失败后直接导致ES不能启动
解决办法(两种):
1.可以把Centos内核升级到Centos7。
2.修改配置文件,关闭ES启动时候的安全检测。具体elasticsearch.yml中配置
bootstrap.memory_lock: false
#这个配置项在memory中可以找到,默认为True,改为false即可。
bootstrap.system_call_filter为false:
#这个配置项配置文件中没有需要添加。```
【1】: max file descriptors [65535] for elasticsearch process is too low, increase to at least [65536]
【2】: max number of threads [1024] for user [es] is too low, increase to at least [4096]
【3】: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
【1】系统设置的文件描述符太少了
【2】为用户设置的可以开启的线程太少了,这两个可以通过配置文件vi /etc/security/limits.conf 更改
切换到root用户,编辑limits.conf 添加类似如下内容
vi /etc/security/limits.conf
添加如下内容:(这里只为启动ES的es用户更改了安全限制)
1
2
3
【1】系统设置的文件描述符太少了
【2】为用户设置的可以开启的线程太少了,这两个可以通过配置文件vi /etc/security/limits.conf 更改
切换到root用户,编辑limits.conf 添加类似如下内容
vi /etc/security/limits.conf
添加如下内容:(这里只为启动ES的es用户更改了安全限制)
【1】: max file descriptors [65535] for elasticsearch process is too low, increase to at least [65536]
【2】: max number of threads [1024] for user [es] is too low, increase to at least [4096]
【3】: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
1
2
3
【1】系统设置的文件描述符太少了
【2】为用户设置的可以开启的线程太少了,这两个可以通过配置文件vi /etc/security/limits.conf 更改
切换到root用户,编辑limits.conf 添加类似如下内容
vi /etc/security/limits.conf
添加如下内容:(这里只为启动ES的es用户更改了安全限制)
es soft nofile 65536 #solf是软限制的意思,hard是硬限制;软限制可以在程序的进程中自行改变(突破限制),而硬限制则不行(除非程序进程有root权限)
es hard nofile 65536 #nofile 文件描述符
es soft nproc 4096 #nproc 进程的限制
es hard nproc 4096
这里两个的设置没有让其立即生效的命令必须要通过重启使其生效。另外网上很多直接把第一项换为“ * ”,*是指所有用户,如果在生产中强烈不建议这样做,可能会对其他用户造成影响。
2019.3.3更正:
这是三项的配置不必重启使其生效,我在配置另外一台虚拟机的es的时候,直接把原来的虚拟机的limits.conf文件使用scp命令拷贝过来后,没有重启电脑便可以直接启动es
【3】虚拟内存区域最大映射值太小了 通过vi /etc/sysctl.conf 可以更改。
切换到root用户修改配置sysctl.conf
vi /etc/sysctl.conf
添加下面配置:
vm.max_map_count=655360
并执行命令:
sysctl -p(可以使其永久)
本机可以访问.但是局域网外的其他机器无法访问
修改elasticsearch.yml配置文件,network.host项,绑定本机的IP
PS:在配置文件中的localhost,回环IP,路径是tmp的一定要注意更改。
SettingsException[Failed to load settings from [elasticsearch.yml]]; nested: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found [VALUE_STRING]];
配置文件格式错误:
配置文件的key:value之间的:后面必须有一个空格。
配置文件格式错误:
配置文件的key:value之间的:后面必须有一个空格。
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c5330000, 986513408, 0) failed; error='Cannot allocate memory' (errno=12)
There is insufficient memory for the Java Runtime Environment to continue.
Native memory allocation (mmap) failed to map 986513408 bytes for committing reserved memory.
内存不足导致Java无法运行,(在elasticsearch和logstash中均可能出现)
解决办法:
这个时候查看一下free -m 查看可用内存,然后查看config下的jvm.options文件,-Xms1g和-Xmx1g配置的内存大小,更改此而配置项或者添加内存均可。
-
启动使用root用户启动,在config目录下创建了文件,需要删除
Error: Port 5601 is already in use. Another instance of Kibana may be running!
这是因为5601的端口被占用了,一般有因为以下几种可能而导致:
netstat -tunlp|grep 5601 #查看端口占用情况,找到端口对应的进程id
ps aux | grep PID #查看对应的进程
#然后根据进程情况确定更改哪一个程序的端口号,使其不冲突即可
[warning][license][xpack] License information from the X-Pack plugin could not be obtained from Elasticsearch for the [data] cluster. [invalid_index_name_exception] Invalid index name [_xpack], must not start with '_'., with { index_uuid="_na_" & index="_xpack" } :: {"path":"/_xpack","statusCode":400,"response":"{\"error\":{\"root_cause\":[{\"type\":\"invalid_index_name_exception\",\"reason\":\"Invalid index name [_xpack], must not start with '_'.\",\"index_uuid\":\"_na_\",\"index\":\"_xpack\"}],\"type\":\"invalid_index_name_exception\",\"reason\":\"Invalid index name [_xpack], must not start with '_'.\",\"index_uuid\":\"_na_\",\"index\":\"_xpack\"},\"status\":400}"}
Kibana连接elasticsearh的时候,浏览器中报错为
Cannot connect to the Elasticsearch cluster currently configured for Kibana.
`To use the full set of free features in this distribution of Kibana, please update Elasticsearch to the default distribution.```
看报错信息显示因该是版本的问题,但是理论上elatic官网上的一套应该是没有问题的,我试着卸载X-pack,发现es不能卸载,然后尝试了很多办法无果后,提交给了官网,收到回复如下:
您好,
非常感谢您的回复。
初步了解您的情况之后,我找到了一个跟您问题相似的帖子,麻烦您参考下
https://discuss.elastic.co/t/license-information-from-the-x-pack-plugin-could-not-be-obtained-from-elasticsearch-for-the-data-cluster/148030/9
不知道您是否方便尝试用下oss only的kibana?
https://www.elastic.co/downloads/kibana-oss
麻烦您看下是否能帮助解决您的问题~ 如果还有问题欢迎随时与我联系。您也可以加我的微信:(这个就不显示了)
希望Elastic能带给您一个无与伦比的使用体验!
Best regards,
重点在上周新版本更新中,我直接用了最新的6.6.1,然后就没有问题了,哈哈
————————————————
12.elasticsearch 6.6.1的新报错
Java HotSpot(TM) 64-Bit Server VM warning: Cannot open file logs/gc.log due to Permission denied
Exception in thread "main" org.elasticsearch.bootstrap.BootstrapException: java.nio.file.AccessDeniedException: /opt/app/elasticsearch-6.6.1/config/elasticsearch.keystore
Likely root cause: java.nio.file.AccessDeniedException: /opt/app/elasticsearch-6.6.1/config/elasticsearch.keystore
第一次启动es使用了root用户,在config目录下创建了文件elasticsearch.keystore,只需要进入之后把文件删除,然后用es的用户启动就可以了。
13.浏览器连接不上Kibana,资源无限重定向(特别早遇到的报错,今天想起来了)
在使用6.6.1的Kibana的时候,集群跑一个周末,不操作,等到周一的时候,会出现浏览器连接补了Kibana的情况,但是Kibana的进程什么的都正常,报错信息好像是因为资源无限重定向这样的信息。
这个问题咨询官网好像也是版本问题,具体情况我忘记了,但是现在记得还有一个这样的问题,大家如果遇到了可以
今天搭建集群的时候遇到新的报错,是因为我在一个节点启动了es,生成了数据文件,然后没有删除数据文件,就把目录用scp拷贝到其他的节点上而造成的,具体的报错信息如下:
failed to send join request to master [{node10}{nIHo2TdDRw-1-nbhr-Lmzw}{n_vGmHO9R2umfw99C5nOSg}{192.168.56.10}{192.168.56.10:9300}{ml.machine_memory=1968349184, ml.max_open_jobs=20, xpack.installed=true, ml.enabled=true}], reason [RemoteTransportException[[node10][192.168.56.10:9300][internal:discovery/zen/join]]; nested: IllegalArgumentException[can't add node {node11}{nIHo2TdDRw-1-nbhr-Lmzw}{XcZDBLmxRCeKsHm4jp2M8w}{192.168.56.11}{192.168.56.11:9300}{ml.machine_memory=1968349184, ml.max_open_jobs=20, xpack.installed=true, ml.enabled=true}, found existing node {node10}{nIHo2TdDRw-1-nbhr-Lmzw}{n_vGmHO9R2umfw99C5nOSg}{192.168.56.10}{192.168.56.10:9300}{ml.machine_memory=1968349184, xpack.installed=true, ml.max_open_jobs=20, ml.enabled=true}
with the same id but is a different node instance];
"type" : "parse_exception",
"reason" : "unknown key [setting] for create index"
{
"error" : {
"root_cause" : [
{
"type" : "parse_exception",
"reason" : "unknown key [mapping] for create index"
}
],
"type" : "parse_exception",
"reason" : "unknown key [mapping] for create index"
},
"status" : 400
}
解决方法
解决办法
原因:索引构建问题,仔细核对是否和我的索引格式一致,有问题欢迎留言。
1.curl方式
curl - H "Content-Type: application/json" - XPUT 'http://127.0.0.1:9200/temporary_index_test1' - d '{
"settings": {
"index": {
"number_of_shards": 5,
"number_of_replicas": 1
}
},
"mappings": {
"properties": {
"news_id": {
"type": "long"
},
"news_title": {
"type": "text"
},
"news_content": {
"type": "text"
}
}
}
}'
七、others
其他人搭建过程
docker-compose搭建elasticsearch集群,整合head
搭建环境
ubantu17 `已经安装好docker 17.06.2-ce`
搭建步骤搭建步骤
- 新建文件es1.yml,es2.yml
/* es1.yml */
network.bind_host: 0.0.0.0
cluster.name: elasticsearch_cluster
node.name: master
node.master: true
node.data: true
http.cors.enabled: true
http.cors.allow-origin: "*"
network.host: 0.0.0.0
discovery.zen.minimum_master_nodes: 1
/* es2.yml */
network.bind_host: 0.0.0.0
cluster.name: elasticsearch_cluster
node.name: node2
node.master: false
node.data: true
http.cors.enabled: true
http.cors.allow-origin: "*"
network.host: 0.0.0.0
discovery.zen.minimum_master_nodes: 1
discovery.zen.ping.unicast.hosts: es1
- 配置head
一定要在镜像中进行配置如下的两个文件
/usr/src/app/Gruntfile.js
/usr/src/app/_site/app.js
Gruntfile.js修改以下片段,
connect: {
server: {
options: {
/* 默认监控:127.0.0.1,修改为:0.0.0.0 */
hostname: '0.0.0.0',
port: 9100,
base: '.',
keepalive: true
}
}
app.js修改以下代码片段:
/* 修改localhost为elasticsearch集群地址,Docker部署中,一般是elasticsearch宿主机地址 */
this.base_uri = this.config.base_uri || this.prefs.get("app-base_uri") || "http://localhost:9200";
为了方便修改将上面的两个文件复制出来挂载在宿主机上,宿主机和容器之间的复制命令为
3.启动docker-compose up
修改虚拟内存
##
cat /etc/sysctl.conf | grep -v "vm.max_map_count" > /tmp/system_sysctl.conf
##
echo "vm.max_map_count=262144" >> /tmp/system_sysctl.conf
##
mv /tmp/system_sysctl.conf /etc/sysctl.conf
docker-compose文件内容
启动
docker-compose up 启动
docker-compose down 关闭
原文链接:https://blog.csdn.net/sinat_31908303/article/details/80496349
Elasticsearch集群详细介绍
ElasticStack整体组成
Elasticsearch集群介绍
集群节点
Elasticsearch的集群是由多个节点组成的,通过cluster.name设置集群名称,并且用于区分其他集群,每个节点通过node.name指定节点的名称。
在Elasticsearch中,节点的类型主要有4种:
Master节点
配置文件中node.master属性为true(默认为true),就有资格被选为master节点。
Master节点用于控制整个集群的操作。比如创建或删除索引,管理其他非master节点等。
Data节点
配置文件中node.data属性为true(默认为true),就有资格被设置成data节点。
Data节点主要用于执行数据相关的操作。比如文档的CRUD。
客户端节点
配置文件中node.master属性和node.data属性均为false.
该节点不能作为master节点,用于响应用户的请求,把请求转发到其他节点
部落节点
当一个节点配置tribe.*的时候,它是一个特殊的客户端,它可以连接多个集群,在所有连接的集群上执行搜索和其他操作。
集群状态的三种颜色:
颜色 | 意义 |
---|---|
green | 所有主分片和复制分片都可用 |
yellow | 所有主要分片可用,但不是所有复制分片都可用 |
red | 不是所有的主要分片都可用 |
分片和副本
颜色加重的0 代表主分片, 未加重的分片为 副本分片
一个分片(shard)是一个最小级别工作单元worker unitr,它只是保存了索引中所有数据的一部分。
我们需要知道是分片就是一个Lucene实例 ,并且它本身就是一个完整的搜索引擎。应用程序不会和它直接通信。
分片可以是主分片(primary shard)或者是复制分(replica shard),
索引中的每个文档属于一个单独的主分片 .所以主分片的数量决定了索引最多能存储多少数据。
复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或者 从别的shard取回文档。
当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整。
故障转移
当一个data节点停止时候,集群状态会变为黄色,主节点分片可用,副本节点分片不完全可用,过一段时间,副本节点会复制到其他节点,集群恢复正常
当一个master节点停止时候,集群主节点会自动切换到其他master为主的节点上,集群状态由黄色变为绿色
特别说明:脑裂情况
配置文件中discovery.zen.minimum_master_nodes设置的不是N/2+1时,会出现脑裂问题,之后宕机的主节点恢复后不会加入到集群。
集群分布式
1、路由问题
首先,来看个问题:
如图所示:当我们想一个集群保存文档时,文档该存储到哪个节点呢?是随机吗?是轮询吗?
实际上,在Elasticsearch中,会采用计算的方式来确定存储到哪个节点,计算公式如下:
shard = hash(routing) % number_of_primary_shards
routing值是一个任意字符串,它默认是_id但也可以自定义。
这个routing字符串通过哈希函数生成一个数字,然后除以主切片的数量得到一个余数(remainder),余数的范围永远是0到number_of_primary_shards-1,这个数字就是特定文档所在的分片。
这就是为什么创建了主分片后,不能修改的原因。
2、文档的写操作
新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上。
下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤 :
1.客户端给Node 1发送新建、索引或删除请求。
2.节点使用文档的_id确定文档属于分片0。它转发请求到Node 3 ,分片0位于这个节点上。
- Node 3在主分片上执行请求,如果成功,它转发请求到相应的位于Node 1和Node 2的复制节点上。当所有的复制节点报告成功,Node 3报告成功到请求的节点,请求的节点再报告给客户端。
客户端接受到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。你的修改生效了。
搜索文档(单个文档)
文档能够从主分片或任意一个复制分片被检索。
下面我们罗列在主分片或复制分片上检索一个文档必要的顺序步骤:
1.客户端给Node 1发送get请求。
2.节点使用文档的_id确定文档属于分片0。分片0对应的复制分片在三个节点上都有。此时,它转发请求到Node 2。
- Node 2返回文档(document)给Node 1然后返回给客户端。
对于读请求,为了平衡负载,请求节点会为每个请求选择不同的分片-- -它会循环所有分片副本。
可能的情况是,-个被索引的文档已经存在于主分片上却还没来得及同步到复制分片上。这时复制分片会报告文档未找到,主分片会成功返回文档。一-旦索引请求成功返回给用户,文档则在主分片和复制分片都是可用的。
全文搜索
对于全文搜索而言,文档可能分散在各个节点上,那么在分布式的情况下,如何搜索文档呢?
搜索,分为2个阶段,搜索(query)+取回(fetch)。
搜索(query)
查询阶段包含以下三步:
1.客户端发送一个search(搜索)请求给Node 3, Node 3创建了一个长度为from+size的空优先级队。
- Node 3转发这个搜索请求到索引中每个分片的原本或副本。每个分片在本地执行这个查询并且结果将结果到一个大小为from+size的有序本地优先队列里去。
3.每个分片返回document的ID和它优先队列里的所有document的排序值给协调节点Node 3。Node 3把这些值合并到自己的优先队列里产生全局排序结果。
取回(fetch)
分发阶段由以下步骤构成:
1.协调节点辨别出哪个document需要取回,并且向相关分片发出GET请求。
2.每个分片加载document并且根据需要丰富(enrich )它们,然后再将document返回协调节点。
- 一旦所有的document都被取回,协调节点会将结果返回给客户端。
到此elasticsearch集群的所有内容已经介绍完成
ELK 部署文档https://blog.csdn.net/kaikai136412162/article/details/103217120
八、语法
- 我们通常用用
_cat
API检测集群是否健康。 确保9200端口号可用:
curl 'localhost:9200/_cat/health?v'
绿色表示一切正常, 黄色表示所有的数据可用但是部分副本还没有分配,红色表示部分数据因为某些原因不可用.
2.通过如下语句,我们可以获取集群的节点列表:
curl 'localhost:9200/_cat/nodes?v'
3。通过如下语句,列出所有索引:
curl 'localhost:9200/_cat/indices?v'
返回结果:
4.创建索引
现在我们创建一个名为“customer”的索引,然后再查看所有的索引:
curl -XPUT 'localhost:9200/customer?pretty'
curl 'localhost:9200/_cat/indices?v'
结果如下:
上图中红框所表示的是:我们有一个叫customer的索引,它有五个私有的分片以及一个副本,在它里面有0个文档。
5.插入和获取
现在我么插入一些数据到集群索引。我们必须给ES指定所以的类型。如下语句:“external” type, ID:1:
主体为JSON格式的语句: { “name”: “John Doe” }
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe"
}'
返回结果为:create:true 表示插入成功。
获取GET,语句如下:
curl -XGET 'localhost:9200/customer/external/1?pretty'
其中含义为:获取customer索引下类型为external,id为1的数据,pretty参数表示返回结果格式美观。
6.删除索引 DELETE
curl -XDELETE 'localhost:9200/customer?pretty'
curl 'localhost:9200/_cat/indices?v'
表示索引删除成功。
7.通过以上命令语句的学习,我们发现索引的增删改查有一个类似的格式,总结如下:
curl -X<REST Verb> <Node>:<Port>/<Index>/<Type>/<ID>
:REST风格的语法谓词
:节点ip
:节点端口号,默认9200
:索引名
:索引类型
:操作对象的ID号
8 修改数据
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe"
}'
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "Jane Doe"
}'
上述命令语句是:先新增id为1,name为John Doe的数据,然后将id为1的name修改为Jane Doe。
9.更新数据
9.1 这个例子展示如何将id为1文档的name字段更新为Jane Doe:
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
{
"doc": { "name": "Jane Doe" }
}'
9.2 这个例子展示如何将id为1数据的name字段更新为Jane Doe同时增加字段age为20:
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
{
"doc": { "name": "Jane Doe", "age": 20 }
}'
9.3 也可以通过一些简单的scripts来执行更新。一下语句通过使用script将年龄增加5:
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
{
"script" : "ctx._source.age += 5"
}'
10 删除数据
删除数据那是相当的直接. 下面的语句将执行删除Customer中ID为2的数据:
curl -XDELETE 'localhost:9200/customer/external/2?pretty'
11 批处理
举例:
下面语句将在一个批量操作中执行创建索引:
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
'
下面语句批处理执行更新id为1的数据然后执行删除id为2的数据
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}
'
12.导入数据集
你可以点击这里下载示例数据集:accounts.json
其中每个数据都是如下格式:
{
"index":{"_id":"1"}
}
{
"account_number": 0,
"balance": 16623,
"firstname": "Bradshaw",
"lastname": "Mckenzie",
"age": 29,
"gender": "F",
"address": "244 Columbus Place",
"employer": "Euron",
"email": "bradshawmckenzie@euron.com",
"city": "Hobucken",
"state": "CO"
}
导入示例数据集:
curl -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary "@accounts.json"
curl 'localhost:9200/_cat/indices?v'
上图红框表示我们已经成功批量导入1000条数据索引到bank索引中。
13.查询
Sample:
curl 'localhost:9200/bank/_search?q=*&pretty'
{
"took" : 63,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1000,
"max_score" : 1.0,
"hits" : [ {
"_index" : "bank",
"_type" : "account",
"_id" : "1",
"_score" : 1.0, "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
}, {
"_index" : "bank",
"_type" : "account",
"_id" : "6",
"_score" : 1.0, "_source" : {"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
}, {
"_index" : "bank",
"_type" : "account",
上面示例返回所有bank中的索引数据。其中 q=* 表示匹配索引中所有的数据。
等价于:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} }
}'
14 查询语言
匹配所有数据,但只返回1个:
curl -XPOST ‘localhost:9200/bank/_search?pretty’ -d ’
{
“query”: { “match_all”: {} },
“size”: 1
}’
注意:如果siez不指定,则默认返回10条数据。
curl -XPOST ‘localhost:9200/bank/_search?pretty’ -d ’
{
“query”: { “match_all”: {} },
“from”: 10,
“size”: 10
}’
返回从11到20的数据。(索引下标从0开始)
curl -XPOST ‘localhost:9200/bank/_search?pretty’ -d ’
{
“query”: { “match_all”: {} },
“sort”: { “balance”: { “order”: “desc” } }
}’
上述示例匹配所有的索引中的数据,按照balance字段降序排序,并且返回前10条(如果不指定size,默认最多返回10条)。
15.执行搜索
下面例子展示如何返回两个字段(account_number balance)
curl -XPOST ‘localhost:9200/bank/_search?pretty’ -d ’
{
“query”: { “match_all”: {} },
“_source”: [“account_number”, “balance”]
}’
返回account_number 为20 的数据:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "account_number": 20 } }
}'
返回address中包含mill的所有数据::
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill" } }
}'
返回地址中包含mill或者lane的所有数据:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill lane" } }
}'
和上面匹配单个词语不同,下面这个例子是多匹配(match_phrase短语匹配),返回地址中包含短语 “mill lane”的所有数据:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_phrase": { "address": "mill lane" } }
}'
以下是布尔查询,布尔查询允许我们将多个简单的查询组合成一个更复杂的布尔逻辑查询。
这个例子将两个查询组合,返回地址中含有mill和lane的所有记录数据:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
上述例子中,must表示所有查询必须都为真才被认为匹配。
相反, 这个例子组合两个查询,返回地址中含有mill或者lane的所有记录数据:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"should": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
上述例子中,bool表示查询列表中只要有任何一个为真则认为匹配。
下面例子组合两个查询,返回地址中既没有mill也没有lane的所有数据:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must_not": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
上述例子中,must_not表示查询列表中没有为真的(也就是全为假)时则认为匹配。
我们可以组合must、should、must_not来实现更加复杂的多级逻辑查询。
下面这个例子返回年龄大于40岁、不居住在ID的所有数据:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "age": "40" } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}'
16.过滤filter(查询条件设置)
下面这个例子使用了布尔查询返回balance在20000到30000之间的所有数据。
curl -XPOST ‘localhost:9200/bank/_search?pretty’ -d ’
{
“query”: {
“bool”: {
“must”: { “match_all”: {} },
“filter”: {
“range”: {
“balance”: {
“gte”: 20000,
“lte”: 30000
}
}
}
}
}
}’
17 聚合 Aggregations
下面这个例子: 将所有的数据按照state分组(group),然后按照分组记录数从大到小排序,返回前十条(默认):
curl -XPOST ‘localhost:9200/bank/_search?pretty’ -d ’
{
“size”: 0,
“aggs”: {
“group_by_state”: {
“terms”: {
“field”: “state”
}
}
}
}’
注意:我们设置size=0,不显示查询hits,因为我们只想看返回的聚合结果。
上述语句类似于以下SQL语句:
SELECT state, COUNT() FROM bank GROUP BY state ORDER BY COUNT() DESC
下面这个实例按照state分组,降序排序,返回balance的平均值:
curl -XPOST ‘localhost:9200/bank/_search?pretty’ -d ’
{
“size”: 0,
“aggs”: {
“group_by_state”: {
“terms”: {
“field”: “state”
},
“aggs”: {
“average_balance”: {
“avg”: {
“field”: “balance”
}
}
}
}
}
}’
九、网上文章
https://blog.csdn.net/beishanyingluo/article/details/106447660
https://www.cnblogs.com/coffee-boy/p/9584846.html
https://blog.csdn.net/gwd1154978352/article/details/82740424
https://www.cnblogs.com/cjsblog/p/10120470.html