七、Sqoop Job:简化与自动化数据迁移任务及免密执行

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,1000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: 平时用 Sqoop 导入导出时,命令一长就容易出错,特别是增量任务还得记 last-value,很麻烦。其实 Sqoop 有 Job 功能,能把命令“存档”,以后直接 --exec 执行,配合调度工具特别省心。本文手把手讲 Job 创建、管理、免密执行技巧(密码文件、Credential Provider),还带实战例子,搞完你就能写出稳稳当当的自动化 Sqoop 作业了!

Apache Sqoop 提供了作业 (Job) 的概念,它允许用户保存和重用复杂的 Sqoop 命令(包括导入或导出所有参数)。这对于定期执行的、参数固定的数据迁移任务非常有用。此外,在自动化脚本中执行 Sqoop 作业时,处理密码是一个关键的安全问题,我们将探讨免密执行的几种方法。

思维导图

image.png
image.png

一、Sqoop Job 基础

什么是 Sqoop Job?
一个 Sqoop Job 是一个 已保存的 Sqoop 命令命名实例。它会 记录下你执行 sqoop importsqoop export使用的所有选项,包括连接字符串、用户名、表名、目标目录、增量导入参数等。

Sqoop Job 的优势:
1. 简化重复操作:只需 创建一次作业,后续 通过作业名即可执行, 无需重复输入冗长的命令。
2. 参数持久化:作业 保存了所有配置参数。
3. 增量导入状态管理:对于 增量导入,Sqoop Job 会 自动记录和更新 --last-value (上次成功导入的 检查点),使得 后续增量导入可以 无缝衔接
4. 易于集成到调度系统:可以 方便地被 Oozie、Azkaban、Airflow 或 Cron 等调度工具调用

Sqoop Metastore:
Sqoop Job 的 元数据 (作业定义、上次执行状态等) 存储在 Sqoop Metastore 中。
默认 Metastore:是一个本地的、基于文件的 HSQLDB 数据库,通常位于用户主目录下的 .sqoop/ 目录或 Sqoop 安装目录下的 metastore 子目录。这种方式只适用于单用户测试环境 共享 Metastore:在 生产环境多用户环境中, 强烈建议配置 Sqoop 使用 外部的关系型数据库 (如 MySQL, PostgreSQL) 作为 共享 Metastore。这需要在 sqoop-site.xml (或旧版本的 sqoop-env.sh) 中进行配置。

### 二、Sqoop Job 常用命令
  • 创建作业 (sqoop job --create)
    sqoop job --create <job-name> -- <tool-name> [tool-arguments]
    
  • <job-name>: 你给作业起的名字。
  • --: 非常重要的分隔符,用于区分 sqoop job 命令本身的选项和被保存的 Sqoop 工具命令 (如 importexport) 及其参数。
  • <tool-name>: importexport
  • [tool-arguments]: 对应 importexport 命令的所有参数。

  • 执行作业 (sqoop job --exec)

    sqoop job --exec <job-name> [override-options]
    
  • 执行已创建的作业。
  • [override-options]: (可选) 可以在执行时临时覆盖作业中已保存的某些参数 (例如 --password,或 --target-dir 用于不同的输出)。

  • 查看作业定义 (sqoop job --show)

    sqoop job --show <job-name>
    
  • 显示作业保存的所有参数当前状态 (如增量导入的 last-value)。

  • 列出所有作业 (sqoop job --list)

    sqoop job --list
    
  • 删除作业 (sqoop job --delete)

    sqoop job --delete <job-name>
    

三、Sqoop Job 代码案例 (以增量导入为例)

假设我们需要定期将MySQL表 mydb.user_activity (包含 idlast_login_ts 列) 的增量数据导入到HDFS。

1. 创建一个增量导入作业 (append 模式):
bash sqoop job --create daily_user_activity_append -- import \ --connect jdbc:mysql://mysql.example.com:3306/mydb \ --username db_user \ --P \ --table user_activity \ --target-dir /data/user_activity/append_mode \ --incremental append \ --check-column id \ --m 1
--P: 提示交互式输入密码。创建作业时不应将密码硬编码到作业定义中。密码会在首次执行显式提供时被Sqoop Metastore (如果配置了安全存储) 安全地记住 (或者依赖后续的免密配置)。

2. 执行作业:
bash sqoop job --exec daily_user_activity_append
Sqoop会 自动使用上次成功执行后保存的 id最大值作为本次导入的 --last-value

