关于ES,不得不说的问题。

什么是ES?为什么选择ES?

是一个高性能的非关系型文档数据库,可以快速检索

        天生分布式:高性能高可用易扩展易维护

        跨平台跨语言:支持主流编程语言

        支持结构化存储、地理位置信息存储

        海量数据的全文检索

        支持日志系统

什么是ES的倒排索引?数据结构如何?

倒排索引其实就是把整个文档的索引放在后面,文档中抽出来的内容放在前面。

举个例子:现在录入一首诗,静夜思,床前明月光

传统的正排索引的存储形式是:

索引在前面,比如索引存储的是月光,而整首诗存储在文档里面

这时候用户搜月光能走索引,比如用户搜床前呢,显然会对文档进行全部查询,

假如有成千上万首诗,就造成了查询效率低的情况。

而倒排索引的存储结构是:

        把整首诗录入,录入时会生成一个文档id,其他诗也会有自己的文档id,录入之后,按照索引引擎去抽出每首诗的关键词,形成一个关键词字典,关键词词典利用的是mysql的B+树实现的。

        这样用户在按关键词查询的时候会第一时间查询到关键词,由关键词去查询出哪些文档有这些数据。

        但是如果存在很多个关键词呢,显然放在磁盘里面进行IO操作的话又是很耗费性能的事情。

        但是也不能放在内存里面,因为数据量实在是太大了,所以又引入了关键词索引的概念。

        关键词索引存储在内存里面,它存储的是针对关键词字典的浓缩部分,主要存储一些关键词的前缀,底层是trie树实现的,它会根据关键词词典抽出一个个的词,然后把这些词的组合方式存储下来形成一个树,用户在搜索的时候实际上是从树上去匹配关键词,各个关键词匹配出来之后会得到一个值,这个值就是关键词在关键词词典树中的位置,然后再根据B+树的特点去找词语,找到之后可以获取到对应的文档id,由文档id查询出哪些诗里面存储了这个关键字。

ES中的核心概念有哪些?

1. 索引:是文档的集合,相当于mysql中库的概念,有唯一的名字去标识它,当要操作索引的时候需要使用名字。

2. 文档:文档相当于传统数据库中行的概念,ES中以json数据来表示,在mysql中插入一行数据就相当于在ES中插入一个文档。

3. 字段:相当于mysql中的列,可以理解为是ES中json数据的键。

4. 映射:映射就是针对每个字段的类型进行定义。

5. 分片:如果索引太大会占用空间,影响查询效率,使用分片就是把索引中的数据分别存储在一个个分片里面。

6. 副本:假设分片所在的服务器故障,导致不可用,为了解决这个情况,引入副本概念,每个分片都有自己的副本。

7. 词项:把大的文本分割成很多小的词语进行存储,利用的是倒排索引。

8. 配置:针对索引进行配置,例如默认分片数、索引数。

9. 分析器:ES在存储文档的时候会针对文档进行分析,分析器包含字符过滤器、分词器、词项处理器。

10. 节点和集群:就是一个ES进程,启动ES的时候就启动了一个节点,很多节点组成了集群。

索引文档的过程?

       第一步:客户端发送请求,向集群中的某个节点写入数据。

        第二步:节点1接收到请求,使用文件ID判断文档属于分片0,此时请求会被转发到其他节点2,此时分片0的主分片分配到节点3上。

        第三步:节点3在主分片上执行操作,成功的话就把请求转发到节点1和2的副分片上,执行成功,响应节点1,由节点1响应结果。

并发情况下如何保证数据一致?

        1、 可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖,由应用层来处理具体的冲突;

        2、 另外对于写操作,一致性级别支持 quorum/one/all,默认为 quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。

        3、 对于读操作,可以设置 replication 为 sync(默认),这使得操作在主分片和副本分片都完成后才会返回;如果设置 replication 为 async 时,也可以通过设置搜索请求参数_preference 为 primary 来查询主分片,确保文档是最新版本。

ES如何实现选举?

第一步:确认候选主节点数达标,elasticsearch.yml 设置的值

discovery.zen.minimum_master_nodes;

第二步:比较:先判定是否具备 master 资格,具备候选主节点资格的优先返回,若两节点都为候选主节点,则 id 小的值会主节点。

ES中有哪些分词器?

        standard:默认的分词器,按词切分,可对大小写处理

        keyword:不切分直接将输入作为输出。

        pattern:按正则处理

        language:提供了30多种常见的分词器

        customer:自定义分词器

什么是ES中的mapping?

   Mapping 类似于数据库中的表结构定义 schema,它有以下几个作用:

        定义索引中的字段的名称定义字段的数据类型,比如字符串、数字、布尔字段,倒排索引的相关配置,比如设置某个字段为不被索引、记录 position ES 早期版本,一个索引下是可以有多个 Type ,从 7.0 开始,一个索引只有一个 Type,也可以说一个 Type 有一个 Mapping 定义。

ES的聚合查询有哪些?

        分桶聚合:类似于grupby

        指标聚合:一般用于计算,求平均值、求和

        管道聚合:对聚合结果的二次聚合,相当于对查询结果进行子查询

ES支持的数据类型?

        字符串:textkeyword

        数字:in、float、double

        日期

        布尔

        二进制

        区间

        地理位置        

写性能调优?

        减少读写之间的资源抢占,读写分离

        大批量的数据写入尽量控制在低检索请求的时间段内,大批量的写入集中处理

        增加flush的时间,减少IO操作频次

        增加refresh_interval的值,减少segment的创建,目的是减少fullGC

读性能调优?

       禁用swap

        使用filter代替query

        避免深度分页,如果数据量大就使用scorll search或者search after

        避免索引之间的耦合

ES中的节点类型?

       主节点

        候选节点

        投票节点

        数据节点

        冷节点

        热节点

什么是深度分页?

 例如:假设现在有40个数据分布在4个分片上,我们请求第1页的10条数据,

使用默认分页from size实现分页的话,假设请求首先打到协调节点上,协调节点去4个分片取出所有的40条数据进行排序,排序之后再取前10条,数据量小的情况下还没问题,如果数据量太大,这就是一个比较耗时的过程。

深度分页的解决方法:

Scroll 遍历查询:滚动查询,类似于浏览网站时使用鼠标滑轮滚动查看下一页的效果。

Search After 查询:每次查询都向后查询,不支持向前查询。

淘宝:删除跳页功能,一次只返回前100页

ES的分片策略?

7.x版本之前默认是5个分片1个副本,7.x版本之后是1个分片对应一个副本。

不允许分片和自己的分片副本在一个节点上

会尽可能的把分片分到多个节点上,但是不会均匀分布

同一个节点上有多个分片存在

分片在索引创建的时候分配数量副本可以在任何时候分配

猜你喜欢

转载自blog.csdn.net/weixin_43195884/article/details/129129497