ElasticSearch
2024-10-24 15:33:29 3 举报
AI智能生成
ElasticSearchV7.8
作者其他创作
大纲/内容
产品初认识
官网
什么是ElasticStack
官方的生态
Logstash
Beats
ElasticSearch
Kibana
Es-Hadoop
发展历史
应用场景
全文搜索领域
Elasticsearch基于Lucene打造,全文索引支持多种文本/语言(中文,英文,数字,特殊符号)分词(插入:整个中文搜索领域是非常难的,国内语义搜索方面做的最好的是百度),关键词文本搜索——可应用在企业知识库、电商商品搜索、以及其它垂直搜索业务领域。也就是说,用ES来做的话,只能做到比较初级的----基于分词来做;
如果你要做的更高一层的话,需要了解另外一个领域---机器学习排序模型(LTR)
电商关键词商品搜索,这种引导式的查询,ES已经做得非常好了
目前,在搜索领域,专门做分词的这个领域,项目需求是越来越少,不建议在该领域深挖。当然,这里整理了一下,文本分词涉及到的技术点--文本分词深入探查:
文本分词应用场景有哪些
文本分词涵盖哪些能力
文本分词使用有哪些局限
中文分词领域探查
自定义分词如何实现
地理应用
地理位置应用搜索,集成Geohash算法,支持大规模的地理位置搜索,结合自生的分布式特性,可以满足海量数据Geo检索。应用在大规模的轨迹项目上,如:物流汽车运输领域,快速检索出汽车历史轨迹路径范围。 据了解,早期,滴滴用的是MongDB来进行大规模的Geo查询,现在,有了ES之后,完全没有必要
向量检索
向量检索,跟机器学习或人工智能有点挂钩,Elasticsearch内置Dense Vector字段类型,借助三方向量产品可以将文字、语音、图片、视频等转换为一个向量坐标,存储在ES中,供业务进行相似性与相关度检索,应用在图片相似、类似语音、问答系统、推荐系统领域。
业务系统查询加速
关系型数据库有严格的事务特性,能保证数据的可靠性,但在应对海量数据查询方面比较弱,分库分表只是解决了存储的问题,并没有解决分库分表合并查询,海量数据查询,复杂条件组合查询等关系型数据库的查询性能瓶颈问题。业界通用的做法会采用DB+ES混合的策略,将数据实时同步到Elasticserch中。
另外,在关系型数据库里面,比如有张表,数据量已经有几千万了,这张表有几百个字段,我要基于任何字段都可以自由组合查询,并且顺序不定,此时索引不管你怎么优化,关系型数据库都是无能为力的。此时,就可以用ES来解决,所有的字段,都给你建立索引--全量索引。
另外,在关系型数据库里面,比如有张表,数据量已经有几千万了,这张表有几百个字段,我要基于任何字段都可以自由组合查询,并且顺序不定,此时索引不管你怎么优化,关系型数据库都是无能为力的。此时,就可以用ES来解决,所有的字段,都给你建立索引--全量索引。
关系数据库与ES怎么结合的呢?
大数据领域
大数据领域,其实算是ES发展的一个方向吧。其强大的数据处理能力,提供Hadoop对外的数据查询服务;通过其自带的大数据处理能力---聚合,转换,上卷, 大规模明细查询。ES非常擅长海量数据查询,大数据计算平台将海量数据经过计算之后,需要把最终的结果数据或者半结果数据存储起来,提供外部查询,传统的做法会选择关系型数据库承载,很容易到达性能瓶颈,此时会搭配Elasticsearch替代;另外ES自有生态也可以进行数据的计算,如:简单场景的数据实时计算,可以直接基于聚合实现。
下面用一副Hadoop+Es混合大数据解决方案场景图,来表明一下ES的地位。
下面用一副Hadoop+Es混合大数据解决方案场景图,来表明一下ES的地位。
日志平台
统一日志平台,采集所有日志,系统日志,程序日志,业务日志;也可以存储所有类型日志----因为ES它是不限制表类型的,可以自由组织架构的这种结构,不限制表的这种结构类型的;查询所有日志----因为它的索引算法相当厉害;分析所有日志----因为它有自带的大数据的处理能力,可以做一些简单的分析图表,告警之类的工作;ES非常适合海量日志存储查询,早已成为业界通用日志平台的代名词,只要遇到日志查询分析需求,第一时间想到的就是ELK。
下面是一些ES已经支持的一些基础中间件的日志采集,都自带可以直接采集的组件,不需要我们过多的去编写规则,只需要指定目录文件位置,命名就可以啦。
基础监控
在基础监控领域,有很多成熟有名的产品,Elastic Stack作为后期之秀快速崛起,得益于其通用数据平台能力,其它基础监控产品多数仅支持指标数据,不支持其它类型,而ES几乎一网打尽,尽量使用一个通用平台搞定所有的监控需求。ES进行指标采集之后, 又可以通过设置字段的排序,把它变成一个时序数据库。如下图用的是ES自带的产品的基础监控指标
APM应用性能监控
同样的问题,研发人员不仅需要应用程序的监控信息,也需要采集应用程序的运行日志,而这又是Elasitc Stack的优势。在APM应用性能监控方面,ES不是最强的,但是作为一个平台级生态应用,ES可以将监控方面的工作一网打尽,在后面的工作中,在一个平台我就可以完成所有的监控。支持Java/Go/Python/.Net/Node.js/JavaScript。下图展示了Java的接口API调用,,一直到数据库的性能情况。
网络安全分析
网络安全分析预测,通过机器学习算法训练,分析预测潜在的网络安全风险。例如,公司有很多人访问很多机器,但是有黑客进来了,我们不知道,但是黑客的行为比较怪异,我们就可以通过ES监测到,从而限制它。Elastic Stack支持多种数据采集,指标数据、文本数据、网络数据等,这些数据组合在一起,可以进行机器学习分析,依据机器学习算法(聚类算法),可以分析出异常点,这个特性非常完美的契合网络安全,可以自动的发现潜在的安全威胁。下图是通过过往数据分析发现某一段时间,数据存在异常行为的异常事件检测分析图。
产品安装与部署
可参考
产品使用指南
索引创建篇
索引创建规范约束以及索引数据模型设计
索引创建规范约束
索引创建规范理论
索引是什么
index索引是个虚拟空间,类似关系型数据库中table;
一个索引至少由1个分片组成;
一个索引可以由主分片和副本分片组成;
索引别名
是什么
索引是虚拟表空间,索引别名则是在索引之上又一层虚拟的索引空间;索引别名默认等同于索引名称;
应用场景
索引重建之后快速切换,应用无感知
索引命名
命名规范建议
业务类型:索引名+数字版本
日志类型:索引名+日期时间
tips
ES索引有重大变更(增加很多字段,改变字段等),建议新建索引,原数据抽取过来;
应用意义
维护管理方便
数据隔离
查询便利
模糊匹配
精确指定索引
举例说明
索引创建方式
动态创建
概念
索引无需提前创建,第一条数据插入即可创建完成;
应用场景
非严格数据模型限制规范的场景,日志,监控
索引模版
通常采用索引模板固定下来里面的字段类型,长度等
可限制自动机制
限制索引名称,限制索引自动创建
应用举例
静态创建
概念
依据客观背景提前创建好索引,提前做好索引数据分布与相应设置
应用场景
业务系统数据需要严格规范;索引分布在极端情况下需要消耗集群资源,避免集中创建索引时,集群响应慢;
应用举例
滚动创建
概念
利用别名alias,利用rollover特性,自动化滚动创建,达到一定阈值创建;新版本才有该特性;
解释:通过别名,代理一个索引,当达到一定阀值(时间,索引大小,磁盘大小,文档数量)时,滚动创建下一个索引
解释:通过别名,代理一个索引,当达到一定阀值(时间,索引大小,磁盘大小,文档数量)时,滚动创建下一个索引
应用场景
日志领域,需要自动化依据触发条件滚动创建;
大数据领域,单索引能力局限需要创建很多;
索引设置
静态设置
索引分片
默认1,创建索引时需要指定,之后索引活动期间,不可变,后期只能重建;根据具体情况,进行评估;一个分片大概存储20~40GB的数据
索引字段类型
字段类型不可变,一旦指定几乎不可变,若要修改,则需要刷新所有历史数据,等同于索引重建;
索引创建规范实际操作
索引创建
动态创建
静态创建、指定别名、滚动创建
索引文档数据模型设计
与关系型数据库对比
数据模型对比
数据库=ES集群
一个关系型数据库等同一个ES集群
数据表=ES索引
一个数据表等同一个ES索引,新版本不支持一个索引多个type
行记录=ES文档
一条数据等同一条ES文档
ES文档模型介绍
文档模型
文档模型
JSON类型
元数据
_index
_type
_id
_version
_seqno
_primary_term:主分片的版本序列号,为了解决主分片挂掉后,后续副本分片升级为主分片后,加以区分;
...
源数据
json结构化
文档模型的种类
平铺型
概念
Json结构平铺
特点
结构简单,解析效率高
应用场景
与数据表1-1对应;常规查询搜索;
对象型
概念
Json对象嵌套
特点
结构复杂,解析效率低,维护成本高,注意控制深度
应用场景
复杂业务场景,复杂对象映射表达
数组型
概念
Json数组对象
特点
解析效率低,维护成本高,注意控制深度
应用场景
常规数据记录
关联类型
概念
父子关系:join字段类型;键值对关系:nested字段类型
特点
结构复杂,解析效率低,维护成本高
应用场景
问答场景,上下文关系,键值对关系,实际应用较少
实际操作
平铺型&对象型操作
数组型操作
索引设计经验建议
索引与分片与副本关系
分片数量
索引分片数量不超过节点数量;1个索引40个分片等同于40个1分片索引
副本数量
索引副本数量少于节点数量;副本数量可多可少
分片容量
数据容量
分片数据容量上限不超过50GB,建议20GB-40GB
数据条数
单分片不超过2的32次方-1(21亿条)
数据模型设计原则
简单模型原则
能用平铺模型搞定,尽量平铺;对象深度建议不要超过2级
最细粒度原则
对象嵌套遵循最细粒度原则,上层数据冗余处理
多索引原则
单一索引尽量满足单一业务场景,不同业务场景索引即使数据模型相似也要分开
大宽表原则
特殊场景合并多个表时,尽量全部合并在一起;ES不支持Join,大宽表可解决查询问题;
实际应用举例
某物流派单项目
模型介绍
多个DB表;一个索引;大宽表结构;
应用场景
查询场景,对象型
常规数据类型字段应用
常用字段类型
数据字段类型体系介绍
字符串
text
文本类型
按规则分词,分成至少1个词,默认分词器standard
应用场景
text,用于需要分词检索的场景,当然也可以禁用分词,最好不要有空值,对性能是很大的浪费
tips
使用分词会使性能有所下降
keyword
关键词类型
不分词,仅仅一个词,早期6.x之前,使用String,通过设置分词属性区别
应用场景
固定文本信息,无需全文检索场景,姓名,省份,商品类目,精准匹配
字符类型背后算法
text,keyword类型
倒排索引
实际使用
注意,上面text类型可以设置分词器,standard是一个内置的分词器,keyword类型不可以设置分词器
简单演示下分词器是如何分词的
数值类型
整数
Long类型
空间占用:64bit
Integer类型
空间占用:32bit
short类型
空间占用:16bit
byte类型
空间占用:8bit
实际使用
创建对应字段类型的索引,创建索引中对应的字段,根据实际的场景,考虑实际的类型,可以避免很多性能的问题;
浮点
Double
64bit
Float
32bit
Half float
16bit
Scaled float
缩放浮点类型,背后基于Long类型实现,会出现精度问题
实际使用
tips
浮点类型精确统计会出现精确性问题,为了避免问题,建议使用整数类型
日期类型
date
日期格式化
format,支持多种自定义格式
tips
建议使用UTC时间格式,一定要使用UTC
实际使用
数值类型背后算法
整型,浮点型,日期类型
BDK树算法,底层存储压缩
复合字段类型
对象类型-object
表现形式
Json对象形式,可以嵌套多种子对象,最多三层;
内部存储实现
内部存储实际非json,通过分隔符建立嵌套关系,字段命名不可以采用分隔符
实际使用
创建包含复合字段类型的索引
数组类型-array
说明
ES未定义数组类型,仅仅是支持,类似object方式支持的,但无需设置,填充数据时设定数据样本即可
支持类型
一维数组,多维数组,对象数组
实际使用
范围类型-range
说明
底层采用BDK树类型
范围类型
整型范围
integer_range
浮点范围
日期范围
IP范围
tips
当我们不知道范围类型时,会用两个字段来存储
应用场景
如,衣服尺寸适合,XL(175~185)
实际使用
创建索引
插入数据
查找数据
索引mapping
索引结构化约束Mapping
Mapping映射
概念介绍
Mapping概念/用途:规范ES索引里面字段的行为
原始数据
其实Es在存储数据时,会存储好几份,其中一份叫做原始数据,它不会改变里面的任何数据,会存到其中某一个文本文件里面去,然后把你的结构按照行式存储起来,它仅仅支持这种key-value的结构查询。所以ES也常常和其它产品搭配使用,例如Cassandra,Cassandra是列式存储db,ES如果和列式数据库结合的话,它就不需要存储source数据。例如HBase存储数据,想做搜索又不好做,那就可以混搭ES来实现搜索。
_source属性默认启用,
_source限制存储字段,包括includes与排除excludes
实际使用
其实在海量数据查询的情况下,例如MySQL里面有几百T的数据,但是想基于这几百T做检索,如果都把它们放ES里面来,加索引,那会非常大,如果把原始数据禁掉的话,ES其实不会很大,一个索引200G估计就可以啦。
映射机制
自动机制
可以通过dynamic,控制索引字段;
禁止映射
dynamic为false
严格机制
字段类型自动检测
field_detect
日期类型自动推断
默认启用,必须要符合对应格式
数值类型自动推断
默认启用
字段模式设计运用
单字段与多字段
系统版本号场景
ES版本号,7.8.1
默认采用1个字段
建议采用3个字段
默认采用1个字段
建议采用3个字段
text与keyword
数值与词项
没有分词的场景的话,不要设置text类型,浪费空间和性能
keyword底层是倒排索引,如果是基于键值查询,keyword类型的性能要远远好于整型和浮点;如果存入的数据,仅仅是为了展示,等号类的查询不要用keyword
整型与浮点
数值与范围
索引字段设计限制
字段数量限制
字段数量限制1000个,当然可以修改
对象字段深度限制
官方限制20层,但尽量不要超过3层
字段命名规范设计
驼峰,全小写_拼接
特殊数据类型字段应用
关联字段类型应用
父子类型-join
概念定义
数据存在父子(一对多)关系;
一条数据可以有多条子数据;
一条子数据仅一条父数据;
优点
数据更新,分离影响
注意事项
父子数据必须在同一分片上;
父子层级深度要注意;
一个索引仅容许一对父子关系约束;
一个父关系可以支持多个子对应关系;
应用领域
具备父子关联的数据需求,例如父子公司
实际使用
创建索引
插入一条父级数据,并查找
插入父级数据和子级数据,并指定分片和绑定父子关系
嵌套类型-nested
概念
数组键值对查询会出现数据查询误差,nested解决键值对查询误差
内置实现
存储多条文档数据,通过内置查询关联合并为一条数据;不建议使用
注意嵌套深度,单条嵌套数据量条数有限制
实际使用
这里插入数据,数组两个元素,其实ES会拆成两条数据
上面的查询条件,就不应该查到数据,因为数组中的同一个对象中没有province为HN且city为HZ的数据
所以nested就是为了解决数组键值查询出现的误差问题,解决方案如下
下面的查询不应该查询到数据才对,如图所示。修改查询条件,province为HN,且city为CC就可以查到数据啦
辅助字段类型应用
别名类型-alias
别名应用
字段代理,字段指向,避免直接暴露原始字段,可以支持多个别名
注意事项
数据不可以更新,别名不存储任何数据,仅仅是路径指向
实际使用
平铺类型-flattened
概念定义
对象object类型的一种改进版本,对象object类型可以动态扩展很多字段,flattend就当成是一个字段,且保证原来的json格式
应用领域
限制索引字段数量,就当成一个字段;
限制索引字段深度;
日志领域,子字段数量与深度不可提前预知;
数据字段与索引字段分离;
实际使用
object类型的area字段,在插入数据时,可能会动态插入很多的字段。
flattened类型的数据,里面的数据值,在ES中不可被检索。可以通过其它条件查询带出来,然后通过Java代码,反序列化出来。
固定值类型-constant_keyword
概念定义
固定的值,无论客户端是否填充,都具备固定的值;固定值字段数据不可二次修改
应用领域
标识数据元数据,安全限制
实际使用
多字段类型-fields
概念定义
一个字段用途多种场景,可设计为多种类型同时支持。原数据仅存储一份,节约空间
应用领域
多用途多场景检索需求如:字符检索效率比数值要高效
实际使用
复制类型-copy_to
概念定义
字段数据来源取其它字段,在原数据中不存储
应用领域
多字段同时组合检索,节约组合字段空间资源
实际使用
假定公司基本信息有地址,地址信息需要省份,城市,区县等组成
地理与图形类型应用
地理位置类型
关键字
geo_point
lat:维度
log:经度
概念介绍
基于经纬度坐标,应用于地址位置检索领域,底层采用GeoHash算法
实际使用
假定公司基本信息应该具备地理坐标信息
地理图形类型
关键字
geo_shape
概念定义
基于地理位置坐标点,扩展了地理位置多边形区域搜索类型,应用于基于地理位置的图形检索
多边图形类型
关键字
shape
概念定义
2D平面类型检索,支持多边形,应用与平面图形检索
特殊行业字段应用
网络地址
关键字
ip
tips
支持IPv4,IPv6
直方图类型
词项统计数
自动完成类型
向量类型
关键字
dense_vector
概念定义
应用于图片相似度检索,问答关联性检索,人工智能领域
特殊字段类型应用注意事项
多字段类型应用
特殊字段类型背后的算法机制
个性化设置数据字段属性
常用数据字段属性应用
字段属性
能否查询
关键字
index
概念介绍
字段是否可以被搜索,取值true/false,默认true,可以被搜索,false不可被搜索;
例如ES里面某些字段,只是用来做存储,不会用来做检索
例如ES里面某些字段,只是用来做存储,不会用来做检索
实际使用
数据索引读写分离的操作,例如一个索引有1000个字段,其中500个字段,只用来存储原始数据,不用来检索,那索引其实也没有多大。可以通过前面说到过的_source的include和这里的index来控制,哪些数据可以用来做搜索,哪些数据可以用来存储原始数据。
tips
_source用来控制存储原始数据,index用来控制存储索引数据
是否存储
关键字
store
概念介绍
ES默认原始数据存储在_source里,其实也可以在Lucene里面存储一份,通过此关键字控制取值范围,true/false,默认false,不存储;
先创建mapping,后续插入数据,对应的mapping才会生效。后续修改mapping,需要重建索引,后续数据才会生效;
先创建mapping,后续插入数据,对应的mapping才会生效。后续修改mapping,需要重建索引,后续数据才会生效;
应用场景
原始数据_source被禁用,也需要修改原始数据,可以在lucene里存储一份,在数据量比较少的时候,检索效率会高很多
实际使用
能否启用
关键字
enable
概念解释
设置字段是否需要被检索,类似index属性,用于对于未知object类型的设置,取值范围true/false,默认为true
应用领域
部分应用领域,一些数据仅仅需要数据字段,不需要被检索与创建查询索引,一般用于对于object类型设置,免于设置太多。
实际使用
当enable设置为false时,area字段仅存储数据,ES不会自动推断mapping。
当ES作为一个大宽表时,里面的索引字段非常多,通过enable把数据和索引分离开,是非常有用的。
能否聚合排序
关键字
doc_value
概念解释
列式数据存储,ES数据存储原始数据一份,列式存储一份,默认有2份数据,取值范围true/false,默认为true;
doc_value对于text类型是没有意义的,但对于keyword类型是有意义的。
doc_value对于text类型是没有意义的,但对于keyword类型是有意义的。
应用领域
基于该字段做聚合分析,基于该字段做排序
实际使用
默认空值
关键字
null_value
概念介绍
空置默认值,ES容许可以不设置字段,没有数据库必须填充选项。此处与数据库里面的默认值有区别,
ES并不会存储这个值,也就是_source中不会存储,仅仅用来做索引检索。
ES并不会存储这个值,也就是_source中不会存储,仅仅用来做索引检索。
应用场景
程序性能提升,避免程序数据异常错误
实际使用
子对象控制
关键字
properties
概念解释
数据模型多种多样,有的需要严格的设置,通过properties来扩展里面的属性
实际使用
子对象动态扩展
关键字
dynamic
概念解释
是否容许对象下面的属性自由扩展,取值范围true、false,strict,默认true;
应用场景
严格限制子对象下面的字段行为,如果在mapping级别上用,整个都是不允许的,用在子对象中,可以灵活控制;
实际使用
字符串长度限定
关键字
ignore_above
概念解释
keyword类型下,字符过于长,检索意义不大,索引会被禁用,数据不可被检索
应用场景
基于keyword类型检索应用,超过限定长度就无法检索出来
实际使用
多字段
关键字
fields
概念解释
多字段属性
应用场景
同一个数据字段,需要满足同时多种业务应用
实际使用
数值强制性约束
关键字
coerce
概念解释
数值类型并非一直符合标准,有的会带一些格式之类的,取值范围true,false,默认false
应用场景
数值类数据写入强制限制,避免数据格式出错
实际使用
高级数据字段属性应用
分词器
关键字
analyzer
概念解释
全文检索分词器,为了兼容原来的lucene,提供了很多的分词器。
分词器关联算法
关键字
similarity
概念解释
全文检索分词之间关联度计算算法
加权
关键字
boost
概念解释
全文检索基于多字段时,部分字段权重设置大一些,优先选择
分词规范化
关键字
norms
概念解释
全文分词检索,需要依据分词打分,分词会提前生成相关参数因子,此特性用于设置是否要生成
规整器
关键字
normalizer
概念解释
针对keyword数据类型,部分数据需要做统一大小写处理等逻辑
字段数据
关键字
fielddata
概念解释
全文分词字段做聚合统计,需要将一些分词数据存储在内存中,加快聚合效率,不推荐
全局序号
关键字
eager global ordinals
概念解释
keyword数据类型term聚合时,需要加快检索效率,可提前将数据生成全局序号,而不必等需要聚合时生成,基于此特性
AQ
问题1:mapping如何修改?修改后的数据有影响不?
mapping修改通过特定语法;PUT 索引名称/_mapping{}
修改后,原来的数据按照原来的mapping走,新数据按照新的mapping走,所以不建议这么干;
修改后,原来的数据按照原来的mapping走,新数据按照新的mapping走,所以不建议这么干;
运用字段动态映射灵活扩展
索引元数据字段
元数据字段有什么用
一条文档数据之外的数据,就叫元数据,它限制了ES的行为,便于后期管理,元数据属于ES的产物,不属于Lucene
应用场景
存储原数据之外的数据,部分属于ES必须,部分属于自定义
标识性元数据
索引名称
概念解释
索引名称元数据,数据增删改查,都需要指定索引名称
_index,元数据关键字
索引类型
概念解释
索引类型是个过时的产物,这里不做过多的解释,索引使用时,需要设定索引类型
跟随在索引名称之后,7.0之前必填,7.0之后固定值_doc,8.0之后移除
_type,元数据关键字
文档ID
概念解释
数据唯一标识。一条文档数据必须有一条ID;一个索引中必须唯一;默认采用自动生成,规则参考objectid算法(类似雪花算法)规则;
可以自己指定,不限制类型,可同时存储数字与字符;ID长度限制512字符;
_id,元数据关键字
实际使用
文档数据元数据
关键字
_source
概述
属性控制存储原始数据
现在业界用ES时,会禁用_source,只存储索引字段,Hbase存储原数据,方便查询
路由元数据
关键字
_route,设置数据分布的分片位置
概述
ES是分片架构设计,文档数据写入需要指定分片位置,路由字段默认数据ID;
实际使用
插入数据时,需要计算hash,设定路由分片位置
自定义元数据
概述
自己定义存储元数据值,有时候,需要在原始的索引mapping里面存一些私货,便于我们追查。
关键字
_meta
实际使用
索引字段静态映射
概述
前面,我们通过在ES索引的mappings里面使用properties字段,来静态化的映射所有字段。这里不在详细展开
字段静态映射
关键字
static
概述
静态设置,提前知晓所有字段,设置好字段的类型与属性
索引字段动态映射
动态字段
关键字
dynamic field
概述
ES默认具备字段推断能力
日期自动检测
关键字
date_detection,关键字,取值范围true、false,默认true
dynamic_date_formats,关键字,设置日期格式
概述
是否启用日期类型自动检测,取值范围true/false,默认自动开启
实际使用
数值类型自动检测
关键字
numeric_detection,关键字,取值范围true/false,默认true
概述
是否启用数值字段自动检测,取值范围true/false,默认true,数值字段检测依据字符本身,可推测出整数,浮点
实际使用
tips
实际使用中,建议提前规划好索引字段,建议关闭自动检测,不然让ES去推测,会有一定的性能损耗;
动态字段模版
概述
ES字段类型设置提供了动态模板机制,非常灵活。通过设置一定的匹配规则,固定下字段的类型与属性
关键字
dynamic_templates,动态匹配关键字
字段类型动态匹配
概述
定义一种规则,依据json字段类型来匹配设定字段类型与属性
关键字
match_mapping_type,动态匹配关键字,匹配字段类型
实际使用
tips
静态设置比动态优先。
字段名称动态匹配
关键字
match/unmatch,动态匹配关键字,匹配字段名称,按照通配符*,必须是符合对象类型
实际使用
tips
在ES里面,_source和索引字段,存储的地方是不一致的,它的数据格式,类型,也可能是不一致的。所以在检索时,也可能出现问题。
字段路径动态匹配
关键字
path_match/path_unmatch,动态匹配关键字,匹配字段名称,按照通配符,而且必须是符合对象类型,生产环境中常用
实际使用
混合方式动态匹配
概述
运用字段名称与字段类型匹配,设定字段类型与属性
混合以上三种动态匹配方式
混合静态与动态匹配方式
实际使用
tips
索引字段数量限制
建议不要超过1000个
索引字段嵌套限制
建议不要超过20层
动态匹配+静态固定结合
结合业务场景,什么场景下应该用静态,什么场景下应该用动态,什么场景下应该动静结合
业务系统:一般静态
日志系统:一般会动态
使用别名与模版助力索引设计
概述
ES提供的任何一个特性,都值得深入探究,探索出很多应用场景。
● 任何一个索引都有一个别名,默认情况下等同于索引名称
● 掌握索引模板特性,更加有利于我们设计有限的索引,规范索引的行为。
● 任何一个索引都有一个别名,默认情况下等同于索引名称
● 掌握索引模板特性,更加有利于我们设计有限的索引,规范索引的行为。
索引别名深入解读
概述
ES索引创建之后,本质都是同过别名访问的,默认情况下索引别名等同与索引名称;
关键字
_alias,别名关键字
_aliases,别名关键字
应用场景
索引代理,业务新旧索引切换,索引访问资源隔离,rollover滚动创建索引基于别名实现
别名绑定
别名绑定方式
创建时绑定,后期维护时绑定
别名绑定特性
多对多绑定关系,一个索引可以绑多个索引别名,一个索引别名可以绑定多个索引;
单索引单别名绑定
概述
创建索引,指定别名,可以在mapping设置时指定,一种是在创建之后指定
实际使用
多索引多别名绑定
实际使用
设置多个索引,设置多个别名
别名解绑
tips
别名有绑定索引,不可以直接删除别名,可以通过解绑的方式处理
实际使用
别名高级使用
别名查询过滤
概述
查询过滤,对外提供多个别名访问,每种别名都代表某一类目;你有一个大索引,数据量2000w左右,ES几十个G就足够了,其实并没有必要拆分成好几个索引,用别名查询过滤就是一个很好的选择。
关键字
filter,查询过滤关键字
示例使用
案例
假设公司员工信息有很多,按照公司编号去做一些隔离查询
实际使用
别名路由控制
概述
关键字
示例使用
索引模板深度使用
索引设计注意事项
索引创建设计总结
参考
索引别名
索引模版
索引mapping
索引数据篇
写入与删除数据如何避坑
索引写入数据
索引删除数据
运用ElasticStack快速导入数据
数据写入与删除注意事项
参考
写入数据
条件删除参考
高效的更新数据实战
了解数据更新过程与内部机制
常用数据更新方式
数据更新并发冲突问题
高级数据更新方式
数据更新注意事项
参考
painless脚本
条件式更新
正确使用Reindex重建索引
重建索引的需求背景
常用重建索引的方式
重建任务管控
高级重建索引
远程重建索引
重建索引注意事项
参考
索引文档重建
使用Ingest加工索引数据
Ingest介绍
常用数据加工Ingest
高级数据加工Ingest
Enrich处理运用
注意事项
参考
Ingest数据预处理参考
Painless脚本语言
数据查询篇
选择合适的数据查询方式
GET查询模式
SEARCH查询模式
DSL查询方式
查询注意事项
1. 优先使用GET查询模式,实时性较高,基本不会存在性能问题;
2. Search查询模式下,Filter查询机制优先,避免分值计算,数据量大的情况下,会很伤;
3. 限制查询返回的字段数量
2. Search查询模式下,Filter查询机制优先,避免分值计算,数据量大的情况下,会很伤;
3. 限制查询返回的字段数量
参考
SEARCH查询参数
ElasticSearch中的_source,store_fields,doc_values性能比较
多条件组合查询实战运用
组合查询
范围查询
关联查询
参考
组合查询
函数组合
范围类型
关联查询
全文文本分词查询
参考
全文文本检索
最小匹配度
词项查询与跨度查询实战运用
参考
词项查询
跨度查询
运用启发式特性引导用户查询
参考
启发式查询
查询结果排序深入解读
参考
查询排序
自定义分值排序
分页查询使用避坑的一些事
参考
分页查询
运用异步机制执行深度查询
参考
异步查询
查询模板
Mustache模板语法
http://mustache.github.io/
http://mustache.github.io/mustache5.html
索引聚合篇
运用指标聚合快速统计数值
参考
指标聚合参考
百分位数
Bucket常用分桶聚合实战
参考
分桶聚合参考
词项分桶聚合
深度优先与广度优先
全局序号博客说明
Bucket特殊分桶聚合实战
参考
组合分桶
运用Pipeline实现二转聚合统计
参考
Pipeline管道聚合
SQL查询篇
运用SQL简化DSL查询
参考
ES-SQL参考
ES-SQL限制性
NLPchina插件
dbeaver官方下载
数据交换篇
运用Rollup减少数据存储
参考
Rollup & Transfroms参考
Druid参考
文本分词深入探查
文本分词深入探查
参考
分词器文档
IK参考
集群掌控篇
深入掌握集群组建与集群设置
参考
集群组件发现
ES跨集群能力探查
参考
跨集群连接配置
跨集群查询CCS
跨集群复制ccr
集群恢复与集群索引分布
参考
集群恢复gateway
集群索引分布
集群扩容与集群升级
参考
集群版本升级
保障集群数据安全
参考
集群安全
集群权限
证书生成工具
集群管理与集群指标监控分析
参考
集群监控参考
集群监控设置项
CAT命令API
grafana监控
cerebro监控
官方地址
docker版本
节点掌控篇
选择恰当的节点角色
参考
节点角色
节点资源掌控设置
参考
节点资源熔断
节点线程池
索引掌控篇
索引数据分布与分段合并
参考
索引配置设置
索引数据分布
索引分段合并
分段强制合并
索引数据可靠性保障机制
参考
索引分片移动
索引文件系统
Lucene文件格式
索引事务日志
数据软删除
主副分片同步checkpoint机制
索引管理操作
参考
索引管理操作API
分片重新分布路由
运用ILM自动化索引
参考
索引备份与还原
索引备份支持插件
SLM快照API
索引ILM机制
索引ILM操作API
ILM参数置
curator参考
资源规划篇
集群容量资源规划
参考
规格容量评估(阿里云)
Elastic 堆外内存
性能调优篇
集群性能调优
参考
explain查询分值计算分析器
profile性能优化器
官方性能优化
日志分析篇
自助分析集群日志
参考
ES日志设置
ES审计日志
ES slowlog
filebeat日志采集
问题诊断篇
自助诊断集群问题
参考
基础环境启动检查
CAT接口
CAT-Shard接口
集群分布explain接口
分片修复移除
产品设计与原理
ElasticSearch
核心概念
和关系型DB的对比
集群Cluster
Elasticsearch设计之初就是分布式的,由一个或者多个节点实例组成。ES集群具备两个特性:
高可用性
服务可用性:允许有节点停止服务;
数据可用性:部分节点丢失,不会丢失数据;
可扩展性
随着请求量的不断提升,数据量的不断增长,系统可以将数据分布到其他节点,实现水平扩展;
ES集群的状态
一个集群中可以有一个或者多个节点;我们采用集群健康值来衡量一个集群的状态:
green:所有主要分片和复制分片都可用;
yellow:所有主要分片可用,但不是所有复制分片都可用;
red:不是所有的主要分片都可用;
注:当集群状态为 red,它仍然正常提供服务,它会在现有存活分片中执行请求,我们需要尽快修复故障分片,防止查询数据的丢失;
节点Node
ES集群是通过多台服务器来搭建,它们拥有一个共同的clustername,比如叫做“escluster”,每台服务器叫做一个节点,用于存储数据并提供集群的搜索和索引功能。
节点拥有自己的唯一名字,默认在节点启动时会生成一个uuid作为节点名,该名字也可以手动指定。
单个集群可以由任意数量的节点组成。如果只启动了一个节点,则会形成一个单节点的集群。其配置文件如下:
节点是一个ElasticSearch的实例,其本质就是一个Java进程;一台机器上可以运行多个ElasticSearch实例,但是建议在生产环境中一台机器上只运行一个ElasticSearch实例;一个Server可以根据硬件资源的配置,上面可以部署多个节点;
节点的类型
ES的节点有很多种类型,有做数据存储的,有做查询的,有做管理的,有做机器学习的,还有做数据转换的。节点的能力有强弱之分,可以进行灵活的设置。
节点类型的设置
在es节点的yml文件中可以配置节点的类型
其中node.master配置表示节点是否具有成为主节点的资格节点。
此属性的值为true,并不意味着这个节点就是主节点。因为真正的主节点,是由多个具有主节点资格的节点进行选举产生的。所以,这个属性只是代表这个节点是不是具有主节点选举资格。
node.data配置表示节点是否存储数据。
node.master和node.data的取值可以有四种情况,表示四种节点类型。
node.master: true并且node.data: true
这种组合表示这个节点即有成为主节点的资格,又存储数据。这个时候如果某个节点被选举成为了真正的主节点,那么他还要存储数据,这样对于这个节点的压力就比较大了。elasticsearch默认每个节点都是这样的配置,在测试环境下这样做没问题。实际工作中建议不要这样设置,这样相当于主节点和数据节点的角色混合到一块了。
node.master: false并且node.data: true
这种组合表示这个节点没有成为主节点的资格,也就不参与选举,只会存储数据。这个节点我们称为data(数据)节点。在集群中需要单独设置几个这样的节点负责存储数据,后期提供存储和查询服务
node.master: true并且node.data: false
这种组合表示这个节点不会存储数据,有成为主节点的资格,可以参与选举,有可能成为真正的主节点。对于master节点而言,这样的配置是最适合的。
node.master: false并且node.data: false
这种组合表示这个节点即不会成为主节点,也不会存储数据,这个节点的意义是作为一个client(客户端)节点,主要是针对海量请求的时候,这些节点负责处理用户请求,实现请求转发,负载均衡等功能。
master节点
拥有选举成为master节点资格的节点经过选举,成为了master节点,Elasticsearch中的master并不像mysql、hadoop集群的master那样,它既不是集群数据的唯一流入点,也不是所有元数据的存放点。所以,一般情况下Elasticsearch的Master负载是很低的。
master的作用
同步集群状态:集群状态信息,由master节点进行维护,并且同步到集群中所有节点。也就是说集群中的任何节点都存储着集群状态信息(经过master的同步),但只有Master能够改变信息。我们可以通过接口读取它,如:/_cluster/state;
集群状态的修改主要包括什么:
集群层面的设置;
集群内有哪些节点的信息;
各索引的设置,映射,分析器和别名等设置;
索引内各分片所在的节点位置;
集群状态的修改:集群状态的修改通过Master节点完成,比如索引的创建删除,mapping的修改等等;
我们知道配置项dynamic=true表示对于未mapping的新字段,es会尝试猜测该字段的类型,并mapping它。此时数据节点需要跟Master通信,通知Master修改Mapping。这个时候的index写入是阻塞的。等Master修改了集群状态之后,再同步到所有节点,才可以继续写入;
索引
ES的索引和传统的数据库中的索引还不太一样,传统的数据库中的索引是一种数据结构或者算法。而在ES中的索引指的是数据存储的逻辑空间,类似于表空间的概念。是文档(Document)的容器,是一类文档的集合。ElasticSearch将它的数据存储在一个或多个索引(index)中。索引就像数据库,可以向索引写入文档或者从索引中读取文档。
索引这个词在 ElasticSearch 会有两种意思:
索引(名词)
类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库(Database)。索引由其名称(必须为全小写字符)进行标识。
索引(动词)
保存一个文档到索引(名词)的过程。这非常类似于SQL语句中的 INSERT关键词。如果该文档已存在时那就相当于数据库的UPDATE。
分片
概念
简单来讲就是在ES中所有数据的文件块,也是数据的最小单元块,整个ES集群的核心就是对所有分片进行索引、负载、路由等操作,来达到惊人的速度。
文档存储在分片中,然后分片分配到集群中的节点上。当集群扩容或缩小,Elasticsearch 将会自动在节点间迁移分片,以使集群保持平衡。假设 IndexA 有2个分片,我们向 IndexA 中插入10条数据 (10个文档),那么这10条数据会尽可能平均的分为5条存储在第一个分片,剩下的5条会存储在另一个分片中。
文档存储在分片中,然后分片分配到集群中的节点上。当集群扩容或缩小,Elasticsearch 将会自动在节点间迁移分片,以使集群保持平衡。假设 IndexA 有2个分片,我们向 IndexA 中插入10条数据 (10个文档),那么这10条数据会尽可能平均的分为5条存储在第一个分片,剩下的5条会存储在另一个分片中。
一个分片(shard)是一个最小级别“工作单元(worker unit)”,大多数情况下,它只是保存了索引中所有数据的一部分。这类似于 MySql 的分库分表。
比索引级别要低一点,数据存储的实际逻辑空间,单分片就是完整索引数据
分片的种类
一个分片就是一个运行的 lucene 实例,一个节点可以包含多个分片,这些分片可以是:
主分片(primary shard)
用于解决数据水平扩展的问题,一个索引的所有数据是分布在所有主分片之上的(每个主分片承担一部分数据,主分片又分布在不同的节点上)
一个索引的主分片数量只能在创建时指定,es默认情况下数量为5,主分片数量一经指定,后期无法修改,除非对数据进行重新构建索引(reindex操作)。
副分片(replica shard)
用于解决数据高可用的问题,一个副本分片即一个主分片的拷贝,其数量可以动态调整,通过增加副本分片也可以实现提升系统读性能的作用。
副本分片还可以实现es的故障转移,如果持有主分片的节点挂掉了,一个副本分片就会晋升为主分片的角色。
为了达到故障转移的作用,主分片和其对应的副本分片是不会在同一个节点上的。
对文档的新建、索引和删除请求都是写操作,必须在主分片上面完成之后才能被复制到相关的副本分片。
为了提高写入的能力,ES这个过程是并发写的,同时为了解决并发写的过程中数据冲突的问题,ES 通过乐观锁的方式控制,每个文档都有一个 _version (版本)号,当文档被修改时版本号递增。一旦所有的副本分片都报告写成功才会向协调节点报告成功,协调节点向客户端报告成功。
ES默认情况下为每个主分片创造一个副本。
分片的优势
突破单节点容量上限,例如我们有10TB大小的总文档,分成20个分片分布于10台节点上,那么每个节点只需要1T的容量即可。
服务高可用,由于有副本分片的存在,只要不是存储某个文档的node全挂了,那么这个文档数据就不会丢。副本分片提供了灾备的能力。
故障转移,当主分片节点故障后,可升级一个副分片为新的主分片来应对节点故障。
扩展性能,通过在所有replicas上并行搜索来提高读性能.由于replicas上的数据是近实时的(near realtime),因此所有replicas都能提供搜索功能,通过设置合理的replicas数量可以极高的提高搜索吞吐量。
Segment分段
数据被分配到特定的分片和副本上之后,最终是存储到磁盘上的,这样在断电的时候就不会丢失数据。具体的存储路径可在配置文件 ../config/elasticsearch.yml中进行设置,默认存储在安装目录的data文件夹下。建议不要使用默认值,因为若ES进行了升级,则有可能导致数据全部丢失。
segment是实现ES近实时搜索的关键,是数据索引(动词)过程中的重要载体。在说segment时,我们需要了解ES数据的存储和检索原理。也就是Elasticsearch的核心算法。
文档
文档,Index里面单条的记录称为Document。等同于关系型数据库表中的行。我们来看下一个文档的源数据,
文档记录具体解析
_index文档所属索引名称。
_type文档所属类型名。
_idDoc的主键。在写入的时候,可以指定该Doc的ID值,如果不指定,则系统自动生成一个唯一的UUID值。
_version文档的版本信息。Elasticsearch通过使用version来保证对文档的变更能以正确的顺序执行,避免乱序造成的数据丢失。
_seq_no严格递增的顺序号,每个文档一个,Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no。
primary_term:primary_term也和_seq_no一样是一个整数,每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1
found查询的ID正确那么ture, 如果 Id 不正确,就查不到数据,found字段就是false。
_source文档的原始JSON数据。
字段
字段,等同MySql数据列。如下图所示,ES这里这里用了一种扁平化的数据管理方式。
词项
单个字段数据拆分成多个独立的词。你可以想象ES在进行信息检索时,为每一个词项都单独建立一个索引,从而实现快速的查询。
借鉴参考
ElasticSearch 核心概念详解
核心算法
1. 倒排索引(Inverted Index)
从具体的例子来认识倒排索引
例子
问题
假设文档集合包含五个文档,每个文档内容下图所示,在图中最左端一栏是每个文档对应的文档编号。我们的任务就是对这个文档集合建立倒排索引。
倒排索引的数据结构
中文和英文等语言不同,单词之间没有明确分隔符号,所以首先要用分词系统将文档自动切分成单词序列。这样每个文档就转换为由单词序列构成的数据流,为了系统后续处理方便,需要对每个不同的单词赋予唯一的单词编号,同时记录下哪些文档包含这个单词,在如此处理结束后,我们可以得到最简单的倒排索引:
“单词 ID” 一栏记录了每个单词的单词编号,第二栏是对应的单词,第三栏即每个单词对应的倒排列表。比如单词 “谷歌”,其单词编号为 1,倒排列表为 {1,2,3,4,5},说明文档集合中每个文档都包含了这个单词。
之所以说上图所示倒排索引是最简单的,是因为这个索引系统只记载了哪些文档包含某个单词,而事实上,索引系统还可以记录除此之外的更多信息:
单词 ID:记录每个单词的单词编号;
单词:对应的单词;
文档频率:代表文档集合中有多少个文档包含某个单词
DocId:单词出现的文档 id
TF:单词在某个文档中出现的次数
POS:单词在文档中出现的位置
以单词 “加盟” 为例,其单词编号为 6,文档频率为 3,代表整个文档集合中有三个文档包含这个单词,对应的倒排列表为 {(2;1;<4>),(3;1;<7>),(5;1;<5>)},含义是在文档 2,3,5 出现过这个单词,在每个文档的出现过 1 次,单词 “加盟” 在第一个文档的 POS 是 4,即文档的第四个单词是 “加盟”,其他的类似。
倒排索引的不变性
写到磁盘的倒序索引是不变的:写到磁盘后,倒排索引就再也不变。
优点
不需要添加锁。如果你从来不用更新索引,那么你就不用担心多个进程在同一时间改变索引。
不变性,导致从磁盘加载到内存中可以一直保留着,不用变化,提交查询性能
写一个单一的大的倒序索引可以让数据压缩,减少了磁盘 I/O 的消耗以及缓存索引所需的 RAM。
缺点
然而,索引的不变性也有缺点。如果你想让新修改过的文档可以被搜索到,你必须重新构建整个索引。
我们来试想一下这样一个场景:对于一个索引内的所有文档,我们将其分词,建立了一个很大的倒排索引,并将其写入磁盘中。
如果索引有更新,那就需要重新全量创建一个索引来替换原来的索引。这种方式在数据量很大时效率很低,并且由于创建一次索引的成本很高,更无法保证时效性。
如果索引有更新,那就需要重新全量创建一个索引来替换原来的索引。这种方式在数据量很大时效率很低,并且由于创建一次索引的成本很高,更无法保证时效性。
分段存储
如何在不丢失不变形的好处下让倒序索引可以更改?答案是:使用不只一个的索引。 新添额外的索引来反映新的更改来替代重写所有倒序索引的方案。
为了解决这个问题,Lucene 引入了段(segment)的概念,简单来说,一个段 segment 存储着若干个文档,以及这些文档的索引信息(如词频,词向量,域(field)索引等),也就是说,一个 segment 是一个完整的倒序索引的子集。
segment 文件中存储的内容,可见【Lucene】Lucene 学习之索引文件结构
所以现在 index 在 Lucene 中的含义就是多个 segments 的集合。
应用方向
全文检索
2. Doc Value列式存储
是什么
应用方向
Elasticsearch数据排序/聚合统计
3. FST有限状态转换
是什么
应用方向
模糊查询
4. Skip List跳表
是什么
应用方向
文档定位跳跃
5. BKD_Tree多维空间树
是什么
应用方向
简单数值,范围数据
6. 压缩位图(RoaringBitmap)
是什么
应用方向
原始数值压缩,查询结果合并
7. TF/IDF/BM25分值计算
是什么
应用方向
文本搜索,排序,分值计算
8. Raft分布式共识
是什么
应用方向
解决集群管理主节点选举问题
添加文档的过程
延迟写策略
如果每次将数据写入磁盘,磁盘的 I/O 消耗会严重影响性能。故而 Lucene 采用延迟写策略,新的文档建立时首先在内存中建立索引 buffer:
refresh
当达到默认的时间(1 秒钟)或者内存的数据达到一定量时,会触发一次刷新(Refresh),将内存中的数据整合,生成到一个新的段。
此时,按理来说,应该将新生成的段刷进磁盘当中,但是将新的 segment 提交到磁盘需要 fsync 来保障物理写入。fsync 是很耗时的,它不能在每次文档更新时就被调用,否则性能会很低。
在内存和磁盘之间是文件系统缓存,于是,ES 先将新生成的段先写入到内核的文件系统缓存中,这个过程很轻量。
默认情况下每个分片会每秒自动 refresh 一次。可以通过参数 index.refresh_interval 来修改这个刷新间隔
我们也可以手动触发 refresh
POST/_refresh 刷新所有索引。
POST/nba/_refresh 刷新指定的索引。
在这个阶段,新生成的 segment(下图灰色)虽然还未写入磁盘,但已经能够被搜索了,这也是 es 近实时搜索的原理。
flush
新增的段被刷新到磁盘中。
段被写入到磁盘后会生成一个提交点,提交点是一个用来记录所有提交后段信息的文件。
这里的内存使用的是 ES 的 JVM 内存,而文件缓存系统使用的是操作系统的内存。
一般 Flush 的时间间隔会比较久,默认 30 分钟,或者当 translog(后文介绍)达到了一定的大小(超过 512M),也会触发 flush 操作。
注意点
新的数据会继续的被写入内存,但内存中的数据并不是以段的形式存储的,因此不能提供检索功能。由内存刷新到文件缓存系统的时候会生成了新的段,并将段打开以供搜索使用,而不需要等到被刷新到磁盘。
注意,在内存中的新文档不一定能够被索引,只有生成段后,新文档才可以被索引。
事务日志(Translog)
虽然通过延时写的策略可以减少数据往磁盘上写的次数,提升了整体的写入能力,但是我们知道文件缓存系统也是内存空间,属于操作系统的内存,只要是内存都存在断电或异常情况下丢失数据的危险。
为了避免丢失数据,Elasticsearch 添加了事务日志(Translog),事务日志记录了所有还没有持久化到磁盘的数据。添加了事务日志后整个写索引的流程如下图所示。
一个新文档被索引(动词)之后,先被写入到内存中,但是为了防止数据的丢失,会追加一份数据到事务日志中。不断有新的文档被写入到内存,同时也会不断被记录到事务日志中。这时新数据还不能被检索和查询。
当达到默认的刷新时间或内存中的数据达到一定量后,会触发一次 refresh,将内存中的数据以一个新段形式刷新到文件缓存系统中并清空内存。这时虽然新段未被提交到磁盘,但是可以提供文档的检索功能且不能被修改。
随着新文档索引不断被写入,当日志数据大小超过 512M 或者时间超过 30 分钟时,会触发一次 flush。内存中的数据被写入到一个新段同时被写入到文件缓存系统,文件系统缓存中数据通过 fsync 刷新到磁盘中,生成提交点,日志文件被删除,创建一个空的新日志。
删除文档的过程
与添加文档的过程类似
删除,由于不可修改,所以对于删除操作,不会把文档从旧的段中移除,而是通过新增一个 .del 文件,文件中会列出这些被删除文档的段信息。
这个被标记删除的文档仍然可以被查询匹配到, 但它会在最终结果被返回前从结果集中移除。
更新文档的过程
更新,不能修改旧的段来进行反映文档的更新,其实更新相当于是删除和新增这两个动作组成。
会将旧的文档在 .del 文件中标记删除,然后文档的新版本被索引到一个新的段中。
可能两个版本的文档都会被一个查询匹配到,但被删除的那个旧版本文档在结果集返回前就会被移除。
ES写操作总结
先写入内存 buffer,在 buffer 里的时候数据是搜索不到的;同时将数据写入 translog 日志文件。
如果 buffer 快满了,或者到一定时间,就会将内存 buffer 数据 refresh 到一个新的 segment file 中,但是此时数据不是直接进入 segment file 磁盘文件,而是先进入 os cache。这个过程就是 refresh。
每隔 1 秒钟,es 将 buffer 中的数据写入一个新的 segment file,每秒钟会写入一个新的 segment file,这个 segment file 中就存储最近 1 秒内 buffer 中写入的数据。
段合并
由于自动刷新流程(refresh)每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦,比如每一个段都会消耗文件句柄、内存和 cpu 运行周期。更重要的是,每个搜索请求都必须轮流检查每个段然后合并查询结果,所以段越多,搜索也就越慢。
Elasticsearch 通过在后台定期进行段合并来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段。段合并的时候会将那些旧的已删除文档从文件系统中清除。被删除的文档不会被拷贝到新的大段中。合并的过程中不会中断索引和搜索。
段合并在进行索引和搜索时会自动进行,合并进程选择一小部分大小相似的段,并且在后台将它们合并到更大的段中,这些段既可以是未提交的也可以是已提交的。合并结束后老的段会被删除,新的段被 flush 到磁盘,同时写入一个包含新段且排除旧的和较小的段的新提交点,新的段被打开可以用来搜索。
段合并的计算量庞大, 而且还要吃掉大量磁盘 I/O,段合并会拖累写入速率,如果任其发展会影响搜索性能。Elasticsearch 在默认情况下会对合并流程进行资源限制,所以搜索仍然有足够的资源很好地执行。
产品特性与选型
第三方社区生态
Flink
Flink它是一个实时的计算流引擎,那我们在做很多数据处理的时候,把上游的数据都存到Kafka,通过Flink做一些大规模的数据解析,解析完之后,要存储起来,供外界查询,这时候,可以选择用ES来承载,ES的分布式存储能力非常强
nifi
nifi它是一个平台化的ETL数据处理产品,跟ES官方自己的Logstash对比的化,它的好处就是可视化,平台化,可以采用多线程,多并行的这种策略,去做很多工作,比原来的Logstash,要复杂一点,但是要强大不少。现已经被Hadoop这个生态,集成到里面去了
Grafane Labs
支持很多种数据源,可以直接连接ES,它本身是一个UI界面,连接ES之后,可以去做一些告警;当然它最重要的一点是,图形化做的非常的漂亮。现在业界,做监控的非常漂亮的图表,基本都会用Grafana去做。
presto
我们知道Hive是FaceBook开发,做纯离线的数据处理的,速度比较慢,随便运行个脚本(一个Sql查询)都要很久。为了解决这个问题,FaceBook又开发了一个presto这样一个查询引擎,它是一个纯内存式的,交互式的,很方便的去跟很多种数据源交互,假设我们需要把ES两个表的数据,做一些join分析,那怎么办呢?你可以用Spark,需要写很多Spark的代码,然后去编译,编译后还要上传,然后还要调度运行,这个过程是很麻烦的,如果我们用presto的话,直接可以去连接ES集群,连接之后,把它的表映射过来,当成两张不同的表映射,非常的快。
StreamSets
和nifi非常相似,也是一个可视化的ETL产品,现在有很多大数据工程师,它做的一个工作,就是利用nifi或者StreamSets来做。
Elassandra
ES和Cassandra的混合,Cassandra是一个非常强大的列式数据库,再做key-value查询是非常快的,但是再做条件式查询时,性能不行。所以业界会选择用ES来承载。传统来说,你得搭建一个Cassandra/Hbase的集群,第二个你得搭建一个ES的集群,中间你还得写个程序把数据同步过来,这个过程对大多数人来说,非常痛苦,要掌握两个数据产品,另外,同步也是一个非常头痛的事情。通过这套产品,这些问题,都解决了。当然,功能上,可能会有一些限制,ES的更新,升级并没有那么快。
AQ
个人博客
ElasticSearch 核心概念详解
视频网站
子主题
收藏
0 条评论
下一页