说在前面
最近在研究 Apache Druid 的原理,在不 debug 的情况下已经无法再进一步深入了,因此想在本地搭一套调试环境,但网上可用的资料很少,只能自己摸索,在这期间走过不少弯路,这里做个记录,希望也能给后来的人一些提示与帮助。
安装部署
1.端口列表
以下是 Druid 默认的端口列表,注意是否和本地其他服务是否有端口冲突,如果有端口被占用会显示启动失败
Role | Port | Description |
---|---|---|
Coordinator | 8081 | 管理集群上的数据可用性 |
Historical | 8083 | 存储/查询 历史数据 |
Broker | 8082 | 处理来自外部 client 的请求 |
Overload | 8090 | 处理数据 ingestion 的负载 |
MiddleManager | 8091 | 负责数据的 ingestion |
Router | 8888 | 将请求路由到 Brokers/Coordinators/Overloads |
2.源代码下载
Apache Druid 主要是方便我们按照自己的需求按模块进行代码 debug,了解其 query 和 ingest 原理。
3.安装包下载
官网安装包下载:download 。我这里下载的是 0.22.1 版本,由于 Druid 运行依赖的组件很多,一个一个启动繁琐不说,还要安装不少依赖项。这个安装包中有封装好的 bin 文件,无需 docker 也可以一键启动所有组件。基于此,我们可以通过该安装包以及源代码来 debug 我们想要了解的组件。
我想要 debug broker 组件,于是:
安装包 - broker + 源代码启动 broker = 完整的 druid 环境
安装包下载完成后解压:
tar -zxvf apache-druid-0.22.1-bin.tar.gz
4.single-server 配置参考
Scale | Required resources |
---|---|
nano-quickstart | 1 CPU,4GB RAM |
micro-quickstart | 4 CPU,16GB RAM |
small | 8 CPU,64GB RAM |
medium | 16 CPU,128GB RAM |
large | 32 CPU,256GB RAM |
xlarge | 64CPU,512GB RAM |
- 启动命令: ./apache-druid-0.22.1/bin/start-nano-quickstart
- 启动配置:./apache-druid-0.22.1/conf/supervise/single-server/nano-quickstart.conf
:verify bin/verify-java
:verify bin/verify-default-ports
:kill-timeout 10
!p10 zk bin/run-zk conf
coordinator-overlord bin/run-druid coordinator-overlord conf/druid/single-server/nano-quickstart
# 这里我们注释掉 broker,改为使用源代码启动
#broker bin/run-druid broker conf/druid/single-server/nano-quickstart
router bin/run-druid router conf/druid/single-server/nano-quickstart
historical bin/run-druid historical conf/druid/single-server/nano-quickstart
!p90 middleManager bin/run-druid middleManager conf/druid/single-server/nano-quickstart
由于我本地机器资源有限,这里以 nano-quickstart 为例,其他的同理,都在上述目录下,不再赘述
5.使用安装包其他其他服务
直接执行上述的 bin 文件,能够得到下图输出,可以看到其中是缺少 broker 的,接下来我们来编译源代码
6. 源代码编译
第一个坑,将 代码 clone 到本地后是 的,要进行一些编译与配置:
如上图所示,Parser 类依赖的 ExprLexer 和 ExprParser 类在整个项目中都找不到,实际的代码需要通过 ANTLR 编译 Expr.g4 文件生成。
ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。 它被广泛用于构建语言、工具和框架。ANTLR 根据语法定义生成解析器,解析器可以构建和遍历解析树。
所有编程语言的语法,都可以用ANTLR来定义。ANTLR提供了大量的官方 grammar 示例,包含了各种常见语言,比如Java、SQL、Javascript、PHP等等。
Twitter 使用 ANTLR 进行语法分析,每天处理超过20亿次查询;Hadoop 生态系统中的 Hive、Pig、数据仓库和分析系统所使用的语言都用到了 ANTLR;Lex Machina 将 ANTLR 用于分析法律文本;Oracle 在 SQL 开发者 IDE 和迁移工具中使用了 ANTLR;NetBeans 的 IDE 使用 ANTLR 来解析 C++;Hibernate 对象-关系映射框架(ORM)使用 ANTLR 来处理 HQL 语言。
6.1 IDEA 安装 ANTLR v4 grammar plugin 插件
安装完成后我们直接来编译 Expr.g4 文件,右键 -> Generate ANTLR Recognizer
接下来不出意外的话马上就要出意外了,果然编译开始报错了hhhhh,如下所示:
这是因为文件中有一些转义字符报错,需要对 Expr.g4 文件进行修改,以下是我修改过的文件:
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
grammar Expr;
start : expr EOF;
expr : NULL # null
| ('-'|'!') expr # unaryOpExpr
|<assoc=right> expr '^' expr # powOpExpr
| expr ('*'|'/'|'%') expr # mulDivModuloExpr
| expr ('+'|'-') expr # addSubExpr
| expr ('<'|'<='|'>'|'>='|'=='|'!=') expr # logicalOpExpr
| expr ('&&'|'||') expr # logicalAndOrExpr
| '(' expr ')' # nestedExpr
| IDENTIFIER '(' lambda ',' fnArgs ')' # applyFunctionExpr
| IDENTIFIER '(' fnArgs? ')' # functionExpr
| IDENTIFIER # identifierExpr
| DOUBLE # doubleExpr
| LONG # longExpr
| STRING # string
| '[' (stringElement (',' stringElement)*)? ']' # stringArray
| '[' longElement (',' longElement)*']' # longArray
| '<LONG>' '[' (numericElement (',' numericElement)*)? ']' # explicitLongArray
| '<DOUBLE>'? '[' (numericElement (',' numericElement)*)? ']' # doubleArray
| '<STRING>' '[' (literalElement (',' literalElement)*)? ']' # explicitStringArray
;
lambda : (IDENTIFIER | '(' ')' | '(' IDENTIFIER (',' IDENTIFIER)* ')') '->' expr
;
fnArgs : expr (',' expr)* # functionArgs
;
stringElement : (STRING | NULL);
longElement : (LONG | NULL);
numericElement : (LONG | DOUBLE | NULL);
literalElement : (STRING | LONG | DOUBLE | NULL);
NULL : 'null';
LONG : [0-9]+;
EXP: [eE] [-]? LONG;
// DOUBLE provides partial support for java double format
// see: https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#valueOf-java.lang.String-
DOUBLE : 'NaN' | 'Infinity' | (LONG '.' LONG?) | (LONG EXP) | (LONG '.' LONG? EXP);
IDENTIFIER : [_$a-zA-Z][_$a-zA-Z0-9]* | '"' (ESC | ~ ["])* '"';
WS : [ \t\r\n]+ -> skip ;
STRING : '\'' (ESC | ~ ['])* '\'';
fragment ESC : '\\' (['"\\/bfnrt] | UNICODE) ;
fragment UNICODE : 'u' HEX HEX HEX HEX ;
fragment HEX : [0-9a-fA-F] ;
MINUS : '-' ;
NOT : '!' ;
POW : '^' ;
MUL : '*' ;
DIV : '/' ;
MODULO : '%' ;
PLUS : '+' ;
LT : '<' ;
LEQ : '<=' ;
GT : '>' ;
GEQ : '>=' ;
EQ : '==' ;
NEQ : '!=' ;
AND : '&&' ;
OR : '||' ;
接着再次 右键 -> Generate ANTLR Recognizer,发现在 core/gen 目录下生成了一些类:
把这些类全部 copy 到 math.expr.antlr 目录下,项目报错就消失了
7.debug 配置
可以先看下官方提供的 idea 配置,懒得看也没关系,看下面的配置就行。
首先一定要在 configuration 中打开这个 Add VM options 配置,在 debug 时组件的配置都通过这个来进行
以下是我的 broker 配置:
- vm options
-server -Ddruid.service=druid/broker -Xms512m -Xmx512m -XX:MaxDirectMemorySize=400m -XX:+ExitOnOutOfMemoryError -XX:+UseG1GC -Duser.timezone=UTC -Dfile.encoding=UTF-8 -Djava.io.tmpdir=var/tmp -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager -Ddruid.extensions.loadList="[]" -Ddruid.plaintextPort=8082
#可根据需要变更
- main class
org.apache.druid.cli.Main
# 固定配置
- Program arguments
server broker
# 固定写法,否则会报错,可根据当前 debug 的不同组件替换成 server historical/ server coordinator 等,解析的代码在 io.airlift.airline.Parser 类的 parse(GlobalMetadata metadata, Iterable<String> params) 方法,可自行 debug
8. Apache Druid,启动!
- 首先把其他组件先启动 ./apache-druid-0.22.1/bin/start-nano-quickstart**
- 接着我们把本地的 broker 启动,目前看起来一切正常
本地浏览器打开locahost:8888,如果能成功出现如下页面,说明你已经成功启动了所有组件
我们在本地代码(SqlResource 类)中打个断点,然后刷新下页面
证明请求确实打到了我们的源代码中,接下来还差最后一步,填充数据
9. 填充测试数据
我们下载的安装包中有提供测试数据,目录是 /apache-druid-0.22.1/quickstart/tutorial/wikiticker-2015-09-12-sampled.json.gz
直接在控制台中 load 即可(也可以使用 hdfs 或 kafka 等,这里不再赘述):
好了这样数据也有了,接下来各位就可以开始自行探索 Apache Druid 的秘密了。
以上就是全部内容,如果这篇文章刚好能帮到你,就给我点个赞吧~