我正在处理一个数据集以分布式方式保存在hdfs
中的集群。 这是我有什么:
[hmi@bdadev-5 ~]$ hadoop fs -ls /bdatest/clm/data/ Found 1840 items -rw-r--r-- 3 bda supergroup 0 2015-08-11 00:32 /bdatest/clm/data/_SUCCESS -rw-r--r-- 3 bda supergroup 34404390 2015-08-11 00:32 /bdatest/clm/data/part-00000 -rw-r--r-- 3 bda supergroup 34404062 2015-08-11 00:32 /bdatest/clm/data/part-00001 -rw-r--r-- 3 bda supergroup 34404259 2015-08-11 00:32 /bdatest/clm/data/part-00002 .... ....
数据的格式是:
[hmi@bdadev-5 ~]$ hadoop fs -cat /bdatest/clm/data/part-00000|head V|485715986|1|8ca217a3d75d8236|Y|Y|Y|Y/1X||Trimode|SAMSUNG|1x/Trimode|High|Phone|N|Y|Y|Y|N|Basic|Basic|Basic|Basic|N|N|N|N|Y|N|Basic-Communicator|Y|Basic|N|Y|1X|Basic|1X|||SAM|Other|SCH-A870|SCH-A870|N|N|M2MC|
所以,我想要做的是统计原始数据文件data
的行数。 我的理解是, part-00000
, part-00001
等分布式块有重叠。 所以只要计算part-xxxx
文件中的行数并将它们相加将不起作用。 另外原始数据集的data
大小~70GB
。 我怎样才能有效地找出总行数?
更高效 – 您可以使用火花来计算不。 线。 以下代码片段有助于计算行数。
text_file = spark.textFile("hdfs://...") count = text_file.count(); count.dump();
这显示了no的计数。 线。
Note: The data in different part files will not overlap
使用hdfs dfs -cat /bdatest/clm/data/part-* | wc -l
hdfs dfs -cat /bdatest/clm/data/part-* | wc -l
也会给你输出,但是这会把所有的数据转储到本地机器上,并且花费更长的时间。
最好的解决方案是使用MapReduce或者spark。 MapReduce将需要更长的时间来开发和执行。 如果安装了火花,这是最好的选择。
如果你只需要找到数据中的行数。 您可以使用以下命令:
hdfs dfs -cat /bdatest/clm/data/part-* | wc -l
你也可以用一个简单的mapreduce程序来编写一个标识映射器,它将输入作为输出。 然后你检查计数器,并找到映射器的输入记录。 这将是您的数据中的行数。
Hadoop一个班轮:
hadoop fs -cat /bdatest/clm/data/part-* | wc -l
资料来源: http : //www.sasanalysis.com/2014/04/10-popular-linux-commands-for-hadoop.html
另一种方法是创建一个map reduce作业,其中mapper为每行发射1,reducer将这些值相加。 请参阅编写MApreduce代码的已接受答案, 以计算解决方案的记录数 。
如果你有一个非常大的文件,大概有相同的行内容(我想象一个JSON或日志条目),你不关心精度,你可以计算它。
例如,我将原始的JSON存储在一个文件中:
文件大小:750Mo第一行的大小:752个字符(==> 752个八位字节)
线=>约1.020.091
运行cat | wc -l
cat | wc -l
给出1.018.932
不那么糟糕^^
这是一个普遍的任务,我希望有一个子命令fs做到这一点(例如, hadoop fs -wc -l inputdir
),以避免将所有内容流式传输到执行“wc -l”命令的计算机。
为了有效地计算行数,我经常使用hadoop streaming和unix命令,如下所示:
hadoop jar ${HADOOP_HOME}/hadoop-streaming.jar \ -Dmapred.reduce.tasks=1 \ -input inputdir \ -output outputdir \ -mapper "bash -c 'paste <(echo "count") <(wc -l)'" \ -reducer "bash -c 'cut -f2 | paste -sd+ | bc'"
每个映射器都会在它所拥有的部分上运行“wc -l”,然后一个reducer将总结所有映射器的计数。
您可以使用hadoop流式传输来解决这个问题。
这是你如何运行它:
hadoop jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-streaming-2.6.0-cdh5.11.0.jar -input <dir> -output <dir> counter_mapper.py -reducer counter_reducery -file counter_mapper.py -file counter_reducer.py
counter_mapper.py
#!/usr/bin/env python import sys count = 0 for line in sys.stdin: count = count + 1 print count
counter_reducer.py
#!/usr/bin/env python import sys count = 0 for line in sys.stdin: count = count +int(line) print count