3. 创建一个增量导入作业 (lastmodified 模式):
bash sqoop job --create hourly_user_activity_lastmod -- import \ --connect jdbc:mysql://mysql.example.com:3306/mydb \ --username db_user \ --P \ --table user_activity --target-dir /data/user_activity/lastmod_mode \ --incremental lastmodified \ --check-column id \ --last-modified-column last_login_ts \ --m 1

4. 执行作业并覆盖密码 (如果需要):
bash sqoop job --exec hourly_user_activity_lastmod \ --password 'yourSecretPassword'
一般不推荐在命令行直接提供密码,这里仅为演示覆盖选项。

### *四、Sqoop 免密执行

自动化脚本调度系统中执行Sqoop作业时,避免在命令或脚本中硬编码密码至关重要。

方法一:使用密码文件 (--password-file)
你可以将密码 存储在一个文件中,并 限制该文件访问权限

1. 创建密码文件 (例如,在 hadoop01 上):
bash echo "yourSecretPassword" > /home/hadoop_user/.sqoop_db_password.txt chmod 400 /home/hadoop_user/.sqoop_db_password.txt

2. 在Sqoop命令或作业定义中使用 --password-file
直接执行时:
bash sqoop import --connect jdbc:mysql://mysql.example.com:3306/mydb \ --username db_user \ --password-file file:///home/hadoop_user/.sqoop_db_password.txt \ --table user_activity \ --target-dir /data/some_dir \ --m 1

