sqoop 创建 impala 拼花桌

Posted

技术标签:

【中文标题】sqoop 创建 impala 拼花桌【英文标题】:sqoop create impala parquet table 【发布时间】:2017-02-08 15:02:12 【问题描述】:

我对 sqooping 的过程比较陌生,所以请原谅任何无知。我一直在尝试将数据源中的表作为 parquet 文件进行 sqoop,并创建一个 impala 表(也作为 parquet),我将在其中插入 sqooped 数据。代码运行没有问题,但是当我尝试选择几行进行测试时出现错误:

.../EWT_CALL_PROF_DIM_SQOOP/ec2fe2b0-c9fa-4ef9-91f8-46cf0e12e272.parquet' has an incompatible Parquet schema for column 'dru_id.test_ewt_call_prof_dim_parquet.call_prof_sk_id'. Column type: INT, Parquet schema: optional byte_array CALL_PROF_SK_ID [i:0 d:1 r:0]

我正在复制我在 cloudera 指南上找到的过程:https://www.cloudera.com/documentation/enterprise/5-8-x/topics/impala_create_table.html。主要是“内部和外部表”部分。我一直在努力避免使用特定的 parquet 文件来推断模式,因为这整个事情每个月都会用一个 bash 脚本启动(而且我也想不出一种方法来将它指向一个文件如果我使用多个映射器)。

这是我使用的代码。我觉得我要么错过了一些小而愚蠢的东西,要么我在没有意识到的情况下把所有主要的事情都搞砸了。任何和所有的帮助表示赞赏。谢谢!

    sqoop import -Doraoop.import.hint=" " \
    --options-file /home/kemri/pass.txt \
    --verbose \
    --connect jdbc:oracle:thin:@ldap://oid:389/cn=OracleContext,dc=[employer],dc=com/EWSOP000 \
    --username [userid] \
    --num-mappers 1 \
    --target-dir hdfs://nameservice1/data/res/warehouse/finance/[dru_userid]/EWT_CALL_PROF_DIM_SQOOP \
    --delete-target-dir \
    --table DMPROD.EWT_CALL_PROF_DIM \
    --direct \
    --null-string '\\N' \
    --null-non-string '\\N' \
    --as-parquetfile 


impala-shell -k -i hrtimpslb.[employer].com


create external table test_EWT_CALL_PROF_DIM_parquet(
CALL_PROF_SK_ID INT,
SRC_SKL_CD_ID STRING,
SPLIT_NM STRING,
SPLIT_DESC STRING,
CLM_SYS_CD STRING,
CLM_SYS_NM STRING,
LOB_CD STRING,
LOB_NM STRING,
CAT_IND STRING,
CALL_TY_CD STRING,
CALL_TY_NM STRING,
CALL_DIR_CD STRING,
CALL_DIR_NM STRING,
LANG_CD STRING,
LANG_NM STRING,
K71_ATOMIC_TS TIMESTAMP)
stored as parquet location '/data/res/warehouse/finance/[dru_userid]/EWT_CALL_PROF_DIM_SQOOP';

【问题讨论】:

您还可以考虑使用选项--hive-import,它会立即使用底层 parquet 文件创建配置单元表,而无需担心。 Impala 使用相同的表元存储,因此没有问题。 @spijs 感谢您的建议!一旦sqooped,这会自动存在于Impala中,还是我必须进入Hue > Impala并刷新metastore?任何数量的手动步骤都是行不通的,因为我们是为业务合作伙伴创建的。 您确实必须刷新元存储。您还需要表名来创建表,因此在脚本中添加 impala 命令可能比定义所有列的工作量要少,这对于使用 --hive-import 是不必要的 @spijs 好吧,我就是这么想的。如果我没记错的话,立即创建一个 impala 表将无需刷新任何内容(除非可以在 bash 脚本中执行刷新) @spijs 我花了一些时间搜索 --hive -import 作业的示例,但找不到太多。您能否在我的代码上向我展示如何促进这一点?非常感谢! 【参考方案1】:

根据 cmets 中的请求,我提供了一个示例,说明如何使用带有 --hive-import 的一个 sqoop 导入来实现相同的目标。出于明显的原因,我没有针对您的特定要求对其进行测试,因此可能需要进行更多调整,这些 sqoop 命令通常是这种情况。 根据我的经验,作为 parquet 导入会强制您使用 --query 选项,因为它不允许您使用 schema.table 作为表。

sqoop import -Doraoop.import.hint=" "\
--verbose \
--connect jdbc:oracle:thin:@ldap://oid:389/cn=OracleContext,dc=[employer],dc=com/EWSOP000 \
--username [userid] \
-m 1 \
--password [ifNecessary] \
--hive-import \
--query 'SELECT * FROM DMPROD.EWT_CALL_PROF_DIM WHERE $CONDITIONS' \
--hive-database [database you want to use] \
--hive-table test_EWT_CALL_PROF_DIM_parquet \
--target-dir hdfs://nameservice1/data/res/warehouse/finance/[dru_userid]/EWT_CALL_PROF_DIM_SQOOP \
--null-string '\\N' \
--null-non-string '\\N' \
--as-parquetfile

基本上你需要--hive-import--hive-database--hive-table--query。 如果您不希望所有列都以字符串形式出现在 Hive 中,您还必须包括:

--map-hive-columns [column_name1=Timestamp,column_name2=Int,...]

您可能也需要类似的--map-java-columns,但我不确定何时需要。 如果您需要多个映射器,则需要--split-by

正如 cmets 中所讨论的,您需要使用 invalidate metadata db.table 来确保 Impala 看到这些更改。您可以从 CL 或单个 bash 脚本发出这两个命令,您可以在其中使用 impala-shell -q [query] 发出 impala 命令。

【讨论】:

非常感谢您的解释和演练!今天我会尽快进行测试。 对于 --hive-database 参数,当您说“您要使用的数据库”时,这是否意味着我们尝试从中进行 sqoop 的 oracle db 的名称或其他名称?跨度> hive 元存储数据库的名称。不是源数据库 请原谅我的无知,但我怎么知道元存储数据库名称是什么? 成功了!非常感谢所有无价的帮助!

以上是关于sqoop 创建 impala 拼花桌的主要内容,如果未能解决你的问题,请参考以下文章

为啥 impala 不显示 Hive 创建的所有表

从 impala 导入 Sqoop

使用java在impala表中插入数据

Impala 查询编辑器总是显示 AnalysisException

用于 ETL 的 Impala shell 或 Spark?

写入 Impala 时自动创建 Impala 表的数据框