Elk环境篇 --- 本地快速搭建你的ElasticSearch及Kibana

前言

ELK的基本介绍

ELK是三个软件产品的首字母缩写,Elasticsearch,Logstash 和 Kibana。这三款软件都是开源软件,一般是配合使用,并且又前后归于 Elastic.co 公司名下,故被简称为 ELK 协议栈html

左边咱们部署了多台服务器,而后咱们经过logstash来采集数据,采集完成咱们发送到ES集群中存起来,而后经过Kibana去展现到咱们的浏览器中,就是这么一个简单的套路node

Elasticsearch是个开源分布式搜索引擎,它的特色有:开箱即用,分布式,零配置,自动发现,索引自动分片,索引副本机制,RESTful风格接口,多数据源,自动搜索负载等。linux

Logstash是一个彻底开源的工具,他能够对你的日志进行收集、过滤,并将其存储供之后使用(好比供ES来进行搜索)。git

Kibana 也是一个开源和免费的工具,它Kibana能够为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,能够帮助您汇总、分析和搜索重要数据日志。github

ELK的实现介绍

ELK 实现语言 简介
ElasticSearch Java 实时的分布式搜索和分析引擎,可用于全文检索,结构化搜索以及分析,基层基于Lucene。相似于Solr
Logstash JRuby 具备实时渠道能力的数据收集引擎,包含输入、过滤、输出模块,通常在过滤模块中作日志格式化的解析工做
Kibana JavaScript 为ElasticSerach提供分析平台和可视化的Web平台。他能够ElasticSerach的索引中查找,呼唤数据,并生成各类维度的表图

ELK的参考资料

ELK官网:https://www.elastic.co/web

ELK官网文档:https://www.elastic.co/guide/...数据库

ELK中文手册:https://www.elastic.co/guide/...apache

ELK中文社区:https://elasticsearch.cn/npm

1、Elasticsearch的部署

1.1 简介

ElaticSearch,简称为ES, ES是一个开源的高扩展的分布式全文检索引擎,它能够近乎实时的存储、检索数据;自己扩展性很好,能够扩展到上百台服务器,处理PB级别的数据。ES也使用Java开发并使用Lucene做为其核心来实现全部索引和搜索的功能,可是它的目的是经过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。bootstrap

下面是搜索引擎提供的一些使用的案例

GayHub

2013年初,GitHub抛弃了Solr,采起ElasticSearch 来作PB级的搜索。它使用ElasticSearch搜索20TB的数据,包括13亿文件和1300亿行代码”

Wiki

维基百科:启动以elasticsearch为基础的核心搜索架构

SoundCloud

SoundCloud使用ElasticSearch为1.8亿用户提供即时而精准的音乐搜索服务

Baidu

