1. ElasticSearch的核心概念
- cluster:代表一个集群,代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个重要概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一 个节点的通信和与整个es集群通信是等价的。
- shards:代表索引分片,es可以吧一个完整的索引分成多个分片,这样就分布到了不同的机器上,构成分布式搜索。分片数量创建后不能修改。默认一个索引库有5个分片。
- replicas:代表索引副本,es可以给索引设置副本,副本的作用一是提高系统的容错性,二是提高es的查询效率,es会自动对搜索请求进行负载均衡。默认是一个分片一个副本。
- gateway:代表es索引的持久化储存方式,es默认是先把索引放入到内存,当内存满的时候再持久化到磁盘中(这点和hbase的memstore很类似)。当集群再次启动的时候会从gateway读取索引数据。(如果需要将数据落地到hadoop的hdfs需要先安装插件 elasticsearch/elasticsearch-hadoop)。
- discovery.zen:代表es的自动发 现节点机制,es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。
- Transport:代表es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、 memcached、zeroMQ等的传输协议(通过插件方式集成)。
2.ElasticSearch的查询
- query and fetch(效率最高)
- query then fetch(默认)
- DFS query and fetch:先分发,排名准确率高。
- DFS query then fetch
以上四种搜索方式举个例子,ElasticSearch的底层的打分机制默认是tf-idf,打分直接影响了ElasticSearch返回的结果顺序。假设现在有3台机器上的ElasticSearch搭成了一个集群,他有分片a,b,c分别再3台机器A,B,C上,分别有125,250,100条数据,当用户需要检索信息的时候,假设用户需要10条信息。如果是query and fetch会根据每台服务器上打分的排名(这里的打分只计算该分片拥有的数据的数量去打分)分别从机器A,B,C上的分片返回相应的元素文档和计算后排名信息一起返回,这样查询方法只要去查询一次,但是各个分片返回的数据之和可能是用户要求的3倍。如果是query then fetch的话,则是先向所有的分片去发出请求,各个分片返回排序和排名相关的数据,取前size数据,然后进行第二步去相关的分片去取文档元素。这种方式返回的元素文档是和用户要求的size是一致的,对分片发了2次请求。而DFS query and fetch和DFS query then fetch和上两个相比,则是多了一部,先去各个分片获取到数据的数量的总和,即125+250+100,然后再将结果发给各个分片,让各个分片根据这个结果去打分,这样的话打分的准确性比较高,但是又多了一次请求。效率低。
3.ElasticSearch的优化
- 调大系统的"最大文件打开数",建议32K甚至64K,命令
ulimit -a(查看) ulimit -n 32000(设置)
- 修改配置文件调整ES的JVM内存大小,直接最大值和最小值一直,防止频繁分配内存。
- 设置mlockall来锁定进程的物理内存地址,避免交换(swapped)来提高性能。修改配置文件elaticsearch.yml,设置bootstrap.mlockall:true。
- 分片多的话,可以提升建立索引的能力,5-20个比较合适。单个分片不宜存太多的索引数据,建议单个分片最多储存20G左右的索引数据。所以,分片数量=数据总量/20G。
- 副本多的话,可以提升搜索的能力,但是设置很多副本也会给服务器带来压力,因为需要同步数据。所以设置2-3个。
- 要定时对索引进行优化,不然segment越多,查询的性能就越差
- 删除文档:在Lucene中删除文档,数据不会马上在硬盘上除去,而是在 lucene索引中产生一个.del的文件,而在检索过程中这部分数据也会参与检索,lucene在检索过程会判断是否删除了,如果删除了在过滤掉。这样也会降低检索效率。所以可以执行清除删除文档
- 如果在项目开始的时候需要批量入库大量数据的话,建议将副本数设置为 0 – 因为es在索引数据的时候,如果有副本存在,数据也会马上同步到副本中,这样会对es增加压力。待索引完成后将副本按需要改回来。这样可以提高索引效率
- 去掉mapping中_all域
ElasticSearch默认为每个被索引的文档都定义了一个特殊的域 - ‘_all’,它自动包含被索引文档中一个或者多个域中的内容, 在进行搜索时,如果不指明要搜索的文档的域,ElasticSearch则会去搜索_all域。_all带来搜索方便,其代价是增加了系统在索引阶段对CPU和存储空间资源的开销.
可以使用"_all" : {“enabled”:false} 开关禁用它