赞
踩
开源搜索引擎,for search
开箱即用:localhost:9200
开发:产品基本功能,底层原理
运维:
方案:解决大数据搜索的解决方案
elastic认证工程师。
内容:入门、集群管理、大数据分析、实战
近实时
分布式 存储/搜索/分析引擎
Solr(Apache)
Splunk
多编程语言类库
RESTful API
功能:搜索、聚合
Lucene 7.x
D:\elasticsearch-5.6.9\bin>elasticsearch-plugin install analysis-icu
- 查询插件 :进入es安装目录的
D:\elasticsearch-5.6.9\bin>elasticsearch-plugin list
localhost:9200/_cat/plugins
节点名称-集群名称-存放数据地址
bin/elasticsearch -E node.name=node1 -E cluster.name=geektime -E pah.data=nod1e_data -d
bin/elasticsearch -E node.name=node2 -E cluster.name=geektime -E pah.data=node2_data -d
bin/elasticsearch -E node.name=node3 -E cluster.name=geektime -E pah.data=node3_data -d
kibana汉化配置
在kibana.yml文件最后一行加
注:5.6.9版本过低,无法通过配置汉化,只能下载汉化包汉化
i18n.locale: "zh-CN"
下载:https://www.elastic.co/cn/downloads/past-releases/logstash-5-6-9https://www.elastic.co/cn/downloads/past-releases/logstash-5-6-9
使用:解压后cmd进入\bin目录使用
bin/logstash -e 'input { stdin { } } output { stdout {} }'
直接输入helloworld
样例:movielens.csv文件,配置config文件,将文件处理后输出到es的端口
设置分片数量和副本数量:
方案1:创建索引的时候设置
PUT twitter
{
"settings" : {
"index" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
}
方案2:创建Mapping的时候设置
PUT test
{
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"type1" : {
"properties" : {
"field1" : { "type" : "text" }
}
}
}
}
单词词典:
倒排列表:
Analyzer组成:
ElasticSearch内置分词器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6rbb893l-1615873812134)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210311095203138.png)]
中文分词:
在elasicsearch的插件中下载ICU Analyzer
Elasticsearch-plugin install analysis
从gitthub中下载IK分词器
https://github.com/medcl/elasticsearch-analysis-ik
THULAC分词器(清华大学)
https://github.com/microbun/elasticsearch-thulac-plugin
DSL:
查询所有数据:
GET /_search
查看集群健康信息
GET /_cat/health?v
查看集群中节点信息
GET /_cat/nodes?v
查看集群中索引信息
GET /_cat/indices?v
简化:
GET /_cat/indices?v&h=health,status,index
创建索引
PUT /baizhi
删除索引
DELETE /baizhi
URI Search
Request Body Search
语法:
搜索的排序,谷歌采用Page Rank算法
ES为了搜索提供了两大类api:URL search 和 Request Body Search
ElasticSearch查询返回结果各个字段的含义
GET /_search
结果略。从上到四个返回值,took,timed_out,_shards,hits。
curl -XGET http://localhost:9200/kibana_sample_data_ecommerce/_search?q=customer_first_name:Eddie
指定字段查询 / 泛查询
q=title:2012 / q=2012
GET /movies/_search?q=2012&df=title
{
"profile":"ture"
}
// 泛查询,正对_all,所有字段
GET /movies/_search?q=2012
// 指定字段
GET /movies/_search?q=title:2012
{
"profile":"true"
}
Type:Disjunction Max Query:分离最大化查询:将任何与任一查询匹配的文档作为结果返回,但只将最佳匹配的评分作为查询的评分结果返回。弥补bool查询的不足
TermQuery:分词精确查询,如:查询hotelName分词后包含hotel的term文档
QueryBuilders.termQuery("hotelName","hotel")
QueryBuilders.termsQuery("hotelName","hotel","test")
// 使用引号,parase
```dsl
GET /movies/_search?q=title:"Beautiful Mind"
{
"profile":"true"
}
```
```dsl GET /movies/_search?q=title:Beautiful Mind { "profile":"true" } ``` ```dsl GET /movies/_search?q=title:(Beautiful Mind) { "profile":"true" } ``` - 分组与引号:
注:profile API 是 Elasticsearch 5.x 的一个新接口。通过这个功能,可以看到一个搜索聚合请求,是如何拆分成底层的 Lucene 请求,并且显示每部分的耗时情况。
可以通过在 query 部分上方提供 “profile: true” 来启用Profile API。
{ "query":{ "bool":{ "must":[ ], "should":[ ], "must_not":[ ], "filter":[ ], "minimum_should_match":0 } } }
- 布尔与分组
GET /movies/_search?q=year:>190
{
"profile":"true"
}
GET /movies/_search?q=title:b*
{
"profile":"true"
}
“match_all”:{} :匹配所有文档
分页
排序
// 对日期进行排序
POST kibana_sample_data_ecommerce/_search
{
"sort":[{"order_date":desc}],
"query":{
"match_all":{}
}
}
对source的内容进行过滤,场景:有些时候不需要返回那么多字段,所以需要过滤掉不需要的字段,只返回需要的字段,类比select。
source filtering
POST kibana_sample_data_ecommerce/_search
{
"_source":[order_date"],
"query":{
"match_all":{}
}
}
"script": {
"lang": "...",
"source" | "id": "...",
"params": { ... }
}
lang:代表language脚本语言,默认指定为:painless。
source:脚本的核心部分,id应用于:stored script。
params:传递给脚本使用的变量参数。
短语搜索 - Match Phrase:和match查询类似,match_phrase查询首先解析查询字符串来产生一个词条列表。然后会搜索所有的词条,但只保留包含了所有搜索词条的文档,并且词条的位置要邻接。
“slop”:1表示短语中单词之间可以有一个其他字符
Query String 类似于Query
Simple Query String
能否更改Mapping的字段类型?
- 控制Dynamic Mapping
字段的数据类型
PUT movies{
"mapping":{
// define your mappings here
}
}
多字段类型
如:为一个字段增加一个子字段keyword,为某些字段加上用英文或者拼音的方式进行分词
精确值和全文本(Exact Value vs Full Text)
注:精确值不需要做分词处理
自定义分词器
当ES自带的分词器无法满足时自定义分词器,实现:通过自组合不同的组件实现。
ES中默认的Character Filters(字符过滤器):在Tokenizer之前对文本进行处理,例如增加删除及替换字符,可以配置多个Character Filter,但这样会影响Tokenizer的Position和offset信息
一些自带的Character Filter: HTML strip(去除html标签),Mapping(字符串替换)、Pattern replace(正则匹配替换)
设置一个自己的Custom Analyzer
Index template定义在创建新index时可以自动应用的settings和mappings
Dynamic template根据ES自动识别的数据类型,结合字段名称,动态设定字段类型
ES除搜索之外,提供了针对ES数据进行统计分析的功能(Aggregation)
集合的分类
- Bucket : 对应GROUP BY brand,一组满足条件的文档
Metric :对应SELECT COUNT(brand) from cars,一些系列的统计方法
Answer:
Answer:
8. Match中terms之间是or的关系,Match phrase的terms之间是and的关系,并且term之间的位置关系也会之间影响搜索的结果
9. slop
10. 直接报错
11. 文档被索引,新增的字段在_source中可见,但是该字段无法被搜索
12. 错,字段类型修改,需要reindex操作
13. 对,在Mapping文件中可以为indexing和searching指定不同的analyzer
范围查询:rang
query filter term搜索对文本不分词,直接拿去倒排索引匹配,你输入的是什么就去匹配什么
“explain”: true,:查看如何算分
以上算分的过程:
上例中,title和body互相竞争:不应该将分数简单叠加,而是应该找到单个最佳匹配的字段的评分
icu
pinyin
search template:"{{field}}" : "{{value}}"
GET /blog_website/blogs/_search/template
{
"inline" : {
"query": {
"match" : {
"{<!-- -->{field}}" : "{<!-- -->{value}}"
}
}
},
"params" : {
"field" : "title",
"value" : "博客"
}
}
相当于
GET /blog_website/blogs/_search
{
"query": {
"match" : {
"title" : "博客"
}
}
}
注:当算分差别非常大的时候,可以通过Modifier平滑曲线
引入factor,更好的控制算分曲线
Boost Mode 和Max Boost
– ES可以指定一个字段,该字段的算分作为主要的参考依据
一致性随机函数
让每个用户能看到不同的***随机排名***,对于同一用户的访问,结果的相对顺序保持一致
只要“seed”的值不变,搜索的结果相对顺序保持一致
Term suggester mode
- 过程:用户输入一个错误的拼写到指定字段搜索,当搜索不到时会根据suggest-mode返回建议的词
Completion Suggester:提供了自动完成的功能。用户每输入一个字符,就需要即时发送一个查询请求到后段查找匹配项。
注意:对性能要求苛刻,ES采用了不同的数据结构,并非通过倒排索引来完成,而是将Analyze的数据编码成FST和索引一起存放。FST会被ES整个加载进内存,速度很快。
FST只能用于前缀查找。
解释:FST是lucene中用来存储字典,并进行检索的核心数据结构,FST本质上是一个比HashMap有更强大功能keyvalue存储结构
使用步骤:
水平拓展痛点:
单集群:水平拓展时,节点不能无限增加。因为当集群的meta信息过多,会导致更新压力变大,单个Active Master会成为性能瓶颈,导致整个集群无法工作
跨集群搜索:Cross -cluster search,ES5.3引入
允许任何节点扮演federated节点,以轻量的方式,将搜索请求代理。
不需要以client node的方式加入
配置及查询
本地启动3个集群
ES分布式架构:
节点:
Coordinating Node:处理请求的节点,索引节点都默认是此节点通过将其他类型设置为false.使其成为Dedicated Coordinating Node
Data Node : 可以保存数据的节点,节点启动后默认就是数据节点,通过设置node.data:false禁止
Data Node的职责:保存分片数据,由Master决定如何把分片分发到数据节点上。通过增加数据节点,可以解决数据水平拓展和解决数据单点问题。
Master Node
Master eligible Node & 选主流程
集群状态信息(cluster state)保存有
在每个节点都保存了集群的状态信息,但只能由Master Node才能修改状态信息并同步至其他节点。
选主流程:
脑裂问题
- 脑裂问题解决方案
配置节点类型
注:Master决定分片会分配到哪个节点。
shard=hash(_rounting)%number_of_primary_shards
不能修改Primary的原因是因为文档到分片的路由算法是由主分片数计算出来的
ES中最小的工作单元是一个Lucene index ,一个分片就是一个Lucene index
问题1:为什么ES的搜索是近实时的?
Refresh频率默认1s/次
Refresh:
问题2:ES如何保证断电时数据也不丢失?
Transaction Log:
问题3:为什么删除文档,并不会立刻释放空间?
删除的文件保存在.del文件中,flush才会被彻底删除
倒排索引不可变性
倒排索引一旦生产,不可更改。
好处:
坏处:如果让一个新文档可以被搜索,需要重建整个索引。
Flush
Merge
通过_version版本号的方式进行乐观锁并发控制
在es内部第次一创建document的时候,它的_version默认会是1,之后进行的删除和修改的操作_version都会增加1。可以看到删除一个document之后,再进行同一个id的document添加操作,版本号是加1而不是初始化为1,从而可以说明document并不是正真地被物理删除,它的一些版本号信息一样会存在,而是会在某个时刻一起被清除。
es提供了一个外部版本号的乐观控制方案来替代内部的_version:
?version=1&version_type=external
"aggregations" : { // 表示聚合操作,可以使用aggs替代
"<aggregation_name>" : { // 聚合名,可以是任意的字符串。用做响应的key,便于快速取得正确的响应数据。
"<aggregation_type>" : { // 聚合类别,就是各种类型的聚合,如min等
<aggregation_body> // 聚合体,不同的聚合有不同的body
}
[,"aggregations" : { [<sub_aggregation>]+ } ]? // 嵌套的子聚合,可以有0或多个
}
[,"<aggregation_name_2>" : { ... } ]* // 另外的聚合,可以有0或多个
}
-注:聚合是和查询同等级的
例:
curl -XPOST "192.168.1.101:9200/student/student/_search" -d ' { "query": { // 可以先使用query查询得到需要的数据集 "term": { "classNo": "2" } }, "aggs": { "min_age": { "min": { "field": "age" } } } } '
支持对聚合分析的结果,再次进行聚合分析;
Pipeline 的分析结果会输出到原结果中,根据位置的不同,分为两类
Sibling - 结果和现有分析结果同级
Parent - 结果内嵌到现有的聚合分析结果之中
例1:平均工资最低的工资类型 | sibling Pipeline
POST employees/_search { "size": 0, "aggs": { "jobs": { "terms": { "field": "job.keyword", "size": 10 }, "aggs": { "avg_salary": { "avg": { "field": "salary" } } } }, "min_salary_by_job":{ "min_bucket": { "buckets_path": "jobs>avg_salary" } } } }
POST employees/_search { "size": 0, "aggs": { "jobs": { "terms": { "field": "job.keyword", "size": 10 }, "aggs": { "avg_salary": { "avg": { "field": "salary" } } } }, "avg_salary_by_job":{ "avg_bucket": { "buckets_path": "jobs>avg_salary" } } } }
POST employees/_search { "size": 0, "aggs": { "age": { "histogram": { "field": "age", "min_doc_count": 1, "interval": 1 }, "aggs": { "avg_salary": { "avg": { "field": "salary" } }, "derivative_avg_salary":{ "derivative": { "buckets_path": "avg_salary" } } } } } }
链接: https://blog.csdn.net/xixihahalelehehe/article/details/114411134.
排序
指定orde,默认情况下按照降序排序
指定size,就能返回相应的桶
ES内部排序
GET /cars/transactions/_search
{
"size":0,
"aggs":{
"popular_colors":{
"terms": {
"field": "color",
"order": { ---表示要对聚合结果做排序
"_count": "desc" ---排序字段是doc_count,顺序是降序
}
}
}
}
}
GET /cars/transactions/_search
{
"size": 0,
"aggs": {
"price": {
"histogram": { ---区间聚合
"field": "price", ---取price字段的值
"interval": 20000, ---每个区间的大小是20000
"order": { ---表示要对聚合结果做排序
"_key": "desc" ---排序字段是桶的key值,这里是每个区间的起始值,顺序是降序
}
}
}
}
}
min 聚合分析的执行流程
Terms Aggregation | 返回参数中的 2 个特殊值
Terms Aggregation | 执行流程
注:返回分桶中文档数最大的 3 个分桶;结果不一定准确;
Term聚合不正确的案例:
文档数最多的 3 个桶应该是 A,B,D,但是 Terms 聚合的结果是 A,B,C;
doc_count_error_upper_bound | 举例分析
左边的分片中,选出来的文档数最大的 3 个桶中的文档数分别是:6, 4, 4,那么遗漏的文档数最大可能就是 4;
右边的分片中,选出来的文档数最大的 3 个桶中的文档数分别是:6, 3, 2,那么遗漏的文档数最大可能就是 2(图中有错);
sum_other_doc_count | 举例分析
索引中全部文档数 - 返回的 3 个桶中的文档总数,29 - 22 = 7;
解决 Terms 聚合不准的问题 | 提升 shard_size 的参数
Terms 聚合分析不准的原因:
数据分散在多个分片上,Coordinating Node 无法获取数据的全貌;
解决方法1:
当数据量不大时,设置 Primary Shard 数为 1,实现准确性;
解决方法2:
当数据分布在多个 Primary Shard 上时,设置 shard_size 参数,提升准确性,其原理是:每次从 Shard 上额外多获取数据,提升准确率;
参数 | shard_size | 设定
通过调大 shard_size 的大小,使得 doc_count_error_upper_bound 的值降低,从而提升准确度,其原理是:增加整体计算量,提高精准度的同时会降低响应时间;
shard_size 默认大小
shard_size = size * 1.5 + 10
参考:https://blog.csdn.net/liuhe2296044/article/details/103745740?utm_source=app&app_version=4.5.5
对象 | Nested 对象 | 局限性
每篇博客的文档中,包含作者信息,当作者信息变更时,整个博客文档都需要变更;
Parent & Child
定义父子关系的步骤
文档父子关系实例:
DELETE my_blogs PUT my_blogs { "settings": { "number_of_shards": 2 }, "mappings": { "properties": { "blog_comments_relation": { "type": "join", "relations": { "blog": "comment" } }, "content": { "type": "text" }, "title": { "type": "keyword" } } } }
参考链接:https://blog.csdn.net/weixin_33669968/article/details/106422331?utm_source=app&app_version=4.5.5
重建索引的场景
重建索引的API: Update By Query Reindex
Update By Query :在现有索引上重建
POST 索引/索引类型/_update_by_query { "script": { "source": "ctx._source['修改的字段名'] = '修改后的值'" }, "query": { "bool": { "must": [ { "term": { "查询条件此处为字段名": "字段的值" } } ], "must_not": [], "should": [] } } }
查询index索引,type等于index_type中数据满足field=value的数据,修改其中field=test,对应的就是关系型数据库的update set … where…语句;
Reindex:在其他索引上重建索引
Reindex基础实现: _reindex会将一个索引的快照数据copy到另一个索引,默认情况下存在相同的_id会进行覆盖(一般不会发生,除非是将两个索引的数据copy到一个索引中),
POST _reindex
{
"source": {
"index": "my_index_name"
},
"dest": {
"index": "my_index_name_new"
}
}
Elasticsearch可以使用自身的Ingest Pipeline功能进行数据预处理, 无须借助Logstash.
Ingest Pipeline介绍:Ingest Pipeline 就是在文档写入Data Node之前进行一系列的数据预处理, 进行数据预处理的就是processor, 一组处理器构成了Pipeline. 所有的预处理都在Ingest Node上执行, 默认情况下所有节点都是Ingest Node.
- 常用的process
split processor
字符串切分成数组
join processor
数组转化成字符串
gsub processor
字符串替换
set processor
创建或替换一个字段.
remove processor
移除一个字段
rename processor
重命名一个字段
lowercase processor
字符串小写化
upcase processor
字符串大写化
script processor
使用painless脚本进行复杂的处理
语法:
PUT /_ingest/pipeline/my_pipeline_id
{
"description": "to split blog tags",
"processors": [
{
"split": {
"field": "tags",
"separator": ","
}
}
]
}
description是对pipeline的描述, processors定义了一组处理器.
PUT /_ingest/pipeline/my_pipeline_id { "description": "to split blog tags", "processors": [ { "split": { "field": "tags", "separator": "," } }, { "script": { "source": """ if(ctx.containsKey("content")){ ctx.content_length = ctx.content.length(); }else{ ctx.content_length = 0; } """ } } ] }
(2)新增文档
PUT /blogs/_doc/1?pipeline=my_pipeline_id
{
"title": "Introducing big data......",
"tags": "hadoop,elasticsearch,spark",
"content": "You konw, for big data"
}
PUT /blogs/_doc/2?pipeline=my_pipeline_id
{
"title":"Introducing cloud computering",
"tags":"openstack,k8s",
"content":"You konw, for cloud"
}
(3) 查看文档
GET /blogs/_search
(4)结果:
"hits" : [ { "_index" : "blogs", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : { "title" : "Introducing big data......", "content" : "You konw, for big data", "content_length" : 22, "tags" : [ "hadoop", "elasticsearch", "spark" ] } }, { "_index" : "blogs", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_source" : { "title" : "Introducing cloud computering", "content" : "You konw, for cloud", "content_length" : 19, "tags" : [ "openstack", "k8s" ] } } ]
- 一些相关的API
- 建模建议(1):如何处理关联关系
注:Kibana目前不支持nested类型和parent/child类型,未来可能会支持。
- 建模建议(2):避免过多字段
- 导致文档中有成百上千的字段原因:
Dynamic VS Strict
建模建议(5):为索引的Mapping加入Meta信息
用户文档信息泄露原因:
数据安全的基本需求
免费方案:
- Authtication - 身份认证
RBAC - 用户鉴权
使用Security API创建用户
开启并配置X-Pack的认证与鉴权
Hot Nodes
用于数据的写入,
Warm Nodes
用于保存只读索引
配置Hot & Warm Architecture
标记节点
配置索引到Hot Node
配置索引到Warm Node
ES7.0开始,新建一个索引时,默认创建一个分片
单分片:
集群增加一个节点后,ES会自动进行分片的移动
如何设计分片?
案例:
分片过多的副作用
ES官方确定主分片数
ES官方确定副分片数
调整分片总数设定,避免分配不均衡
容量规划
评估业务的性能需求
常见用例
硬件配置
部署方式
容量规划案例
管理单个集群
ECE:管理多个ES集群
Kubernetes:
构建自己的管理系统
Development VS Production Mode
Bootstrap Checks
JVM设定
集群的API设定
系统设置
参考官方手册
网络
内存设定计算实例
存储
服务器硬件
Throttles限流
关闭Dynamic Indexes
集群安全设定
ES stas 相关的API
ES Task 相关的API
The index & Query Slow Log
如何创建监控Dashboard
集群健康度
-
Health相关的API
案例分析
集群变红:
集群变黄
分片没有被分配的一些原因
常见问题与解决方法
提升写性能的方法
服务器端优化写入性能的一些手段
关闭无关功能
针对性能的取舍
数据写入过程
分片的设定
Bulk,线程池和队列大小
一个索引设定的例子
尽量Denormalize数据
数据建模
- 测试目标
- 测试脚本
- ES Rally
Merge优化
Force Merge
诊断内存情况
常见内存问题
Circuit Breaker(断路器)
Codec Plugind
Filter Plugins
Queue
-
多Pipeline实例
logstash Queue
Codec Plugin -single Line
Codec Plugin -multiline
Filter Plugin
6.0以上版本的ElasticSearch直接导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
6.0以下2版本的ElasticSearch依赖配置
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>5.6.9</version> </dependency> <!-- 尤其是要注意这里!下面的三个依赖,需要你打开ES页面, 查看lucene_version参数的版本,要一一对应!!!! --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>6.6.1</version> </dependency> <!-- https://mvnrepository.com/art... --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-highlighter</artifactId> <version>6.6.1</version> </dependency> <!-- https://mvnrepository.com/art... --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-queries</artifactId> <version>6.6.1</version> </dependency>
注:版本号获取
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NuxCkTIB-1615873812156)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210312112549525.png)]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。