百度目前普遍使用ElasticSearch做为文本数据分析,采集百度全部服务器上的各种指标数据及用户自定义数据,经过对各类数据进行多维分析展现,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部20多个业务线(包括Casio、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大100台机器,200个ES节点,天天导入30TB+数据

Sina:使用ElasticSearch分析处理32亿条实时日志

Alibaba:使用ElasticSearch构建挖财本身的日志采集和分析体系

1.2 使用准备

我把我用到的安装包都上传到百度云了,有须要的能够自提,避免网络的尴尬🤣

连接:https://pan.baidu.com/s/17m0LmmRcffQbfhjSikIHhA 
提取码:l1lj

首先咱们得注意的是,ES是不能经过root用户来进行启动的,必须经过普通用户来安装启动,这里咱们使用一个新建的用户

解决方案也能够直接参考这个 https://www.cnblogs.com/gcgc/...

首先是下安装包,而后再解压一下便可,操做比较简单这里就不说明了

以后咱们建立两个文件夹,都在ES的目录下建立便可

mkdir -p /usr/local/elasticsearch-6.7.0/logs/
mkdir -p /usr/local/elasticsearch-6.7.0/datas

就是建立了一个数据文件和一个日志的存储文件夹而已

以后修改一下配置文件,在config文件夹中 vim elasticsearch.yml

cluster.name: myes
node.name: node3
path.data: 本身的安装路径/elasticsearch-6.7.0/datas
path.logs: 本身的安装路径/elasticsearch-6.7.0/logs
network.host: 本身节点的地址
http.port: 9200
discovery.zen.ping.unicast.hosts: ["node1", "node2", "node3"]
bootstrap.system_call_filter: false
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"

cluster.name --- 集群的名字,默认ElasticSearch
node.name --- 节点名
path.data --- 数据文件存放路径
path.logs --- 日志文件存放路径
http.port --- 访问端口号
discovery.zen.ping.unicast.hosts: 集群自动发现功能
bootstrap.system_call_filter: 
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"

这里要注意path.data 和 path.logs记得路径前要/,好比个人就是 path.data: /usr/local/elasticsearch-6.7.0/datas,固然你们都是聪明的孩子,估计是不会忘的

咱们还能够设置一下最大和最小堆内存,在jvm.option配置文件中,修改完以后分发到另外的节点上去便可,固然另外两个节点的那个配置文件也是按照上方的套路去改就行了。

cd /usr/local
scp -r elasticsearch-6.7.0/ node2:$PWD
scp -r elasticsearch-6.7.0/ node3:$PWD

因为个人前两台虚拟机不知道咋地就崩掉了,自己本身的电脑内存就不足。因此我就单节点了🤣

1.3 修改一些系统配置

1.3.1 普通用户打开文件的最大数限制

问题错误信息描述:

max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]

解决方案:解除普通用户打开文件的最大数限制,否则ES启动时可能会报错

sudo vi /etc/security/limits.conf

* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096

这四行粘贴上去便可

1.3.2 普通用户启动线程数限制

sudo vi /etc/sysctl.conf

添加下面两行
vm.max_map_count=655360
fs.file-max=655360

执行 sudo sysctl -p,使得配置生效

注意:以上两个问题修改完成以后,必定要从新链接linux生效。关闭secureCRT或者XShell工具,而后从新打开工具链接linux便可

1.3.3 从新链接工具后的行动

执行下面4个命令,没问题便可

[hadoop@node01 ~]$ ulimit -Hn
131072
[hadoop@node01 ~]$ ulimit -Sn
65536
[hadoop@node01 ~]$ ulimit -Hu
4096
[hadoop@node01 ~]$ ulimit -Su
4096

1.3.4 启动ES集群

nohup /usr/local/elasticsearch-6.7.0/bin/elasticsearch 2>&1 &

启动成功以后jsp便可看到es的服务进程,而且访问页面

http://node3:9200/?pretty

注意:若是哪一台机器服务启动失败,那么就到哪一台机器的logs去查看错误日志便可

出现这个页面,就是已经启动了,很是丑陋

1.3.5 elasticsearch-head插件

因为es服务启动以后,访问界面比较丑陋,为了更好的查看索引库当中的信息,咱们能够经过安装elasticsearch-head这个插件来实现,这个插件能够更方便快捷的看到es的管理界面

首先安装一下node.js

1.3.6 Node.js

Node.js是一个基于 Chrome V8 引擎的 JavaScript 运行环境。

Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。Node.js 不是一个 JavaScript 框架,不一样于CakePHP、Django、Rails。Node.js 更不是浏览器端的库,不能与 jQuery、ExtJS 相提并论。Node.js 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言分庭抗礼的脚本语言。

安装步骤参考:https://www.cnblogs.com/kevin...

下载好安装包以后,咱们解压,进行些配置便可

sudo ln -s /usr/local/node-v8.1.0-linux-x64/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm
sudo ln -s /usr/local/node-v8.1.0-linux-x64/bin/node /usr/local/bin/node

而后修改环境变量

sudo vim .bash_profile

export NODE_HOME=/usr/local/node-v8.1.0-linux-x64
export PATH=:$PATH:$NODE_HOME/bin

而后source一下

出现以上的这个node和npm的版本便可

