本文介绍了如何将数据从现有的RDBMS迁移到Trafodion数据库。从其它的RDBMS或外部数据源向Trafodion集群中导入大量的重要数据,可以通过下面两步完美实现:

  1. 在Trafodion集群中,将数据从源头导入Hive表。使用下列方法之一:
    • 在Trafodion系统中,使用一个类似Apache SqoopTM的工具,将数据从远程的RDBMS(例如,MySQL或Oracle)迁移到Hive表。更多信息,请参阅使用Sqoop将数据导入Hive
    • 在Trafodion集群中,将需要导入Trafodion的数据复制到HDFS。使用Hive外部表,使这些数据能从Hive中看到。更多信息,请参阅创建Hive外部表
  2. 使用Trafodion的LOAD语句,将数据从Hive导入Trafodion表。更多信息,请参阅使用Bulk Load将数据加载到Trafodion表

使用Sqoop将数据导入Hive

使用Apache SqoopTM工具,在关系型数据库和Apache Hadoop生态系统之间实现高效的海量数据传输。

默认情况下,Sqoop并非安装在Trafodion集群中。可以通过Ambari或Cloudera Manager GUI,在Trafodion集群中安装并启动Sqoop。更多信息,请参阅Scoop用户指南

安装必需软件

在Trafodion集群中安装JDK 1.8 and the Oracle JDBC 驱动,仅用于将数据从RDBMS导入Hive表。请设置以下环境变量:

export JAVA_HOME=/opt/java/jdk1.8.0_11
export JAVA_OPTIONS=-Dmapred.child.java.opts=\-Djava.security.egd=file:/dev/urandom+

以下是使用sqoop命令的几个示例。关于可与sqoop一起使用的更多选项,请参阅Scoop用户指南

列出所有Oracle表

sqoop list-tables –driver oracle.jdbc.OracleDriver –connect jdbc:oracle:thin:@:/ –username  –password

将数据导入Hive

sqoop import –connect jdbc:oracle:thin:@/ –username   –password  –table  –split-by  –hive-import –create-hive-table –hive-table  –hive-overwrite –null-string ” –null-non-string ” –hive-drop-import-delims –verbose

参数说明
–split-by默认情况下,如果未指定拆分列,sqoop会使用主键列作为拆分列,但这在大多数时候并非最优。此外,如果表未定义主键列,您必须手动指定拆分列。
–null-string表示字符串(string)列中的空值。
–null-non-string表示非字符串(string)列中的空值。
–hive-drop-import-delims导入Hive时,丢掉\n、\r和\01字符串域。注意:如果数据包含\n或\r,并且您不使用–hive-drop-import-delims选项,那么数据将会被清除。在数据迁移期间,可以通过定义你想要使用的分隔符(不存在于数据中),使用额外的Sqoop选项。

创建Hive外部表

Hive表必须从Hive接口(例如,Hive shell)中创建。在加载期间使用Hive的外部表会非常方便。你可以将源数据文件复制到单个HDFS文件夹下,并创建一个指向该文件夹的Hive外部表,从而将数据轻松导入Hive表。

Hive表各列的数据类型必须与源数据一致。关于创建外部表的语法,请参阅Hive wiki。关于Hive表可用的数据类型,请参阅Hive语言手册类型

可以通过Trafodion的整型、字符串型和字符型的列,访问Hive表。若要填充外部表,请使用以下类型的Hadoop命令,将数据复制到HDFS文件夹下:

hadoop fs -copyFromLocal

新建Trafodion表和索引

使用包含SALT USING PARTITIONS子句(salting)的CREATE TABLE语句,新建Trafodion表。例如:

CREATE TABLE TRAFODION.SCH.DEMO
(
demo_sk int not null,
name varchar(100),
primary key (demo_sk)
)
SALT USING 8 PARTITIONS ON (demo_sk);

表中任何的索引都可能被盐粒分布(salted),也可能未被盐粒分布(salted)。如果被盐粒分布了,则盐粒分布的键和分区数必须与表一致。

CREATE INDEX demo_ix ON sch.demo(name)
SALT LIKE TABLE;

选择一个主键

必须根据访问表的工作负载,选择Trafodion表的主键。由于HBase是键值(key-value)存储,所以通过键来访问Trafodion表非常有效率。当您知道一些语句在断言(predicate)和连接(join)条件之外来访问一张表,您可以选择一个主键,使头键列有很高的选择断言。这会限制在HBase中需要被扫描的行数。如果断言只出现在边键列而非头键列中,Trafodion使用MDAM来限制被扫描的行数。如果头键列(没有断言出现)的唯一条目数(unique entry count)很低,MDAM能很好工作。

盐粒分布(Salting)一张表

Trafodion表能被盐粒分布,以避免热污点(hot-spotting)。在一些工作负载下,有了排列分区数据,数据的某种键的排列会比另一些排列有更多对表的访问量。这会导致某些HBase RegionServers处理大多数的加载,从而出现不平衡的使用行为。

对于本机HBase表,往往可以通过设计合适的键来处理。在Trafodion中,一旦您选择了表的键(请参阅选择一个主键),就可以使用盐粒分布(salting)来均匀分布数据。盐粒分布对salt键使用一个哈希函数,并且根据该哈希的值来将数据分布到分区中。这个哈希的值被物理存储在表中,作为头键值。表的每次拆分只会有一个salt键值。salting键可以是主键的任意子集(包括主键本身)。

保持salting键尽可能小,这是一个很好的实践。这个键必须提供数据平均分配。当键值有很大的唯一条目数(unique entry count)并没有严重倾斜的时候,能够实现数据的平均分配。在创建表的时候,必须指定分区数。分区数取决于集群的大小和表的期望大小。

如果添加的数据量超出了原本的预期,则盐粒分布的表就能被拆分。这会导致有多个分区具有salt值相同的行,也可能产生基于该表的次优执行计划。

您也可以选择不盐粒分布Trafodion表,这就与传统RDBMS的range分区类似。分区数随着表的增大而增多,并且range的边界由HBase根据指定的拆分策略而确定。

使用Bulk Load将数据加载到Trafodion表(将数据从Hive加载到Trafodion)

使用命令接口工具(例如,trafci),设置控制查询默认(Control Query Defaults,CQD),从而提高加载性能:

cqd hive_max_string_length ‘1000’; // if the widest column is 1KB

如果目标的Trafodion表具有时间相关的列,则需要进行以下设置:

cqd allow_incompatible_assignment ‘on’;

使用LOAD语句,将数据从Hive加载到Trafodion表。例如:

LOAD WITH NO POPULATE INDEXES INTO trafodion.sch.demo SELECT * FROM hive.hive.demo;

关于LOAD语句的语法,请参阅《Trafodion SQL 参考手册》.

如果多次调用LOAD语句,向单个目标表逐渐加载数据集,则目标表的每个分区会有多个HFile。这会导致SELECT查询期间无效率的访问,也可能导致数据压缩(基于HBase设置中的配置策略)。为了避免这种情况,可以针对表(短期内被两个以上的LOAD语句所加载)执行一个大的数据压缩。使用以下的HBase shell命令,执行这样的压缩:

major_compact ‘TRAFODION.SCH.DEMO’

这个命令不需要等待时间,并且会立即返回。通常,对一张大表执行数据压缩会花费大量的时间(几分钟到几小时不等)。您可以通过HBase Master Web UI,监控数据压缩的进程。