架构知识总结--1、es的分布式架构

目录

 

(1)es的分布式架构原理能说一下么(es是如何实现分布式的啊)?

(2)es写入数据的工作原理是什么啊?es查询数据的工作原理是什么啊?

工作原理

写数据底层原理

删除操作底层原理

es读数据过程

es搜索数据过程

(3)es在数据量很大的情况下(数十亿级别)如何提高查询性能啊?

案例

扫描二维码关注公众号,回复: 8607983 查看本文章

数据预热

冷热分离 

document模型设计 

分页性能优化

(4)es生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片?


(1)说一下es的分布式架构原理(es是如何实现分布式的)?

es是基于lucene实现的分布式搜索引擎——elasticsearch。核心思想是在多台机器上启动多个es进程实例,组成了一个es集群。

es中存储数据的基本单位是索引,比如说你现在要在es中存储一些订单数据,你就应该在es中创建一个索引,order_idx,所有的订单数据就都写到这个索引里面去,一个索引差不多就是相当于是mysql里的一张表。

index -> type -> mapping -> document -> field。

type:没法跟mysql里去对比,一个index里可以有多个type。好比说,有一个index,是订单index,里面专门是放订单数据。就好比说你在mysql中建表,有些订单是实物商品的订单,就好比说一件衣服,一双鞋子;有些订单是虚拟商品的订单,就好比说游戏卡,话费充值。就两种订单大部分字段是一样的,但是少部分字段可能有略微的一些差别。所以就会在订单index里,建两个type,一个是实物商品订单type,一个是虚拟商品订单type。相当于每个type代表是具体的一个mysql中的表。

mapping:每个type有一个mapping,如果你认为一个type是一个具体的一个表,index代表了多个type的同属于的一个类型,mapping就是这个type的表结构定义,定义字段类型;

document:实际上你往index里的一个type里面写的一条数据,叫做一条document,一条document就代表了mysql中某个表里的一行数据

field:每个document有多个field,每个field就代表了这个document中的一个字段的值

es是如何实现分布式的:

搭建es cluster集群配合ha机制实现主从架构之后,es底层存储数据的流程:首先创建一个索引,这个索引中的数据就会被分成多个shard切片,通过路由算法也就是计算id的hash值,然后与分片数进行floorMod运算(整个过程类似hash取余)。将数据分别放入到对应的节点上,每个节点都有自身的主从架构(HA机制),每个节点上的主从架构中,又分了primary shard和replication shard,也就是主shard和拷贝shard,一个节点下只能是一个primaryshard 对应多个replication shard ,写数据只能通过primary shard写入,读数据可以通过replication shard,这样就实现了读写分离

 

(2)es中写入数据的工作原理是什么啊?es查询数据的工作原理是什么啊?

性能扩容

由于primary shard 在创建的时候就已经固定了,不可以再修改,也就是说在分布式集群节点上是不可能在扩展机器,所以要进行性能提高,只能纵向扩容,也就是通过增加每个结点下面的主从架构中的从节点服务器,这样一来增加了replication shard的数量,提高了读的性能。

容量扩容

对于容量上的扩容,由于primary shard 在创建的时候就已经固定了,所以无法进行水平扩容来增加存储shard的服务器;所以当前我所能想到的办法就是扩容服务器的磁盘,因为每个节点下面都是主从架构,这个的话,一台台的停机然后对服务器进行磁盘扩容。

写数据底层原理

首先一条数据进入到协调节点上,协调节点计算出它id的hash值,然后与分片值就行floormod运算(类似于hash取余),然后进入到对应的primary shard节点上,首先数据写入到buffer里面,在buffer里的时候数据是搜索不到的,同时将数据写入translog日志文件中。这个时候buffer并不是马上就将数据写入到os cache中,buffer需要满足要么写满了,要么默认等待1秒之后写入os cache中,这个过程也叫做refresh。然后进入os cache 之后,形成segment文件来存放写入的数据,这里不是马上写入到磁盘中,要么os cache满了,要么默认等待5秒之后写入到磁盘中。

在数据放入到os cache中之后其他客户端才能够访问到这条数据,所以es是准实时的NRT,near real-time。默认是每隔1秒refresh一次的,也就是写入1秒后才能读到数据

 

commit操作(也称之为flush操作):1、写入commit point;2、将os cache数据fsync强刷到磁盘上去;3、清空translog日志文件,4、创建一个新的translog日志文件

 

删除操作底层原理

es执行删除操作的时候,并不是马上去磁盘中删掉该数据,而是生产一个.del文件,并且将该doc数据标识为deleted状态,当外部搜索的时候,发现该doc数据为deleted状态,就返回该数据不存在。

真正执行删除操作是在merge合并的时候,就是将单个segment file文件合并到一起的时候回根据deleted状态来删除掉该数据,这个时候就先保存着旧的segment file文件供外部搜索使用。执行merge合并操作之后删除掉。

 

es读数据过程

get某条数据的时候,进入到协调节点,先通过获取id的hash值,将hash值于切片数通过floormod运算,知道对应的shard切片节点,然后进入到该节点获取到数据,然后返回给协调节点,协调节点在返回给客户端

es全文搜索数据过程

进入到协调节点,将搜索请求转发给所有的shard,每个shard将查询到的所有数据都返回给协调节点,协调节点整理好数据之后返回给客户端

(3)es在数据量很大的情况下(数十亿级别)如何提高查询性能啊?

es在第一次搜索数据的时候,查询效率较低,因为第一次查询的数据是在磁盘中查询的,查询完之后,数据就进入到系统内存中,第二次在查询的时候,就直接从内存中查询,速度就会明显比第一次快。所以要提高性能就必须想办法将磁盘中需要查询的数据写入到系统内存中去。

具体提高性能的办法:

1、对es搜索库中的数据进行分表处理,也就是说将document中基本上不怎么查询的属性去除掉,减少es搜索库中数据量;

2、对es搜索库中的数据进行分库处理,也就是说将经常查询的数据建立单独的索引,不经常查询的数据建立单独的索引,总的来说就是将一个index分为两个index,这个的话他们分开在不能的节点上,不经常查询的数据就不会占用经常查询的数据的内存。

 

分页性能优化

对于es分页来说,es对分页支持非常差,比如说当你要查询某一页100条的数据的时候,它实际上是去每一个shard上找到了100条数据,如果是默认的5个shard那就会查询500条数据,然后返回给协调节点,协调节点在筛选100条数据返回给客户端。如果要通过es来实现分页的话只能使用scroll api实现下拉刷新的效果,也就是手机抖音上面一条条往下拉取然后显示

 

发布了469 篇原创文章 · 获赞 94 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/qq_37909508/article/details/99223073