[toc]
ElasticSearch简介
Elasticsearch
一个基于Apache Lucene(TM)的开源搜索引擎。
ES能做什么?
全文检索(全部字段)、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)
Elasticsearch使用案例
同类产品
Solr、ElasticSearch、Hermes(腾讯)(实时检索分析)
Lucene是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎
ElasticSearch
准备工作
安装Centos7、内存2G以上、java1.8、关闭防火墙
ElasticSerach单机安装
只能写192.168那个地址,写hostname不行,原因未知。
Elasticsearch的交互方式
1、restfull
2、程序语言的客户端
Elasticsearch操作工具
- REST访问ES方式
- postman\浏览器
- Kibana的Dev Tools
Elasticsearch数据存储
存储方式
(1)面向文档
这也是Elasticsearch能够执行复杂的全文搜索的原因之一。
(2)JSON
在Elasticsearch中将对象转化为JSON并做索引要比在表结构中做相同的事情简单的多。
存储结构
结构图:
比如创建文档语句:
1 | PUT mxx/doc/1 |
查询这条数据:GET mxx/doc/1,返回结果:
1 | { |
解释:
1 | _index:文档所在索引名称 |
名词:
索引 index(对应数据库)
一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。
类型 type(对应表)
Es6之后,一个index中只能有一个type
字段Field
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识
document
一个文档是一个可被索引的基础信息单元。文档以JSON格式来表示。在一个index/type里面,你可以存储任意多的文档。
Elasticsearch检索
检索文档
Mysql : select * from user where id = 1
ES : GET /mxx/doc/1
我们通过HTTP方法GET来检索文档,同样的,我们可以使用DELETE方法删除文档,使用HEAD方法检查某文档是否存在。如果想更新已存在的文档,我们只需再PUT一次(_version字段+1)。
简单检索
Mysql : select * from user
ES : GET /mxx/doc/_search
返回:
1 | 响应内容不仅会告诉我们哪些文档被匹配到,而且这些文档内容完整的被包含在其中—我们在给用户展示搜索结果时需要用到的所有信息都有了。 |
全文检索
ES : GET /mxx/doc/_search?q=zhangsan
查询出所有文档字段值为haha的文档。(字段值需要完全匹配)
搜索(模糊查询)
GET /mxx/doc/_search?q=haha
查询出所有文档字段值分词后包含hello的文档
1 | PUT /mxx/doc/1 |
聚合
Group by
Elasticsearch有一个功能叫做聚合(aggregations),它允许你在数据上生成复杂的分析统计。它很像SQL中的GROUP BY但是功能更强大。
比如,Group by一下age这个字段。
1 | PUT /mxx/doc/3 |
查询结果:
1 | { |
这些数据并没有被预先计算好,它们是实时的从匹配查询语句的文档中动态计算生成的。
还可以添加约束(所有姓”Smith”的人的共同兴趣爱好):
1 | GET /mxx/doc/_search |
Elasticsearch搜索原理
正排索引和倒排索引
分词
分词机制
分词API
Elasticsearch自带的分词器
中文分词
Character Filters
在进行Tokenizer之前对原始文本进行处理,如增加、删除或替换字符等
Token Filter
对输出的单词(term)进行增加、删除、修改等操作
自定义分词api
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36PUT my_analyzer
{
"settings": {
"analysis": {
"analyzer": {
"my":{
"tokenizer":"punctuation",
"type":"custom",
"char_filter":["emoticons"],
"filter":["lowercase","english_stop"]
}
},
"tokenizer": {
"punctuation":{
"type":"pattern",
"pattern":"[.,!?]"
}
},
"char_filter": {
"emoticons":{
"type":"mapping",
"mappings":[
":)=>_happy_",
":(=>_sad_"
]
}
},
"filter": {
"english_stop":{
"type":"stop",
"stopwords":"_english_"
}
}
}
}
}测试:
Code1
2
3
4
5POST my_analyzer/_analyze
{
"analyzer": "my",
"text":"l'm a :) person,and you?"
}结果:
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18{
"tokens": [
{
"token": "l'm a _happy_ person",
"start_offset": 0,
"end_offset": 15,
"type": "word",
"position": 0
},
{
"token": "and you",
"start_offset": 16,
"end_offset": 23,
"type": "word",
"position": 1
}
]
}
- 分词使用场景
IK分词器
是一个中文分词器
下载安装
测试
IK提供了两个分词算法ik_smart 和 ik_max_word,其中 ik_smart 为最少切分,ik_max_word为最细粒度划分
1 | POST _analyze |
Mapping
定义数据库中的表的结构的定义,通过mapping来控制索引存储数据的设置
- 获取索引mapping
1 | GET /atguigu/_mapping |
响应:
1 | ... |
自定义mapping
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19PUT my_index #索引名称
{
"mappings":{
"doc":{ #类型名称
"dynamic":false,
"properties":{
"title":{
"type":"text" #字段类型
},
"name":{
"type":"keyword"
},
"age":{
"type":"integer"
}
}
}
}
}dynamic设置
true:允许自动新增字段(默认的配置)
False:不允许自动新增字段,但是文档可以正常写入,无法对字段进行查询操作
strict:文档不能写入(如果写入会报错)
支持的类型
…
数据类型
…
文档操作
CRUD
创建文档
1、索引一个文档
2、使用自己的ID
3、自增ID
获取文档
1、检索文档
2、pretty
3、检索文档的一部分
Code1
GET /website/blog/123?_source=title,text
更新
删除文档
Code1
DELETE /website/blog/123
局部更新
批量插入
Code1
2POST test_search_index/doc/_bulk
{}检索多个文档
Code1
2POST /_mget
{}
Search API(URI)
查询案例
1、批量创建文档
Code1
2
3
4
5
6
7
8
9POST test_search_index/doc/_bulk
{"index":{"_id":1}}
{"username":"alfred way","job":"java engineer","age":18,"birth":"1991-12-15","isMarried":false}
{"index":{"_id":2}}
{"username":"alfred","job":"java senior engineer and java specialist","age":28, "birth":"1980-05-07", "isMarried":true}
{"index":{"_id":3}}
{"username":"lee", "job":"java and ruby engineer","age":22,"birth":"1985-08-07","isMarried":false}
{"index":{"_id":4}}
{ "username":"lee junior way", "job":"ruby engineer","age":23, "birth":"1986-08-07","isMarried":false}2、泛查询
3、查询语句执行计划查看
4、term查询
5、phrase查询
6、group查询
7、布尔操作符
Search API(Request Body Search)
Match Query
对字段作全文检索,最基本和常用的查询类型。通过operator参数可以控制单词间的匹配关系,可选项为or和and
Code1
2
3
4
5
6
7
8
9
10
11GET test_search_index/_search
{
"query":{
"match": {
"username": {
"query":"alfred way",
"operator":"and"
}
}
}
}
Elasticsearch集群
ElasticSerach集群安装
克隆虚拟机、改hostname、改ip地址、重启网络、修改配置文件。
注意:清空data和logs数据
安装集群监控
解压cerebro-0.8.1.tgz,运行bin/cerebro即可,访问elk111:9000
输入任意一个elk的地址:
1 | http://192.168.1.111:9200 |
就可以进入集群监控页。
集群简介
集群节点
集群健康
| 颜色 | 意义 |
|---|---|
| green | 所有主要分片和复制分片都可用 |
| yellow | 所有主要分片可用,但不是所有复制分片都可用 |
| red | 不是所有的主要分片都可用 |
集群分片
主分片:负载
副本分片:高可用
故障转移
集群操作原理
路由
操作数据节点工作流程
检索流程
Logstash
logstsh架构
logstash安装
logstsh input插件
Stdin
file
Elasticsearch
Code1
2
3
4
5
6
7
8
9
10
11
12
13input {
elasticsearch {
hosts => "192.168.1.111"
index => "mxx"
query => '{ "query": { "match_all": {} }}'
}
}
output {
stdout {
codec => "rubydebug"
}
}
logstsh filter
Filter是logstsh功能强大的原因,它可以对数据进行丰富的处理,比如解析数据、删除字段、类型转换等
date:日期解析
grok:正则匹配解析
dissect:分割符解析
mutate:对字段作处理,比如重命名、删除、替换等
json:按照json解析字段内容到指定字段中
geoip:增加地理位置数据
ruby:利用ruby代码来动态修改logstsh Event
Kibana
1 | vim kibana.yml |
综合应用:每日访问量统计
logstash搜集nginx产生的日志,转化为json,存到es里了,最后使用kibana分析生成图表。
1、在elk111上装tomcat,放一个项目到webapps,测试能访问成功
2、安装nginx,修改配置文件,代理tomcat的项目,浏览器访问nginx代理,测试成功。
1 | location / { |
3、刷新页面,用tail监控日志文件,发现日志数据一直在变化。
1 | tail -f /var/log/nginx/access.log |
4、编辑logstash脚本
1 | 输入:监控nginx日志文件access.log |
日志数据格式:
1 | 192.168.1.5 - - [27/Dec/2019:19:07:18 +0800] "GET /blog/css/main.css?v=6.4.2 HTTP/1.1" 404 995 "http://elk111/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36" |
过滤正则:
1 | /home/machine/logstash/job/patterns/ |
logstash脚本
1 | /home/machine/logstash/job |
nginx_logstash.conf
1 | input { |
5、执行写好的logstash脚本,进行监控。刷新页面,看控制台效果
1 | bin/logstash -f /home/machine/logstash/job/nginx_logstash.conf |
6、使用Kibana在Management那创建一个 index pattern,名字:logstash* (匹配所有的日志数据索引)
按时间戳进行匹配
7、查一下某个索引的数据是否存在,刷新页面,看是否实时增加了
1 | GET logstash-nginx_access-2019.12.27/_search |
8、创建图表,选择logstash*的索引
1 | Y count |
9、生成图表,可以save保存图表。







