Impala是由Cloudera开发的高性能实时计算工具,相比Hive性能提升了几十、甚至近百倍,基本思想是将计算分发到每个 Datanode所在的节点,依靠内存实现数据的缓存进行快速计算,类似的系统还有Berkeley的Shark。从实际测试来看,Impala效率确实 不错,由于Impala大量使用C++实现,不使用CDH的Image而自己编译安装要费不少功夫,这里记录一下安装配置过程和碰到的一些问题。我在测试 时候使用的是CentOS6.2。
一些基本的安装步骤在这里,但我在安装的时候碰到一些问题,这里再详细说明一下过程。
1.安装所需的依赖lib,这一步没有什么不同
sudo yum install boost-test boost-program-options libevent-devel automake libtool flex bison gcc-c++ openssl-devel make cmake doxygen.x86_64 glib-devel boost-devel python-devel bzip2-devel svn libevent-devel cyrus-sasl-devel wget git unzip
2.安装LLVM,按照流程做即可,注意要在多台机器上编译安装Impala的话,只用在一台机器上执行下面蓝色的部分,再把llvm分发到多台机器上执行后面红色部分的指令就可以了,没必要每个机器都通过svn下载一遍源代码,很费时。
wget http://llvm.org/releases/3.2/llvm-3.2.src.tar.gz
tar xvzf llvm-3.2.src.tar.gz
cd llvm-3.2.src/tools
svn co http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_32/final/ clang
cd ../projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_32/final/ compiler-rt
cd ..
./configure –with-pic
make -j4 REQUIRES_RTTI=1
sudo make install
3.安装Maven,这个没什么好说的,按照步骤,设置一下环境变量即可,Maven是为了后面build impala源代码用的。
wget http://www.fightrice.com/mirrors/apache/maven/maven-3/3.0.4/binaries/apache-maven-3.0.4-bin.tar.gz
tar xvf apache-maven-3.0.4.tar.gz && sudo mv apache-maven-3.0.4 /usr/local
修改~/.bashrc,增加maven环境变量
export M2_HOME=/usr/local/apache-maven-3.0.4
export M2=$M2_HOME/bin
export PATH=$M2:$PATH
更新环境变量,查看mvn版本是否正确
source ~/.bashrc
mvn -version
4.下载Impala源代码
git clone https://github.com/cloudera/impala.git
5.设置Impala环境变量,编译时需要
cd impala
./bin/impala-config.sh
6.下载impala依赖的第三方package
cd thirdparty
./download_thirdparty.sh
注意这里其中一个包cyrus-sasl-2.1.23可能下载失败,可以自行搜索(CSDN里面就有)下载下来然后解压缩到thirdparty 文件夹,最好是在执行完download_thirdparty.sh之后做这一步,因为download_thirdparty.sh会把所有目录下下 载下来的tar.gz给删除掉。
7.理论上现在可以开始build impala了,但是实际build过程中可能会出现问题,我碰到的问题和 Boost相关的(具体错误不记得了),最后发现是由于boost版本太低导致的,CentOS 6.2系统默认yum源中的boost和boost-devel版本是1.41,但是impala编译需要1.44以上的版本,因此需要做的是自己重新编 译boost,我用的是boost 1.46版本。
#删除已安装的boost和boost-devel
yum remove boost
yum remove boost-devel
#下载boost
#可以去(http://www.boost.org/users/history/)下载boost
#下载后解压缩
tar xvzf boost_1_46_0.tar.gz
mv boost_1_46_0 /usr/local/
cd /usr/include
./bootstrap.sh
./bjam
#执行后若打印以下内容,则表示安装成功
# The Boost C++ Libraries were successfully built!
# The following directory should be added to compiler include paths:
# /usr/local/boost_1_46_0
# The following directory should be added to linker library paths:
# /usr/local/boost_1_46_0/stage/lib
#现在还需要设置Boost环境变量和Impala环境变量
export BOOST_ROOT=’/usr/local/boost_1_46_0′
export IMPALA_HOME=’/home/extend/impala’
#注意一下,这里虽然安装了boost,但是我在实际使用的时候,编译还是会报错的,报的错误是找不到这个包:#libboost_filesystem-mt.so,这个包是由boost-devel提供的,所以我的做法是把boost-devel给重新装上
#我没有试过如果之前不删除boost-devel会不会有问题,能确定的是按这里写的流程做是没问题的
yum install boost-devel
8.现在终于可以编译impala了
cd $IMPALA_HOME
./build_public.sh -build_thirdparty
#编译首先会编译C++部分,然后再用mvn编译java部分,整个过程比较慢,我在虚拟机上大概需要1-2个小时。
#Impala编译完后的东西在be/build/debug里面
9.启动impala_shell需要用到的python包
#第一次执行impalad_shell可能会报错,这里需要安装python的两个包:thrift和prettytable,使用easy_install即可
easy_install prettytable
easy_install thrift
10.如果你以为到这里就万事大吉就太天真了,在配置、启动、使用Impala的时候还会有很多奇葩的问题;
问题1:Hive和Hadoop使用的版本
CDH对版本的依赖要求比较高,为了保证Impala正常运行,强烈建议使用Impala里面thirdparty目录中自带的Hadoop(native lib已经编译好的)和Hive版本。
Hadoop的配置文件在$HADOOP_HOME/etc/hadoop中,要注意的是需要启用native lib
#修改hadoop的core-site.xml,除了这个选项之外,其他配置和问题2中的core-site.xml一致
<property>
<name>hadoop.native.lib</name>
<value>true</value>
<description>Should native hadoop libraries, if present, be used.</description>
</property>
问题2:Impala的配置文件位置
Impala默认使用的配置文件路径是在bin/set-classpath.sh中配置的,建议把CLASSPATH部分改成
CLASSPATH=\
$IMPALA_HOME/conf:\
$IMPALA_HOME/fe/target/classes:\
$IMPALA_HOME/fe/target/dependency:\
$IMPALA_HOME/fe/target/test-classes:\
${HIVE_HOME}/lib/datanucleus-core-2.0.3.jar:\
${HIVE_HOME}/lib/datanucleus-enhancer-2.0.3.jar:\
${HIVE_HOME}/lib/datanucleus-rdbms-2.0.3.jar:\
${HIVE_HOME}/lib/datanucleus-connectionpool-2.0.3.jar:
即要求Impala使用其目录下的Conf文件夹作为配置文件,然后创建一下Conf目录,把3样东西拷贝进来:core-site.xml、hdfs-site.xml、hive-site.xml。
core-site.xml的配置,下面几个选项是必须要配置的,
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://10.200.4.11:9000</value>
</property>
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
<property>
<name>dfs.client.use.legacy.blockreader.local</name>
<value>false</value>
</property>
<property>
<name>dfs.client.read.shortcircuit.skip.checksum</name>
<value>false</value>
</property>
</configuration>
hdfs-site.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>dfs.block.local-path-access.user</name>
<value>${your user}</value>
</property>
<property>
<name>dfs.datanode.hdfs-blocks-metadata.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>${yourdatadir}</value>
</property>
<property>
<name>dfs.client.use.legacy.blockreader.local</name>
<value>false</value>
</property>
<property>
<name>dfs.datanode.data.dir.perm</name>
<value>750</value>
</property>
<property>
<name>dfs.client.file-block-storage-locations.timeout</name>
<value>5000</value>
</property>
<property>
<name>dfs.domain.socket.path</name>
<value>/home/extend/cdhhadoop/dn.8075</value>
</property>
</configuration>
最后是hive-site.xml,这个比较简单,指定使用DBMS为元数据存储即可(impala必须和hive共享元数据,因为impala无 法create table);Hive-site.xml使用mysql作为metastore的说明在很多地方都可以查到,配置如下:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://10.28.0.190:3306/impala?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
<description>password to use against metastore database</description>
</property>
</configuration>
记得把mysql-connector的jar包给拷贝到hive的lib里面去,同样也要拷贝给impala ( 拷贝至$IMPALA_HOME/fe/target/dependency)
11.启动Impala。到此,Impala是可以正常启动的。这里说明一下,官方文档没有说很清楚Impala的Service之间是如何互相协调的,按照官方的步骤,最后通过如下方法来在一台机器上启动Impala Service:
#启动单机impala service
${IMPALA_HOME}/bin/start-impalad.sh -use_statestore=false
#启动impala shell
${IMPALA_HOME}/bin/impala-shell.sh
然后impala-shell就可以连接到localhost进行查询了;注意,这里只是单机查询,可以用来验证你的Impala是否正常work 了;如何启动一个Impala集群,跳到第12步。这里继续说一下可能遇到的问题,我遇到的一个比较奇葩的问题是show tables和count(1)没有问题,但是select * from table的时候impala在读取数据的时候就崩溃了(有时报错could not find method close from class org/apache/hadoop/fs/FSDataInputStream with signature ()V ),这里修改了两个地方解决这个问题:
a.修改impala的set-classpath.sh并移除$IMPALA_HOME/fe/target/dependency目录中除了hadoop-auth-2.0.0-*.jar之外所有hadoop-*开头的jar包。
#把impala dependency中和hadoop相关的包给弄出来,只保留auth
mv $IMPALA_HOME/fe/target/dependency/hadoo* $IMPALA_HOME
mv $IMPALA_HOME/hadoop-auth*.jar mv $IMPALA_HOME/fe/target/dependency
#修改bin/set-classpath.sh,将$HADOOP_HOME中的lib给加入,在set-classpath.sh最后一行export CLASSPATH之前#添加
for jar in `ls $HADOOP_HOME/share/hadoop/common/*.jar`; do
CLASSPATH=${CLASSPATH}:$jar
done
for jar in `ls $HADOOP_HOME/share/hadoop/yarn/*.jar`; do
CLASSPATH=${CLASSPATH}:$jar
done
for jar in `ls $HADOOP_HOME/share/hadoop/hdfs/*.jar`; do
CLASSPATH=${CLASSPATH}:$jar
done
for jar in `ls $HADOOP_HOME/share/hadoop/mapreduce/*.jar`; do
CLASSPATH=${CLASSPATH}:$jar
done
for jar in `ls $HADOOP_HOME/share/hadoop/tools/lib/*.jar`; do
CLASSPATH=${CLASSPATH}:$jar
done
b.注意到Impala对待table的时候只能够使用hive的默认列分隔符,如果在hive里面create table的时候使用了自定义的分隔符,Impala servive就会在读数据的时候莫名其妙的崩溃。
12.启动Impala 集群
Impala实际上由两部分组成,一个是StateStore,用来协调各个机器计算,相当于Master,然后就是Impalad,相当于Slave,启动方法如下:
#启动statestore
#方法1,直接利用impala/bin下面的这个python脚本
#这个脚本会启动一个StateStore,同时启动-s个数量的Impala Service在本机
$IMPALA_HOME/bin/start-impala-cluster.py -s 1 –log_dir /home/extend/impala/impalaLogs
#方法2,手动启动StateStore
$IMPALA_HOME/be/build/debug/statestore/statestored -state_store_port=24000
#启动impala service
#在每个编译安装了impala的节点上执行命令
#参数-state_store_host指定启动了stateStore的机器名
#-nn即namenode,指定hadoop的namenode
#-nn_port是namenode的HDFS入口端口号
$IMPALA_HOME/bin/start-impalad.sh -state_store_host=m11 -nn=m11 -nn_port=9000
正常启动之后,访问http://${stateStore_Server}:25010/ 可以看到StateStore的状态,其中的subscribers页面可以看到已经连接上的impala service node;
13.使用Impala客户端
这一步最简单,随便找一个机器启动
$IMPALA_HOME/bin/impala-shell.sh
#启动之后可以随便连接一个impala service
connect m12
#连接上之后就可以执行show tables之类的操作了
#需要注意的是,如果hive创建表或更新了表结构,impala的节点是不知道的
#必须通过客户端连接各个impala service并执行refresh来刷新metadata
#或者重启所有impala service