一.简介
Elasticsearch是一个基于Apache Lucene的分布式搜索分析引擎
分布式:分布式的实时文件存储
搜索引擎:基于lucene的实时分析搜索引擎,每个字段都被索引并可被搜索
海量数据:可以扩展到上百台服务器,处理PB级结构化或非结构化数据
ps:默认新索引的文件会有1秒的延时方能搜索到(默认设置index.refresh_interval:1s)
es准实时原理:
二.Lucene
正排索引:文档id为key,记录文档中关键词的位置信息;
倒排索引:关键词为key,记录出现该关键词的文档id和次数、位置。
Lucene词典现在采用的数据结构为FST,它的特点就是:
词查找复杂度为O(len(str))
共享前缀、节省空间
内存存放前缀索引、磁盘存放后缀词块
文档索引过程代码:
文档分词, 语言处理, 添加索引
|
三.基本概念
1. Cluster
集群是各个节点的集合,保存了所有的数据并提供了数据检索能力。
2. Node
多个节点构成了集群,集群的数据存储和数据检索也是依赖于节点来完成的。
3. Shards
数据分片,提供了index数据量无限增大的能力。出现数据分片的原因:单个node容不下某个index中所有的数据。等同于db分表。
4. Replicas
既然有了数据分片,也就意味着数据不在同一个物理节点上存储,那么某次查询就会可能出现某个数据分片所在的节点挂掉的情况,此时的解决方案就是进行数据复制
+ 默认情况下,elasicsearch有5个数据分片和1次复制,这就意味着如果集群中只有两个nodeA和B,加入nodeA保存着源数据,那么经过一个数据复制之后,nodeB中也会存在一份相同的数据
es不会将主分片分配给与其副本相同的节点,也不会将同一分片的两个副本分配给同一个节点
如果数据份数(主+复制)>节点数,那就意味着必然有份数据没有节点可供分配
5. Index
索引是document的集合,通过索引你可以查询,更新,删除document
索引相当于数据库
+ 索引的名称必须全部是小写
+ 集群中你可以定义多个index
6. Type
Type可以理解为数据库中的表,Document就是通过该类创建出来的实例,推荐一个index只有一个type
7. Document
Document是可以被检索到的最小数据单元集合
+ Document数据全部是JSON格式
+ Document有自己的字段,称为Field,每个Field可设置是否支持搜索、分词搜索等
8.mapping
记录es索引的结构和字段
number_of_shards表示分片数,number_of_replicas表示每个分片有几个副本(0表示无副本,n表示同样的数据要复制n份)
type表示数据类型,新版本es(5.x+)对一些数据类型做了变动,如text,keyword。es的field也支持嵌套结构,可根据官方文档学习。
index:not_analyzed表示不分词但支持搜索,no表示不支持搜索,analyzed表示分词搜索。
还有一个store字段表示是否在文档中存储
五.elasticsearch 客户端
有业务曾经用spring-data-elasticsearch插件,也有原生的客户端支持(比如The Java High Level REST Client等等)。
目前用到es业务的有标签、活动投稿、bi路由日志等。
六.其他
1.es深分页问题
深分页的危害:
导致打爆节点内存引起集群整体不可用
ES处理查询的流程如下:
-
Client需要第N到N+m条结果
-
接到这个请求的ES server(后继称之为协调者)向每一个数据分片所在的数据节点发送请求
-
每一个数据节点都需要向协调者返回(N+m)个结果
-
如果有n个数据分片,那么协调者拿到n * (N+m)个结果,排序,扔掉(n-1) * (N+m)个结果,返回给client N+m个结果
-
如果N是10W,100W,那么协调者的内存压力会非常大
- 在2.1版本中,ES已经不容许N>10000
推荐使用scroll查询,分页时需指定一个游标
官方2.1版本demo:https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.1/java-search-scrolling.html
2.精确匹配的搜索
可以使用matchPhraseQuery ,即使是打开了分词的索引字段,也可以支持关键词的精确匹配。
例如搜索“数码达人”,用matchQuery可能会返回包含数码或达人的文档;用matchPhraseQuery只会返回包含“数码达人”这四个字的文档。
参考资料:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-api.html
https://es.xiaoleilu.com/010_Intro/00_README.html