1.3.7 elasticsearch-head插件的安装

在线安装的话不太推荐,由于你们的网速都(你懂的),固然像我这种提早准备好了安装包的就不同了

这时候咱们把它解压,而后修改一下Gruntfile.js

cd /usr/local/elasticsearch-head
vim Gruntfile.js

你能够直接先shift+:,转到命令模式,使用/hostname来找到这个参数,hostname: '你本身的节点ip'

以后

cd /usr/local/elasticsearch-head/_site
vim app.js

和上面一样的套路,先找http://这个关键字,而后把localhost改为本身的节点ip

以后咱们就能够开启服务了

cd /usr/local/elasticsearch-head/node_modules/grunt/bin/
nohup ./grunt server >/dev/null 2>&1 &

以后访问 http://你的节点ip:9100/便可访问,固然也是一个好看不到哪去的页面,还有就是,我这里有两个虚拟机傻了,因此没办法就启动了个单节点的

1.3.8 如何关闭

执行如下命令找到elasticsearch-head的插件进程,而后使用kill -9 杀死进程便可

sudo yum install net-tools     
netstat -nltp | grep 9100
kill -9 88297

1.3.9 Kibana的安装

这个东西基本就是解压就能用了

先准备个安装包,而后解压出来

cd /usr/local/kibana-6.7.0-linux-x86_64/config/
vi kibana.yml


​ 配置内容以下:
​ server.host: "node3"
​ elasticsearch.hosts: ["http://node3:9200"]

而后咱们就能够开始启动了

cd /usr/local/kibana-6.7.0-linux-x86_64
nohup bin/kibana >/dev/null 2>&1 &

这种时候须要的就是等待便可

额,咱们再等一小下😂

这里说它通知你你的集群里面啥数据都没有,这时候随便点第一个就是了

这种时候就算是安装完成了。以后咱们的交互方式就是DEV tools---开发者工具那里去进行和ES的交互

2、使用RESTful的方式去操做ElasticSearch

2.1 ES的一些概念

咱们使用传统的关系型数据库来类比一下

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices   -> Types  -> Documents -> Fields

咱们平时接触的好比MySQL,它是否是有多个数据库,每一个数据库中有多张表table,每张表都有不少条数据Rows,而后数据又有字段 Columns

而一个ES下面有不少个索引库Indices,而它下面又有不少的Types,相似于table的东西,每一条数据都是documents,而后字段就是Fields

2.2 一些专有名词的解释

2.2.一、索引 index

一个索引就是一个拥有几分类似特征的文档的集合。好比说,你能够有一个客户数据的索引,另外一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须所有是小写字母的),而且当咱们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,能够定义任意多的索引。

2.2.二、类型 type

在一个索引中,你能够定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义彻底由咱们来定。一般,会为具备一组共同字段的文档定义一个类型。好比说,咱们假设你运营一个博客平台而且将你全部的数据存储到一个索引中。在这个索引中,你能够为用户数据定义一个类型,为博客数据定义另外一个类型,固然,也能够为评论数据定义另外一个类型。

2.2.三、字段Field

至关因而数据表的字段,对文档数据根据不一样属性进行的分类标识

2.2.四、映射 mapping

其实就是相似于JavaBean同样的东西。mapping是处理数据的方式和规则方面作一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面能够设置的,其它就是处理es里面数据的一些使用规则设置也叫作映射,按着最优规则处理数据对性能提升很大,所以才须要创建映射,而且须要思考如何创建映射才能对性能更好。

2.2.五、文档 document

一个文档是一个可被索引的基础信息单元。好比,你能够拥有某一个客户的文档,某一个产品的一个文档,固然,也能够拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个处处存在的互联网数据交互格式。
在一个index/type里面,你能够存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。

2.2.六、接近实时 NRT

Elasticsearch是一个接近实时的搜索平台。这意味着,从索引一个文档直到这个文档可以被搜索到有一个轻微的延迟(一般是1秒之内)

2.2.七、分片和副本 shards & replicas

