安装ES与集群的健康值分析与mapping的介绍
https://www.elastic.co/cn/downloads/elasticsearch
-
解压缩
tar -zxvf elasticsearch-7.12.0-linux-x86_64.tar.gz
-
创建目录
mkdir -p /usr/local/elasticsearch
-
剪切
mv elasticsearch-7.12.0 /usr/local/elasticsearch/
-
进入Elasticsearch目录
cd /usr/local/elasticsearch/
-
添加用户(es禁止使用root用户运行)
useradd esuser
-
修改Elasticsearch目录所有者和所有组
chown -R esuser:esuser elasticsearch-7.12.0/
[root@localhost elasticsearch]# ll 总用量 4 drwxr-xr-x. 9 esuser esuser 4096 3月 18 14:21 elasticsearch-7.12.0
-
切换用户
su esuser
-
启动ES
./elasticsearch -d
-
验证
ps -ef | grep elasticsearch
ES开箱即用,非常简单,启动之后可以进入localhost:9200验证。
ES配置文件
elasticsearch.yml文件:
# 指定ES集群名称,默认是Elasticsearch
cluster.name: my-application
# 节点的名称,每一个ES进程就是一个节点
node.name: node-1
# 数据目录
path.data: /path/to/data
# 日志目录
path.logs: /path/to/logs
# 允许其他机器访问
network.host: 0.0.0.0
# 端口号
http.port: 9200
jvm.options文件:
# ES是Java编写的,运行在jvm上,对jvm的参数进行适当的配置可以优化ES的运行性能
Elasticsearch-head插件
https://github.com/mobz/elasticsearch-head
es-head是使用js编写的插件,作者提供了三种使用方式:
- 如果有node.js与npm环境的话,可以通过node.js去启动
- 如果有docker环境的话可以通过docker去运行es-head镜像
- 在chrome商店中去安装es-head插件,这种方式不需要去开启跨域
集群健康值分析
-
启动Elasticsearch进程
./elasticsearch -d
-
打开es-head
(图一,初次进入,无任何索引) sdgasPF是节点名称,由于我没有在配置文件中指定节点的名称,所以会默认分配一个;
集群健康值用于展示集群的健康状态,它分为green、yellow、red三种状态来表示集群的健康程度。我们可以通过es-head来直观查看,也可以通过
GET /_cluster/health
api接口来获取集群健康值。- green:所有的shard和replica都在正常运行。
- yellow:所有的shard都在正常运行,但是有replica不是正常运行。
- red:有shard不在正常运行。
由于此时节点中一个索引都还没有,所以它的健康值是green (0 of 0).
-
创建一个索引
(图二,选择5个shard,每个shard分配1个replica)
(图三,集群的健康值变为了yellow 5 of 10 ) 同时出现了一个灰色的unassigned区域,这是因为新创建的index,有5个shard,这5个shard都分配上去了,但是由于shard和replica不能位于同一个节点,所以yellow 5 of 10,还有5个replica未分配。
unassigned就是与每个shard对应的replica,但是它们此时都未运行,所以是灰白的。
我们可以通过
postman
发送请求http://192.168.95.130:9200/_cat/health?v
去验证:
重点关心以下字段:
- cluster:节点名
- node.total:集群中节点总数
- unassign:未运行的节点
- active_shards_percent:正常的节点百分比
我们再解压一个Elasticsearch.tar,并将它启动,然后再次观察:
可以看到又多出来一个随机命名的节点*CwCefu_*,在它上面分配了5个replica,所以此时集群的健康状态变为了`green`。
再次使用postman
发送请求http://192.168.95.130:9200/_cat/health?v
去验证:
mappings详解
什么是mapping
mapping是ES中document
结构的映射,它类似于数据库中的表结构定义,mapping会将document
映射为Lucene
需要的扁平化格式①。
mapping可以:
- 定义
index
里面的字段和名称 - 定义
field
的类型 - 定义
field
是否需要分词等。
①扁平化格式是指:mysql中的person表,可能有address这个字段,mysql是无法直接存储address数据的,只能用address表的ID与之关联。
而ES是基于json存储的,它可以将address嵌套到person中,这就是扁平化格式。
为什么需要定义mapping
写入文档的时候,如果索引不存在,会自动创建索引, 无需手动创建,ES会根据内容推断字段的类型,推断会不准确,可能造成某些功能无法使用
定义mapping
-
发送创建
index
的请求,同时定义mappingPUT
http://192.168.95.130:9200/index_mapping
// 请求体 { "mappings": { // 文档中的属性 "properties": { // 属性名,即field "realname": { "type": "text", // 类型,分词 "index": true // 是否需要索引,默认就是true }, "username": { "type": "keyword", // keyword不分词 "index": false } } } }
// 响应体 { "acknowledged": true, "shards_acknowledged": true, "index": "index_mapping" }
-
再次刷新es-head可以看到多出来一个名为index_mapping的
index
,它有1个shard和1个replica,同时它的mappings结构如下:{ "mappings":{ "_doc":{ "properties":{ "realname":{ "type":"text" }, "username":{ "index":false, "type":"keyword" } } } } }
-
发送请求进行分词验证:
GET
http://192.168.95.130:9200/index_mapping/_analyze
// 请求体 { "field": "realname", "text": "this is analyze test!" }
// 响应体 { "tokens": [ { "token": "this", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 0 }, { "token": "is", "start_offset": 5, "end_offset": 7, "type": "<ALPHANUM>", "position": 1 }, { "token": "analyze", "start_offset": 8, "end_offset": 15, "type": "<ALPHANUM>", "position": 2 }, { "token": "test", "start_offset": 16, "end_offset": 20, "type": "<ALPHANUM>", "position": 3 } ] }
修改mapping
修改mapping只能新添加新的field
,不能修改原有的field
-
发送请求增加
id
和age
属性POST
http://192.168.95.130:9200/index_mapping/_mapping
// 请求体 { "properties": { "id": { "type": "long" }, "age": { "type": "integer" }, "money1": { "type": "float" }, "money2": { "type": "double" }, "gender": { "type": "byte" }, "score": { "type": "short" }, "is_teen": { "type": "boolean" }, "birthday": { "type": "date" }, "relationship": { "type": "object" } } }
// 响应体 { "acknowledged": true }
-
尝试修改
realname
属性// 请求体 { "properties": { "realname": { "type": "long" } } }
// 响应体 { "error": { "root_cause": [ { "type": "illegal_argument_exception", "reason": "mapper [realname] cannot be changed from type [text] to [long]" } ], "type": "illegal_argument_exception", "reason": "mapper [realname] cannot be changed from type [text] to [long]" }, "status": 400 }