MapReduce从文件系统中读取数据的格式在InputFormat中定义。输出的格式由OutputFormat定义。
Hadoop实现的InputFormat和OutputFormat。
实现的InputFormat :
TextInputFormat . key : LongWritable , Value : Text .
KeyValueTextInputFormat . key: Text , Value : Text . 默认分隔符为 \t ,可自定义。
SequenceFileInputFormat<K,V> , 自定义键值对,读取Hadoop专用的压缩二进制文件。
实现的OutputFormat :
TextOutputFormat<K,V> , 将每个记录写为一行文本,键值对以字符串形式写入(key和alue都成了Text),以 \t 为分割符。 对应KeyValueTextInputFormat
SequenceFileOutputFormat<K,V> , 以Hadoop专有序列文件写入键值对。 对应 SequenceFileInputFormat<K,V>
Hadoop Streaming:
Streaming 使用Unix流与程序进行交互。 从STDIN读入数据,输出到STOUT。
数据必须为文本,且每行视为一个记录。
Streaming中每个mapper都会看到完整的数据流,也正是mapper负责将数据流分割成记录。
标准Java模式中,InputFormat负责分割数据,将键值传递给map( )
Unix命令使用Streaming:
先把input文件输入HDFS
接下来运行程序
开始没找到streaming.jar , ‘hadoop实战‘上的路径比较老,之后用find -name找到了streaming。
这里用Unix命令来代替mapper和reducer部分。
cut -f 2-3 -d , file // 输出file文件,以‘,’为分隔符,输出每行的第2,3个分割。
uniq // 去除相邻的重复行。
运行过程:
运行结果:
这个文件mapper后本身就是有序的,现在测试一下文件本身无序,是否sort。
文件变成了无序的,并且删除了以前的input和output文件。
执行后结果如下:
输出变成了有序的。
因为Streaming的数据必须为文本,所以这里的排序也是字典序的排序。
通过脚本替代mapper或reducer
数据取自STDIN,输出STDOUT即可。
eg: hadoop jar hadoop-streaming.jar -input /input -output /output -mapper ‘xxx.py’ -file xxx.py
这里用python脚本当mapper,这里没有设置reducer,默认用IdentityReducer,输入直接转向输出。
Streaming中的键值对
mapper: 首先mapper从input中读取数据流,并分割成记录,然后映射后输出。
mapper的输出以 \t 为分隔符,前为键,后为值,如果没有 \t 则默认都为键,值为空。
shuffle+sort: 根据键来shuffle到各个Reducer,然后根据键来排序。
reducer: reducer接收排好序的键值对,但不像Java模式中相同键的已经进行合并。
output: reducer处理后输出到指定文件夹。
使用Aggregate包代替reducer
hadoop中实现了一些reducer,在Aggregate包中,并且都内置了combiner。
有LongValueMax LongValueSum UniqValueCount ValueHistogram等等。
使用时设置reducer即可 ‘-reducer aggregate‘
并且要求mapper的输出格式为 function:key\tvalue // eg: LongValueSum:US 6
使用ValueHistogram时要求格式为 function:key\tvalue\tcount // 因为这个reducer要求平均值等,为了使用combiner,所以需要输出count属性,表示这种键值对的个数。