Elasticsearch安装, 配置, 启动

一, 安装Elasticsearch

1, 环境需求

1, jdk是jdk1.8.0_131以上版本(Elasticsearch是用Java语言开发的)

2, 至少需要为虚拟机分配至少1.5G以上的内存

3, 从5.0开始,ElasticSearch 安全级别提高了,不允许采用root帐号启动

2, 安装ES

1, 下载

ElasticSearch官网: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
[1]说是文件创建权限不足

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
max number of threads [1024] . . . . . 线程开启限制问题

默认的 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地址加端口

You Know, for Search

二, 客户端

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目录下

kibana.bat


测试

浏览器访问:http://127.0.0.1:5601

2, head

1, 解压即安装


2, 运行

npm run start

浏览器访问: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
在my.dic文件中添加的词是'奥利给'
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"
    }

3, field属性的设置标准

编辑于 2022-09-24 10:34