Elasticsearch安装, 配置, 启动
一, 安装Elasticsearch
1, 环境需求
1, jdk是jdk1.8.0_131以上版本(Elasticsearch是用Java语言开发的)
2, 至少需要为虚拟机分配至少1.5G以上的内存
3, 从5.0开始,ElasticSearch 安全级别提高了,不允许采用root帐号启动
2, 安装ES
1, 下载
ElasticSearch官网:https://www.elastic.co/cn/ 太卡了
2, 设置虚拟机内存
3, 创建用户
Elasticsearch 安全级别提高了,不允许采用root帐号启动,所以要添加一个用户
#创建用户组 : elk
[root@localhost ~]# groupadd elk
#创建用户 : admin
[root@localhost ~]# useradd admin
[root@localhost ~]# passwd admin
#将admin用户添加到elk组
[root@localhost ~]# usermod -G elk admin
#为用户分配权限
#chown将指定文件的拥有者改为指定的用户或组 -R处理指定目录以及其子目录下的所有文件
[root@localhost ~]# chown -R admin:elk /usr/upload
[root@localhost ~]# chown -R admin:elk /usr/local
#切换用户:amdin
[root@localhost ~]# su admin
[admin@localhost root]$
4, 安装
ES是Java开发的应用,解压即安装:
#先上传到 /usr/upload目录下 , 解压到 /usr/local目录下
[admin@localhost root]$ cd /usr/upload/
[admin@localhost upload]$ rz
[admin@localhost upload]$ tar -zxvf elasticsearch-6.2.3.tar.gz -C /usr/local
ES目录结构是:
bin 目录:可执行文件包
config 目录:配置相关目录
lib 目录:ES 需要依赖的 jar 包,ES 自开发的 jar 包
logs 目录:日志文件相关目录
modules 目录:功能模块的存放目录,如aggs、reindex、geoip、xpack、eval
plugins 目录:插件目录包,三方插件或自主开发插件
data 目录:在 ES 启动后,会自动创建的目录,内部保存 ES 运行过程中需要保存的数据。
3, 配置文件
ES安装目录config中配置文件如下:
#进入目录下
[admin@localhost local]$ cd /usr/local/elasticsearch-6.2.3/config/
[admin@localhost config]$ ll
总用量 16
#用于配置Elasticsearch运行参数 elasticsearch.yml
-rw-rw----. 1 admin admin 2853 3月 13 2018 elasticsearch.yml
#用于配置Elasticsearch JVM设置 jvm.options
-rw-rw----. 1 admin admin 2767 3月 13 2018 jvm.options
#用于配置Elasticsearch日志 log4j2.properties
-rw-rw----. 1 admin admin 5091 3月 13 2018 log4j2.properties
elasticsearch.yml 本次配置如下:
由于这个文件下都是注释, 直接在下面添加即可
这里只开一台9200
cluster.name: 自定义命名
node.name: 自定义命名
network.host: 0.0.0.0
http.port: 9200
transport.tcp.port: 9300
discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301"]
path.data: /usr/local/elasticsearch-6.2.3/data
path.logs: /usr/local/elasticsearch-6.2.3/logs
http.cors.enabled: true
http.cors.allow-origin: /.*/
注意意path.data和path.logs路径配置正确
解释一下:
cluster.name:
配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称。
node.name:
节点名,通常一台物理服务器就是一个节点,es会默认随机指定一个名字,建议指定一个有意义的名称,
方便管理一个或多个节点组成一个cluster集群,集群是一个逻辑的概念,节点是物理概念
path.data:
设置索引数据的存储路径,默认是es_home下的data文件夹,可以设置多个存储路径,用逗号隔开。
path.logs:
设置日志文件的存储路径,默认是es_home下的logs文件夹
network.host:
设置绑定主机的ip地址,设置为0.0.0.0表示绑定任何ip,允许外网访问,生产环境建议设置为具体的ip。
http.port: 9200
设置对外服务的http端口,默认为9200。
transport.tcp.port: 9300
集群结点之间通信端口
discovery.zen.ping.unicast.hosts:[“host1:port”, “host2:port”, “…”]
设置集群中master节点的初始列表。
discovery.zen.ping.timeout: 3s
设置ES自动发现节点连接超时的时间,默认为3秒,如果网络延迟高可设置大些。
http.cors.enabled:
是否支持跨域,默认为false
http.cors.allow-origin:
当设置允许跨域,默认为*,表示支持所有域名
jvm.options 设置 -Xms和-Xmx:
默认内存占用太多了,我调小一些:
# 最小及最大的JVM堆内存大小
-Xms512m
-Xmx512m
log4j2.properties 注意日志级别
4, 启动
[admin@localhost elasticsearch-6.2.3]$ cd bin
[admin@localhost bin]$ ./elasticsearch
Linux 默认来说,一般限制应用最多创建的文件是 4096个。但是 ES 至少需要 65536 的文件创建权限。我们用的是admin用户,而不是root,所以文件权限不足。
使用root用户修改配置文件:
[admin@localhost bin]$ su root
[root@localhost bin]# vim /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
再启动
[root@localhost bin]# su admin
[admin@localhost bin]$ ./elasticsearch
默认的 Linux 限制 root 用户开启的进程可以开启任意数量的线程,其他用户开启的进程可以开启1024 个线程。必须修改限制数为4096+。因为 ES 至少需要 4096 的线程池预备。
如果虚拟机的内存是 1G,最多只能开启 3000+个线程数。至少为虚拟机分配 1.5G 以上的内存
使用root用户修改配置:
上上图还有一个错误 虚拟内存问题
[3]: max virtual memory areas vm.max_map_count [65530] . . . . . . .
还是修改刚才那个文件
[admin@localhost bin]$ su root
[root@localhost bin]# vim /etc/security/limits.conf
添加
* soft nproc 4096
[3]: max virtual memory areas vm.max_map_count [65530] . . . . . 这个错误
ES 需要开辟一个 262144字节以上空间的虚拟内存
[root@localhost bin]# vim /etc/sysctl.conf
然后执行命令,让sysctl.conf配置生效:
[root@localhost bin]# sysctl -p
vm.max_map_count = 655360
启动测试
./elasticsearch
#或
./elasticsearch -d #这个是后台启动
ps -ef | grep elasticsearch 看一下
ES 中只要启动了任意一个 ES 应用就是启动了一个 ES的 cluster 集群。默认的 ES集群命名为 elasticsearch。如果启动了多个应用(可以在多个节点或单一节点上启动多个应用),默认的ES 会自动找集群做加入集群的过程
浏览器访问:192.168.131.132:9200 本机IP地址加端口
二, 客户端
1, Kibana
在window中安装Kibana很方便,解压即安装
修改config目录下kibana.yml配置:
默认是注释,直接放开就行
server.port: 5601
server.host: "0.0.0.0" #允许来自远程用户的连接
elasticsearch.url: http://192.168.131.132:9200 #Elasticsearch实例的URL 不要用字符串"http://............."
启动
bin目录下
测试
浏览器访问:http://127.0.0.1:5601
2, head
1, 解压即安装
2, 运行
npm run start
浏览器访问:http://127.0.0.1:9100/
.......................................
三, ES基本操作
ES作为一个索引及搜索服务,对外提供REST接口,先使用kibana来测试,目的是对ES的使用方法及流程有个初步的认识。
1, index管理
1, 创建index索引库
索引库。包含若干相似结构的 Document 数据,相当于数据库的database。
语法:PUT /index_name
PUT /elasticsearch
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1
}
}
-----------------右边显示↓-----------------------
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "elasticsearch"
}
number_of_shards - 表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力
number_of_replicas - 是为每个 primary shard分配的replica shard数,提高了ES的可用性,如果只有一台机器,设置为0
2, 修改index
注意:索引一旦创建,primary shard 数量不可变化,可以改变replica shard 数量。
语法:PUT /index_name/_settings
PUT /elasticsearch/_settings
{
"number_of_replicas": 0
}
-----------------右边显示↓-----------------------
{
"acknowledged": true
}
ES 中对 shard 的分布是有要求的,有其内置的特殊算法:
Replica shard 会保证不和他的那个 primary shard 分配在同一个节点上;如过只有一个节点,则此案例执行后索引的状态一定是yellow。
3, 删除index
DELETE /index_name
DELETE /elasticsearch
-----------------右边显示↓-----------------------
{
"acknowledged": true
}
2, mapping管理
映射,创建映射就是向索引库中创建field(类型、是否索引、是否存储等特性)的过程,下边是document和field与关系数据库的概念的类比:
注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES6.x 版本之后,type概念被弱化ES官方将在ES7.0版本中彻底删除type。
1, 创建mapping
语法:POST /index_name/type_name/_mapping
POST /elasticsearch/user/_mapping
{
"properties": {
"name":{
"type": "text"
},
"des":{
"type": "text"
},
"birthday":{
"type": "keyword"
}
}
}
-----------------右边显示↓-----------------------
{
"acknowledged": true
}
效果:
2, 查询mapping
查询所有索引的映射:
GET /elasticsearch/user/_mapping
-----------------右边显示↓-----------------------
{
"elasticsearch": {
"mappings": {
"user": {
"properties": {
"birthday": {
"type": "keyword"
},
"des": {
"type": "text"
},
"name": {
"type": "text"
}
}
}
}
}
}
3, 更新mapping
映射创建成功可以添加新字段,已有字段不允许更新。可以直接删index库
4, 删除mapping
通过删除索引来删除映射
DELETE /elasticsearch
3,document管理
1.创建document
ES中的文档相当于MySQL数据库表中记录的数据。
POST语法
此操作为 ES 自动生成 id 的新增 Document 方式。
语法:POST /index_name/type_name/id
POST /elasticsearch/user/1
{
"name": "python从入门到放弃",
"des": "人生苦短,我用Python",
"birthday": "221002"
}
-----------------右边显示↓-----------------------
{
"_index": "elasticsearch",
"_type": "user",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
自动生成id
POST /elasticsearch/user
{
"name":".net从入门到放弃",
"description":".net程序员谁都不服",
"studymodel":"221003"
}
-----------------右边显示↓-----------------------
{
"_index": "elasticsearch",
"_type": "user",
"_id": "WtMtaoMBC3PKtD6xT61z",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
PUT语法
此操作为手工指定 id 的 Document 新增方式
PUT /elasticsearch/user/2
{
"name":"php从入门到放弃",
"des":"php是世界上最好的语言",
"birthday":"221004"
}
结果:
{
"_index": "elasticsearch", 新增的 document 在什么 index 中,
"_type": "user", 新增的 document 在 index 中的哪一个 type(相当于表) 中。
"_id": "2", 指定的 id 是多少
"_version": 1, document 的版本是多少,版本从 1 开始递增,每次写操作都会+1
"result": "created", 本次操作的结果,created 创建,updated 修改,deleted 删除
"_shards": { 分片信息:
"total": 1, 分片数量只提示 primary shard 的
"successful": 1, 数据 document 一定只存放在 index 中的某一个 primary shard 中
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
2. 查询document
根据id查 语法:GET /index_name/type_name/id
GET /elasticsearch/user/2
↓↓↓
{
"_index": "elasticsearch",
"_type": "user",
"_id": "2",
"_version": 1,
"found": true,
"_source": {
"name": "php从入门到放弃",
"des": "php是世界上最好的语言",
"birthday": "221004"
}
}
根据关键字查
查询名称中包括php 关键字的的记录
GET /elasticsearch/user/_search?q=name:php
↓↓↓
{
"took": 25, 执行的时长。单位毫秒
"timed_out": false, 是否超时
"_shards": {
"total": 2,
"successful": 2,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1, 总计多少数据,符合搜索条件的数据数量
"max_score": 0.6931472, 最大相关度分数,和搜索条件的匹配度
"hits": [
{
"_index": "elasticsearch",
"_type": "user",
"_id": "2",
"_score": 0.6931472,
"_source": {
"name": "php从入门到放弃",
"des": "php是世界上最好的语言",
"birthday": "221004"
}
}
]
}
}
查询所有
GET /elasticsearch/user/_search
3, 删除document
ES 中执行删除操作时,ES先标记Document为deleted状态,而不是直接物理删除。当ES 存储空间不足或工作空闲时,才会执行物理删除操作,标记为deleted状态的数据不会被查询搜索到(ES 中删除 index ,也是标记。后续才会执行物理删除。所有的标记动作都是为了NRT(近实时)实现)
语法:DELETE /index_name/type_name/id
DELETE /elasticsearch/user/1
4, ES读写过程
documnet routing(数据路由)
当客户端创建document的时候,es需要确定这个document放在该index哪个shard上,这个过程就是document routing。
路由过程:
路由算法:shard = hash(5) %number_of_primary_shards
id:document的_id,可能是手动指定,也可能是自动生成,决定一个document在哪个shard上
number_of_primary_shards:主分片数量。
为什么primary shard数量不可变
原因:假如我们的集群在初始化的时候有5个primary shard,我们往里边加入一个document id=5,假如hash(5)=23,这时该document 将被加入 (shard=23%5=3)P3这个分片上。如果随后我们给es集群添加一个primary shard ,此时就有6个primary shard,当我们GET id=5 ,这条数据的时候,es会计算该请求的路由信息找到存储他的 primary shard(shard=23%6=5) ,根据计算结果定位到P5分片上。而我们的数据在P3上。所以es集群无法添加primary shard,但是可以扩展replicas shard。
luke查看ES的逻辑结构
. . .
四, IK分词器
1, 测试分词器
在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。
测试当前索引库使用的分词器
POST /_analyze
{
"text":"测试分词器"
}
会发现分词的效果将“测试”这个词拆分成两个单字“测”和“试”,这是因为当前索引库使用的分词器对中文就是单字分词。
2, 中文分词器
IK依然不过时
使用IK分词器可以实现对中文分词的效果。
下载, 解压
并将解压的文件拷贝到ES安装目录的plugins下的ik(重命名)目录下,重启es
测试分词效果:
POST /_analyze
{
"text":"中华人民共和国人民大会堂",
"analyzer":"ik_smart"
}
3, 两种分词模式
ik分词器有两种分词模式:ik_max_word和ik_smart模式。
1、ik_max_word
会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民大会堂、人民、共和国、大会堂、大会、会堂等词语。
2、ik_smart
会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。
4, 自定义词库
如果要让分词器支持一些专有词语,可以自定义词库。
iK分词器自带的main.dic的文件为扩展词典,stopword.dic为停用词典。
也可以上边的目录中新建一个my.dic文件,
文件格式一定得为utf-8
可以在其中自定义词汇:
配置文件中 配置my.dic,
[admin@localhost config]$ vim IKAnalyzer.cfg.xml
POST /_analyze
{
"text":"奥利给 ",
"analyzer":"ik_max_word"
}
↓↓↓↓↓↓↓↓↓↓↓
{
"tokens": [
{
"token": "奥利给",
"start_offset": 0,
"end_offset": 3,
"type": "CN_WORD",
"position": 0
}
]
}
五, field详细
安装了ik分词器,如何在索引和搜索时去使用ik分词器呢, 如何指定field的类型, 比如日期类型、数值类型等。
ES 6.2核心的字段类型如下:
1, field属性介绍
1, type:
通过type属性指定field的类型。
"name": {
"type": "text"
},
2, analyzer:
通过analyzer属性指定分词模式。
"name": {
"type": "text",
"analyzer":"ik_max_word"
}
上边指定了analyzer是指在索引和搜索都使用ik_max_word,如果单独想定义搜索时使用的分词器则可以通过search_analyzer属性。对于ik分词器建议是索引时使用ik_max_word将搜索内容进行细粒度分词,搜索时使用ik_smart提高搜索精确性。
"name": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
3, index:
通过index属性指定是否索引。默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到。但是也有一些内容不需要索引,比如:图片,只展示不进行搜索图片,此时可以将index设置为false。
"pic": {
"type":"text",
"index":false
}
4, source:
如果某个字段内容非常多,业务里面只需要能对该字段进行搜索,比如:物品描述。查看文档内容会再次到mysql或者hbase中取数据,把大字段的内容存在Elasticsearch中只会增大索引,这一点文档数量越大结果越明显,如果一条文档节省几KB,放大到亿万级的量结果也是非常可观的。
如果只想存储某几个字段的原始值到Elasticsearch,可以通过incudes参数来设置,在mapping中的设置如下:
"_source": {
"includes":["description"]
}
同样,可以通过excludes参数排除某些字段:
"_source": {
"excludes":["description"]
}
2, 常用field类型
1, text文本字段
创建新映射:
POST /java/book/_mapping
{
"_source": {
"excludes": ["des"]
},
"properties": {
"name":{
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"des":{
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"pic":{
"type": "text",
"index": false
},
"studymodel":{
"type": "keyword"
},
"price":{
"type": "float"
}
}
}
插入文档
PUT /java/book/1
{
"name": "spring开发基础 ",
"des": "spring在java领域非常流行, java程序员都在用",
"pic": "250.png",
"studymodel": "22年9月24日",
"price": 99.8
}
查询测试
GET /java/book/_search?q=price:99.8
http://192.168.153.122:9200/java/book/_search?q=studymodel:22年9月24日
http://192.168.153.122:9200/java/book/_search?q=des:非常
2, keyword关键字字段
keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段往索引目录写时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。
查询方式是精确查询。
"studymodel":{
"type": "keyword"
},
3, date日期类型
日期类型不用设置分词器,通常日期类型的字段用于排序。1)format通过format设置日期格式,多个格式使用双竖线||分隔, 每个格式都会被依次尝试, 直到找到匹配的
"properties": {
"timestamp": {
"type": "date",
"format": "yyyy-MM-dd"
}
}
4, Numeric类型
es中的数字类型经过分词(特殊)后支持排序和区间搜索
"price":{
"type": "float"
}