一个索引能够存储超出单个结点硬件限制的大量数据。好比,一个具备10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分红多份的能力,这些份就叫作分片。当你建立一个索引的时候,你能够指定你想要的分片的数量。每一个分片自己也是一个功能完善而且独立的“索引”,这个“索引”能够被放置到集群中的任何节点上。分片很重要,主要有两方面的缘由:

容许你水平分割/扩展你的内容容量。 
容许你在分片之上进行分布式的、并行的操做,进而提升性能/吞吐量。

至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是彻底由Elasticsearch管理的,对于做为用户的你来讲,这些都是透明的。

在一个网络环境里,失败随时均可能发生,在某个分片/节点不知怎么的就处于离线状态,或者因为任何缘由消失了,这种状况下,有一个故障转移机制是很是有用的。为此目的,Elasticsearch容许你建立分片的一份或多份拷贝,这些拷贝叫作 replicas,或者中文翻译过来可能叫副本。

replicas之因此重要,有两个主要缘由:

在分片/节点失败的状况下,提供了高可用性。由于这个缘由,复制分片从不与原/主要(original/primary)分片置于同一节点上。扩展你的搜索量/吞吐量,由于搜索能够在全部的 replicas 上并行运行。总之,每一个索引能够被分红多个分片。一个索引也能够被复制0次(意思是没有复制)或屡次。一旦复制了,每一个索引就有了主分片(做为复制源的原来的分片)和复制分片(主分片的拷贝)之别。shards & replicas 的数量能够在索引建立的时候指定。在索引建立以后,你能够在任什么时候候动态地改变 replicas 的数量,可是你过后不能改变分片的数量。

默认状况下,Elasticsearch中的每一个索引被分片5个主分片和1个replicas,这意味着,若是你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个彻底拷贝),这样的话每一个索引总共就有10个分片。

2.2.八、一个管理工具

curl是利用URL语法在命令行方式下工做的开源文件传输工具,使用curl能够简单实现常见的get/post请求。简单的认为是能够在命令行下面访问url的一个工具。在centos的默认库里面是有curl工具的,若是没有yum安装便可。

yum -y install curl

curl
-X 指定http的请求方法 有HEAD GET POST PUT DELETE
-d 指定要传输的数据
-H 指定http请求头信息

2.3 使用 Xput建立索引

2.3.1 建立索引

此时咱们的索引中是仅有Kibana默认帮咱们建立的索引的

在咱们的kibana的dev tools当中执行如下语句

curl -XPUT http://node3:9200/blog01/?pretty

kibana会自动帮咱们进行一些格式的调整

执行成功后,此时咱们又能看到所谓好看的页面了🤣

2.3.2 插入一条数据

curl -XPUT http://node3:9200/blog01/article/1?pretty -d  '{"id": "1", "title": "What is ELK"}'

使用 PUT 动词将一个文档添加到 /article(文档类型),并为该文档分配 ID 为1。URL 路径显示为index/doctype/ID(索引/文档类型/ID)。

咱们能够在数据浏览模块点击blog01进行查看

若是出现问题:Content-Type header [application/x-www-form-urlencoded] is not supported

此缘由时因为ES增长了安全机制, 进行严格的内容类型检查,严格检查内容类型也能够做为防止跨站点请求伪造攻击的一层保护。 官网解释

http.content_type.required

2.3.3 查询数据

curl -XGET http://node3:9200/blog01/article/1?pretty

这个命令能够在Kibana执行,也能够在集群执行

2.3.4 更新文档

更新操做和插入基本一致,由于就是有id就更新,无id就插入,和Java那块的操做比较像

curl -XPUT http://node3:9200/blog01/article/1?pretty -d  '{"id": "1", "title": " What is elasticsearch"}'

图就不贴啦,玩玩就好

2.3.5 搜索文档

curl -XGET "http://node3:9200/blog01/article/_search?q=title:elasticsearch"

2.3.6 删除文档及索引

删除文档

