es 实现myql field排序 es排序java_数据


搜索引擎面试题

题目和解答来自于中华石杉和自己整理总结而得,希望能够有所帮助。搜索引擎主要考察ElasticSearch 以及对应底层的Lucene技术。主要面试题集中于:

  1. es分布式架构原理
  2. es的插入与查询
  3. es在数据量很大的情况下如何提高性能
  4. es在生产集群的部署架构是什么,每个索引有多大的数据量,每个索引有多少分片

1. es分布式架构原理

首先需要明白es是如何存储数据的,es把对应的数据转换为index。基于倒排索引的方式,每个index上存储了多个type类型,每个type对应一个document。而一个index会被分成多个shard(默认是5个)。在分布式部署时,每个shard会被复制,即一个shard有primary和replica 每个es进程存储的是不同shard的primary和replica。es集群多个节点,会自动选举一个节点为master节点,这个master节点其实就是干一些管理的工作的,比如维护索引元数据拉,负责切换primary shard和replica shard身份拉取之类的。


es 实现myql field排序 es排序java_分布式架构_02


2. es的数据写入与读取

2.1 es数据的写入

2.1.1 es数据的写入过程

注意,客户端是可以在任意节点进行写入数据的,与Kakfa不同。1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)2)coordinating node,对document进行路由得到对应应该存储到哪个shard,将请求转发给对应的node(有primary shard)3)实际的node上的primary shard处理请求,然后将数据同步到replica node4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端


es 实现myql field排序 es排序java_分布式架构_03


2.1.2 es数据的写入原理

es数据写入原理主要可以分为4个操作:

  1. refresh
  2. commit
  3. flush
  4. merge

搜索引擎面试题

搜索引擎主要考察ElasticSearch 以及对应底层的Lucene技术。 主要面试题集中于:

  1. es分布式架构原理
  2. es的插入与查询
  3. es在数据量很大的情况下如何提高性能
  4. es在生产集群的部署架构是什么,每个索引有多大的数据量,每个索引有多少分片

1. es分布式架构原理

首先需要明白es是如何存储数据的,es把对应的数据转换为index。基于倒排索引的方式,每个index上存储了多个type类型,每个type对应一个document。而一个index会被分成多个shard(默认是5个)。 在分布式部署时,每个shard会被复制,即一个shard有primary和replica 每个es进程存储的是不同shard的primary和replica。es集群多个节点,会自动选举一个节点为master节点,这个master节点其实就是干一些管理的工作的,比如维护索引元数据拉,负责切换primary shard和replica shard身份拉,之类的。


es 实现myql field排序 es排序java_客户端_04


2. es的数据写入与读取

2.1 es数据的写入

2.1.1 es数据的写入过程

注意,客户端是可以在任意节点进行写入数据的,与Kakfa不同。 1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点) 2)coordinating node,对document进行路由得到对应应该存储到哪个shard,将请求转发给对应的node(有primary shard) 3)实际的node上的primary shard处理请求,然后将数据同步到replica node 4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端


es 实现myql field排序 es排序java_数据_05


2.1.2 es数据的写入原理

es数据写入原理主要可以分为4个操作: 1. refresh 2. commit 3. flush 4. merge

| | 操作触发条件 | 操作过程 | | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | refresh | 1. 每隔1s进行一次refresh操作
2. buffer已满,则进行一次refresh操作 | 1. buffer将数据写入segment file
2. 清空buffer | | commit | 1. 每隔30分钟执行一次translog
2. translog日志已满 | 1. 会主动进行一次refresh操作,把buffer中的数据写入到segment file
2. 生成一个 commit point 文件标识此次操作一件把buffer数据执行到了哪一个segment文件
3. 执行flush操作 | | flush | commit操作中 | 1. 把file system上的文件全部强制fsync(持久化)到磁盘
2. 清空translog文件
3. 生成一个新的translog文件 | | merge | 后台检查 | 1. 将多个segment文件合并为一个文件,并把.del文件删除
2. commit log 更新标识目前的segment
3. 打开segmentfile 到file cache 以供快速搜索
4. 删除旧的segment file |


es 实现myql field排序 es排序java_客户端_06


2.2 es数据的读取

2.2.1 读取数据

