DataX的如何使用hdfsreader/writer

说明:DataX的hdfs读取或写入一般用的比较少,国内用datax通常都是用它完成数据仓库之间的数据迁移,很少以文件的形式直接迁移,对于hdfs来讲,datax提供了hdfsreader和hdfswriter,本篇以文件的方式导入或导出hive数据为例,展示datax的hdfsreader/writer怎么用,因为整体的技术大环境下使得datax提供的hdfsreader/writer也是以结构化数据的方式传递文件,但是要提前说明的是,虽然hive不是数据库,它只是hdfs数据的结构化管理工具,但是hive支持jdbc的形式使用,所以datax默认没有自带所谓的hivereader/writer,如果你的技术环境很干净的场景下,例如你使用的就是原生的或者hdp这种定制化不高,一般用在基础架构上的技术环境的话,你可以直接采用jdbcreader/writer去迁移hive数据。本篇只是为了展示hdfsreader/writer如何写任务Json配置,所以借用hive为使用例子,因为它底层就是hdfs的文件。同样的正是因为datax本身并没有自带所谓的hivereader/writer,所以如大家在工作中使用的中台之类的产品,你看到的日志中输出的hivereader之类的配置,那都是中台自己的RD二次开发的,同时datax本身也支持用户二次开发reader/writer。言归正传,用hive为例hdfsreader/writer使用方式如下。

第一种:全字段数据,源数据hive,目的库关系型数据库,比如mysql。全表时hdfsreader的column可以简写为*

json 复制代码
{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "hdfsreader", 
                    "parameter": {
                        "column": ["*"], 
                        "defaultFS": "hdfs://hdp1:9000",
                        "encoding": "UTF-8",
                        "fieldDelimiter": ",",
                        "fileType": "text",
                        "path": "/hiveData/test"
                    }
                }, 
                "writer": {
                    "name": "mysqlwriter", 
                    "parameter": {
                        "column": [
                            "id",
                            "name",
                            "sex"
                        ], 
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://192.168.0.103:3306/shop?useUnicode=true&characterEncoding=utf8", 
                                "table": ["test"]
                            }
                        ], 
                        "password": "123456", 
                        "username": "root", 
                        "writeMode": "insert"
                    }
                }
            }
        ], 
        "setting": {
            "speed": {
                "channel": "1"
            }
        }
    }
}

第二种,部分字段,源数据hive,目的库关系型数据库,比如mysql。

json 复制代码
{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "hdfsreader", 
                    "parameter": {
                        "column": [
                                {"index":1,"name": "name", "type": "string"},
                                {"index":2,"name": "sex", "type": "string"},
                        ], 
                        "defaultFS": "hdfs://hdp1:9000",
                        "encoding": "UTF-8",
                        "fieldDelimiter": ",",
                        "fileType": "text",
                        "path": "/hiveData/test"
                    }
                }, 
                "writer": {
                    "name": "mysqlwriter", 
                    "parameter": {
                        "column": [
                            "name","sex"
                        ], 
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://192.168.0.103:3306/shop?useUnicode=true&characterEncoding=utf8", 
                                "table": ["test"]
                            }
                        ], 
                        "password": "123456", 
                        "username": "root", 
                        "writeMode": "insert"
                    }
                }
            }
        ], 
        "setting": {
            "speed": {
                "channel": "1"
            }
        }
    }
}

如果你要对,目的端在数据落库之前做一些预处理,可以在writer的Json部分写如下配置,比如要删掉目的mysql表中的一些数据

bash 复制代码
"preSql": [
     "delete from paper_avgtimeandscore where s='1' "
]

从hive数据里抽,一般就上面这两种情况,注意原生情况下hdfsreader是没有提供数据过滤能力,就是where,因为抽取的时候一般都是按分区抽,或者干脆就是全量,对于where的需求在hive里面就已经解决了,一般是做一个dwd报表,说白了数据从hive出来的时候就没有where的业务必要,所以hdfsreader就不含有这种能力,除非向开头说的那样市场上存在的第三方hivereader插件。

第三种:从其他数据端抽取数据落到hive中,比如从mysql抽,最后落库到hive

json 复制代码
{
    "job": {
        "setting": {
            "speed": {
                "channel": 1
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "123456",
                        "connection": [
                            {
                                "jdbcUrl": ["jdbc:mysql://192.168.0.103:3306/shop?useUnicode=true&characterEncoding=utf8"],
                                "querySql": ["SELECT id, name, sex FROM your_table_name"]
                            }
                        ]
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "defaultFS": "hdfs://hdp1:9000",
                        "fileType": "text",
                        "path": "/hiveData/test",
                        "fileName": "part-0101",
                        "column": [
                            {"name": "id", "type": "string"},
                            {"name": "name", "type": "string"},
                            {"name": "sex", "type": "string"}
                        ],
                        "fieldDelimiter": ",",
                        "writeFormat": "text",
                        "writeMode": "append"
                    }
                }
            }
        ]
    }
}

