终于有时间记录一下最近学习的知识了,其实除了写下的这些还有很多很多,但懒得一一写下了;

ElasticSearch添加修改删除原理:
ElasticSearch的倒排索引和文档一旦生成就不允许修改(其实这是lucene的特性,包括下面的也是,毕竟ElasticSearch是基于lucene的),而提供的修改操作其实是新生成了一个文档,并将之前文档中的不进行修改的json保存到新的文档中,之后对老的文档添加一个删除标记(是添加标记,但并不删除,不过你也访问不到),等到某个时刻就会统一删除掉所有的有删除标记的文档,具体是什么时候看下文;
而在新添文档的时候,是先把文档存到一个在内存中的一个缓冲区in-memory buffer里,并且每一秒生成一个新的段(Segment)并将
这个缓冲区中的文档生成倒排索引并存入(此时是在内存中生成一个段(segment,一个分片中保存的倒排索引是分布式存于多个段中的),并存入,这个时间是可以修改的,也可以修改为-1,永远不会自动添加,直到我们手动调用_reflush接口),最后提交(也就是和commit point(一个分片就是一个lucene实例,而每个实例都对应一个commit point,这是lucene维护的一个保存着每个可用的Segment的信息)相关联),
这样就能搜索,之后会清空缓存,等待新的文档数据存入;
再回到更新的问题上,如何保证当我们搜寻的时候是我们更改后的数据呢,因为每个commit point维护着一个.del文件,里面记录了每个文档的删除和修改,这样在我们搜寻数据的时候,就会通过.del文件自动把老的数据过滤掉,只返回新的文档数据;
同时为了避免Segment产生太多影响搜索效率,ElasticSearch会定期的将多个小的Segment合并成一个大的Segment.并且在合并的过程中,会根据.del文件将老的文档丢弃掉;
在es中,可以使用forcemerge接口,来控制segment的合并。如: POST/logstash-2014-10/_forcemerge?max_num_segments=1(也可以人为控制合并,比如在晚上的时候,服务器性能空闲期间进行合并)
那么问题来了,如何保证在出现意外情况下,我们的文件缓冲区的数据的可靠性呢?这个就要靠我们Es维护的Translog日志文件了,在我们添加或更新或删除文档的时候,会fsync到我们的日志文件上(也可以设置成异步,不过不推荐,网上也有很多人做了实验,性能提高不明显),
之后在我们的Translog到512M的时候(这个是默认配置,可以更改,为时间单位),就会自动flush,然后将我们内存中segment文件的缓存数据进行刷盘(从内存刷新到硬盘上),当然我们也可以手动调用flush接口进行刷新,刷盘完成之后就会清空我们的Translog文件.
那么我们的ES是怎么根据Translog进行文件恢复的呢?它是根据CommitPoint文件中记录的segment(段)的记录,之后根据记录在我们的Translog文件里拿到对应的数据记录,再进行相对应的数据恢复;

ElasticSearch搜索查询:
如果查询的是日期或者整数,那么他们会将字符串作为日期或整数对待。
如果查询的是一个未分析的精确值字符串字段(比如,类型是keyword的话,是不分词的。),像我们存储邮编号,身份证号之类。它们会将整个查询字符串作为单个词项对待;
如果查询的是一个经过分词器解析过后的全文字段,它们首先会将查询字符串也经过分词器解析,然后生成一个词项列表再去对应着倒排索引找到对应的document;

queryString语法(下面的示例都是针对整个索引的,如果想缩小搜索查找范围,可以加上type字段,比如/school/highSchool):
1:全文检索:
GET /school/_search?q=zhangsan(如果查找的文档的相应字段进行过分词,那么也会将此搜索参数进行分词,zhangsan也就会变成zhang san)
2: 单字段全文检索:
GET /school/_search?q=name:zhangsan
3: 单字段精确检索:
GET /school/_search?q=mark:"good day"(查找mark字段的值里包含"good day"的文档并返回,这种的必须要包含good和day两个词并且位置也要相同)
4:多个检索条件的组合:
GET /school/_search?q=name:("zhangsan" OR "lisi") AND NOT course:spring (必须要name为"zhangsan"或"lisi"并且course不为spring)
5:判断字段是否存在:
GET /school/_search?q=_exists_:mark(返回存在mark字段的文档)
GET /school/_search?q=NOT _exists_:mark (返回不存在mark的字段)
6:通配符:
用?表示单字符,*表示任意个字符
GET /school/_search?q=name:zh???san (返回开头是zh,结尾是san,忽略中间三个字符)
GET /school/_search?q=name:zh*san (返回开头是zh,结尾是san,忽略中间任意个字符)

