ElasticSearch
2022-08-28 15:20:09 3 举报
AI智能生成
登录查看完整内容
ElasticSearch架构、语法、原理
作者其他创作
大纲/内容
决定分片被分配到哪个节点
负责索引的创建与删除
维护并且更新cluster state
主节点
数据节点
查询节点
部落节点
给字段增加属性
append
对字段类型进行转换
covnert
将字段解析成一个标准文档的格式
grok
将文档分配到符合指定时间格式的索引中
date_index_name
对字段值进行正则匹配替换
gsub
将原本一个数组类型的字段值,分解成以指定分隔符分割的一个字符串
join
将字符串格式的字段转换成一个标准的 JSON 格式
json
kv
对字段值转换为小写
lowercase
对字段值转换为大写
uppercase
删除原文档中的某些字段值的
remove
修改某个文档的字段的名称
rename
用于将一个以指定分隔分开的字符串转换成一个数组类型的字段
split
将某个数组类型的字段中的元素按照升序或降序来对原元素进行排序
sort
pipeline
PUT _ingest/pipeline/管道处理名称{ "processors": [ { 处理器定义 } ]}
定义pipeline
PUT 索引名称/_doc/1?pipeline=管道处理名称
应用pipeline
预处理节点,Ingest node
节点类型
节点
/_cat/nodes
分片
/_cat/shards
索引
/_cat/indices
段
/_cat/segments
cat API
索引可见
默认1秒发生一次
refresh
索引落盘持久化
默认30分钟调用一次
flush
_snapshot/backup
_snapshot/backup/_restore
备份、恢复
master选举,只有候选主节点(master:true)的节点才能成为主节点
最小主节点数(min_master_nodes)的目的是防止脑裂
若两节点都为候选主节点,则 id 小的值会主节点
选举
if_seq_no + if_primary_term
内部版本控制
version + version_type=external
外部版本控制
乐观并发控制
indices.breaker.total.limit所有breaker使用的内存值,默认值为 JVM 堆内存的70%,当内存达到最高值时会触发内存回收
Indices Circuit Breaker
indices.breaker.fielddata.limitfield数据使用内存限制,默认为JVM 堆的60%
indices.breaker.fielddata.overheadelasticsearch使用这个常数乘以所有fielddata的实际值作field的估算值。默认为 1.03
Fielddata circuit breaker
indices.breaker.request.limitrequest数量使用内存限制,默认为JVM堆的40%
indices.breaker.request.overheadelasticsearch使用这个常数乘以所有request占用内存的实际值作为最后的估算值。默认为 1
Request circuit breaker
断路器
管理
所有的节点信息
所有的索引和其相关的mapping、setting信息
分片的路由信息
每个节点上都保存了集群的状态信息
只有master节点可以修改集群状态信息
cluster state
hot
warm
cold
delete
生命周期策略与索引模板的rollover
生命周期
索引别名可以指向一个或多个索引
字段别名
别名
open、close
shrink、split、rollover
mmapfs:index映射到内存
niofs :并发多线程以NIO的方式读取index文件
索引存储类型(index.store.type)
index
7.0版本后已废弃,默认只有_doc
type
代表一条数据
document
日期型:date
布尔型:boolean
二进制型:binary
对象类型: object
嵌套类型: nested
地理坐标类型: geo_point
地理形状类型: geo_shape
IPl类型:ip
计数数据类型: token_count
数据类型
field
enabled:仅存储、不做搜索和聚合分析
analyzed:字段被索引,会做分词,可搜索
not_analyzed:字段值不分词,会被原样写入索引
no:字段不写入索引,当然也就不能搜索
docs:索引文档号
freqs:文档号+词频
positions:文档号+词频+位置,通常用来距离查询
offsets:文档号+词频+位置+偏移量,通常被使用在高亮字段
分词字段默认是positions,其他默认时docs
index_option:存储倒排索引的哪些信息
字段标准化规则;如把所有字符转为小写
normalizer
norms:用来计算文档/字段得分(Score)的"调节因子"、如果字段仅用于过滤和聚合分析、可关闭
用于字段的排序或者聚合
支持大部分字段类型,但是text 字段类型不支持
占用磁盘空间
doc_value
fielddata:是否为text类型启动fielddata,实现排序和聚合分析
store:是否从_source字段中分离,只能搜索,不能获取值,占用内存空间
coerce:是否开启自动数据类型转换功能
multifields:灵活使用多字段解决多样的业务需求
dynamic:控制mapping的自动更新
data_detection:是否自动识别日期类型
analyzer:指定分词器
boost:字段级别的分数加权
fields:可以对一个字段提供多种索引模式
ignore_above:超过设置个数字符的文本,将会被忽略,不被索引
null_value:设置一些缺失字段的初始化,只有string可以使用,分词字段的null值也会被分词
similarity:默认时TF/IDF算法,指定一个字段评分策略,仅仅对字符串型和分词类型有效
指定某几个字段拼接成自定义
copy_to
字段属性
默认会存储一份_source字段作为原始文档
_source
通用属性
mappings
number_of_shards\t分片数
number_of_replicas\t副本数
mappings\t结构化数据设置 下面的一级属性 是自定义的类型
properties\t类型的属性设置节点,下面都是属性
epoch_millis\t表示时间戳
settings
逻辑存储
shard_num = hash(_routing) % num_primary_shards
routing默认是文档ID
路由
_primary:只查询主shard,也就是说不管你有多少个副本,只对主shard进行检索,这种场景可以用在所有副本不可用的时候,强制读取主shard数据。
_primary_first:优先读取主shard,如果主shard无效或者失败,则会读取其他shard
_replica:只查询replia
_replica_first:优先查询replia,如果replia无效就查询其他的shard
_local:尽可能在本地执行查询,不跨网络
_only_nodes :限制在特定的node上执行操作
偏好
副本
tiered(默认)
log_byete_size
log_doc
合并策略
段文件,存储提交点信息
segments.gen、segments_N
锁文件,用来阻止多个indexWriter向同一个文件写数据
write.lock
段信息,存储段的元数据信息
.si
复合文件,一个可选的虚拟文件,包括所有其他索引文件系统频繁用完的文件句柄
字段信息,存储字段的信息
.fnm
字段索引,包含指向字段值的指针
.fdx
字段数据,存储文档里面的字段信息
.fdt
词典,存储词信息
包含每个字段中的术语列表,以及每个术语的统计信息(比如docfreq),以及指向.doc、.pos和.pay文件中的频率、位置、有效负载和跳过数据的指针
.tim
词索引,指向词典的索引
为每个字段都包含一个独立的FST。FST可以将一个term前缀映射到磁盘块上。这个磁盘块保存了以这个前缀开始的所有term
.tip
频率信息,包含那些含有每一个词的频率的文档列表
.doc
位置信息,存储词在索引中出现的位置信息
.pos
额外存储每个位置的元数据信息,如字符偏移和用户负载
.pay
文档和字段的length和boost系数的编码
额外的得分系数或者每个文档的值信息编码
词向量索引,存储文档的偏移数据文件
.tvx
词向量文件,包含有词向量的文档信息
.tvd
词向量字段,关于词向量的字段级信息
.tvf
删除文档,关于什么文件被删除的信息
.del
Lucene文件存储
物理存储
包括了indexing buffer和其他ES运行需要的class。indexing buffer由indices.memory.index_buffer_size参数控制, 默认最大占用10%,当full up后,该部分数据被刷入磁盘对应的Segments中。这部分空间是可以被回收反复利用的
common space
是node级别的filter过滤器结果缓存,大小由indices.queries.cache.size 参数控制,默认10%。使用LRU淘汰策略
queryCache
requestCache
fieldDataCache
segmentsMemory
内存
存储结构
ik_max_word
ik_smart
分词器
字符串查询
name: acchu nagesh:查询name包含acchu和nagesh其中的任意一个book.\\*:(quick OR brown):book的任何子字段比如book.title和book.content,包含quick或者brown_exists_: title:title字段包含非null值name: acch*:通配符,匹配任何acch开头的字段name:/joh?n(ath[oa]n)/:正则表达式,需要把内容放到两个斜杠/中间name: acch~:模糊匹配,默认编辑距离为2,不过80%的情况编辑距离为1就能解决问题name: acch~1count:[1 TO 5]:范围查询,或者count: >10
query_string
+表示AND操作
|表示OR操作
-表示否定
"用于圈定一个短语
*放在token的后面表示前缀匹配
()表示优先级
~N放在token后面表示模糊查询的最大编辑距离fuzziness
~N放在phrase后面表示模糊匹配短语的slop值
simple_query_string
关键字查询
term
数据类型自动转换
字段是keyword,查询时不会对查询条件进行分词
字段可以分词,查询时条件会进行分词
match_all
match
multi_match
id匹配
ids
前缀匹配
prefix
纠错模糊查询
fuzzy
通配符查询
wildcard
数值类型范围查询
range
正则查询
regexp
嵌套查询,数据属性是数组的可以单独建立索引匹配
nested
from size
记录最后的排序边界值,根据边界值进行后续分页查询
search after
缓存所有记录,不支持实时分页查询
GET /索引库名称/_search?scroll=保存时长&scroll_id=xxx
scroll
分页查询
pre_tags
post_tags
fragment_size
highlight
must
must not
should
minimum_should_match
不会计算评分,效率更高
bitset机制缓存数据
filter
bool查询
positive
negative
negative_boost
boosting查询
复合查询
查询类型
聚合查询类型
"avg_bucket" : { "buckets_path": "聚合计算的权值对象" }"max_bucket" : { "buckets_path": "聚合计算的权值对象"}"min_bucket" : { "buckets_path": "聚合计算的权值对象" }"sum_bucket" : { "buckets_path": "聚合计算的权值对象" }"stats_bucket" : { "buckets_path": "聚合计算的权值对象"}
管道聚合类型
搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch
在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)
每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列,每个分片返回各自优先队列中所有文档的 ID 和排序值给协调节点
协调节点合并这些值到自己的优先队列中来产生一个全局排序后的结果列表
接下来就是取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并丰富文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端
搜索的时候是会查询Filesystem Cache的,但是有部分数据还在Memory Buffer,所以搜索是近实时的。
处理流程
从TermStats中拿到当前term的DF值(即出现了该term的文档数量)
从TermMetadata中拿到对应的指向.doc中的跳跃表,docIdList的指针,指向.pos .pay的指针等
倒排查询
搜索
统计聚合查询
avg/sum/min/max/stats
数值以内的所占百分比
percentiles
扩展统计聚合查询
extend_stats
去重计数查询
cardinality
metric
范围统计查询
直方图聚合查询
histogram
基于索引内字段值动态聚合查询
terms
bucket
结果内嵌到现有的聚合分析结果中
parent
结果与现有聚合分析结果同级
sibling
聚合
分片数一般根据节点数设置
索引分片数初始化后不能修改,扩容的话需要通过reindex进行索引重建
索引分片数的设计和扩容
相同索引别名的物理索引有 一致的Mapping和数据结构,以提升检索效率
批量大小值可能太小。需要结合堆内存、线程池调整大小好的起点是每批处理5-15 MB,默认一批处理1000条
借助scroll的slices提升写入效率针对单索引,slices大小=分片数;针对多索引,slices=分片的最小值
目标索引副本数设置为0
目标索引增加refresh间隔
reindex性能优化
不需要评分,字段的norms设置为false
不要默认string类型映射,会同时生成text和keyword类型,浪费空间
动态索引基于模板+时间+rollover api 滚动创建索引,冷热数据分离,定期forcemerge和shrink压缩操作
java heap通常设置为32G以下,否则Zero-Based Compressed Ordinary Object Pointers (oops)不会被启用,将会导致更多的内存消耗
关闭不需要字段的doc values
关闭不需要查询字段的_source功能,不将此存储在ES中以节省磁盘空间
关于排序:我们增加一个long字段,它用于存储时间和ID的组合(通过移位即可),正排与倒排性能相差不明显
关于CPU消耗,检索时如果需要做排序则需要字段对比,消耗CPU比较大,如果有可能尽量分配16cores以上的CPU,具体看业务压力
关于合并被标记删除的记录,设置为0表示在合并时一定删除被标记记录,默认应大于10%才删除:"merge.policy.expunge_deletes_allowed":"0"
方案一:针对精确度要求高的方案:两套分词器结合,standard和ik结合,使用match_phrase检索。
方案二:针对精确度要求不高的替代方案:建议ik分词,通过match_phrase和slop结合查询
数据量级达到TB+甚至更高之后,wildcard在多字段组合的情况下很容易出现卡死
禁用swapping,设置bootstrap.memory_lock:true,锁定内存
fielddata内存大小默认没有限制,可能导致频繁的OOM。建议修改配置项indices.fielddata.cache.size: 10%控制大小,避免堆内存不够GC压力过大
性能优化
增加scroll context的配置数量,这个消耗内存,根据机器配置设置一个合理值,一个数据分片会占用一个context
游标查询结束后及时清理,释放context,避免并发大时context超出最大限制
使用游标查询,scroll context超过限制
分片有最大数的限制,默认是单个节点有1000个分片,总共允许的分片数=单节点最大分片数*节点数
索引分片数限制
查询的短语数限制,默认值的1024,如果bool查询短语超过限制会报错
绝大部分堆内存主要被 FST( Finite State Transducer )占用了
慢查询模板
FAQ
AbstractQueryBuilder
使用QueryBuilders创建
query
ValuesSourceAggregationBuilder
使用AggregationBuilders创建
aggregation
from
size
SearchSourceBuilder
source
SearchRequest
SearchScrollRequest
ClearScrollRequest
SearchResponse
查询API-RestHighLevelClient.search()
CreateIndexRequest
创建索引API-RestHighLevelClient.indices().create()
DeleteIndexRequest
删除索引API-RestHighLevelClient.indices().delete()
IndexRequest
新增或更新文档API-RestHighLevelClient.index()
DeleteRequest
删除文档API-RestHighLevelClient.delete()
BulkRequest
批量操作文档API-RestHighLevelClient.bulk()
高阶API
ActionPlugin
BaseRestHandler
自定义rest接口服务
IngestPlugin
AbstractProcessor
自定义pipeline processor
<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>${elasticsearch.version}</version><scope>provided</scope></dependency>
maven依赖包引入
开发
基于sql查询数据
SELECT [ COUNT | AVG | SUM | MIN | MAX | STATS | EXTENDED_STATS ] FROM INDEX_NAME GROUP BY [DATE_HISTOGRAM | RANGE | DATE_RANGE | TERMS ]
1、where语句不支持数学运算表达式2、不支持子查询里有GROUP BY or ORDER BY3、join只支持两个索引进行join操作,join的索引必须使用别名4、join 的on条件参数只支持and拼接5、不支持对join的结果做聚合,join不支持group by6、只支持基本查询的分页,不支持join查询的分页7、支持指定分片语法 SELECT /*! ROUTINGS(DT) */ * from book-index
语法限制
扩展sql样例
opendistro_sql
第三方插件
插件
ElasticSearch
0 条评论
回复 删除
下一页