curl -XDELETE "http://node3:9200/blog01/article/1?pretty"

删除索引

curl -XDELETE http://node3:9200/blog01?pretty

执行就会删除了,这里我就不执行了

2.4 ES的条件查询

这里先模拟一些数据出来

POST /school/student/_bulk
{ "index": { "_id": 1 }}
{ "name" : "tellYourDream", "age" : 25 , "sex": "boy", "birth": "1995-01-01" , "about": "i like bigdata" }
{ "index": { "_id": 2 }}
{ "name" : "guanyu", "age" : 21 , "sex": "boy", "birth": "1995-01-02" , "about": "i like diaocan" }
{ "index": { "_id": 3 }}
{ "name" : "zhangfei", "age" : 18 , "sex": "boy", "birth": "1998-01-02" , "about": "i like travel" }
{ "index": { "_id": 4 }}
{ "name" : "diaocan", "age" : 20 , "sex": "girl", "birth": "1996-01-02" , "about": "i like travel and sport" }
{ "index": { "_id": 5 }}
{ "name" : "panjinlian", "age" : 25 , "sex": "girl", "birth": "1991-01-02" , "about": "i like travel and wusong" }
{ "index": { "_id": 6 }}
{ "name" : "caocao", "age" : 30 , "sex": "boy", "birth": "1988-01-02" , "about": "i like xiaoqiao" }
{ "index": { "_id": 7 }}
{ "name" : "zhaoyun", "age" : 31 , "sex": "boy", "birth": "1997-01-02" , "about": "i like travel and music" }
{ "index": { "_id": 8 }}
{ "name" : "xiaoqiao", "age" : 18 , "sex": "girl", "birth": "1998-01-02" , "about": "i like caocao" }
{ "index": { "_id": 9 }}
{ "name" : "daqiao", "age" : 20 , "sex": "girl", "birth": "1996-01-02" , "about": "i like travel and history" }

直接copy到kibana下面执行便可

此时在ES-head这边也能看的见

2.4.1 一、使用match_all作查询

GET /school/student/_search?pretty
{
    "query": {
        "match_all": {}
    }
}

问题:经过match_all匹配后,会把全部的数据检索出来,可是每每真正的业务需求并不是要找所有的数据,而是检索出本身想要的;而且对于es集群来讲,直接检索所有的数据,很容易形成GC现象。因此,咱们要学会如何进行高效的检索数据

2.4.2 经过关键字段进行查询

GET /school/student/_search?pretty
{
    "query": {
         "match": {"about": "travel"}
     }
}

若是此时想查询喜欢旅游的,而且不能是男孩的,怎么办?
【这种方式是错误的,由于一个match下,不能出现多个字段值[match] query doesn't support multiple fields】,须要使用复合查询

2.4.3 bool的复合查询

当出现多个查询语句组合的时候,能够用bool来包含。bool合并聚包含:must,must_not或者should, should表示or的意思
例子:查询非男性中喜欢旅行的人

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "match": {"about": "travel"}},
      "must_not": {"match": {"sex": "boy"}}
     }
  }
}

2.4.四、bool的复合查询中的should

should表示无关紧要的(若是should匹配到了就展现,不然就不展现)
例子:
查询喜欢旅行的,若是有男性的则显示,不然不显示

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "match": {"about": "travel"}},
      "should": {"match": {"sex": "boy"}}         
     }
  }
}

2.4.五、term匹配

使用term进行精确匹配(好比数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型))
语法

{ "term": { "age": 20 }}
{ "term": { "date": "2018-04-01" }}
{ "term": { "sex": “boy” }}
{ "term": { "about": "travel" }}

例子:查询喜欢旅行的

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "term": {"about": "travel"}},
      "should": {"term": {"sex": "boy"}}         
     }}
}

2.4.六、使用terms匹配多个值

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "terms": {"about": ["travel","history"]}}          
     }
  }
}

2.4.七、Range过滤

Range过滤容许咱们按照指定的范围查找一些数据:操做范围:

