文章目录
- 一些配置和前提说明
- hadoop的一些说明
- 代码的一些说明
- pom.xml
- 获取行数
- 使用FileSystem获取文件行数
- 使用spark获取hdfs 文件的条数
- 获取大小
- 第一种解决办法:使用getBytes()
- 第二种解决办法:使用listStatus()
- 简单的情况
- 比较麻烦的情况
- 第三种解决办法:使用getContentSummary()
- 额外说点hadoop fs -dus
最近有一个需求,就是定时去统计,hdfs上的文件的大小和行数,也就是统计这段时间内新增的数据的条数和占用空间。
举个例子:一天24小时,每6个小时统计一次,这6个小时内,新增了多少条数据,以及这些数据在hdfs上占用了多少空间。
一些配置和前提说明
hadoop的一些说明
在这里,假设hdfs上的文件没有任何压缩格式,且hdfs中的数据是整齐无缺损的,其中存在用来筛选的时间字段。
举个例子:
1
2
3
4
51 159298900 15 2 159298900 45 3 159298901 12 .......
这里的第一个字段和第三个字段不用管,第二个字段是表示数据的时间的,不过要注意,这个字段表示的是秒还是毫秒
代码的一些说明
这里无论你是用java还是scala,都不影响。
就我个人涉及到的知识面而言,无非就是java的FileSystem,以及spark的textFile。所以这个说明其实就是:如何用FileSystem或spark读取hdfs的数据。
这个在这写太麻烦了,请看下面的链接:
java 使用FileSystem读取hadoop文件
使用spark读取hadoop文件的具体内容
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<dependencies> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.0.0</version> </dependency> </dependencies>
获取行数
使用FileSystem获取文件行数
这种方法的步骤是:读取hadoop文件,统计行数,没啥难度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; public class testNewFile { public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException { FileSystem fs=FileSystem.get( new URI( "hdfs://172.0.0.1:9000"), new Configuration(), "root"); FSDataInputStream in = fs.open( new Path( "hdfs://172.0.0.1:9000/user/hive/warehouse/test.db/t1/dt=3/t1")); BufferedReader d = new BufferedReader(new InputStreamReader(in)); long count = 0; String line; while ((line = d.readLine()) != null) { count += 1L; } System.out.println( count ); d.close(); in.close(); fs.close(); } }
使用spark获取hdfs 文件的条数
习惯用scala了,所以这里也用Scala了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import org.apache.spark.{SparkConf, SparkContext} /** * Created by admin on 2020/7/3. */ object test01 { def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("test").setMaster("local[*]") val sc = new SparkContext(conf) val hadoopRdd = sc.textFile( "hdfs://172.0.0.1:9000/user/hive/warehouse/test.db/t1/dt=3/t1" ) println(hadoopRdd.count()) } }
获取大小
第一种解决办法:使用getBytes()
这个其实也是最笨的一个方法,把每条数据读出来,然后value.getBytes().length
,就可以获取到当前这一行数据的大小。
具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; public class test { public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException { FileSystem fs=FileSystem.get( new URI( "hdfs://172.0.0.1:9000"), new Configuration(), "root"); FSDataInputStream in = fs.open( new Path( "hdfs://172.0.0.1:9000/user/hive/warehouse/test.db/t1/dt=3/t1")); BufferedReader d = new BufferedReader(new InputStreamReader(in)); long count = 0; long store = 0; String line; while ((line = d.readLine()) != null) { count += 1L; store += line.getBytes().length; } System.out.println( count ); System.out.println( store ); d.close(); in.close(); fs.close(); } }
第二种解决办法:使用listStatus()
hadoop的jar包里,有这么个api,可以获取一个路径下所有文件、文件夹的状态。这个状态,其中就包含了block的数量,以及文件大小。
简单的情况
假设该文件夹下面全都是文件,没有文件夹套文件夹套文件的情况。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; public class test { public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException { FileSystem fs=FileSystem.get( new URI("hdfs://127.0.0.1:9000"), new Configuration(), "root"); FileStatus[] in = fs.listStatus(new Path( "hdfs://127.0.0.1:9000/user/hive/warehouse/test.db/t1/dt=3")); System.out.println( in[0].getLen() ); fs.close(); } }
因为我知道我这一个文件夹底下只有一个文件,所以我in[0]
就完事了。如果一个文件夹下面有N多文件,则需要循环遍历,且相加。
比较麻烦的情况
这种方法虽然简单,但是最好文件夹下面就全是文件,不要文件夹下面还有文件夹,然后还有文件。也就是说,这种方法不太适合于文件夹下面还有文件夹的情况。
不是说处理不了,而是如果变成了文件夹下面有N层的话,你就得像统计一个文件夹有多大那样写递归了…很麻烦。
1
2
3
4
5
6FileStatus[] in = fs.listStatus( new Path( "hdfs://172.0.0.1:9000/user/hive/warehouse/test.db/t1/dt=3")); System.out.println( in[0].getLen() ); System.out.println( in[0].isDirectory() ); System.out.println( in[0].isFile() );
有 isDirectory()
和 isFile()
方法,递归也可以算出来,但是太麻烦了,想写自己写吧,我这里就不写了…
第三种解决办法:使用getContentSummary()
上述的那种麻烦的情况,可以使用这种方法来解决。
hadoop的jar包里,有这么个api,可以获取一个文件夹下,文件的数量,文件夹的数量,以及这个文件夹的大小。不过我只关心这个文件夹的大小,其他的不关心。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.ContentSummary; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; public class test { public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException { FileSystem fs=FileSystem.get( new URI("hdfs://172.0.0.1:9000"), new Configuration(), "root"); ContentSummary in = fs.getContentSummary(new Path( "hdfs://172.0.0.1:9000/user/hive/warehouse/test.db/t1/dt=3")); System.out.println( in.getLength() ); fs.close(); } }
这样就可以直接获取文件夹的大小了,不用考虑递归什么的了。
额外说点hadoop fs -dus
这个命令就是显示文件的大小。
1
2
3
4[root@Sla2 ~]# hdfs dfs -dus /tmp/root/ dus: DEPRECATED: Please use 'du -s' instead. 4217122515 /tmp/root/
hadoop fs -dus 的源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public static void dus(String src,Configuration conf) throws IOException { Path srcPath = new Path(src); FileSystem srcFs = srcPath.getFileSystem(conf); FileStatus status[] = srcFs.globStatus(new Path(src)); if (status==null || status.length==0) { throw new FileNotFoundException("Cannot access " + src + ": No such file or directory."); } for(int i=0; i<status.length; i++) { long totalSize = srcFs.getContentSummary(status[i].getPath()).getLength(); String pathStr = status[i].getPath().toString(); System.out.println(("".equals(pathStr)?".":pathStr) + "t" + totalSize); } }
看到里面的getContentSummary()
了么
最后
以上就是彩色火最近收集整理的关于Java,Scala - 使用代码统计hadoop中hdfs的文件大小以及文件夹大小一些配置和前提说明获取行数获取大小额外说点hadoop fs -dus 的全部内容,更多相关Java,Scala内容请搜索靠谱客的其他文章。
发表评论 取消回复