起因
公司使用了icebery存储数据,presto作为提供给用户查询的引擎,当前使用的版本对icebery支持较弱,存在读parquet异常问题,需要将版本升级到430。
合并代码
老版本我们当时为了支持hive的视图功能,以及其他一些功能,在原来版本的基础上做了一些代码更改,原本是我想两个版本库的代码直接合并的,后面灵哥跟我说,你可以直接使用git rebase 的功能,讲自己更改的代码有选择的合并到当前的最新分支上。这是一个及其好用的工具,特别是我们这种,对于开源的代码更改不多,同时也希望可以跟着社区升级的。
上线不顺利
当我把patch打回去,编译好代码,觉得万事俱备,JDK也改为11,可以准备上线,我在测试环境部署了新版本的presto,事情没有想象中的顺利,worker 起不来..我们是使用yarn来部署presto的worker的,presto-server是安全无恙的,但是worker起不来,我把yarn上的日志拿下来之后,发现报了如下异常:
``` ...skipping... at io.prestosql.plugin.hive.HiveConnectorFactory.create(HiveConnectorFactory.java:63) at io.prestosql.connector.ConnectorManager.createConnector(ConnectorManager.java:349) at io.prestosql.connector.ConnectorManager.createCatalog(ConnectorManager.java:208) at io.prestosql.connector.ConnectorManager.createCatalog(ConnectorManager.java:200) at io.prestosql.connector.ConnectorManager.createCatalog(ConnectorManager.java:186) at io.prestosql.metadata.StaticCatalogStore.loadCatalog(StaticCatalogStore.java:88) at io.prestosql.metadata.StaticCatalogStore.loadCatalogs(StaticCatalogStore.java:68) at io.prestosql.server.Server.doStart(Server.java:117) at io.prestosql.server.Server.lambda$start$0(Server.java:72)
at io.prestosql.$gen.Presto3402g0416013dirty_20200817055536_1.run(Unknown Source) at io.prestosql.server.Server.start(Server.java:72) at io.prestosql.server.PrestoServer.main(PrestoServer.java:38)
Caused by: java.lang.RuntimeException: failed to load Hadoop native library at io.prestosql.hadoop.HadoopNative.requireHadoopNative(HadoopNative.java:59) at io.prestosql.plugin.hive.HdfsEnvironment. (HdfsEnvironment.java:39) ... 52 more Caused by: java.lang.RuntimeException: native snappy library not available: SnappyCompressor has not been loaded. at org.apache.hadoop.io.compress.SnappyCodec.checkNativeCodeLoaded(SnappyCodec.java:72) at org.apache.hadoop.io.compress.SnappyCodec.getDecompressorType(SnappyCodec.java:195) at io.prestosql.hadoop.HadoopNative.loadAllCodecs(HadoopNative.java:72) at io.prestosql.hadoop.HadoopNative.requireHadoopNative(HadoopNative.java:53) ... 53 more
```
native snappy library not available: SnappyCompressor has not been loaded
怎么会出现这个异常呢?
此时此刻我出现了一千万个问号,presto跟其他项目最大的不同在于,presto几乎把他所依赖项目都自己实现,例如hive connector中依赖的hadoop,用的就是presto-hadoop-apache 项目。
从异常上看,就是夹在native包有问题,第一个反应是去看一下代码,跟踪到了可能问题出现在这段代码
``` public final class NativeCodeLoader {
private static final Logger LOG = LoggerFactory.getLogger(NativeCodeLoader.class);
private static boolean nativeCodeLoaded = false;
static { // Try to load native hadoop library and set fallback flag appropriately if(LOG.isDebugEnabled()) { LOG.debug("Trying to load the custom-built native-hadoop library..."); } try { System.loadLibrary("hadoop"); LOG.debug("Loaded the native-hadoop library"); nativeCodeLoaded = true; } catch (Throwable t) { // Ignore failure to load if(LOG.isDebugEnabled()) { LOG.debug("Failed to load native-hadoop with error: " + t); LOG.debug("java.library.path=" + System.getProperty("java.library.path")); } }
if (!nativeCodeLoaded) {
LOG.warn("Unable to load native-hadoop library for your platform... " +
"using builtin-java classes where applicable");
}
}
```
这里只要打开debug日志,就可以看到为什么会出现load snappy有问题的情况了,于是,我按照官网,在/etc/下新增配置文件log.properties,重启,见证奇迹的那一刻到了! ``` io.prestosql=DEBUG org.apache.hadoop=DEBUG
```
然后,现实给我重重的一击,没有打印出来org.apache.hadoop的DEBUG日志,但是io.prestosql的DEBUG日志有的,怎么回事?为什么会这样呢?
在尝试了在jvm的启动参数新增log4j的配置文件没有效果之后,不得不去社区问一下,如何才能新增DEBUG日志,社区还是牛人多,有人给我贴了一个链接:https://github.com/prestosql/presto/issues/2360
他们也是有这个需求,打开hadoop相关的DEBUG日志,但是社区在最新的版本因为考虑到了输出的日志比较多,就把日志关闭了,如果想要开启的话,可以自己更改一下pom.xml编译。
好吧!白折腾了一下下午,改一下配置,重新编译!
``` org.slf4j slf4j-jdk14 ${dep.slf4j.version} runtime
```
日志
经历了一个下午的折腾,晚上终于把日志打出来了
``` 2020-08-19T20:11:18.537+0800 DEBUG main org.apache.hadoop.util.NativeCodeLoader Trying to load the custom-built native-hadoop library... 2020-08-19T20:11:18.538+0800 DEBUG main org.apache.hadoop.util.NativeCodeLoader Failed to load native-hadoop with error: java.lang.UnsatisfiedLinkError: Native Library /opt/c loudera/parcels/CDH-XX/lib/hadoop/lib/native/libhadoop.so.1.0.0 already loaded in another classloader
``` 通过日志,我们发现presto的worker在启动的时候会把系统当中的native包load到内存里面,跟presto的hadoop包里面的resouce里面自带的native冲突到了,导致进程无法启动。同时我看到了有人也出现过这个问题,https://app.slack.com/client/TFKPX15NC/CFLB9AMBN/thread/CP1MUNEUX-1585270167.019800 不得不说,社区真是宝藏。
原因
为什么worker启动的时候会把系统本地的native包的路径带进去呢?通过阿里提供的工具arthas,我们发现在nodemanger启动我们的worker的时候,会通过LDLIBRARYPATH 这个参数把系统参数传递到子进程。
明白了原因,解决方式也比较简单,就是在启动worker的时候,将LDLIBRARYPATH设置为空就可以了。
终于搞定。
总结
- 社区是一个好东西,遇到的问题可以先去slack先查询
- 要善于利用工具
- 对整个运行机制还不够熟悉,还需要多刻意练习。
本文记录了在升级Presto到430版本过程中遇到的worker启动失败问题,由于native snappy library加载冲突导致。通过日志分析,发现是系统级别的native包与Presto自带的hadoop库冲突。解决办法是通过设置LDLIBRARYPATH环境变量避免加载系统库。这次经验强调了查询社区和深入理解运行机制的重要性。
914

被折叠的 条评论
为什么被折叠?