gt: --- 大于
gae: --- 大于等于
lt: --- 小于
lte: --- 小于等于

例子:查找出大于20岁,小于等于25岁的学生

GET /school/student/_search?pretty
{
"query": {
   "range": {
    "age": {"gt":20,"lte":25}
         }
      }
}

2.4.八、exists和 missing过滤

exists和missing过滤能够找到文档中是否包含某个字段或者是没有某个字段

例子:
查找字段中包含age的文档

GET /school/student/_search?pretty
{
"query": {
   "exists": {
    "field": "age"  
         }
      }
}

2.4.九、bool的多条件过滤

用bool也能够像以前match同样来过滤多行条件:

must: --- 多个查询条件的彻底匹配,至关于 and 。
must_not: --- 多个查询条件的相反匹配,至关于 not 。
should: --- 至少有一个查询条件匹配, 至关于 or

例子:
过滤出about字段包含travel而且年龄大于20岁小于30岁的同窗

GET /school/student/_search?pretty
{
  "query": {
    "bool": {
      "must": [
        {"term": {
          "about": {
            "value": "travel"
          }
        }},{"range": {
          "age": {
            "gte": 20,
            "lte": 30
          }
        }}
      ]
    }
  }
}

2.4.十、查询与过滤条件合并

一般复杂的查询语句,咱们也要配合过滤语句来实现缓存,用filter语句就能够来实现

例子:查询出喜欢旅行的,而且年龄是20岁的文档

GET /school/student/_search?pretty
{
  "query": {
   "bool": {
     "must": {"match": {"about": "travel"}},     
     "filter": [{"term":{"age": 20}}]
     }
  }
}

2.5 ES 中的重要概念Mappings & Settings

Mappings主要用于定义ES中的字段类型,在es当中,每一个字段都会有默认的类型,根据咱们第一次插入数据进去,es会自动帮咱们推断字段的类型,固然咱们也能够经过设置mappings来提早自定义咱们字段的类型

DELETE  document
PUT document
{
  "mappings": {
    "article" : {
      "properties":
      {
        "title" : {"type": "text"} , 
        "author" : {"type": "text"} , 
        "titleScore" : {"type": "double"} 
        
      }
    }
  }
}

以后可使用get document/article/_mapping来查看

Settings 主要用于定义分片数及副本数。

DELETE document
PUT document
{
  "mappings": {
    "article" : {
      "properties":
      {
        "title" : {"type": "text"} , 
        "author" : {"type": "text"} , 
        "titleScore" : {"type": "double"} 
        
      }
    }
  }
}

GET /document/_settings

由于个人节点就只有一个,就不截图ES-head那边的图了,没啥用😂

3、ES的分页解决方案

模拟一些数据再说,直接复制上去Kibana执行便可

DELETE us
POST /_bulk
{ "create": { "_index": "us", "_type": "tweet", "_id": "1" }}
{ "email" : "john@smith.com", "name" : "John Smith", "username" : "@john" }
{ "create": { "_index": "us", "_type": "tweet", "_id": "2" }}
{ "email" : "mary@jones.com", "name" : "Mary Jones", "username" : "@mary" }
{ "create": { "_index": "us", "_type": "tweet", "_id": "3" }}
{ "date" : "2014-09-13", "name" : "Mary Jones", "tweet" : "Elasticsearch means full text search has never been so easy", "user_id" : 2 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "4" }}
{ "date" : "2014-09-14", "name" : "John Smith", "tweet" : "@mary it is not just text, it does everything", "user_id" : 1 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "5" }}
{ "date" : "2014-09-15", "name" : "Mary Jones", "tweet" : "However did I manage before Elasticsearch?", "user_id" : 2 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "6" }}
{ "date" : "2014-09-16", "name" : "John Smith",  "tweet" : "The Elasticsearch API is really easy to use", "user_id" : 1 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "7" }}
{ "date" : "2014-09-17", "name" : "Mary Jones", "tweet" : "The Query DSL is really powerful and flexible", "user_id" : 2 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "8" }}
{ "date" : "2014-09-18", "name" : "John Smith", "user_id" : 1 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "9" }}
{ "date" : "2014-09-19", "name" : "Mary Jones", "tweet" : "Geo-location aggregations are really cool", "user_id" : 2 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "10" }}
{ "date" : "2014-09-20", "name" : "John Smith", "tweet" : "Elasticsearch surely is one of the hottest new NoSQL products", "user_id" : 1 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "11" }}
{ "date" : "2014-09-21", "name" : "Mary Jones", "tweet" : "Elasticsearch is built for the cloud, easy to scale", "user_id" : 2 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "12" }}
{ "date" : "2014-09-22", "name" : "John Smith", "tweet" : "Elasticsearch and I have left the honeymoon stage, and I still love her.", "user_id" : 1 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "13" }}
{ "date" : "2014-09-23", "name" : "Mary Jones", "tweet" : "So yes, I am an Elasticsearch fanboy", "user_id" : 2 }
{ "create": { "_index": "us", "_type": "tweet", "_id": "14" }}
{ "date" : "2014-09-24", "name" : "John Smith", "tweet" : "How many more cheesy tweets do I have to write?", "user_id" : 1 }

