Elasticsearch是什么
Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。不管在开源仍是专有领域,Lucene能够被认为是迄今为止最早进、性能最好的、功能最全的搜索引擎库html
可是,Lucene只是一个库。想要使用它,你必须使用Java来做为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene很是复杂,你须要深刻了解检索的相关知识来理解它是如何工做的。sql
Elasticsearch也使用Java开发并使用Lucene做为其核心来实现全部索引和搜索的功能,可是它的目的是经过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单数据库
因此,能够理解成Elasticsearch(如下简称Elastic)对Lucene进行了封装,让它变得好用api
简化的描述:缓存
Elastic的主要运用领域
Elastic是一个很是著名的开源搜索和分析系统,目前被普遍应用于互联网多种领域中,尤为是如下三个领域特别突出。架构
- 搜索领域,成为不少搜索系统的不二之选,好比全文检索;
- Json文档数据库,相对于MongoDB(笔者未作比较,感兴趣能够比较一下),读写性能更佳,并且支持更丰富的地理位置查询以及数字、文本的混合查询等;
- 时序数据分析处理,目前是日志处理、监控数据的存储、分析和可视化方面作得很是好,好比我们公司里面使用的api访问日志的就是Elastic了,而后使用Kibana可视化日志,感受仍是很方便的
Elastic的一些基本概念的介绍
- 节点(Node):物理概念,一个运行的Elasticearch实例,通常是一台机器上的一个进程,好比咱们在本身的机器上面起了两个Elastic,就至关因而两个节点了。
- 索引(Index),逻辑概念,包括配置信息settings和mapping和倒排正排数据文件,一个索引的数据文件可能会分布于一台机器,也有可能分布于多台机器。索引的另一层意思是建立一条数据,索引一个文件的意思。
- 类型(type):是属于index下一层级的概念,index下面的mapping,映射关系,字段集合等,能够理解成相似Mysql的表结构,而后index理解成库;
- 分片(Shard):为了支持更大量的数据,索引通常会按某个维度分红多个部分,每一个部分就是一个分片,分片被节点(Node)管理。一个节点(Node)通常会管理多个分片,这些分片多是属于同一份索引,也有可能属于不一样索引,可是为了可靠性和可用性,同一个索引的分片尽可能会分布在不一样节点(Node)上,不然一个节点崩了,整个index都无法使用了。分片有两种,主分片和副本分片。
- 副本(Replica):同一个分片(Shard)的备份数据,一个分片可能会有0个或多个副本,这些副本中的数据保证强一致或最终一致
- 文档(doc): 在Elastic中,一条数据称为一个文档,就是相似Mysql里面的一行数据了。
elastic的各个版本差别较大,这也是比较坑的地方,有些默认配置可能会不太同样,好比在早期的elastic版本中,一个index里面能够有多个type,可是多个type里面若是有相同的字段,则这些字段的类型必须同样,可是在elastic 6.x版本里面,好比,咱们当前使用的是elastic 6.7版本,一个index里面只能够定义一个type;
因此若是没有特别说明,全文的elastic表示6.7版本,在这个版本下面,一个index默认有5个主分片和1个副本分片,而后统一主分片和副本分片不能够在同一个节点下面app
- number_of_shards, 主分片数量,索引一旦建立,不能够更改
- number_of_replicas, 副本分片数量,默认为1, 这个能够更改

Elastic的写操做流程
Elastic总体上采用的是一主多副的架构
异步
- 先根据_routing规则选择发给哪一个Shard, 集群中找出出该Shard的Primary节点
Index Request中能够设置使用哪一个Filed的值做为路由参数,若是没有设置,则使用Mapping中的配置,若是mapping中也没有配置,则使用_id做为路由参数,而后经过_routing的Hash值选择出Shard
- 请求接着会发送给Primary Shard
- 在Primary Shard上执行成功后, 再从Primary Shard上将请求同时发送给多个Replica Shard
- 请求在多个Replica Shard上执行成功并返回给Primary Shard
- 写入请求执行成功,返回结果给客户端
须要说明的一点是,写入成功,是指写入到Lucene,并不包含refresh的操做完成,这个后面会涉及到在实际工做中出现的一个bugelasticsearch
针对上面的写入的方式,写入操做的延时就等于latency = Latency(Primary Write) + Max(Replicas Write),缺点是写入效率比较低,除了写入主分片,还须要写入全部副本分片,好处也很明显,经过副本分片能够拓展读性能,由于读的时候,仅仅须要任一副本分片就能够读取数据,除此以外,就是避免在某个分片所在的节点崩了以后,数据不会丢失。分布式
Elastic的TransLog
是为了减小磁盘的IO来保证读写性能,同时也为了保证对于那些已经写入内存可是还没写进磁盘的数据在发生宕机的时候,数据不会丢失。

