背景
收到磁盘告警后,第一时间查看hdfs容量趋势变化,下图中红色圈起来的部分,因为事情发生在昨天:
如上,当时看到hdfs的整体容量是突增起来的,而不是主键增长起来的,然后和业务确定了近期的插入量并不大后,就基本可以确定应该是hadoop本身出问题了,而不是确实有那么大的量产生,于是查看下到底是什么占用了这么大的空间:
1
2
3
4
5
6
7
|
[ root @ aly - bigdata - hadoop - client ~ ] # hadoop fs -du -h /
77.6 M 2.0 G / hbase
124.7 M 297.8 M / kylin
0 0 / system
1.6 T 4.9 T / tmp
1.7 T 5.0 T / user
262.4 G 787.3 G / var
|
如上,我发现 /tmp 目录占了很大的空间,继续深入查看:
1
2
3
4
5
6
7
8
9
|
[ root @ aly - bigdata - hadoop - client ~ ] # hadoop fs -du -h /tmp
56 168 / tmp / . cloudera_health_monitoring_canary _files
0 0 / tmp / hadoop - yarn
0 0 / tmp / hbase - staging
1.6 T 4.7 T / tmp / hive
0 0 / tmp / kylin
92.9 G 278.8 G / tmp / logs
153 459 / tmp / partitions_1a3c689d - a2f1 - 44c7 - a1d4 - c224ab4df7ec
153 459 / tmp / partitions_9e39fd42 - cba4 - 4dc0 - adc9 - 95e93e9e37cf
|
如上,是hive的临时目录占了很多空间,那么里面存的都是什么呢 ?
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
|
[ root @ aly - bigdata - hadoop - client ~ ] # hadoop fs -du -h /tmp/hive/hive/
0 0 / tmp / hive / hive / 0030d2fb - eacc - 4068 - 8337 - 3d989dd8e8f9
0 0 / tmp / hive / hive / 00373670 - c0f3 - 4860 - 9c94 - 7881395b5818
0 0 / tmp / hive / hive / 003eddc2 - 71c2 - 416e - b194 - 7f0780675f42
0 0 / tmp / hive / hive / 004792b6 - ae5b - 49c4 - 9090 - c08f6d40e2b5
0 0 / tmp / hive / hive / 0051d4a9 - b8cf - 4616 - a787 - d07448bc0359
0 0 / tmp / hive / hive / 005bae02 - 4a05 - 4e32 - 872a - ff19787b5ede
0 0 / tmp / hive / hive / 0099afb4 - 7eff - 4d16 - be77 - 40e5b1603849
0 0 / tmp / hive / hive / 009d4002 - e718 - 41e1 - 81f8 - 4b0d64c9e25f
935.7 M 2.7 G / tmp / hive / hive / 00bdfa7a - 4fe5 - 4778 - a5ec - 06fb78b92e51
0 0 / tmp / hive / hive / 00c92ea7 - 7288 - 4a17 - 960f - 0ba52bfd3bb7
0 0 / tmp / hive / hive / 00d63bbc - 7287 - 4e95 - a2a8 - 7f638b958fae
85.5 M 256.4 M / tmp / hive / hive / 0162335c - c562 - 49f8 - aa0c - 54a835c87680
0 0 / tmp / hive / hive / 016f626e - f47c - 4368 - a459 - 2fee64e796c2
0 0 / tmp / hive / hive / 017cfa83 - beda - 404a - b211 - 6264a3735f1a
280.7 K 842.0 K / tmp / hive / hive / 018f6e83 - 92fd - 4d55 - b670 - 95264de6f854
0 0 / tmp / hive / hive / 02867e9d - bfe5 - 498d - b5d7 - 2c6879779439
0 0 / tmp / hive / hive / 02adebe7 - e46e - 4d1f - b3e2 - 42c210362509
0 0 / tmp / hive / hive / 02e14fd7 - 3035 - 479a - bd8c - 73b19b104c63
0 0 / tmp / hive / hive / 02f68c38 - 3fd7 - 46df - 8fd3 - a34c13a20510
0 0 / tmp / hive / hive / 03095e0e - 81f1 - 49eb - b90b - 331010ab8143
349.4 M 1.0 G / tmp / hive / hive / 030cc6d8 - e54b - 4cce - 9e54 - 0908bdf69345
0 0 / tmp / hive / hive / 0316a7b7 - 36a6 - 437e - 81d1 - 6b5848926580
0 0 / tmp / hive / hive / 0332013a - 8af6 - 4495 - 82e2 - bf9ea95a2586
773.5 M 2.3 G / tmp / hive / hive / 0334f6ee - 1905 - 4c84 - 8fbf - 59d573a81e00
|
如上,存的都是一些编码格式的文件,小的几十K,大的几个G,经网上查阅后发现,在application 运行过程中会产生一些中间表(HIVE默认就存放在 /tmp 目录下,如果是CDH,则就是 /tmp/hive/hive),如果某些application在运行过程中由于某些原因失败了,则这些临时表不会被回收删除。 我们可以设置 hive.exec.compress.intermediate 参数来使得这部分中间结果压缩。
或者是可以删除那些时间比较久的文件,可以下面的脚本方式修改进行:
file= 3}’ | while read line; do # 过滤出 hive_ 开头的文件 file= {line##*/} # 得到文件名,比如 hive_2018-06-19_08-02-33_543_5311727044302147693-1 date= {file:5:10} # 文件名里的日期,只有hive_开头的才有,所以上面过滤了
if [[ -n {file:5:10} # 文件名里的日期,只有hive_开头的才有,所以上面过滤了 if [[ -n date ]]; then days= ((( ( ( ( now - (date+ ( d a t e + date))/60/60/24 )) if (( days > days > expired_days )); then dir= lineecho“removeexpiredlog l i n e e c h o “ r e m o v e e x p i r e d l o g dir …” hadoopfs−rm−r−skipTrash h a d o o p f s − r m − r − s k i p T r a s h dir #sleep 1 fi fi done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
hadoop = hadoop
expired_days = 7
now = </span><spanclass="crayon−sy">(</span><spanclass="crayon−v">date</span><spanclass="crayon−h"></span><spanclass="crayon−o">+</span><spanclass="crayon−o"> < / s p a n >< s p a n c l a s s =" c r a y o n − s y "> ( < / s p a n >< s p a n c l a s s =" c r a y o n − v "> d a t e < / s p a n >< s p a n c l a s s =" c r a y o n − h ">< / s p a n >< s p a n c l a s s =" c r a y o n − o "> + < / s p a n >< s p a n c l a s s =" c r a y o n − o "> ( date + % s )
hadoop fs - du / tmp / hive / hive /* | grep ‘hive_’ | awk ‘{print 3}' | while read line; do # 过滤出 hive_ 开头的文件 file= 3}' | while read line; do # 过滤出 hive_ 开头的文件 file= {line##*/ } # 得到文件名,比如 hive_2018-06-19_08-02-33_543_5311727044302147693-1
date = {file:5:10} # 文件名里的日期,只有hive_开头的才有,所以上面过滤了 if [[ -n {file:5:10} # 文件名里的日期,只有hive_开头的才有,所以上面过滤了 if [[ -n date ] ] ; then
days = </span><spanclass="crayon−sy">(</span><spanclass="crayon−sy">(</span><spanclass="crayon−h"></span><spanclass="crayon−sy">(</span><spanclass="crayon−sy"> < / s p a n >< s p a n c l a s s =" c r a y o n − s y "> ( < / s p a n >< s p a n c l a s s =" c r a y o n − s y "> ( < / s p a n >< s p a n c l a s s =" c r a y o n − h ">< / s p a n >< s p a n c l a s s =" c r a y o n − s y "> ( < / s p a n >< s p a n c l a s s =" c r a y o n − s y "> ( ( ( now - </span><spanclass="crayon−sy">(</span><spanclass="crayon−v">date</span><spanclass="crayon−h"></span><spanclass="crayon−o">+</span><spanclass="crayon−o"> < / s p a n >< s p a n c l a s s =" c r a y o n − s y "> ( < / s p a n >< s p a n c l a s s =" c r a y o n − v "> d a t e < / s p a n >< s p a n c l a s s =" c r a y o n − h ">< / s p a n >< s p a n c l a s s =" c r a y o n − o "> + < / s p a n >< s p a n c l a s s =" c r a y o n − o "> ( date + % s - d date ) ) / 60 / 60 / 24 ) )
if ( ( days > days > days > expired _days ) ) ; then
dir = line echo "remove expired log line echo "remove expired log dir …”
</span><spanclass="crayon−e">hadoop</span><spanclass="crayon−v">fs</span><spanclass="crayon−h"></span><spanclass="crayon−o">−</span><spanclass="crayon−v">rm</span><spanclass="crayon−h"></span><spanclass="crayon−o">−</span><spanclass="crayon−v">r</span><spanclass="crayon−h"></span><spanclass="crayon−o">−</span><spanclass="crayon−i">skipTrash</span><spanclass="crayon−h"></span><spanclass="crayon−sy"> < / s p a n >< s p a n c l a s s =" c r a y o n − e "> h a d o o p < / s p a n >< s p a n c l a s s =" c r a y o n − v "> f s < / s p a n >< s p a n c l a s s =" c r a y o n − h ">< / s p a n >< s p a n c l a s s =" c r a y o n − o "> − < / s p a n >< s p a n c l a s s =" c r a y o n − v "> r m < / s p a n >< s p a n c l a s s =" c r a y o n − h ">< / s p a n >< s p a n c l a s s =" c r a y o n − o "> − < / s p a n >< s p a n c l a s s =" c r a y o n − v "> r < / s p a n >< s p a n c l a s s =" c r a y o n − h ">< / s p a n >< s p a n c l a s s =" c r a y o n − o "> − < / s p a n >< s p a n c l a s s =" c r a y o n − i "> s k i p T r a s h < / s p a n >< s p a n c l a s s =" c r a y o n − h ">< / s p a n >< s p a n c l a s s =" c r a y o n − s y "> hadoop fs - rm - r - skipTrash dir
#sleep 1
fi
fi
done
|
如上,我们在删除的时候用了 -skipTrash 参数,此参数这里稍作解释一下:
HDFS 会为每一个用户目录下创建一个回收站目录,即:/user/username/.Trash。比如hive用户:
1
2
3
4
5
6
7
8
9
10
11
|
[ root @ aly - bigdata - hadoop - client ~ ] # hadoop fs -ls /user/hive/
Found 8 items
drwx – – – - hive hive 0 2018 - 06 - 30 11 : 00 / user / hive / . Trash
drwxr - xr - x - hive hive 0 2018 - 06 - 30 11 : 36 / user / hive / . sparkStaging
drwx – – – - hive hive 0 2018 - 06 - 30 11 : 55 / user / hive / . staging
drwxr - xr - x - hive hive 0 2018 - 05 - 16 20 : 33 / user / hive / 2684f9e1c0e99fcb0fd49e2bd52222c1.csv
drwxr - xr - x - hive hive 0 2018 - 06 - 30 11 : 36 / user / hive / _sqoop
- rw - r – r – 3 hive hive 26 2018 - 05 - 16 14 : 21 / user / hive / data
drwxr - xr - x - hive hive 0 2018 - 04 - 18 16 : 39 / user / hive / py
drwxrwx – x + - hive hive 0 2018 - 06 - 26 11 : 20 / user / hive / warehouse
[ root @ aly - bigdata - hadoop - client ~ ] #
|
每一个被执行删除的文件和目录,都会有一个回收周期(fs.trash.interval)。在这个回收周期内,文件不会立即删除,而是被移动到这个回收站目录下面,如果用户发现误删除,可以进行恢复,直接mv回去就可以。当回收周期到达时,HDFS就会将这个文件/目录彻底删除。
CDH下的默认相关配置如下:
在HDFS内部的具体实现就是在NameNode中开启了一个后台线程 Emptier,这个线程专门管理和监控系统回收站下面的所有文件/目录,对于已经超过生命周期的文件/目录,这个线程就会自动的删除它们,不过这个管理的粒度很大。Emptier每隔 fs.trash.interval 分钟就清空一次用户回收站。即先检查每个用户回收站目录,然后删除寿命超过 fs.trash.interval 的目录,最后将当前存放删除的目录 /user/用户名/.Trash/current 重命名为一个 /user/用户名/.Trash/yyMMddHHmm。
如下,current 是当前使用的,每到删除时间,删除超时的最老目录,将当前的currnt重命名为日期时间名,然后新建一个current:
1
2
3
4
|
[ root @ aly - bigdata - hadoop - client ~ ] # hadoop fs -du -h /user/hive/.Trash
46.1 G 138.3 G / user / hive / . Trash / 180701090000
22.4 G 67.1 G / user / hive / . Trash / 180701100000
11.1 G 33.4 G / user / hive / . Trash / Current
|
如果想删除的时候避免回收站这一步,可以在删除的时候指定 -skipTrash 参数。