3.1 size+from浅分页

按照通常的查询流程来讲,若是我想查询前10条数据:

  1. 客户端请求发给某个节点
  2. 节点转发给个个分片,查询每一个分片上的前10条
  3. 结果返回给节点,整合数据,提取前10条
  4. 返回给请求客户端

from定义了目标数据的偏移值,size定义当前返回的事件数目

查询前5条的数据

GET /us/_search?pretty
{
  "from" : 0 , "size" : 5
}

从第5条开始算,查询5条

GET /us/_search?pretty
{
  "from" : 5 , "size" : 5
}

以后咱们在Java API当中就是这样来查询咱们ES的数据,不过这种浅分页只适合少许数据,由于随from增大,查询的时间就会越大,并且数据量越大,查询的效率指数降低

优势:from+size在数据量不大的状况下,效率比较高

缺点:在数据量很是大的状况下,from+size分页会把所有记录加载到内存中,这样作不但运行速递特别慢,并且容易让ES出现内存不足而挂掉

3.2 深分页scroll

对于上面介绍的浅分页,当Elasticsearch响应请求时,它必须肯定docs的顺序,排列响应结果。

若是请求的页数较少(假设每页20个docs), Elasticsearch不会有什么问题,可是若是页数较大时,好比请求第20页,Elasticsearch不得不取出第1页到第20页的全部docs,再去除第1页到第19页的docs,获得第20页的docs。

解决的方式就是使用scroll,scroll就是维护了当前索引段的一份快照信息--缓存(这个快照信息是你执行这个scroll查询时的快照)。
能够把 scroll 分为初始化和遍历两步: 一、初始化时将全部符合搜索条件的搜索结果缓存起来,能够想象成快照; 二、遍历时,从这个快照里取数据;

初始化

GET us/_search?scroll=3m
{ 
"query": {"match_all": {}},
 "size": 3
}

初始化的时候就像是普通的search同样,其中的scroll=3m表明当前查询的数据缓存3分钟。Size:3 表明当前查询3条数据

在遍历时候,拿到上一次遍历中的scrollid,而后带scroll参数,重复上一次的遍历步骤,知道返回的数据为空,就表示遍历完成

GET /_search/scroll
{
  "scroll" : "1m",
  "scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAShGFnE5ZURldkZjVDFHMHVaODdBOThZVWcAAAAAAAEoSRZxOWVEZXZGY1QxRzB1Wjg3QTk4WVVnAAAAAAABKEcWcTllRGV2RmNUMUcwdVo4N0E5OFlVZwAAAAAAAShIFnE5ZURldkZjVDFHMHVaODdBOThZVWcAAAAAAAEoShZxOWVEZXZGY1QxRzB1Wjg3QTk4WVVn"
}