queryString语法也可以使用正则表达式进行搜索查询,但一般不推荐使用,麻烦且效率低

match查询步骤:
1:检查作为搜索条件的字段的字段类型
2:分析查询字符串(如果查找的字段不是分词的字段,那么搜索参数也不会进行分词)
3:查找匹配字段
4:为每个文档评分(评分是根据,你要搜索的参数条件在文档中出现的频率结合一些其它条件作为判断然后用一个评分算法来算出(这是lucene的功能),如果没有特定需求(也就是排序),可以关掉评分功能,以提高性能)
match_all搜索查询
1.空查询,查询该索引下的所有的文档
GET school/_search
{
"query":{
"match_all":{}
}
}

2.不匹配任何文档
GET school/_search
{
"query":{
"match_none":{}
}
}

3.根据单个or多个字段查询
GET school/_search
{
"query":{
"match":{
"mark":"Day"
"name":"zhangsan"
}
}
}(查找school索引下mark字段的包含Day的文档并返回)

match_phrase短语匹配:
GET school/_search
{
"query":{
"match_phrase":{
"mark":"good day",
"slop":1(slop的参数意思为只要如果good day中间有一个词的话那么就忽略,依然会返回这个文档)
}
}
}
执行步骤:
1.分析查询字符串,分解成词项;(因为是短语)
2.查找匹配文档(只要文档中的被搜索字段拥有分解后的词项列表的其中一个词,那么条件就会成立)
3.将匹配后的字段再进行两次过滤,一次是必须拥有词项列表中所有的搜索参数,一个是必须位置也相同;
可以用slop指定词项间间隔的范围

match_phrase_prefix短语前缀匹配:
GET school/_search
{
"query":{
"match_phrase_prefix":{
"mark":"good day",(此字段前缀必须为good day)
"slop" 1,(如果good day中间有一个词,那么忽略,依然返回此文档)
"max_expansions":10(此参数意为返回前10个)
}
}
}
执行步骤:
1.分析查询字符串,分解成词项;(因为是短语,当然也可以输入单个字母,比如a)
2.查找匹配文档(文档中的被搜索字段的前缀必须是短语中的词列表,且位置相同;有slop参数除外)

Multi_Match多个字段上进行Match匹配:
GET school/_search
{
"query":{
"multi_match":{
"query":"elasticsearch",
"fields":["mark","co*"]
}
}
}
(查询school索引下,所有type中,mark字段,和co开头的字段的值包含elastisearch的文档(是否将elasticsearch分词,先看搜索的字段,如果搜索的字段是经过分词的,那么再视此字段的分词器而定,因为有可能分词器会将elasticsearch视为一个完整的单词,而不进行分词))

term精确查询:
GET school/_search
{
"query":{
"term":{
"mark":"happy day"
}
}
}(term查询不会对查询参数进行分词,不管要查询的字段是否经过分词,如果你要查的字段的字段类型为text,并且你的搜索参数还是多个词组成的词,如示例中的happy day,那么你是查不出任何文档的,因为在text中是默认会分词的,那么happy day在倒排索引中就已经被分词了)

terms多参数精确查询:
GET school/_search{
"query":{
"terms":{
"name":["zhangsan","lisi"]
}
}
}(同样对于输入的查找参数不进行分析)

range范围查询:
GET school/_search{
"query":{
"range":{
"age":{
"gte":30,(大于等于30)
"lte":20(小于等于20)
}
}
}
}(大于的话是gt(grate than),小于是lt(less than))

