ElasticSearch实践与原理剖析
1.1 全文检索
大多数互联网系统都具有关键词检索的能力,如何快速检索数据,如何从海量的数据中检索出需要的信息,就可以使用 es 来进行大数据检索服务;
ES 具有优秀能力:
1)分布式的数据存储服务
2)完全可以根据索引检索数据
3)底层使用的是 lucene 全文检索技术
4)ES 在数据存储上使用分片存储方式,具备很强大横向扩展能力;
思考:数据可以被快速检索?
1)数据存储在内存(es 近实时的检索,就是可以直接从内存命中数据)
2)索引(ES 倒排索引来实现数据的检索,因此 es 可以非常快速命中需要的数据)
3)多线程(分片存储)
4)顺序存储(减少磁道寻址时间)
第一大能力:互联网网站数据资源变多后必须具备的数据检索能力
1.2 日志存储分析
互联网公司中使用非常普遍的能力,使用 elasticSearch 存储系统业务日志,主要使用 es存储业务日志然后便于分析系统问题位置;(系统上线后,发现系统接口失败率上升,为了定位这个问题,就去查看系统日志,通过日志精确定位问题位置)在企业中:
1)使用 promethues 监控系统问题,一旦发现问题 promethues 立马报警(钉钉,微信—压力比较大—保证代码质量)
2)使用 kibana 分析定位问题位置
排查系统 bug:
Key:value -> msg:err | project : order timeout –> 快速问题的位置;
1.3 数据存储
直接利用 elasticSearch 服务作为数据存储服务,因为 es 具有海量的数据检索能力,强大的横向扩展能力,因此在一些数据检索服务中,可以使用 es 作为数据服务;
ES 可以作为地图数据检索;
2 全文检索
2.1 什么是全文检索
全文检索:查询(类似与数据库的模糊查询 like “%搜索%”,根据关键词搜索目标数据)
1)结构化数据(具有固定的格式或有限长度的数据,例如:数据库一行数据,每一个数据都有字段长度,字段类型)
2)非结构化数据(不定长或无固定格式的数据,例如:互联网网页数据,邮件,word文档,excel 文档……)
全文检索基本概念:对非结构化数据/结构化数据 建立索引,再对索引进行搜索文档数据
(json 数据)的过程,叫做全文检索(full text search);
ES 建立索引和文档检索对比图:
类比:通过关键词可以检索出需要的文档数据;
2.2 检索算法
Elasticsearch 搜索采用的是倒排索引法,根据索引(关键词)倒推检索出整个文档数据的过程,就叫做倒排索引;
例如:
1)顺序扫描:诗词大全,但是这个书没有目录,查询 <静夜思>, 将会从第一页开始查询数据;一直查询到最后一页(如果这首诗恰好在最后一页);
2)倒排索引:诗词大全,但是这个书有目录(索引),先看目录(诗词名称-对应页码),快速跟进目录定位到诗词的位置;
2.3 倒排索引
全文检索:为什么不使用数据库 like 关键词做查询??
模糊查询: select * from t where title like “%静夜思%”;
原因:
1)全表扫描
2)分词问题
3)海量数据检索问题
2.4 全文检索结构
问题:索引库中索引是从哪儿来的?? (要实现搜索,索引库必须先有数据,才能检索到需要的结果)
2.5 索引库结构
1)索引库结构
2.6 检索流程
3 ES 实践与集群架构
3.1 ES 的集群架构
ES 是一个分布式的文档数据库(一个高可扩展性,分布式的搜索引擎,关键之处就在于海量数据的检索,也涉及到海量的数据存储)一个 master 节点对应一群 node 节点,master 节点负责管理集群,维护集群状态,同时 master节点也负责读写数据;
ES 底层使用的是 lucene,屏蔽掉了 lucene 一些复杂操作(当检索的数据量越来越大的时候,lucene 无能为力,如果还必须使用 lucene,那么我们必须自己开发大量数据维护的代码,lucene 可能在单机服务器检索没有问题),es 帮助我们解决了海量的数据检索问题;
1)启动 es 节点(观察 es 节点特点)
集群状态:
1)黄色: 表示集群可用,但是集群处于不健康状态(亚健康),因为没有副本分片(数据只存储了一个主分片数据,没有副本分片)-- 只要有一个副本分片不存在,集群就是黄色的;
2)红色:表示集群不可用(有主分片不在)
3)绿色:表示集群非常健康,集群可用的;
- 主节点副本节点如何区分?
1)☆ : 主节点(master 节点)
2)○ : 副本节点(slave 节点,node 节点)
3.2 ES 分片结构
ES 存储原理
ES 采用分片的方式进行存储数据,把数据均衡的分散每一个节点进行存储,分担服务器读写压力;
ES 索引库:默认创建 5 个 primary shard , 5 个 replica shard ;
创建分片数量
{“settings”: { “index”: { “number_of_shards”: “2”, #分片数
“number_of_replicas”: “0” #副本数
} } }
ES 分片存储分片结构:
1) Es 分片均衡的分布在每一个节点中: 分片数量/节点数量 = num 就是均衡分配的
数量,如果除不尽,从第一个节点开始,每一个节点多分片一个分片即可;
2) 无论是主节点,还是从节点都可以进行读写操作;
3) 在一个节点中,主分片和自己的副本分片不能放在同一个节点中;
4) 分片均衡分布在每一个节点,相当于把请求均衡分配给每一个节点(类似负载均衡)
3.3 节点类型
节点类型
1)master 节点:维护集群状态,管理集群
配置文件设置:
-
node.master : true – 有参与竞选成为 master 的权利
-
node.data: true – 表示这个节点具有多重身份,既可以作为 master,又可以存储数据;
2)数据节点:负责存储数据(索引数据)
-
node.master : false* node.data: true
3)协调节点:根据路由算法,把请求转发到对应的分片进行处理 -
node.master: false * node.data:false
表示这个节点只作为协调节点;
注意:每一个节点类型都不是单一的,如果都设置为 true,表示这个节点具有 3 重身份;
4 ES 高级进阶
4.1 集群故障转移
多个 es 集群节点,有一个节点异常退出了(宕机了),此时 es 必须发生故障转移,解决 es 可用性问题;
当一个节点宕机了,分片将会进行转移,转移到健康的节点中继续提供服务,保证集群正常性;
高级特性:
1)分布式 es 集群:主分片数量一旦确定,无法更改(在企业中,主分片数量一开始必须确定好),如果必须更新主分片数量,必须重新创建索引库;
2)副本分片理论上可以无限制扩容,但是实际情况需要考虑 master 节点维护能力(是否可以维护这么庞大副本分片集群,如果分片太多,超过了 master 节点维护能力,性能反而可能会下降,同时也需要节点 cpu,内存,io 资源限制分片数量)
3)一个文档只能存储在一个分片,不能分散存储
4)主分片数量确定了可以存储的容量,而副本分片仅仅是主分片数据拷贝
5)主分片理论上可以存储无限制大小的数量(一个物理机只分配一个分片,这个分片存储的数据就是整个物理机磁盘),如果一个分片太大,在读取数据,故障转移的时候都会影响性能;一般情况下,一个分片最大大小设置为:50G
6)极限分片:一个物理节点只存储一个分片(一个 shard 独立占用机器 cpu,内存,io)
4.2 横向扩容能力
需求:构建 es 集群后,并发访问压力越来越大,数据量急剧增大??
初始化构建 ES 集群节点: 2 个节点,2 primary shard , 2 replica shard
1)扩容一:极限分片法,一个分片,一个服务器
每一个分片:独占 CPU,io 资源,性能会有一定的提升;
2)扩容二:并发量持续增大如果并发量增大,可以持续对副本分片进行扩容,增大读数据的能力;提升读性能;
4.3 ES 脑裂现象
在 es 集群中,由于网络的原因,master 节点和其他的节点失联了,造成失联节点重新选举一个 master, 就意味着一个集群有 2 个 master,因此产生了脑裂现象;
如何解决 es 脑裂现象??
设置一个选举条件,当前集群网络中节点数量是否 >= 集群候选节点(node.master=true)
数量/2 + 1 , 如果满足这个条件可以参与选举,否则无法进行选举,且对 master 进行降级处理(把 master 降级为 node 节点)
4.4 文档读写路由
ES 文档读写路由公式:
shardN = hash(routing) % number_of_primary_shards
1)hash 算法,es 提供 hash 算法
2)routing
- _id 默认是文档 id , 默认 routing=_id;* 自定义 routing 值:
/doc/11?routing=xx
- number_of_primary_shards 主分片的数量
问题:为什么主分片数量一旦确定,不能发送改变呢??
理由算法:shardN = hash(routing) % number_of_primary_shards(主分片数量)
原来:21 % 3 = 0 ,从 p0 的分片查询,写入数据
现在:21 % 4 = 1,从 p1 的分片查询(查询不到原来的数据),写入数据