无论是你导入还导出一定要注意的点:在本例中两端的列名定义,一定要一一对应,比方说hdfsreader的column中,你可以不定义name属性,但必须定义index,index的值是hdfs文件中列的下标,从零开始,并且每一个column中的Json对象定义时的位置,要和输出端,如在本例中是mysqlwriter的column部分一一对应,不能错列,就是说你reader端第一个column定义的是hdfs文件中下标为2的列,那么下面输出端的column中第一个也必须是hdfs文件中下标为2这一列数据你希望对应的mysql列,反过来也是一样的,DataX不会给你自动识别位置的,因为hdfsreader/writer本身就是为了文件传递而存在,开发用意上就没考虑hive,或者说是元数据的存在。因此它没办法在其他数据库导入数据到hive时,完成部分字段导入,要实现这一点就要去自定义hivereader或者用jdbc,你直接用hdfswriter写的话会发现数据任然是顺序依次的系列化,和列明对不上的。而hive数据导出到其他数据库的时候可以部分字段导,那是因为本质上输出端还是用的对应数据库的jdbc,只不过列名的元数据信息是你提供的罢了。如果还是没有反应过来,也可以通俗的理解为,hdfsreader以你给定的列元数据json对象顺序依次读数据,读出来的数据集是从文件出来的,只有json对象对应的位置顺序,而没有列名这一层概念,因此需要在写入的时候采用你指定的writer端列名给数据集一个元数据信息,并且这个元数据信息不会影响数据集每一列本身的顺序,如果此时你的writer端是一个jdbc,那么数据的写入自然就依靠数据库自身的jdbc能力写在了对应列上,所以应用在本例中,导出hive数据的时候可以全字段或部分字段,而反过来当你的数据是从其他的地方抽过来,要导入hdfs上时,同理虽然你是从拥有元数据的地方抽过来的数据集,但是写入的目的就是文件,自然就不需要考虑内容是不是有元数据,依次导入对文件内容系列化即可,此时除非从其他地方抽数据时,将不希望有数据的列直接映射为空数据,否则落盘的时候就是单纯的文件,只不过内容是可以结构化使用的罢了。

在使用DataX的时候,对于高可用的Hadoop集群,要注意一点,我上面写的例子都是直接指定的namenode,如果你要把抽取程序运行到高可用的集群上的话,就要在hdfswriter或hdfsreader的parameter中加如下配置,既高可用namenode节点的配置信息,当然配置改成你自己的

bash 复制代码
"hadoopConfig":{
     "dfs.nameservices": "mycluster",
     "dfs.ha.namenodes.mycluster": "nn1,nn2",
     "dfs.namenode.rpc-address.mycluster.nn1": "hadoop101:8020",
     "dfs.namenode.rpc-address.mycluster.nn2": "hadoop102:8020",
     "dfs.client.failover.proxy.provider.mycluster": "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
}

然后上面json文件里defaultFS也就写高可用逻辑组名就行

bash 复制代码
"defaultFS": "hdfs://mycluster",

之所以要这么干,是因为DataX不去识别你的本地Hadoop配置,或者是HOME,它本身就允许你不在Hadoop集群节点上跑数据。

相关推荐
CoookeCola3 小时前
MovieNet(A holistic dataset for movie understanding) :面向电影理解的多模态综合数据集与工具链
数据仓库·人工智能·目标检测·计算机视觉·数据挖掘
K_i13411 小时前
Hadoop 集群自动化运维实战
运维·hadoop·自动化
Q264336502314 小时前
【有源码】基于Python与Spark的火锅店数据可视化分析系统-基于机器学习的火锅店综合竞争力评估与可视化分析-基于用户画像聚类的火锅店市场细分与可视化研究
大数据·hadoop·python·机器学习·数据分析·spark·毕业设计
想ai抽1 天前
深入starrocks-多列联合统计一致性探查与策略(YY一下)
java·数据库·数据仓库
starfalling10241 天前
【hive】一种高效增量表的实现
hive
顧棟1 天前
【Yarn实战】Yarn 2.9.1滚动升级到3.4.1调研与实践验证
hadoop·yarn
D明明就是我1 天前
Hive 拉链表
数据仓库·hive·hadoop
嘉禾望岗5031 天前
hive join优化和数据倾斜处理
数据仓库·hive·hadoop
yumgpkpm1 天前
华为鲲鹏 Aarch64 环境下多 Oracle 数据库汇聚操作指南 CMP(类 Cloudera CDP 7.3)
大数据·hive·hadoop·elasticsearch·zookeeper·big data·cloudera
忧郁火龙果1 天前
六、Hive的基本使用
数据仓库·hive·hadoop