使用命令行查找 hdfs 分布式文件中的总行数

Finding total number of lines in hdfs distributed file using command line

我正在一个集群上工作,其中数据集以分布式方式保存在 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-00000part-00001 等分布式块有重叠。因此,仅计算 part-xxxx 文件中的行数并将它们相加是行不通的。此外,原始数据集 data 的大小为 ~70GB。如何有效地找出总行数?

如果您只需要查找数据中的行数。您可以使用以下命令:

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 对值求和。有关解决方案,请参阅 Writing MApreduce code for counting number of records 已接受的答案。

更高效 -- 您可以使用 spark 来计算次数。线。以下代码片段有助于计算行数。

text_file = spark.textFile("hdfs://...")
count = text_file.count();
count.dump();

这显示没有。行数。

Note: The data in different part files will not overlap

使用 hdfs dfs -cat /bdatest/clm/data/part-* | wc -l 也会给你输出,但这会将所有数据转储到本地机器并且需要更长的时间。

最佳解决方案是使用 MapReduce 或 spark。 MapReduce 将需要更长的时间来开发和执行。如果安装了spark,这是最好的选择。

这是一项如此常见的任务,我希望 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 将汇总所有映射器的计数。

如果你有一个包含相同行内容的非常大的文件(我想象一个 JSON 或一个日志条目),并且你不关心精度,你可以计算它。

例如,我将原始 JSON 存储在一个文件中:

文件大小:750Mo 第一行的大小:752 个字符(==> 752 个八位字节)

行 => 大约 1.020.091

运行 cat | wc -l 给出 1.018.932

还不错^^

你可以使用 hadoop streaming 来解决这个问题。

你是这样运行的:

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