(注意 file:/// 前缀,表示本地文件系统路径)
创建作业时 (更推荐,密码文件路径会被保存到作业定义中):
bash sqoop job --create my_secure_import_job -- import \ --connect jdbc:mysql://mysql.example.com:3306/mydb \ --username db_user \ --password-file file:///home/hadoop_user/.sqoop_db_password.txt \ --table user_activity --target-dir /data/some_dir \ --m 1
之后执行 sqoop job --exec my_secure_import_job 时,Sqoop会自动读取密码文件。

方法二:使用 Hadoop Credential Provider API (更安全)
Hadoop提供了一个 凭证提供者API,可以将 敏感信息 (如密码) 存储在加密凭证文件 (keystore) 中。Sqoop可以 集成这个API。

1. 创建凭证文件并存储密码别名
(需要在 Hadoop环境中执行 hadoop credential 命令)
bash hadoop credential create mysql.db.password -provider jceks://hdfs/user/hadoop_user/credentials/sqoop.jceks
执行上述命令后,会 提示你输入密码。密码会以 mysql.db.password (别名) 存储在 HDFS 上的 sqoop.jceks 文件中 (路径可以自定义)。

2. 配置Sqoop以使用Credential Provider
修改 sqoop-site.xml (位于Sqoop的 conf 目录),添加以下属性:
xml <property> <name>sqoop.metastore.client.record.password</name> <value>false</value> <description>If true, Sqoop will record passwords in the metastore. Set to false if using a password-file or credential provider.</description> </property> <property> <name>hadoop.security.credential.provider.path</name> <value>jceks://hdfs/user/hadoop_user/credentials/sqoop.jceks</value> <description>Path to the Hadoop credential provider keystore.</description> </property>

3. 在Sqoop命令或作业中使用密码别名
不需要再提供 --password--password-file。Sqoop会 自动尝试从配置的Credential Provider中 查找连接相关的密码别名 (Sqoop会 基于JDBC URL和用户名构造一个 预期的别名,或者你可以 显式指定,但这 不常见--password 选项)。
常见的是,如果 连接参数用户凭证别名某种方式对应 (具体机制可能依赖Sqoop版本和配置细节),Sqoop在 需要密码时会 自动查询

稳妥的做法是让Sqoop在创建作业交互式提示密码 (--P),如果配置了Credential Provider,Sqoop可能会将此密码存入配置的provider中,并与该作业关联。这样,后续执行作业时就无需再次提供密码。

方法三:使用 --password-alias (如果JDBC驱动和Sqoop版本支持)
某些JDBC驱动和较新版本的Sqoop可能支持 直接通过JDBC URL特定选项引用 存储在外部密码库中的 密码别名。这 依赖具体实现

### 五、重要安全提示
切勿在脚本或版本控制中硬编码密码 使用 权限最小化原则为Sqoop数据库用户授权。
定期审计和轮换密码及凭证。 保护好 密码文件或凭证库文件访问权限

总结: Sqoop Job 极大简化重复的数据迁移任务,特别是对于 增量导入。结合 密码文件Hadoop Credential Provider,可以 安全地实现 自动化、免密的Sqoop作业执行。

---

### 练习题

背景:
你有一个MySQL数据库 sales_db,其中有一个表 daily_sales (id INT AUTO_INCREMENT PRIMARY KEY, product_name VARCHAR(100), quantity_sold INT, sale_date DATE, last_update TIMESTAMP)。你需要定期将此表的新增和更新数据导入到HDFS目录 /data/sales_reports_hdfs

题目:

  1. 创建增量导入作业:创建一个名为 import_daily_sales_lastmod 的Sqoop作业,该作业使用 lastmodified 模式,以 id 为检查列,last_update 为最后修改时间列,将数据导入到HDFS的 /data/sales_reports_hdfs 目录。首次执行时,你需要交互式输入数据库密码。
  2. 执行作业:写出执行上题创建的 import_daily_sales_lastmod 作业的命令。
  3. 创建密码文件:假设你的数据库密码是 MyS@l3sP@ss!。在你的用户主目录下创建一个名为 .sales_db_pwd.txt 的密码文件,并设置其权限为只有属主可读。
  4. 修改作业以使用密码文件:Sqoop Job创建后,其核心参数是固定的。如果想让已创建的 import_daily_sales_lastmod 作业使用上一步创建的密码文件,你通常需要怎么做?(提示:考虑作业的可修改性执行时覆盖,但最佳实践是什么?)
  5. 思考题: 如果你配置了Hadoop Credential Provider,并且在创建Sqoop作业时使用了 --P 交互式输入了密码,Sqoop Metastore (特别是共享的、配置良好的Metastore) 通常会如何处理这个密码以便后续作业执行时不再需要输入?
答案:
  1. 创建增量导入作业:

    sqoop job --create import_daily_sales_lastmod -- import \
    --connect jdbc:mysql://your_mysql_host:3306/sales_db \
    --username sales_user \
    --P \
    --table daily_sales \
    --target-dir /data/sales_reports_hdfs \
    --incremental lastmodified \
    --check-column id \
    --last-modified-column last_update \
    --m 1
    
  2. 执行作业:

    sqoop job --exec import_daily_sales_lastmod
    
  3. 创建密码文件:

    echo "MyS@l3sP@ss!" > ~/.sales_db_pwd.txt
    chmod 400 ~/.sales_db_pwd.txt
    
  4. 修改作业以使用密码文件:
    Sqoop作业一旦创建,其核心参数 (如连接串、表名、增量模式等) 通常不能直接修改。你不能简单地 "alter" 一个作业来添加或更改 --password-file 选项。
    最佳实践删除旧作业,然后用包含 --password-file 的新定义重新创建作业:

    sqoop job --delete import_daily_sales_lastmod
    sqoop job --create import_daily_sales_lastmod -- import \
    --connect jdbc:mysql://your_mysql_host:3306/sales_db \
    --username sales_user \
    --password-file file:///home/your_user_name/.sales_db_pwd.txt \
    --table daily_sales \
    --target-dir /data/sales_reports_hdfs \
    --incremental lastmodified \
    --check-column id \
    --last-modified-column last_update \
    --m 1
    
  5. 思考题答案:
    如果配置了Hadoop Credential Provider,并且在创建Sqoop作业时使用了 --P 交互式输入了密码,Sqoop (特别是当连接到配置良好共享Metastore时,该Metastore自身也可能与Credential Provider集成或有安全存储机制) 可能会尝试将这个密码安全地存储起来。

  • 一种可能是Sqoop Metastore本身对密码进行加密存储
  • 另一种更理想的情况是,Sqoop Metastore会与配置的 Hadoop Credential Provider 交互,将用户输入的密码以一个与该作业或连接相关别名存储到Credential Provider的keystore中。
    这样,当后续执行该作业时 (sqoop job --exec job_name),Sqoop会自动从Metastore通过Metastore间接从Credential Provider中检索所需的凭证 (密码),从而实现免密执行,用户无需再次输入密码。这个过程对用户是透明的
目录
相关文章
|
3月前
|
安全 Linux Shell
四、Linux核心工具:Vim, 文件链接与SSH
要想在Linux世界里游刃有余,光会“走路”还不够,还得配上几样“高级装备”。首先是Vim编辑器,它像一把瑞士军刀,让你能在命令行里高效地修改文件。然后要懂“软硬链接”,软链接像个快捷方式,硬链接则是给文件起了个别名。最后,SSH是你的“传送门”,不仅能让你安全地远程登录服务器,还能用scp轻松传输文件,设置好密钥更能实现免-密登录,极大提升效率。
372 3
|
2月前
|
存储 运维 Cloud Native
Apache Doris 与 ClickHouse:运维与开源闭源对比
Doris 与 ClickHouse 各有优势,但在运维效率、集群自动化能力、故障恢复机制以及开源治理模型方面,Doris 展现出了更成熟、更开放、更面向云原生架构的产品能力。对于希望构建可控、弹性、高可用分析平台的团队而言,Doris 提供了一个更具确定性和长期价值的选择。而 ClickHouse 仍是极具性能优势的分析引擎,但其闭源方向的转变可能需要用户在技术与商业之间做出更谨慎的权衡。
313 9
Apache Doris 与 ClickHouse:运维与开源闭源对比
|
2月前
|
Dubbo Java 应用服务中间件
Apache ShenYu 架构学习指南
Apache ShenYu 是一款高性能、插件化的微服务API网关,基于Spring WebFlux + Reactor 构建,支持多协议、动态配置与实时数据同步。本指南以通俗类比和实战路径,带你深入理解其架构设计、核心流程与源码实现,助力快速掌握并参与贡献。
309 12
|
机器学习/深度学习 人工智能 自然语言处理
构建企业级数据分析助手:Data Agent 开发实践
本篇将介绍DMS的一款数据分析智能体(Data Agent for Analytics )产品的技术思考和实践。Data Agent for Analytics 定位为一款企业级数据分析智能体, 基于Agentic AI 技术,帮助用户查数据、做分析、生成报告、深入洞察。由于不同产品的演进路径,背景都不一样,所以只介绍最核心的部分,来深入剖析如何构建企业级数据分析助手:能力边界定义,技术内核,企业级能力。希望既能作为Data Agent for Analytics产品的技术核心介绍,也能作为读者的开发实践的参考。
594 1
构建企业级数据分析助手:Data Agent 开发实践
|
2月前
|
负载均衡 Java API
grpc-java 架构学习指南
本指南系统解析 grpc-java 架构,涵盖分层设计、核心流程与源码结构,结合实战路径与调试技巧,助你从入门到精通,掌握高性能 RPC 开发精髓。
256 7
|
消息中间件 存储 Kafka
Flink---11、状态管理(按键分区状态(值状态、列表状态、Map状态、归约状态、聚合状态)算子状态(列表状态、广播状态))
Flink---11、状态管理(按键分区状态(值状态、列表状态、Map状态、归约状态、聚合状态)算子状态(列表状态、广播状态))
|
3月前
|
存储 安全 前端开发
CC&LG实践|基于 LangGraph 一步步实现 Claude-Code 核心设计
本文旨在深入剖析 Claude-Code 的核心设计思想与关键技术实现,逆向分析其功能模块,结合 LangGraph 框架的能力,系统性地演示如何从一个最基础的 ReAct Agent 出发,逐步构建一个功能完备的简版 Claude-Code。
1529 19
CC&LG实践|基于 LangGraph 一步步实现 Claude-Code 核心设计
|
3月前
|
人工智能 前端开发 JavaScript
前端工程化演进之路:从手工作坊到AI驱动的智能化开发
前端工程化演进之路:从手工作坊到AI驱动的智能化开发
583 18
前端工程化演进之路:从手工作坊到AI驱动的智能化开发
|
2月前
|
JavaScript 前端开发 安全
Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
每日激励:“如果没有天赋,那就一直重复”。我是蒋星熠Jaxonic,一名执着于代码宇宙的星际旅人。用Vue 3与TypeScript构建高效、可维护的前端系统,分享Composition API、状态管理、性能优化等实战经验,助力技术进阶。
Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
|
2月前
|
人工智能 文字识别 安全
2025年企业防范员工向第三方人工智能工具泄露数据的全面防护方案
随着生成式人工智能工具的普及,企业员工在日常工作中越来越依赖ChatGPT、DeepSeek等第三方AI服务提升效率。然而,这种便利背后隐藏着严重的数据泄露风险。调查显示,近六成企业发生过敏感数据提交事件,其中三成导致实际泄露。传统防护手段在面对AI数据泄露场景时效果有限,企业急需建立针对性的防护体系。

热门文章

最新文章