Doris On ES

Doris-On-ES将Doris的分布式查询规划能力和ES(Elasticsearch)的全文检索能力相结合,提供更完善的OLAP分析场景解决方案:

  1. ES中的多index分布式Join查询
  2. Doris和ES中的表联合查询,更复杂的全文检索过滤
  3. ES keyword类型字段的聚合查询:适用于index 频繁发生变化、单个分片文档数量千万级以上且该字段基数(cardinality)非常大

本文档主要介绍该功能的实现原理、使用方式等。

名词解释

  • FE:Frontend,Doris 的前端节点。负责元数据管理和请求接入。
  • BE:Backend,Doris 的后端节点。负责查询执行和数据存储。
  • Elasticsearch(ES):目前最流行的开源分布式搜索引擎。
  • DataNode:ES的数据存储与计算节点。
  • MasterNode:ES的Master节点,管理元数据、节点、数据分布等。
  • scroll:ES内置的数据集游标特性,用来对数据进行流式扫描和过滤。

如何使用

创建外表

  1. CREATE EXTERNAL TABLE `es_table` (
  2. `id` bigint(20) COMMENT "",
  3. `k1` bigint(20) COMMENT "",
  4. `k2` datetime COMMENT "",
  5. `k3` varchar(20) COMMENT "",
  6. `k4` varchar(100) COMMENT "",
  7. `k5` float COMMENT ""
  8. ) ENGINE=ELASTICSEARCH
  9. PARTITION BY RANGE(`id`)
  10. ()
  11. PROPERTIES (
  12. "host" = "http://192.168.0.1:8200,http://192.168.0.2:8200",
  13. "user" = "root",
  14. "password" = "root",
  15. "index" = "tindex”,
  16. "type" = "doc"
  17. );

参数说明:

参数说明
hostES集群连接地址,可指定一个或多个,Doris通过这个地址获取到ES版本号、index的shard分布信息
user开启basic认证的ES集群的用户名,需要确保该用户有访问: /_cluster/state/_nodes/http等路径权限和对index的读权限
password对应用户的密码信息
indexDoris中的表对应的ES的index名字,可以是alias
type指定index的type,默认是_doc
transport内部保留,默认为http

查询

基本条件过滤

  1. select * from es_table where k1 > 1000 and k3 ='term' or k4 like 'fu*z_'

扩展的esquery sql语法

通过esquery函数将一些无法用sql表述的ES query如match、geoshape等下推给ES进行过滤处理,esquery的第一个列名参数用于关联index,第二个参数是ES的基本Query DSL的json表述,使用花括号{}包含,json的root key有且只能有一个,如match、geo_shape、bool等

match查询:

  1. select * from es_table where esquery(k4, '{
  2. "match": {
  3. "k4": "doris on elasticsearch"
  4. }
  5. }');

geo相关查询:

  1. select * from es_table where esquery(k4, '{
  2. "geo_shape": {
  3. "location": {
  4. "shape": {
  5. "type": "envelope",
  6. "coordinates": [
  7. [
  8. 13,
  9. 53
  10. ],
  11. [
  12. 14,
  13. 52
  14. ]
  15. ]
  16. },
  17. "relation": "within"
  18. }
  19. }
  20. }');

bool查询:

  1. select * from es_table where esquery(k4, ' {
  2. "bool": {
  3. "must": [
  4. {
  5. "terms": {
  6. "k1": [
  7. 11,
  8. 12
  9. ]
  10. }
  11. },
  12. {
  13. "terms": {
  14. "k2": [
  15. 100
  16. ]
  17. }
  18. }
  19. ]
  20. }
  21. }');

原理

  1. +----------------------------------------------+
  2. | |
  3. | Doris +------------------+ |
  4. | | FE +--------------+-------+
  5. | | | Request Shard Location
  6. | +--+-------------+-+ | |
  7. | ^ ^ | |
  8. | | | | |
  9. | +-------------------+ +------------------+ | |
  10. | | | | | | | | |
  11. | | +----------+----+ | | +--+-----------+ | | |
  12. | | | BE | | | | BE | | | |
  13. | | +---------------+ | | +--------------+ | | |
  14. +----------------------------------------------+ |
  15. | | | | | | |
  16. | | | | | | |
  17. | HTTP SCROLL | | HTTP SCROLL | |
  18. +-----------+---------------------+------------+ |
  19. | | v | | v | | |
  20. | | +------+--------+ | | +------+-------+ | | |
  21. | | | | | | | | | | |
  22. | | | DataNode | | | | DataNode +<-----------+
  23. | | | | | | | | | | |
  24. | | | +<--------------------------------+
  25. | | +---------------+ | | |--------------| | | |
  26. | +-------------------+ +------------------+ | |
  27. | Same Physical Node | |
  28. | | |
  29. | +-----------------------+ | |
  30. | | | | |
  31. | | MasterNode +<-----------------+
  32. | ES | | |
  33. | +-----------------------+ |
  34. +----------------------------------------------+
  1. 创建ES外表后,FE会请求建表指定的主机,获取所有节点的HTTP端口信息以及index的shard分布信息等,如果请求失败会顺序遍历host列表直至成功或完全失败

  2. 查询时,会根据FE得到的一些节点信息和index的元数据信息,生成查询计划并发给对应的BE节点

  3. BE节点会根据就近原则即优先请求本地部署的ES节点,BE通过HTTP Scroll方式流式的从ES index的每个分片中并发的获取数据

  4. 计算完结果后,返回给client端

Push-Down operations

Doris On Elasticsearch一个重要的功能就是过滤条件的下推: 过滤条件下推给ES,这样只有真正满足条件的数据才会被返回,能够显著的提高查询性能和降低Doris和Elasticsearch的CPU、memory、IO利用率

下面的操作符(Operators)会被优化成如下下推filters:

SQL syntaxES 5.x+ syntax
=term query
interms query
> , < , >= , ⇐range
andbool.filter
orbool.should
notbool.must_not
not inbool.must_not + terms
esqueryES Query DSL

其他说明

  1. ES的版本要求

    ES主版本大于5,ES在2.x之前和5.x之后数据的扫描方式不同,目前支持5.x之后的

  2. 是否支持X-Pack认证的ES集群

    支持所有使用HTTP Basic认证方式的ES集群

  3. 一些查询比请求ES慢很多

    是,比如_count相关的query等,ES内部会直接读取满足条件的文档个数相关的元数据,不需要对真实的数据进行过滤