2012-09-20
回归来的第一篇,另外还有好几篇躺在 published:false
中,还没搞好 :-(
这个礼拜最大的收获是编译啥啥啥还是蛮简单的,又没叫你去改代码。有些东西动手尝试一下,往往会发现没有多难,不能停留在口上上说说而已。看到 一段相关但不是很切题的话 :
不可忽视的一点是:在技术性团体里,做永远比说要来的有效。在想法成熟之前就贸然游说,往往会招致相反的效果。大家都是工程师,不会贸然接纳陌生事物。如果自己都还没有想清楚就开始大肆游说,往往会被大家提出的实际的工程问题驳斥地体无完肤。当你哑口无言之时,大家也已经对你的方案产生了难以磨灭的 “不靠谱”的第一印象,这时要再想咸鱼翻身,可就没那么容易了。
相对的,首先自行查阅文档资料并进行试验,制作demo,通过试验发现和解决实际出现的问题。在想法基本成型时,和个别观念开放的同仁进行探讨,这时往往可以发现大量之前自己没有考虑到的问题,再转而细化方案。这个过程反复迭代几次之后,方案和demo逐渐成熟,同时也潜移默化地达到了传教的目的。等到方案完全成熟之后,再拿出实际可工作的demo开始游说,这时自然就成竹在胸了。
进入正题,这里主要是参考几篇文章,说说编译hive和打补丁, 或者说贴贴链接= =
hive 代码编译
install hive on linux
使用ant编译hive
hive打补丁编译hive
这里我在ubuntu上操作的, 编译hive需要依赖 JAVA, ANT (这里不依赖hadoop原因是ant会自动去下载hadoop)。
安装好后export JAVA_HOME
, ANT_HOME
变量 (我直接加入.bashrc当中了)。
接下来去官网下载hive源码包。这里我使用的是 hive.0.9.0
。 解压之后进入src目录,需要修改一些配置:
1 2 3 4 5 6 7 8 9 |
|
接下来执行 ant package
即开始编译了, 结果默认会放在 build/dist
目录中,使用 -Dtarget.dir=xxx
可以更新目标位置。
如果BUILD FAIL的话,一般参考提示可以看出是哪里出了问题(遇到比较多还是被墙的问题= =)。
hive 单元测试
hive中的单元测试
hive中的test case
QtestUtil.java
hive unit test
hive 中的 单元测试 还是蛮有趣的,既有传统的单元测试代码,又可以批量执行查询脚本判断结果是否一致:
在hive中会有大量的.q的文件即执行测试的query文件,.q.out是测试的结果文件。 进行新测试后产生的结果和标准的q.out一致则表示测试成功。
具体来说,src/ql/src/test/queries下面是测试用例,clientpositive是运行成功的用例,clientnegative是运行失败,返回非0的用例。 src/ql/src/test/results 下面是测试用例对应的输出结果。 如src/ql/src/test/queries/case_sensitivity.q对应的输出结果是src/ql/src/test/results/case_sensitivity.q.out 。
使用 ant test
运行单元测试,不过此命令要跑好多测试, 光TestCliDriver一项就要跑好几个小时 , 我们可以
1 2 3 4 5 |
|
使用 -Doverwrite=true
可以覆盖结果文件,后面有新的更新想测试表现是否一致的时候就可以使用了, 通常在我们增加新的udf的时候可以这么来生成测试数据。
hive代码打补丁
下载了 hive 0.9.0
稳定版,不过发布之后还是有若干bug,这时搜索一下 hive jira
一般能看到相应ticket,比如 这个substr遇到UTF8的问题 。一般打的补丁会走一个 publish-review-apply
的 过程 ,准确解决问题的补丁会被加入版本库中,而临时补丁一般不会采用。作为用户,有时难免得打一些这样的补丁。打补丁也很方便,下载社区提供的补丁之后,使用 patch
命令即可以应用到源码中, 后续在进行编译测试即可。
另外我们有时会有需求将 自己使用的 udf 编译到hive当中以方便使用 ,这其实也可以看成打补丁的行为。
打补丁多了,管理是后面会遇到的问题。 就个人而言,可以自己载个官方的git仓库,然后开分支来维护自己的变更。如果要多人协作的话,可以创建一个新的git仓库,然后添加两个远端, 其中一个是官方的git仓库,另外一个可以是大家从某个分支开始维护的版本。纯属yy,实际操作起来也未必省心。 这里看起来使用 github organization 是蛮适合的。
当然,可以预见的是,大部分时间我们都不会打补丁,可能只会在新增一些UDF= =, 于是似乎完全没有必要这么干, 大概 类似这样就可以了 , 看起来一般将用到的udf打包,然后要用的时候加一句声明即可。
不过我还是蛋疼去搞了一个 organization , fork一下官方代码。 我在本地git加入 apache/hive
作为另一个远端, 称为 mirror
。由于我们目前使用的是 0.9, 故我考虑的是在 origin/branch-0.9
下做开发,并将 mirror/branch-0.9
定期 merge 回 branch-0.9
。至于 trunk
则不动。
这样一来我就开始捣鼓了,首先还是改 build.properties
, 我将这些也一并提交到分支里面了。 然后我开始将 udf 编译进去,这次遇到一个比较坑爹的问题就是 编译一直成功,但是执行单元测试一直找不到新的UDF 。 捣鼓了很久无果后找小美支援,小美在分析一阵之指出测试的时候没有引用到编译的 FunctionRegistry.class
, 估计使用到别的旧的文件了。又过了一段时间之后我确实发现有个地方 ~/.ivy2/
下面有一些cache, 简单google之后又发现 hive jira
上已经有一个 tck , 看了大概是由 HIVE-2646 引入的, 导致测试的时候会从ivy cache来加载hive相关的类而不是 build/dist/lib
。这个改动恰恰不在 0.9.0发布版但是 commit到 branch-0.9
中了, 所以我从 branch-0.9
的代码开始编译就中招了。这个patch有加入trunk中,故 cherry-pick
一下即可(本来我打算直接打patch的)。当然这里我不清楚为啥这个补丁不加入 0.9 分支,估计不算大问题? 没有运行bug?从版本库编译就是比较坑爹= =