Elasticsearch数据库优化实战:让你的ES飞起来
摘要:ES已经成为了全能型的数据产品,在很多领域越来越受欢迎,本文旨在从数据库领域分析ES的使用。
本文分享自华为云社区《Elasticsearch数据库加速实践》,原文作者:css_blog 。
一、方案说明
Elasticsearch主要功能是什么,不同的场景有不同的定位,在日志场景我们可以用ELK生态搭建日志分析系统,在搜索领域ES是当前最热门的搜索引擎。在大数据领域,ES可以对标Hbase提供海量日志的数据仓库;在数据库领域ES可以作为查询分析型的分析型数据库使用。ES已经成为了全能型的数据产品,在很多领域越来越受欢迎,本文旨在从数据库领域分析ES的使用。
ES不是关系型数据库,数据更新采用乐观锁,通过版本号控制,不支持事务处理,这也是ES区别于传统数据库(Mysql)的地方;但是ES支持精确查询加速,多条件任意组合查询,多种聚合查询,查询速度很快,可以替代数据库复杂条件查询的场景需求,甚至可以代替数据库做二级索引。
在数据库加速场景通常的做法是客户产生的商品订单数据会写入Mysql类关系型数据库,数据库写入保证事务性,但是随着商品订单的数据越来越多,同时客户查询的条件多变,无法所有字段都建立索引,数据库的查询能力远远不能满足查询诉求。我们考虑用ES全量同步数据库数据,在ES中做多条件聚合查询,查询的结果可以在Mysql中做关联搜索,在查询商品订单详情展示, Mysql数据和ES数据可以不要求实时一致,可以通canal消费Mysql binlog日志信息, 同步到ES,实现一次写入,保证数据一致性。以下数据库都以Mysql为例进行说明。
二、索引原理分析
ES为什么查询能力远远超过Mysql关系型数据库,主要是他们的实现原理和底层存储的数据结构差异决定的,以下比较两种产品的实现原理。
Elasticsearch会对所有输入的文本进行处理,建立索引放入内存中,从而提高搜索效率。在这一点上ES要优于MySQL的B+树的结构,MySQL需要将索引放入磁盘,每次读取需要先从磁盘读取索引然后寻找对应的数据节点,但是ES能够直接在内存中就找到目标文档对应的大致位置,最大化提高效率。并且在进行组合查询的时候MySQL的劣势更加明显,它不支持复杂的组合查询比如聚合操作,即使要组合查询也要事先建好索引,但是ES就可以完成这种复杂的操作,默认每个字段都是有索引的,在查询的时候可以各种互相组合。
(1)数据库索引B+树
数据库中索引都是以树来组织的,常用的有B tree,B-tree,B+tree,以下介绍B+tree的组织结构。
首先我们先想象下为什么需要建立索引,假设我们有一张表book,存储了我们保持的书籍信息,名称,作者,发布时间等,我们有10000条记录,如果我们需要找一本为《database》的书,那我们的SQL为:
select name,author form book where name = ‘database’;
我们需要扫描整个表,全量比较才可以,如果我们对name建立索引,书名已经按照顺序排序,查询时只需要找到对应位置就可以快速获取结果。
索引的本质是通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。
数据库采用B+tree建立索引:

B+tree 数据只存储在叶子节点中。这样在B树的基础上每个节点存储的关键字数更多,树的层级更少所以查询数据更快,所有指关键字指针都存在叶子节点,所以每次查找的次数都相同所以查询速度更稳定。
(2)Elasticsearch索引原理
ES建立索引采用倒排索引的方式存储。
对输入的所有数据都建立索引,并且把所有和文档对应起来,在我们查找数据的时候我们直接查找词典(Term),在找到Term对应的文档ID,进而找到数据。这和Mysql使用B+tree树建立索引的方式类似,但是如果词典Term很大,对Term的搜索就会很慢,ES进一步建议了词典索引(FST),提升词典的搜索能力。