还可以指定日期类型的字段作为搜索条件(因为日期在ElasticSearch内部存储的时候是存储为long型的)
GET school/_search{
"query":{
"range":{
"study_date":{
"gte":"2018-2-11",
"lte":"2019",
"format":"yyyy-MM-dd||yyyy"(自定义一下格式化方式,否则会按照默认的格式化方式来对日期进行格式化)
}
}
}
}
甚至还可以使用自带的/d/M/y一系列参数
GET school/_search{
"query":{
"range":{
"study_date":{
"gte":"now-10d/d",(大于等于现在的日期往前推十天,并且是当天的0点0分0秒)
"lte":"now+1M/M",(小于等于现在的日期往后推一个月,并且是那个月的最后一天的23时59分59秒)
"format":"yyyy-MM-dd"(自定义一下格式化方式,否则会按照默认的格式化方式来对日期进行格式化)
}
}
}
}(这种做法好处在于,不但固定查询条件,而且利用了ElasticSearch的缓存策略直接去拿缓存,减轻了服务器压力(ElasticSearch缓存策略和浏览器一样,只有你发的查询url完全一样,才会去拿缓存))

missing查询:
GET school/_search
{
"query":{
"bool":{
"must_not":{
"exists":{
"filed":"mark"
}
}
}
}
}
bool里所有的判断条件都是and与关系

fuzzy模糊查询:
GET school/student/_search
{
"query":{
"fuzzy":{
"name":{
"value":"zhangsan",
"fuzziness":2(意思是可以忽略掉两个字符的误差,比如搜索条件name:zhangsi也会出现name里为zhangsan的文档)
}
}
}
}

搜索性能优化
1.查询和过滤,query和filter
filter拥有和query同样的功能,并且不需要进行评分,以及拥有缓存,query是查询"此文档与查询条件的匹配程度",而filter则是"此文档是否匹配查询条件"。所以多用filter;
2.尽量使用Bool组合代替AND OR
bool条件组合可以一次性添加多个条件,并且会把通过条件的文档保存在bitset中,直接做交集运算。而AND OR这种则是一个个文档进行处理,如果非用不可,那么请和sql语句一样,根据语句执行顺序,将过滤文档多的条件放在前面;
3.增加刷新时间
每次刷新ElasticSearch都会增加一个新的段(segment),并且会使缓存失效,所以尽量将刷新时间变长一点

4.增加Translog的flush时间

 因为每次flush都会把未存储到硬盘中的segment中的数据刷到硬盘上,而这种与硬盘交互的IO操作是极其浪费性能的,所以在对于数据安全性要求不是非常高的情况下可以把Translog的刷新时间和大小调长和大一些。

5.做好冷热分层,最好能指定一下空间位置

每台服务器的性能都不一样,而这是需要我们自己手动去调整的,可以定义好匹配模板,将新加入的索引强制分配到那些性能较好的服务器上(也就是hot),也可以在某些时候定时的将一些索引迁移到性能居中的服务器上(也就是warm)。而针对服务器安全性方面,我们为了保证索引中同样两个分片不在同一个机房,机架上,可以强行指定zone;

6.不要使用swap虚拟内存,因为会导致性能比较慢,可以直接在elasticSearch.yml里禁用

7.关于分页,不要使用size,from这种,因为它们会先到若干个数据节点中拿到所有的分页数据,之后在协调节点上再进行过滤,比如10000,10010,我们只要后面十条,但是却会到若干个节点上(比如5个)都拿10010条数据,最后返回到协调节点上就是50050条数据。所以我们在分页上使用scroll这种游标的形式来进行分页;