使用RestFul API向对应的node发送查询请求,根据did来判断在哪个shard上,返回的是primary和replica的node节点集合 这样会负载均衡地把查询发送到对应节点,之后对应节点接收到请求,将document数据返回协调节点,协调节点把document返回给客户端


es 实现myql field排序 es排序java_数据_07


2.2.2 全文检索

(1) 客户端使用RestFul API向对应的node发送查询请求
(2)协调节点将请求转发到所有节点(primary或者replica)所有节点将对应的数据查询之后返回对应的doc id 返回给协调节点
(3)协调节点将doc进行排序聚合
(4) 协调节点再根据doc id 把查询请求发送到对应shard的node,返回document

3 es在数据量很大的情况下如何提高性能

3.1 filesystem

es每次走fileSystem cache查询速度是最快的 所以将每个查询的数据50% 容量 = fileSystem cache 容量。

3.2 数据预热

数据预热是指,每隔一段时间,将热数据 手动在后台查询一遍,将热数据刷新到fileSystem cache上

3.3 冷热分离

类似于MySQL的分表分库 将热数据单独建立一个索引 分配3台机器只保持热机器的索引 另外的机器保持冷数据的索引,但有一个问题,就是事先必须知道哪些是热数据 哪些是冷数据

3.4. document设计

在使用es时 避免使用复杂的查询语句(Join 、聚合),就是在建立索引时, 就根据查询语句建立好对应的元数据。

3.5 实际设计

采用elasticSearch + Hbase的架构方式。es中只存放少量关键数据建立索引,通过es查询到doc id 再去Hbase中查询完整的数据信息。

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

生产环境部署情况 (1)es生产集群我们部署了5台机器,每台机器是6核64G的,集群总内存是320G
(2)我们es集群的日增量数据大概是2000万条,每天日增量数据大概是500MB, 每月增量数据大概是6亿,15G。目前系统已经运行了几个月,现在es集群里数据总量大概是100G左右。
(3)目前线上有5个索引(这个结合你们自己业务来,看看自己有哪些数据可以放es的), 每个索引的数据量大概是20G,所以这个数据量之内,我们每个索引分配的是8个shard,比默认的5个shard多了3个shard。

2.2 es数据的读取

2.2.1 读取数据

使用RestFul API向对应的node发送查询请求,根据did来判断在哪个shard上,返回的是primary和replica的node节点集合这样会负载均衡地把查询发送到对应节点,之后对应节点接收到请求,将document数据返回协调节点,协调节点把document返回给客户端


es 实现myql field排序 es排序java_数据_08


2.2.2 全文检索

(1) 客户端使用RestFul API向对应的node发送查询请求
(2)协调节点将请求转发到所有节点(primary或者replica)所有节点将对应的数据查询之后返回对应的doc id 返回给协调节点
(3)协调节点将doc进行排序聚合
(4) 协调节点再根据doc id 把查询请求发送到对应shard的node,返回document

3 es在数据量很大的情况下如何提高性能

3.1 filesystem

es每次走fileSystem cache查询速度是最快的所以将每个查询的数据50% 容量= fileSystem cache 容量。

3.2 数据预热

数据预热是指,每隔一段时间,将热数据手动在后台查询一遍,将热数据刷新到fileSystem cache上

3.3 冷热分离

类似于MySQL的分表分库将热数据单独建立一个索引 分配3台机器只保持热机器的索引另外的机器保持冷数据的索引,但有一个问题,就是事先必须知道哪些是热数据 哪些是冷数据

3.4. document设计

在使用es时 避免使用复杂的查询语句(Join 、聚合),就是在建立索引时,就根据查询语句建立好对应的元数据。

3.5 实际设计

采用elasticSearch + Hbase的架构方式。es中只存放少量关键数据建立索引,通过es查询到doc id 再去Hbase中查询完整的数据信息。

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

生产环境部署情况(1)es生产集群我们部署了5台机器,每台机器是6核64G的,集群总内存是320G
(2)我们es集群的日增量数据大概是2000万条,每天日增量数据大概是500MB,每月增量数据大概是6亿,15G。目前系统已经运行了几个月,现在es集群里数据总量大概是100G左右。
(3)目前线上有5个索引(这个结合你们自己业务来,看看自己有哪些数据可以放es的),每个索引的数据量大概是20G,所以这个数据量之内,我们每个索引分配的是8个shard,比默认的5个shard多了3个shard。