注意:每次都要传参数scroll,刷新搜索结果的缓存时间,另外不须要指定index和type(不要把缓存的时时间设置太长,占用内存)

对比:

浅分页,每次查询都会去索引库(本地文件夹)中查询pageNum*page条数据,而后截取掉前面的数据,留下最后的数据。 这样的操做在每一个分片上都会执行,最后会将多个分片的数据合并到一块儿,再次排序,截取须要的。

深分页,能够一次性将全部知足查询条件的数据,都放到内存中。分页的时候,在内存中查询。相对浅分页,就能够避免屡次读取磁盘。

4、ES的中文分词器IK

ES默认对英文文本的分词器支持较好,但和lucene同样,若是须要对中文进行全文检索,那么须要使用中文分词器,同lucene同样,在使用中文全文检索前,须要集成IK分词器。那么咱们接下来就来安装IK分词器,以实现中文的分词

4.1 下载

wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.7.0/elasticsearch-analysis-ik-6.7.0.zip

而后在ES的目录中新建一个目录存放这个插件

mkdir -p /usr/local/elasticsearch-6.7.0/plugins/analysis-ik

unzip elasticsearch-analysis-ik-6.7.0.zip  -d /usr/local/elasticsearch-6.7.0/plugins/analysis-ik/

而后你再分发到其它的机器便可

cd /usr/local/elasticsearch-6.7.0/plugins 
scp -r analysis-ik/ node2:$PWD

以后你须要重启ES的服务

ps -ef|grep elasticsearch | grep bootstrap | awk '{print $2}' |xargs kill -9
nohup /kkb/install/elasticsearch-6.7.0/bin/elasticsearch 2>&1 &

4.2 体验一把

在kibana中建立索引库并配置IK分词器

delete iktest
PUT /iktest?pretty
{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "ik" : {
                    "tokenizer" : "ik_max_word"
                }
            }
        }
    },
    "mappings" : {
        "article" : {
            "dynamic" : true,
            "properties" : {
                "subject" : {
                    "type" : "text",
                    "analyzer" : "ik_max_word"
                }
            }
        }
    }
}

在建立索引库的时候,咱们指定分词方式为ik_max_word,会对咱们的中文进行最细粒度的切分,如今来看下效果

这里你能够看到,个人id被分红了好几块

你还能够用下面的语法对你的查询进行高亮,好比这个效果

POST /iktest/article/_search?pretty
{
    "query" : { "match" : { "subject" : "抗击肺炎" }},
    "highlight" : {
        "pre_tags" : ["<font color=red>"],
        "post_tags" : ["</font>"],
        "fields" : {
            "subject" : {}
        }
    }
}

4.3 配置热词更新

咱们能够发现个人ID是被分割成好几块的,由于在插件它的视角中“说出你的愿望吧”并非个热词,可是咱们能够告诉它我这是个热词🤣

好比如今,影流之主,蔡徐坤,都是被分掉的,那咱们怎么配置呢?就须要咱们常常可以实时的更新咱们的网络热词,咱们能够经过tomcat来实现远程词库来解决这个问题。

4.4 安装一个tomcat

安装tomcat就随便来一个就行了

而后你须要去到它的ROOT路径下,好比个人是

cd /usr/local/apache-tomcat-8.5.34/webapps/ROOT
而后new一个file出来
vi hot.dic


而后保存退出便可

接下来启动你的tomcat,要是启动成功就会能看到一个bootstrap服务

能访问到hot.dic便可

4.5 修改一下分词器的配置

其实就是修改这个文件

点进来有一些中文注释,而后你看到这个

把这一行的注释去掉,而后就配置上咱们刚刚能够访问到的tomcat的词的路径,也就是 http://192.168.200.11:8080/hot.dic 便可

而后把这个配置文件也分发到另外两个节点上

而后咱们重启一下ES便可,如今再进行分词,就会有关键字了

finally

这篇主要就是部署了,后面会涉及操做一些api啥的,篇幅就不搞这么长啦😶

相关文章
相关标签/搜索