Term Index 以树的形式保存在内存中,运用了FST+压缩公共前缀方法极大的节省了内存,通过Term Index查询到Term Dictionary所在的block再去磁盘上找term减少了IO次数。
Term Dictionary 排序后通过二分法将检索的时间复杂度从原来N降低为logN。
三、查询对比分析
以下对于数据库搜索常用的场景对比ES和数据库:
- 全文检索
ES支持全文检索,可以对数据分词,每个词通过FSP建立词典索引,而Mysql关系数据库则不支持,想象下如果搜索的不是整个字段而是字段中的几个关键词,使用Mysql搜索必须全表扫描。
- 精确搜索
如果Mysql对该字段建立过索引,使用ES搜索和Mysql搜索性能差异不大,可能Mysql更快点,但是ES是分布式系统,可以支持PB级别的数据搜索,对大表搜索ES优势更明显。
- 多条件查询
我们知道Mysql需要对字段建立索引才能加速搜索过程,而ES默认是全索引的,对于多条件查询,触发Mysql建立联合索引,否则多个字段搜索,Mysql 先选择一个字段搜索,结果在使用第二个字段过滤得到最终结果。
ES则采用多个字段结果集交并操作,使用bitmap或者skiplist加快搜索速度,相比Mysql优势明显。
- 聚合搜索
Mysql聚合搜索如果没有建立索引需要全表扫描排序,如果建立索引在B+tree上进行范围查询。
ES为了加快聚合搜索速度,通过Doc value来解决聚合搜索问题。DocValue就是列式存储。
存储结果如下:

Docvalue数据按照文档ID排序,DocValue将随机读取变成了顺序读取,
在es中,因为分片的存在,数据被拆分成多份,放在不同机器上。但是给用户体验却好像只有一个库一样。对于聚合查询,其处理是分两阶段完成的:
- Shard 本地的 Lucene Index 并行计算出局部的聚合结果。
- 收到所有的 Shard 的局部聚合结果,聚合出最终的聚合结果。
这种两阶段聚合的架构使得每个 shard 不用把原数据返回,而只用返回数据量小得多的聚合结果。这样极大的减少了网络带宽的消耗。
- 多副本加速
我们知道ES有shard和replica的概念,副本一方面可以保证数据的可靠性,另一方面多副本可以加快搜索速度提高搜索并发能力。
四、数据库到Elasticsearch同步方案
结合用户实际的使用方式和数据量的大小,Mysql数据到ES可以有多种不同的方式选择。
- Canal=>Elasticsearch
使用Canal直接消费Mysql binlog日志写入ES,这种方式如果Mysql写入量大,会面临Canal写入阻塞问题。
- Canal =>Kafka=>Elasticsearch
Canal数据写入到Kafka,使用另外的app消费Kafka数据同步到ES
五、问题汇总
1.索引shard问题
在Mysql数据同步到ES中面临索引的建立的问题,在数据写入ES之前我们需要提前规划数据的shards和replicas的个数,replicas 可以动态修改,但是shards数创建完成后不能修改。
随着Mysql数据量的增加,如果shard太少,就会导致每个shard的数据量太大的问题。
如果一个索引600G,只有3 个shard,每个shard就200G,会极大的损耗查询能力,也不利于数据迁移。
我们可以按照月来滚动创建索引,通过索引别名把所有索引关联起来使用。
test_data-202101
test_data-202102
2.查询加速问题
在使用ES对数据库进行加速的场景,我们希望的是ES查询能力尽可能快。在ES查询不满足要求的时候我们需要对查询进行调优。
常用的方法有:

Elasticsearch数据库优化实战:让你的ES飞起来的更多相关文章
- mysql数据库优化实战--日期及IP地址的正确存储方式
- Elasticsearch数据库 | Elasticsearch-7.5.0应用搭建实战
Elasticsearch 是一个可用于分布式以及符合RESTful 风格的搜索和数据分析引擎.-- Elastic Stack 官网 搭建Elasticsearch的"那些事儿" ...
- 知识点:Mysql 数据库索引优化实战(4)
知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 一:插入订单 业务逻辑:插 ...
- Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析
Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析 生鲜电商搜索引擎的特点 众所周知,标准的搜索引擎主要分成三个大的部分,第一步是爬虫系统,第二步是数据分析,第三步才 ...
- Elasticsearch.net项目实战
elasticsearch.net项目实战 目录 Elasticsearch+kibana 环境搭建 windows 10环境配置 安装Elasticsearch head安装(非必需) 安装kiba ...
- Elasticsearch核心技术(1)--- Docker容器中运行ES、Kibana、Cerebro
Docker容器中运行ES,Kibana,Cerebro和Logstash安装与数据导入ES 想加强ES有关的知识,看了阮一鸣老师讲的<Elasticsearch核心技术与实战>收获很大, ...
- 【C#】项目优化实战
[C#]项目优化实战 一. 数据库设计 1. 常量的枚举值直接存中文不要存数字(注意是常量,如果显示值可变就不能) 例如:男女,在数据库中不要存1和0,直接存男和女. 这样的好处:读取数据的时候可以避 ...
- 基于Oracle的SQL优化(社区万众期待 数据库优化扛鼎巨著)
基于Oracle的SQL优化(社区万众期待数据库优化扛鼎巨著) 崔华 编 ISBN 978-7-121-21758-6 2014年1月出版 定价:128.00元 856页 16开 编辑推荐 本土O ...
- 知识点:Mysql 索引优化实战(3)
知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 索引原理知识回顾 索引的性 ...
随机推荐
- SqlServer视图的创建与使用
SqlServer系列之视图的创建与使用: 什么是视图? 视图的概述 在数据查询中,可以看到数据表设计过程中,考虑到数据的冗余度低.数据一致性等问题,通常对数据表的设计要满足范式的要求,因此也会造成一 ...
- " "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问>
" "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问> 经过前面两章的学习,应该很清楚当你在 shell prompt 后面敲打键盘.直到 ...
- ES 分页方案
ES 中,存在三种常见的分页方案: FROM, SIZE Search-After Scroll 下面将依次比较三种方案之间的 trede-off,并给出相应建议的应用场景. 常见分页,FROM, S ...
- Day1---Java 基本数据类型 - 四类八种 --九五小庞
一.Java四大数据类型分类 1.整型 byte .short .int .long 2.浮点型 float . double 3.字符型 char 4.布尔型 boolean 二.八种基本数据类型 ...
- Laravel源码解析 — 服务容器
前言 本文对将系统的对 Laravel 框架知识点进行总结,如果错误的还望指出 阅读书籍 <Laravel框架关键技术解析> 陈昊 学习课程 Laravel5.4快速开发简书网站 轩脉刃 ...
- Apache Hudi 0.8.0版本重磅发布
1. 重点特性 1.1 Flink集成 自从Hudi 0.7.0版本支持Flink写入后,Hudi社区又进一步完善了Flink和Hudi的集成.包括重新设计性能更好.扩展性更好.基于Flink状态索引 ...
- 火爆外网的 DGS 框架使用
Netflix 已开放其 Domain Graph Service(DGS)框架的源代码 ,该框架是为了方便整合 GraphQL 使用,用于简化 GraphQL 的实现. GraphQL 主要是作用于 ...
- Warm_up(HCTF_2018)
Warm up 考察知识点: 文件包含漏洞 代码审计 解题步骤 首先我们进来看到了一个滑稽的表情,没啥别的东西,先看看源码 源码中发现有注释 source.php 我们访问source.php,得到代 ...
- 横趟!面试中遇到的 ZooKeeper 问题
本文作者:HelloGitHub-老荀 本文是 HelloZooKeeper 系列的最后一篇文章,接下来主要聊聊面试中如果被问到 ZooKeeper 的问题如何回答,也可以当作学完本系列的测试. 准备 ...
- 【pytest官方文档】解读fixtures - 11. fixture的执行顺序,3要素详解(长文预警)
当pytest要执行一个测试函数,这个测试函数还请求了fixture函数,那么这时候pytest就要先确定fixture的执行顺序了. 影响因素有三: scope,就是fixture函数的作用范围,比 ...