Hadoop是目前比较流行的大数据计算平台,而SAP IQ是业内领先的列式商用分析型关系数据库引擎。本文将向大家介绍在系统中集成SAP IQ和Hadoop的一种方法。希望朋友们能够把这些技术运用到系统中,构建出互联网+下满足企业创新需求的应用系统。
在这篇博文中,将介绍如何把IQ数据库中表的数据导出到Hadoop HDFS中,以及如何把存储在HDFS中的数据文件装载到IQ数据库表中的方法。
1. 环境说明
本文中示例所使用的环境说明如下:
* VMware虚拟机1个:2 CPU、4GB内存、操作系统Cent OS 6.6 64bit ,运行”伪分布式" Hadoop HDFS集群。
* Hadoop 2.6.0
* SAP IQ 16.0 sp08.30(即sp 08 pl 30)。在我的环境中是运行在另一个虚拟机中。
2. 安装Hadoop集群
关于在虚拟机环境中安装”伪分布式" Hadoop HDFS集群的方法在这里不做详细介绍,读者可以参考本人的另一篇博文 “伪分布式Hadoop 2.6.0安装和配置”。
3. 在SAP IQ所在机器上安装和配置Hadoop
(1) 安装
由于IQ Server需要作为hadoop 客户端访问Hadoop HDFS集群,读取和写入数据文件,所以需要在IQ数据库所在的机器上安装hadoop。安装方法与第2步相同,只是不需要启动hadoop hdfs的各种服务进程,而是作为客户端访问hadoop hdfs集群。
(2) 配置
在启动IQ Server的操作系统账户(例如,sybiq,下同)的.profile中增加如下内容:
./opt/sybiq/16.0/IQ.sh
$HADOOP_HOME/etc/hadoop/hadoop-env.sh
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HBASE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$HADOOP_HOME/lib/native:/usr/lib64:$LD_LIBRARY_PATH
检查IQ Server所在机器的$HADOOP_HOME/etc/hadoop目录下的core-site.xml文件中的fs.defaultFS属性是否指向了正确的HDFS集群NameNode的服务地址。本人的core-site.xml如下:
(3) 在hadoop hdfs集群中创建用于存放IQ导出和导入数据文件的目录并进行授权。在hadoop分布式集群下执行如下命令:
hadoop fs -mkdir /user/sybiq
hadoop fs -chown sybiq:sybase /user/sybiq
(4) 测试IQ数据库所在机器是否能够正常访问hadoop hdfs集群
使用操作系统账户sybiq登录,执行如下命令:
hadoop fs -ls
如果能够正常显示hdfs文件系统目录,那么表示IQ数据库所在的机器配置正常。
(5) 在IQ数据库所在机器上创建命名管道文件:
mkfifo /tmp/pipe.out
由于IQ不能直接读写hdfs,需要用管道文件作为”中间媒介",具体参见后面的例子。
4. 创建测试表并插入示例数据
(1) 创建测试表
create table test (id int, transamt decimal(18,2), primary key (id))
(2) 插入测试数据
insert into test values(1,10000);
insert into test values(2,20000);
insert into test values(3,30000);
commit;
5. 导出测试表数据到HDFS中
(1) 编写导出sql脚本
--exp.sql
set temporary option temp_extract_row_delimiter = '\x0a';
set temporary option temp_extract_column_delimiter = '|!';
set temporary option temp_extract_null_as_empty = 'OFF';
set temporary option temp_extract_append = 'OFF';
set temporary option temp_extract_binary = 'OFF';
set temporary option temp_extract_swap = 'OFF';
set temporary option temp_extract_name1='/tmp/pipe.out';
set temporary option TEMP_EXTRACT_SIZE1='536870912';
select * from test;
set temporary option temp_extract_name1 = '';
注意上面红色的就是命名管道文件,IQ Server会把test表中的数据写入管道文件;使用hadoop命令shell从这个命名管道中读取数据写入到HDFS中。
(2) 执行数据导入
--首先执行如下命令
dbisql -c "uid=user1;pwd=sql" -nogui exp.sql &
--然后执行
hadoop fs -copyFromLocal /tmp/pipe.out /user/sybiq/test.dat &
执行时,由于IQ Server把数据写入到命名管道文件,会阻塞,直到有人读取管道的数据。
--导出完成后,执行如下命令查看文件及文件内容
hadoop fs -ls /user/sybiq/test.dat
hadoop fs -cat /user/sybiq/test.dat
6. 从HDFS中导入数据到IQ
(1) 编写数据导入sql脚本
--imp.sql
load Table test
(
id '|!',
transamt '|!'
)
FROM '/tmp/pipe.out'
escapes off
quotes off
Notify 10000
ROW DELIMITED BY '\x0a'
WITH CHECKPOINT ON;
COMMIT;
(2) 执行数据导入
--首先执行数据装载脚本(在执行前需要把test表数据清空)
dbisql -c "uid=user1;pwd=sql" -nogui imp.sql &
--然后执行 copy_to_local
./copy_to_local /user/sybiq/test.dat /tmp/pipe.out &
说明:copy_to_local是一个使用hadoop libdfs(C API)编写的c程序。 关于这个程序的说明参见本人的博文“解决hadoop shell copyToLocal时 本地文件不能存在的问题”。