2014年10月15日星期三

hive启动debug问题

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
hive启动debug问题  阅读原文»

hive启动debug问题

最近在debug hive的一个bug,之前都是使用打印日志来跟踪源码,这种方式效率比较低(每次更改了源码都要重新编译并替换线上的jar包),java的应用可以支持remote debug的,hive也不例外,主要是通过hive --debug来实现.

在运行hive --debug时遇到如下问题:

ERROR:CannotloadthisJVMTIagenttwice,checkyourjavacommandlineforduplicatejdwpoptions.
ErroroccurredduringinitializationofVM
agentlibraryfailedtoinit:jdwp

根据错误信息,可以看到是由于重复的jdwp参数导致。hive其实是一个shell脚本,追踪其运行情况:

cd${HIVE_HOME}/bin;sh-x./hive--debug

查看hive --debug的调用情况:

if["$DEBUG"];then
if["$HELP"];then
get_debug_params"$DEBUG"
exportHADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS$HIVE_MAIN_CLIENT_DEBUG_OPTS"

这里是:

HIVE_MAIN_CLIENT_DEBUG_OPTS='-XX:+UseParallelGC
-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=y'

HIVE_MAIN_CLIENT_DEBUG_OPTS 变量是在${HIVE_HOME}/bin/ext/debug.sh中,这个脚本控制了debug的参数,比如说端口

get_debug_params(){
set_debug_defaults
#ForDebug-XX:+UseParallelGCisneeded,asitisa(unfortunatelynotperfect)
#workaroundforJVM6862295bug,thataffectssomeJVMsstillinuse
ifdoes_jvm_support_ti;then
exportHIVE_MAIN_CLIENT_DEBUG_OPTS="-XX:+UseParallelGC
-agentlib:jdwp=transport=dt_socket,server=y,$port,$main_suspend"
exportHIVE_CHILD_CLIENT_DEBUG_OPTS="-XX:+UseParallelGC
-agentlib:jdwp=transport=dt_socket,server=y,$child_suspend"
exportHIVE_MAIN_CLIENT_DEBUG_OPTS="-XX:+UseParallelGC
-Xdebug-Xrunjdwp:transport=dt_socket,server=y,$port,$main_suspend"
exportHIVE_CHILD_CLIENT_DEBUG_OPTS="-XX:+UseParallelGC
-Xdebug-Xrunjdwp:transport=dt_socket,server=y,$child_suspend"

最终hive运行的命令为:

exec${HADOOP_HOME}/bin/hadoopjarhive-cli-0.13.1.jar
org.apache.hadoop.hive.cli.CliDriver--hiveconfhive.aux.jars.path=xxxxx

而在${HADOOP_HOME}/bin/hadoop中,设置HADOOP_OPTS时,又引用了HADOOP_CLIENT_OPTS这个变量,就导致jdwp的参数重复了

只需要注释下面一行即可以:

HADOOP_OPTS="$HADOOP_OPTS$HADOOP_CLIENT_OPTS"

这其实是一个bug:

相关的bug id

https://issues.apache.org/jira/browse/HADOOP-9455

https://issues.apache.org/jira/browse/HIVE-3936

bug描述:

HADOOP_CLIENT_OPTSappendedtwicecausesJVMfailures

在官方提供的bug id中可以看到hive0.13是fix这个bug的,具体的patch如下:

diff--gitbin/hivebin/hive
index40e2c75..434ea6c100755
Android开发实践:多线程编程小结  阅读原文»

我们知道,Android系统为了提高程序的实时响应能力,不允许在UI线程中进行耗时的操作,否则会出现ANR异常,因此必须将耗时的任务放到非UI线程中执行。Android/Java提供了很多类来帮助大家完成异步操作,比如:Thread类,Timer类,AsyncTask类,HandlerThread类,以及Executor接口。这些类都分别在什么场合下使用呢?

本文简单地总结一下Android开发中常见的多线程类型和解决方案,并比较和分析了各个方案的区别,以便更好地理解和应用这些API接口。

1. 单项异步任务

[场景]:下载一个APK文件,拷贝一个大文件。

[方案]:Thread类,AsyncTask类

[比较]:

AsyncTask提供了onProgressUpdate和onPostExecute通知调用者任务执行的进度和结果,在函数内可以直接执行UI操作。

而Thread中不能直接操作UI界面,而要通过Activity.runOnUiThread或者借助Handler来完成UI的更新。

所以Thread更适合执行一些不需要跟UI频繁交互的单项任务,而AsyncTask相反。

2. 定时/循环执行的任务

[场景]:定时刷新UI(如:秒表),保持TCP心跳连接。

[方案]:"Thread + sleep",定时器Timer

[比较]:

"Thread + sleep" 方案示例:

newThread(Runnable(){
Thread.sleep(1000);
mListener.onTimeArrived();

两者都不能在循环中执行UI更新操作,而必须借助Activity.runOnUiThread或者Handler来完成UI的更新。

由于Thread方案中onTimeArrived()占用了部分时间,所以这种方案的定时并不准确,而Timer是由系统创建异步通知的定时器,会更加准确,所以推荐使用Timer来完成定时任务。

3. 工作线程

工作线程启动后处于一种等待"命令"/"消息"的休眠状态,当接收到"命令"/"消息"后,将它放入"命令"/"消息"队列,然后唤醒线程依次串行或者并行执行。

[场景]:"生产者--消费者"模式,TCP Server端命令处理程序

[方案]: "Thread + condition/lock" ,HandlerThread类,线程池Executor

[比较]:

HandlerThread类是Android系统提供了封装好了Loop循环的Thread类,可以更加便捷地完成CallerThread和WorkThread的命令/消息交互。当然,我们也可以用Thread和Condition/Lock方式实现同样的效果,只不过要自己实现更多的代码。

前面的两种方式,都是"串行"的方式在执行"命令",如果希望提供并发性,同时开启和管理多个线程来执行任务,则可以考虑使用Executor

以上就是我对Android多线程编程的简单小结,文中有任何不清楚或者不正确的地方,欢迎留言或者来信lujun.hust@gmail.com交流讨论。

本文出自 "对影成三人" 博客,请务必保留此出处http://ticktick.blog.51cto.com/823160/1564055

返回顶部

阅读更多内容

没有评论:

发表评论