2018/2/11 ELK技术栈之ElasticSearch学习笔记二的更多相关文章

  1. 2018/2/5 ELK技术栈之ElasticSearch学习笔记

    npm config set registry https://registry.npm.taobao.org npm config get registry 支持跨域访问http.cors.enab ...

  2. Elasticsearch学习笔记二

    PS:上一篇已经介绍了ES的一些基础概念以及单机版ES的安装,配置,本文主要介绍ES的集群管理,CRUD以及简单聚合查询. 集群管理 ES的集群部署起来也很方便,将单机版SCP复制几分,修改elast ...

  3. ELK技术栈之-Logstash详解

    ELK技术栈之-Logstash详解   前言 在第九章节中,我们已经安装好Logstash组件了,并且启动实例测试它的数据输入和输出,但是用的是最简单的控制台标准输入和标准输出,那这节我们就来深入的 ...

  4. 应用编排服务之ELK技术栈示例模板详解

    日志对互联网应用的运维尤为重要,它可以帮助我们了解服务的运行状态.了解数据流量来源甚至可以帮助我们分析用户的行为等.当进行故障排查时,我们希望能够快速的进行日志查询和过滤,以便精准的定位并解决问题. ...

  5. 2018/2/13 ElasticSearch学习笔记三 自动映射以及创建自动映射模版,ElasticSearch聚合查询

    终于把这些命令全敲了一遍,话说ELK技术栈L和K我今天花了一下午全部搞定,学完后还都是花式玩那种...E却学了四天(当然主要是因为之前上班一直没时间学,还有安装服务时出现的各种error真是让我扎心了 ...

  6. ElasticSearch学习笔记(超详细)

    文章目录 初识ElasticSearch 什么是ElasticSearch ElasticSearch特点 ElasticSearch用途 ElasticSearch底层实现 ElasticSearc ...

  7. Elasticsearch学习笔记一

    Elasticsearch Elasticsearch(以下简称ES)是一款Java语言开发的基于Lucene的高效全文搜索引擎.它提供了一个分布式多用户能力的基于RESTful web接口的全文搜索 ...

  8. elasticsearch学习笔记——相关插件和使用场景

    logstash-input-jdbc学习 ES(elasticsearch缩写)的一大优点就是开源,插件众多.所以扩展起来非常的方便,这也造成了它的生态系统越来越强大.这种开源分享的思想真是与天朝格 ...

  9. 【原】无脑操作:ElasticSearch学习笔记(01)

    开篇来自于经典的“保安的哲学三问”(你是谁,在哪儿,要干嘛) 问题一.ElasticSearch是什么?有什么用处? 答:截至2018年12月28日,从ElasticSearch官网(https:// ...

随机推荐

  1. javascript 对象-13

    对象 无序属性的集合,属性可以包含基本值.对象或者函数,简单理解为对象是若干属性的集合:我们常说的面向对象(oop)编程其实是指的一种编码的思想,简单理解为用对象来封装数据,利用封装.继承.多态对代码 ...

  2. solr服务的搭建(以solr4.1实现)

    1.准备工作:一个干净的Tomcat,solr-4.10.3. 2.新建一个文件夹我这里命名为solr,将Tomcat和solr-4.10.3放进去.新建一个solrhome的文件夹,里面放的是sol ...

  3. input[type=file]中使用ajaxSubmit来图片上传

    今天在使用input[type=file]上传图片到服务器时,因为项目要求,并不是像常见的通过按钮来提交表单事件,而是图片上传后就自动执行表单提交事件,将上传的图片信息传给服务器. 刚开始我是这样执行 ...

  4. Mybatis中是否需要依赖配置文件的名称要和mapper接口的名称一致 params错误

    一:当核心配置文件mapper标签下以resource形式指向依赖配置文件时,不需要 这样就可以加载到其相应的依赖配置文件通过namespace找到其相应的方法 二:如果mapper标签下以packa ...

  5. git常见操作

    本地仓库关联远程仓库 新建本地目录scala git init 这样就新建了一个本地仓库 在远端如github上新建仓库scala 关联远程仓库 git remote add origin git@g ...

  6. https和http有什么区别

    在URL前加https://前缀表明是用SSL加密的. 你的电脑与服务器之间收发的信息传输将更加安全. Web服务器启用SSL需要获得一个服务器证书并将该证书与要使用SSL的服务器绑定. http和h ...

  7. 织梦dede在首页调用留言本

    织梦dedecms在首页调用留言本 . {dede:loop table=dede_guestbook sort=dtime row=10 titlelen=36 typeid=40 if=ische ...

  8. Eclipse版本

    Eclipse  3.1  IO 木卫一,伊奥                       2005Eclipse  3.2  Callisto 木卫四,卡里斯托        2006Eclipse ...

  9. 基于 HTML5 WebGL 的 3D 网络拓扑结构图

    现在,3D 模型已经用于各种不同的领域.在医疗行业使用它们制作器官的精确模型:电影行业将它们用于活动的人物.物体以及现实电影:视频游戏产业将它们作为计算机与视频游戏中的资源:在科学领域将它们作为化合物 ...

  10. 如何用docker部署redis cluster

    前言 由于本人是个docker控,不喜欢安装各种环境,而且安装redis-trib也有点繁琐,索性用docker来做redis cluster. 本文用的是伪集群,真正的集群放到不同的机器即可.端口是 ...