1. 絮絮叨叨
- 从工作开始,同事就说你要领一个mac,这样方便你的开发工作
- 毕竟习惯了操作Linux服务器,在mac上使用常见的Linux命令,毫无障碍
- 哪里像windows,使用shell命令都要先上网查一下
- 最近不信邪,想在windows上、基于IDEA搭建Presto的开发环境
- 编译、导入IDEA都还很顺利,等到运行时,就傻眼了
2. 准备工作
2.1 JDK
- 安装JDK,要求1.8及以上,自己选择的是1.8
- 安装教程,可以参考本人之前的博客:win10安装jdk1.8(附国内下载镜像)
2.2 maven 3.x
- 安装maven,自己选择的是maven3.8.2
- 安装教程,可以参考本人之前的博客:
- 年代久远,建议配置
settings.xml
的中本地仓库时,不要放在系统盘(C盘)
2.3 安装git
-
安装git,自己直接下载的官网最新版本
2.37.1
-
安装教程,可以参考博客:Windows系统Git安装教程(详解Git安装过程)
-
Presto-的
presto-cli
模块,在编译时需要使用Linux命令,如chmod
。 -
如未正确设置,会编译报错:
[ERROR] Failed to execute goal org.skife.maven:really-executable-jar-maven-plugin:1.0.5:really-executable-jar (default) on project presto-cli: FAILURE!: FAILURE! [ERROR] Cannot run program "chmod": CreateProcess error=2, 系统找不到指定的文件。
-
git bash是支持Linux命令的,可以借助git使得windows支持这些命令
-
实现方法:在系统环境变量中,设置
GIT_HOME
和Path
-
GIT_HOME
为git的安装路径,默认安装路径为:C:\Program Files\Git
-
编辑
Path
,新建%GIT_HOME%\usr\bin
-
设置完成后,新开一个命令行提示符中,运行Linux命令
chmod
进行测试
2.4 修改presto-maven-plugin-0.3的源码
-
下载
presto-maven-plugin-0.3
源码的压缩包,下载地址:https://github.com/prestodb/presto-maven-plugin/tags
-
ctrl + N
搜索ServiceDescriptorGenerator
类,修改其122行的代码// 源代码 String className = classPath.substring(0, classPath.length() - 6).replace('/', '.'); // 修改后的代码 String className = classPath.substring(0, classPath.length() - 6).replace(File.separatorChar, '.');
-
执行
mvn clean install -DskipTests
, 将修改后的presto-maven-plugin-0.3
安装到本地仓库
3. 编译Presto源码
- 通过
git clone
下载presto源码,并导入IDEA
3.1 修改根目录下的pom.xml文件
3.1.1 注释掉多余模块
-
修改根目录下的
pom.xml
文件,注释掉presto-doc
和presto-server-rpm
模块。这两个模块用于生成doc和rpm安装包,一般使用不到<!--<module>presto-server-rpm</module>--> <!--<module>presto-docs</module>-->
-
注意: 也可以注释掉其他含有Java代码的模块,但为了避免编译出错,暂不建议
-
也有博客(Presto 官方版使用 Windows 编译源码)说,需要修改与git有关的配置,自己没做修改能成功编译
3.1.2 解决RequireUpperBoundDeps failed
错误
-
编译过程中,当变异到presto-druid模块时,出现
org.apache.maven.plugins.enforcer.RequireUpperBoundDeps failed
的错误[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireUpperBoundDeps failed with message: Failed while enforcing RequireUpperBoundDeps. The error(s) are [ Require upper bound dependencies error for org.apache.httpcomponents:httpclient:4.5.5 paths to dependency are: +-com.facebook.presto:presto-druid:0.240 +-org.apache.druid:druid-core:0.19.0 +-org.apache.httpcomponents:httpclient:4.5.5 (managed) <-- org.apache.httpcomponents:httpclient:4.5.10 and +-com.facebook.presto:presto-druid:0.240 +-com.facebook.presto:presto-tests:0.240 +-com.facebook.presto:presto-client:0.240 +-com.google.auth:google-auth-library-oauth2-http:0.12.0 +-com.google.http-client:google-http-client:1.27.0 +-org.apache.httpcomponents:httpclient:4.5.5 (managed) <-- org.apache.httpcomponents:httpclient:4.5.10
-
解决办法: 修改父模块presto-root的pom.xml的
maven-enforcer-plugin
配置,去除对org.apache.httpcomponents:httpclient
的<requireUpperBoundDeps>
配置<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <configuration> <rules> <requireUpperBoundDeps> <excludes combine.children="append"> ... <exclude>org.apache.httpcomponents:httpclient</exclude> </excludes> </requireUpperBoundDeps> </rules> </configuration> </plugin>
3.2 修改presto-checks.xml
-
修改根目录下的
src/checkstyle/presto-checks.xml
,注释掉与\r
有关的RegexpMultiline
规则<!--<module name="RegexpMultiline"> <property name="format" value="\r" /> <property name="message" value="Line contains carriage return" /> </module>-->
-
如果不去除,编译时将会报错
[ERROR] src\main\resources\com\facebook\presto\common\type\zone-index.properties:[403] (regexp) RegexpMultiline: Line contains carriage return [ERROR] src\main\resources\com\facebook\presto\common\type\zone-index.properties:[404] (regexp) RegexpMultiline: Line contains carriage return [ERROR] src\main\resources\com\facebook\presto\common\type\zone-index.properties:[405] (regexp) RegexpMultiline: Line contains carriage return
3.3 修改Presto源码
-
修改
PrestoSystemRequirements
类 -
Presto要求系统环境为Linux或mac OS,如果为windows程序会运行失败。
-
这时,需要将其改为
warn
并非fail
// 修改前 failRequirement("Presto requires Linux or Mac OS X (found %s)", osName); // 修改后 warnRequirement("Presto requires Linux or Mac OS X (found %s)", osName);
-
改为
warn
后,程序运行不会再失败
-
从系统获取你文件句柄数,改为使用固定值
// 修改前 Object maxFileDescriptorCount = mbeanServer.getAttribute(ObjectName.getInstance(OPERATING_SYSTEM_MXBEAN_NAME), "MaxFileDescriptorCount"); // 修改后 Object maxFileDescriptorCount = 10000;
-
注意: 如果IDEA没有设置自动去除无用
import
,需要手动注释掉由于代码修改带来的无用import
// import javax.management.ObjectName; ... import static com.google.common.collect.ImmutableList.toImmutableList; // import static java.lang.management.ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
3.4 编译源码
-
执行如下命令,完成Presto源码的编译
mvn clean install -DskipTests
4. 运行PrestoServer
4.1 配置Presto
4.1.1 配置config.properties
-
在
presto-main/etc
目录下,找到config.properties
文件,将其修改如下:# 默认为true,可以不用设置 coordinator=true # 既是coordinator,又是worker node-scheduler.include-coordinator=true http-server.http.port=8080 discovery-server.enabled=true # coordinator包含discovery server,所以discovery.uri就是coordinator的地址 discovery.uri=http://localhost:8080 # 加载plugin的方法:1. 直接加载plugin目录;2. 通过plugin.bundles,设置需要加载的plugin # 这里选择方法2,只保留需要加载的关键模块 plugin.bundles=\ ../presto-memory/pom.xml,\ ../presto-jmx/pom.xml,\ ../presto-raptor/pom.xml,\ ../presto-hive-hadoop2/pom.xml,\ ../presto-example-http/pom.xml,\ ../presto-local-file/pom.xml, \ ../presto-i18n-functions/pom.xml,\ ../presto-function-namespace-managers/pom.xml,\ ../presto-cluster-ttl-providers/pom.xml,\ ../presto-node-ttl-fetchers/pom.xml,\ ../presto-hive-function-namespace/pom.xml # 使用这种加载方式,一定要设置好maven命令对应的本地repo # maven.repo.local的默认值为~/.m2/repository,如果在settgins.xml中自定义了本地repo,这个默认值则不是本地repo maven.repo.local=/Users/xxx/repo
4.1.2 去除无用的catalog properties文件
-
如果在config.propertis的
plugin.bundles
中,去除了一些暂时无用的plugin,则需要同步修改presto-main/etc/catalog
-
将这些plugin对应的catalog配置文件,移动到临时目录catalog_unused;或者为catalog文件增加bak后缀,例如,
hive.properties
,改为hive.properties.bak
-
因为Presto会先加载catalog配置文件,再根据配置文件中的
connector.name
去加载对应的catalog。如果plugin不加载,却配置了catalog文件,则出现如下类似错误:2023-03-07T15:47:54.422+0800 INFO main com.facebook.presto.metadata.StaticCatalogStore -- Loading catalog properties etc/catalog/blackhole.properties -- 2023-03-07T15:47:54.428+0800 INFO main com.facebook.presto.metadata.StaticCatalogStore -- Loading catalog blackhole -- 2023-03-07T15:47:54.428+0800 ERROR main com.facebook.presto.server.PrestoServer No factory for connector blackhole java.lang.IllegalArgumentException: No factory for connector blackhole at com.google.common.base.Preconditions.checkArgument(Preconditions.java:216) at com.facebook.presto.connector.ConnectorManager.createConnection(ConnectorManager.java:212) at com.facebook.presto.metadata.StaticCatalogStore.loadCatalog(StaticCatalogStore.java:123) at com.facebook.presto.metadata.StaticCatalogStore.loadCatalog(StaticCatalogStore.java:98) at com.facebook.presto.metadata.StaticCatalogStore.loadCatalogs(StaticCatalogStore.java:80) at com.facebook.presto.metadata.StaticCatalogStore.loadCatalogs(StaticCatalogStore.java:68) at com.facebook.presto.server.PrestoServer.run(PrestoServer.java:151) at com.facebook.presto.server.PrestoServer.main(PrestoServer.java:86)
4.2 设置Run Configuration
- 新增一个Run Configuration,创建Presto的Application
- Use classpath of module:
presto-main
- Main class:
com.facebook.presto.server.PrestoServer
- VM options:
-ea -XX:+UseG1GC -XX:G1HeapRegionSize=32M -XX:+UseGCOverheadLimit -XX:+ExplicitGCInvokesConcurrent -Xmx2G -Dconfig=etc/config.properties -Dlog.levels-file=etc/log.properties
- Working directory:
$MODULE_DIR$
- Use classpath of module:
- 最后点击
Run
按钮,成功启动PrestoServer
- 标志性的日志:
com.facebook.presto.server.PrestoServer ======== SERVER STARTED ========
5. 题外话
5.1 Hadoop native library问题 —— 最后放弃
-
其实,Presto的众多connector中,使用最多的还是Hive connector
-
原本已经配置好了
hive.properties
,但是启动以后报错:1) Error injecting constructor, java.lang.RuntimeException: failed to load Hadoop native library at com.facebook.presto.hive.HdfsEnvironment.<init>(HdfsEnvironment.java:47) at com.facebook.presto.hive.HiveClientModule.configure(HiveClientModule.java:167) while locating com.facebook.presto.hive.HdfsEnvironment for the 1st parameter of com.facebook.presto.hive.S3SelectRecordCursorProvider.<init>(S3SelectRecordCursorProvider.java:54) while locating com.facebook.presto.hive.S3SelectRecordCursorProvider at com.facebook.presto.hive.HiveClientModule.configure(HiveClientModule.java:121) while locating com.facebook.presto.hive.HiveRecordCursorProvider annotated with @com.google.inject.internal.Element(setName=,uniqueId=32, type=MULTIBINDER, keyType=) Caused by: java.lang.RuntimeException: failed to load Hadoop native library at com.facebook.presto.hadoop.HadoopNative.requireHadoopNative(HadoopNative.java:58) at com.facebook.presto.hive.HdfsEnvironment.<init>(HdfsEnvironment.java:52) ... # 省略细节 at com.facebook.presto.metadata.StaticCatalogStore.loadCatalogs(StaticCatalogStore.java:80) at com.facebook.presto.server.PrestoServer.run(PrestoServer.java:138) at com.facebook.presto.server.PrestoServer.main(PrestoServer.java:77) Caused by: java.lang.RuntimeException: library not found: /nativelib/Windows_10-amd64/hadoop.dll at com.facebook.presto.hadoop.HadoopNative.loadLibrary(HadoopNative.java:88) at com.facebook.presto.hadoop.HadoopNative.requireHadoopNative(HadoopNative.java:47) ... 46 more
-
网上查阅资料,也咨询了同事,通用的解决方法:
- 获取对应版本的(有人说,大版本一致就OK)、适合win10环境的Hadoop native library,包括
hadoop.dll
和winutils.exe
- 将这两个文件放到
C:\Windows\System32
中
- 获取对应版本的(有人说,大版本一致就OK)、适合win10环境的Hadoop native library,包括
-
自己从github,下载了2.7.3版本的Hadoop的library放到
C:\Windows\System32
中 -
重启程序、重启IDEA、甚至重启电脑,都没有解决问题
-
本来还想着上班了,找同事问问他是怎呢么实现HDFS、Spark在windows上运行的,结果同事说他的方法就是跟我一样的
-
最后自己想通了,你看人家官网和源码都明确限制windows了,还费那个劲干啥,你又不是大神 😝 😝