针对上图,须要说明的几点是:
- refresh表示将Lucene内存中的对象转化为完整的Segment以后,才能够被搜索到,这个时间通常是1秒,因此咱们通常写入Elastic的数据,1秒以后才能够被搜索到,Elasticsearch在搜索方面是NRT(Near Real Time)近实时的系统
- 可是Elastic还有做为NoSQL的一面,若是咱们按照GetById方法查询,这个时候就变成了RT系统,这是由于这种查询方式是直接查询TransLog(上面那个),这个是能够直接被查到的,这个也是我后面才看到了,因此当时的那个问题,我并无采用这种方式
- 每隔一段时间以后,Lucene会将内存中的Segment flush到磁盘上,此时数据被持久化了,历史的Translog就会被清理掉。
Elastic的读操做
Elasticsearch中每一个Shard都会有多个Replica,主要是为了保证数据可靠性,除此以外,还能够增长读能力,由于写的时候虽然要写大部分Replica Shard,可是查询的时候只须要查询Primary和Replica中的任何一个就能够了。

而后针对上面说的GetById的查询方式和普通的Search,下面有个示意图

整体而言读的流程就是
- 在全部分片中根据筛选条件找出docid(主分片和副本分片只须要一个),query
- 而后根据docid取出完整的文档,fetch
- 搜索里面有一种算分逻辑是根据TF(Term Frequency)和IDF(Inverse Document Frequency)计算基础分
- 上面的三个步骤都是在一个shard里面进行的,最后一步将全部内容汇总,根据评分排名,取出部分数据
PS:从上面能够看到Elastic不太适合深度分页,深度分页会比较慢,若是须要获取因此数据,可使用scan,里面是使用的scroll
TF:目标词在字段中出现的次数,加分
IDF:目标词在全部文档中出现的次数,减分
Elastic在使用中的出现的问题和须要注意的地方
索引index按照日期分组
class Record(Document):
class Index:
name = "purifier-record-*"
def save(self, **kwargs):
kwargs['index'] = self.date_created.strftime('purifier-record-%Y%m%d')
return super(Record, self).save(**kwargs)
- 按照日期分index的缘由:index一旦创建,主分片的数量是不能够改变的,至关因而没法水平拓展,若是后期数据量比较大,有可能会致使一台机器空间不足,(PS: 若是你要说有钱,加机器硬件,当我没说,可是一个机器的性能毕竟有限,特别是面对海量日志之类的东西的时候),全部咱们对index进行切分了,按照月份也能够:
- 致使的问题:咱们在使用Elastic搜索的时候,没有指定index,因此最后至关因而全量搜索es,速度很慢,常常接口超时,lambda是15秒,后来咱们查询的时候加上了时间做为筛选项,快了不少,基本都是100ms如下吧
Elastic默认的返回数量是10条,
这个须要注意,不然有可能会遇到明明数据库存在,都是就是查找不出来的状况,坑过
Elastic做为搜索引擎是近乎实时的
这个须要主要,以前我遇到过刚写入数据,而后立马更新缓存或者执行异步任务的时候,缓存更新的是以前的数据,异步任务里面没有搜到刚才那条数据,多是我搜索方式不对,以后可使用GetbyId的方式,我试试看
docid做为其余type的字段时候
假如说在Record里面的_id,保存在Task里面为record_id,而后咱们使用record_id查询进行filter过滤的的时候,要使用keyword查询,就是不分析,由于docid默认的里面有大写字母,而后进行搜索的时候,若是没有配置分词器的话,使用默认的standard分词器,会将大写所有变为小写,因此就查不到了。
最后放上学习资料
Elastic权威指南,版本比较老,看看一些思想,有些操做在新版本须要修改或者废弃了
Elasticsearch技术探讨,阿里的技术人写的一些分享
最后极客时间,前两天新上了Elasticsearch视频课,我先试试毒,买课如山倒,看课如抽丝