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

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. N的N次方

    题目描述 现给你一个正整数N,请问N^N的最左边的数字是什么? 输入 输入包含多组测试数据.每组输入一个正整数N(N<=1000000). 输出 对于每组输入,输出N^N的最左边的数字. 样例输 ...

  2. Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务

    一.引言 今天本来没有打算写这篇文章,当初我感觉使用这个工具应该很简单,下载的过程也不复杂,也没有打算记录下来.但是在使用的过程中还是出现了一些问题,为了给第一次使用Redis Desktop Man ...

  3. Linux 将本地文件上传Linux服务器, 即ssh 命令上传本地文件

    利用ssh传输文件   在linux下一般用scp这个命令来通过ssh传输文件. 1.从服务器上下载文件 scp username@servername:/path/filename /var/www ...

  4. 认识Java(2)

    注释 对程序的一段文字描述 可方便其他用户的阅读,增加代码的可读性.可以注销掉代码,等需要的时候再用. 编译器会自动忽视被注释的内容. 分类: 单行注释 // 多行注释 /* */ 文档注释/** * ...

  5. ecshop商城_

    一.Ecshop简介: ECShop是Comsenz公司推出的一款B2C独立网店系统,适合企业及个人快速构建个性化网上商店.系统是基于PHP语言及MYSQL数据库构架开发的跨平台开源程序. ECSho ...

  6. Spring @Scheduled 在tomcat容器里面执行两次

    今天在用spring里面的@Scheduled执行定时任务,但是发现到触发定时任务的时间点总会执行两次.原因是修改了tomcat conf包下面的server.xml文件导致的.配置如下: <H ...

  7. P1361 小M的作物

    P1361 小M的作物 题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号). 现在,第 ...

  8. Intellij 设置生成serialVersionUID的方法

  9. Git工具的使用教程

    Git 是一种版本控制工具,也叫作版本管理软件(分布式管理软件).这里介绍Git的基本使用步骤,关于 Git 更详细的介绍,读者可以参考其官方网站提供的文档. 1  安装Git 在Ubuntu系统中安 ...

  10. java精确运算

    public class ArithUtil { /** * 加法 * @param * @return double * @throws Exception * @author zhangyn * ...