Elaticsearch ,简称为es,es是一个开源的 高扩展的分布式全文检索引擎,它可以近乎 实时的存储、检索数据,本身扩展性很好可以扩展到上百台服务器,处理 PB级别(大数据时代)的数据。es也使用java开发并使用Luene(基于倒排索引的)作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API(一个请求可以有不同的请求方法get post put delete)来隐藏Lucene的复杂性,从而让全文搜索变得简单。
Elaticsearch 和Slor的区别:
- es基本是开箱即用(解压就可以用!),非常简单。Solr安装略微复杂一丢丢!
- Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能
- Solr 支持更多格式的数据,比如SON、XML、CSV,而 Easticsearch 仅支持ison文件格式
- Solr 官方提供的功能更多,而 Elasticsearh 本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要kibana友好支撑
- Solr 查询快,但更新索引时慢( 即插入删除慢),用于电商等查询多的应用
ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索
Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用 - Solr比较成熟,有一个更大,更成熟的用户、开发和贡献者社区,而 Elasticsearch相对开发维护者较少,更新太快,学习使用成本较高。
ES核心概念
elasticsearch是一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能。
elasticsearch是面向文档的。文档数据会被序列化为json格式后存储在elasticsearch中,而Json文档中往往包含很多的字段(Field),类似于mysql数据库中的列。
索引、字段类型、文档
和数据库的对比:索引(数据库)、类型(表)、文档(行)、fields(字段)
es中可以包含多个索引,每个索引中包含多个类型,每个类型又包含多个文档,每个文档又包含多个字段
物理设计:es在后台把每个索引划分成多个分片,每个分片可以在集群中的不同服务器中迁移
逻辑设计:文档、类型、
倒排索引
正向索引:逐行扫描,也就是全表扫描,随着数据量的增加,查询效率会越来越低(索引查询效率高,模糊查询效率低)
倒排索引:文档(用来搜索的数据,每条数据就是一个文档);词条(对文档数据进行分析,得到一个个词条(term))
创建倒排索引的过程:
- 将每一个文档的数据利用算法分词,得到一个个词条
- 创建表,每行数据包括词条,词条所在的文档id、位置等信息
- 词条唯一性,可以给词条创建索引
倒排索引的搜索过程: - 对用户的输入进行分词,得到词条
- 在倒排索引中查找词条,得到包含词条的文档id
- 拿到文档id之后在正向索引中查找具体文档
优缺点:
- 正向索引:
- 优点:可以给字段创建索引;根据索引字段搜索排序时,速度非常快
- 缺点:根据非索引字段,或索引字段中的部分词条查找时,智能全表扫描
- 倒排索引:
- 优点:根据词条搜索、模糊搜索时,速度非常快
- 缺点:只能给词条创建索引,而不是字段;无法根据字段排序
ES
- elasticsearch是面向文档的(就像数据库中的一行数据)。文档数据会被序列化为json格式后存储在elasticsearch中,而Json文档中往往包含很多的字段(Field),类似于mysql数据库中的列。
- 索引就是相同类型的稳当的集合 (索引就像数据库中的表,映射就像数据库中定义的表结构) —> 数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。
- DSL是es提供的JSON风格的请求语句,用来操作es,实现crud。
Mysql和es
mysql:擅长事务类型操作,可以确保数据和安全的一致性
elasticsearch: 擅长海量数据的搜索分析计算
往往二者结合使用:
- 对安全性较高的写操作,使用MySQL实现
- 对查询性能较高的搜索请求,使用es实现
- 二者再实现数据的同步,保证一致性
分词器的作用是什么?
创建倒排索引时对文档分词
用户搜索时,对输入的内容分词
IK分词器有几种模式?
- ik_smart:智能切分,粗粒度
ik_max_word:最细切分,细粒度
IK分词器如何拓展词条?如何停用词条?
利用config目录的IkAnalyzer.cfg.xml文件添加拓展词典和停用词典
在词典中添加拓展词条或者停用词条
es索引库操作
mapping映射属性
索引库的crud
- 创建索引库:PUT /索引库名
PUT /name
{
"mapping":{
"properties": {
"字段名":{
"type": "text",
"analyzer": "ik_smart"
},
"字段名2":{
"type": "keyword",
"index": "false"
},
}}}
- 查询索引库:GET /索引库名
GET /name
- 删除索引库:DELETE /索引库名
DELETE /name
- 修改索引库(添加字段):PUT /索引库名/_mapping
只能增加新的字段到库中(若修改已有的字段,会对倒排索引产生影响)
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}
文档操作
- 新增文档
POST /索引库名/_doc/文档id
- 查询文档
GET /{索引库名称}/_doc/{id}
//批量查询:查询该索引库下的全部文档
GET /{索引库名称}/_search
-
删除文档
DELETE /{索引库名}/_doc/id值
-
修改文档(全量修改(直接覆盖原来的文档{根据指定的id删除文档,新增一个相同id的文档})和增量修改(修改文档中的部分字段))
es聚合种类
数据同步
集群
master eligible节点的作用是什么?
- 参与集群选主
- 主节点可以管理集群状态、管理分片信息、处理创建和删除索引库的请求
data节点的作用是什么?
- 数据的CRUD
coordinator节点的作用是什么?
-
路由请求到其它节点
-
合并查询到的结果,返回给用户
脑裂问题
ES 7.0后默认配置了( eligible节点数量 + 1 )/ 2来解决脑裂问题
脑裂是因为集群中的节点失联导致的。
例如一个集群中,主节点与其它节点失联,此时,其他节点认为主节点宕机,就会重新选主。新的主节点当选后,集群继续对外提供服务,node2和node3自成集群,node1自成集群,两个集群数据不同步,出现数据差异。
当网络恢复后,因为集群中有两个master节点,集群状态的不一致,出现脑裂的情况。
解决脑裂的方案是,要求选票超过 ( eligible节点数量 + 1 )/ 2 才能当选为主,因此eligible节点数量最好是奇数。对应配置项是discovery.zen.minimum_master_nodes,在es7.0以后,已经成为默认配置,因此一般不会发生脑裂问题
集群分布式存储
当新增文档时,应该保存到不同分片,保证数据均衡
原理:
- elasticsearch会通过hash算法来计算文档应该存储到哪个分片:
集群分布式查询
elasticsearch的查询分成两个阶段:
- scatter phase:分散阶段,coordinating node会把请求分发到每一个分片
- gather phase:聚集阶段,coordinating node汇总data node的搜索结果,并处理为最终结果集返回给用户
集群故障转移
集群的master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移。
参考链接:https://www.cnblogs.com/buchizicai/p/17093719.html