分享

mapreduce同时读取mysql和hdfs文件

strivecheng 发表于 2015-1-3 18:46:06 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 9 50573
请教大家个问题 mapreduce中如何同时读取mysql中一张表和hdfs中的一个日志文件 他们有关联字段id 将DBInputFormat 和 普通的TextInputFormat整合起来一起用 他们用不同的map处理 最后汇总到一个reduce 这要怎么去实现啊 ?

已有(9)人评论

跳转到指定楼层
strivecheng 发表于 2015-1-3 20:40:11
好吧,举个实际例子吧!就是:
MySQL中有个用户表,表结构如下
        id        name
        1        zhangsan
        2        lisi
        3        wangwu
       
       
  HDFS中有个交易日志表,日志结构如下
        1        11
        2        22
        3        33
如何实现产生结果形式如下
        zhagnsan        11
        lisi                22
        wangwu                33
回复

使用道具 举报

desehawk 发表于 2015-1-3 21:44:08
有两种解决方案:

第一种把hdfs文件,导入到数据库中,然后通过join实现
也就是把
HDFS中有个交易日志表,
        1        11
        2        22
        3        33

转换成mysql表,这个可以通过sqoop实现。

第二种读取mysql,然后通过hdfs api读取文件,只读去第一列,id相同,则读取整行。
回复

使用道具 举报

strivecheng 发表于 2015-1-3 21:56:20
desehawk 发表于 2015-1-3 21:44
有两种解决方案:

第一种把hdfs文件,导入到数据库中,然后通过join实现

嗯,第二种方案,具体怎么操作啊,要读取hdfs和mysql,关键点就是我不知道怎么同时处理这两个输入,之前只做过在hdfs上的多文件输入,不同类型的输入就不知道怎么弄了!能不能给点意见?!
回复

使用道具 举报

desehawk 发表于 2015-1-3 22:09:40
strivecheng 发表于 2015-1-3 21:56
嗯,第二种方案,具体怎么操作啊,要读取hdfs和mysql,关键点就是我不知道怎么同时处理这两个输入,之前 ...
首先hdfs文件读取这个相信难不倒你,
mysql的读取相信也难不倒你。

如果你在hdfs读取里面,嵌套mysql相信你也应该会的。
比如首先读取第一行第一个字段,这个值保存到数组中,或则变量中,都是可以的,然后在去mysql中查询这个值。
这样就达到目的了。
回复

使用道具 举报

strivecheng 发表于 2015-1-3 22:17:29
desehawk 发表于 2015-1-3 22:09
首先hdfs文件读取这个相信难不倒你,
mysql的读取相信也难不倒你。

嗯,如果是分别查询到没问题,关键是我不知道怎么在读hdfs是嵌套mysql查询,其实我要问的就是这个了,因为这样可能要用到DBInputFormat和TextInputFormat,在main函数中怎么去配置这两个map啊,之前用MultipleInputs只能配置两个hdfs路径,这里一个hdfs一个mysql就凌乱了!由于刚学没多久,可能有点浅显,见笑了!
回复

使用道具 举报

desehawk 发表于 2015-1-3 22:29:11
strivecheng 发表于 2015-1-3 22:17
嗯,如果是分别查询到没问题,关键是我不知道怎么在读hdfs是嵌套mysql查询,其实我要问的就是这个了,因 ...

一、java数据类型对应Hadoop里面的数据类型
java基本类型Writable实现
booleanBooleanWtitable
byte
ByteWritable
int
IntWritable
float
FloatWritable
long
LongWritable
double
DoubleWritable
String
Text




在对比的过程中,你可以都转换成Java数据类型。输出的时候,首先这两个值已经找到了。
找到之后,转换为hadoop数据类型,然后输出。

map只要使用TextInputFormat即可,数据库可以直接读取,不需要DBInputFormat 。
把他们读取之后,都放到变量中,然后统一输出到hdfs文件中。


// 输出姓名(name)和日志(log)
context.write(name, new IntWritable(log));



zhagnsan        11
    lisi                22
   wangwu        3


回复

使用道具 举报

strivecheng 发表于 2015-1-3 22:46:23
desehawk 发表于 2015-1-3 22:29
一、java数据类型对应Hadoop里面的数据类型

谢谢你这么耐心的回复,但是我还是有个疑问,数据库直接读取?这个不通过DBInputFormat怎么实现啊,难道在map中直接写jdbc代码?不太明白!
回复

使用道具 举报

tntzbzc 发表于 2015-1-4 01:08:05
strivecheng 发表于 2015-1-3 22:46
谢谢你这么耐心的回复,但是我还是有个疑问,数据库直接读取?这个不通过DBInputFormat怎么实现啊,难道 ...
楼主这个出发点感觉就不对。
这个应该属于关系型数据内容,用大数据来处理是不合适的。
如果将mysql变成hdfs文件,就变成了两个文件比较,而且是两个hdfs文件比较,更不幸的是楼主还想通过mapreduce来实现。这个本身存在了很多的不可能性。

思路有两个:
第一个:多个map,
1.通过map将mysql转换成hdfs file。然后map读取hdfs文件
2.最后两个hdfs文件比较
这个属于:MapReduce依赖关系组合式,详细参考让你真正明白什么是MapReduce组合式,迭代式,链式


第二个思路:
一个map,将mysql转换成hdfs file
reduce中接受map的values,然后读取hdfs文件,进行逐一比较。

这里面的缺点是hdfs文件不能太大,否则reduce会被卡主,甚至拖死。





建议楼主采用另外的思路:
通过hdfs文件,读如到mysql中,然后通过数据库操作,这样简单容易实现。数据量不是太大,性能也挺快的。








回复

使用道具 举报

strivecheng 发表于 2015-1-4 10:02:49
tntzbzc 发表于 2015-1-4 01:08
楼主这个出发点感觉就不对。
这个应该属于关系型数据内容,用大数据来处理是不合适的。
如果将mysql变 ...

谢谢,有点明白了,也看了你介绍的帖子,很好。其实我也觉得直接去读数据库不太好,就是想试试看能不能实现!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条