上亿文件PB级数据治理

上亿文件PB级数据治理

Date: Jun 4, 2021

背景介绍

平台提供了专门的训练存储给用户进行日常训练使用;

随着用户数据量的增加,存储虽然经历了几次扩容依然不够用;

分析用户数据,发现有很多数据是训练的中间产物,不过很少有用户及时删除,直到配额满了影响现有任务后才会想着删除数据;

根据这种情况,平台定期执行了自动清理数据策略;

自19年11月至今已有效删除文件数9亿+;文件量1.7PB+

近期整理里下相关内容,现分享出来,与大家共同交流

1、规则制定

从背景可以看出,任务的重点是找到用户的临时数据并删除;

由于数据是训练数据,可以由原始数据再次生成,因此为了后续清理的便捷,需要用户区分出存储中的非训练数据,如原始数据、训练工具等;并将这类数据转移至对应存储上

与用户沟通,普遍反映,训练数据保留2-3个月即可,部分用户有些文件可能需要长期保存

最终定下的清理规则如下:

1、平台检索出训练存储中用户2个月未访问的文件,并将文件列表和目录列表公示给用户

2、用户根据平台给出的文件、目录列表,区分出重要数据反馈平台

3、平台根据用户反馈,更新文件列表

4、公示阶段结束,平台根据最终的文件列表,将文件移动到待删除区,并发送邮件给用户做最后的检查,如果有数据是需要的,从待删除区自行mv回原来对应的目录下;并给出最终时间点,和用户沟通后定为3天

5、用户最终确认阶段结束后,平台先检索出待删除区各个用户的文件数、文件总量、整体的文件数、文件总量;之后执行删除操作;删除操作完成后发送最终总结邮件给用户,包括哪些人参加了清理、每个用户清理的数据量是怎样的。

6、计划每个月执行一次

2、实际操作

规则制定完成后,需要根据规则完成各个阶段的代码编写,需要保证效率及正确性,还需要考虑到部分用户的特殊需求

2-1、检索阶段

第一个拦路虎就是检索阶段,由于训练存储达到了PB级别,文件数有几十亿个,如果仅仅使用find命令,时间上不允许。

经过几个月的调研,最终决定使用mpifileutils;现在来看完全是个神器;这个后续会另写一篇详细介绍;整个自动清理用到了这个工具集中的dfind(检索阶段)、dwalk(统计阶段)、drm(删除阶段)

整体思路:

  1. 使用dfind生成每个用户的文件索引数据库;
  2. dfind读取数据库,生成文件列表和目录列表
  3. 发送自动清理启动邮件,检索阶段结束(对应规则中的1号规则)

下面给下各个阶段的代码(非原代码):

1、dfind 生成数据库:(find_tmp_create,.sh)

#!/bin/bash
# host: xx.xx.xx.xx #这个是执行dfind的主节点,dfind需要结合mpi使用,开启多进程加速整个检索过程
mkdir /storage/delete_2mouth/group/dfind_tmp #这里的storage就是训练存储,dfind_tmp存储放的是这个组内所有人的文件索引数据库
echo `date +%F-%T` >> log 
for user in `ls /storage/group` # 这个目录是用户数据存放目录
do
echo $user >> log
mpirun --allow-run-as-root -machinefile /root/dfind/hostf -mca btl_tcp_if_include netdev --oversubscribe -np 150 dfind \ 
--type f --atime +60 --size +50KB /storage/group/$user -o /storage/delete_2mouth/group/dfind_tmp/$user"_tmp" >> log 
done
# 这里的netdev是指定主节点和子节点交互时使用的网卡名,需要根据实际指定

2、dfind读取数据库,生成文件列表和目录列表(qfind.sh username)

mkdir /storage/delete_2mouth/group/check_xxxxxxx #根据检索的日期创建check目录

cd /storage/delete_2mouth/group/check_xxxxxxx

执行方法:

mkdir /storage/delete_2mouth/group/check_xxxxxxx #根据检索的日期创建check目录
cd /storage/delete_2mouth/group/check_xxxxxxx
for user in `ls /storage/group`
do
qfind $user
done

qfind.sh:

#!/bin/bash

#start load environment 加载mpi环境,执行过程中可能需要使用到dfind
echo "[`date +%F-%T`] start load environment"
module load /opt/tool/modulefiles/spack/spack # 这里将mpifiutils装在了opt中并配置了module (module的使用后续再另写文章)
. /opt/tool/spack/share/spack/setup-env.sh
spack load mpifileutils
module load /opt/tool/modulefiles/mpi/openmpi-3.1.1

#config
multinum=`lscpu | grep '^CPU(s):' | awk '{print $2}'`
echo $multinum

#find filelist
echo "[`date +%F-%T`] start find $1 file"
mkdir $1
echo "[`date +%F-%T`] start find $1 file" >> $1/$1"_checklist"
echo >> $1/$1"_checklist"

if [[ ! -f /storage/delete_2mouth/group/dfind_tmp/$1"_tmp" ]];then #如果索引库中没有索引
  days=60
  echo "start to dfind $1 $days ago files"
	mpirun --allow-run-as-root  --oversubscribe -np $multinum dfind --type f --atime +60 --size +50KB /storage/group/$1 \
  -o /storage/delete_2mouth/group/dfind_tmp/$1"_tmp" >> $1/$1"_checklist" 2> $1/$1"_errlist"
fi

if [[ ! -f /storage/delete_2mouth/group/dfind_tmp/$1"_tmp" ]];then #再次判断,当用户文件中没有匹配的文件,索引库不会生成
  > $1/$1"_filelist"
	> $1/$1"_filelist_tmp"
else
	dfind -i /storage/delete_2mouth/group/dfind_tmp/$1"_tmp" --type f --atime +60 --print |grep -v "] Read" |sed 's#\\#\\\\#g' > $1/$1"_filelist_tmp" 
fi # 这里sed是对特殊的目录名或文件名做处理,比如中文的(、?等

#check link file
# 这里把link文件检索出来,不处理
if [[ -s $1/$1"_filelist_tmp" ]];then #再次判断,当用户文件中没有匹配的文件,索引库不会生成
	echo "$1/$1'_filelist_tmp' is not empty ,start to check "
	dfind -i /storage/delete_2mouth/group/dfind_tmp/$1"_tmp" --type l --atime +60 --print |grep -v "] Read" |sed 's#\\#\\\\#g' > $1/$1"_filelist_tmp_line" 
fi # 这里sed是对特殊的目录名或文件名做处理,比如中文的(、?等

if [[ -s $1/$1"_filelist_tmp_line" ]];then # 如果link存在,需要结合tmp去重
	cat $1/$1"_filelist_tmp_line" $1/$1"_filelist_tmp" | sort | uniq -c | grep '^[ \t ]*1' | sed 's/[ \t ]//g' |grep -v "用户需要保留的文件目录" \
	> $1/$1"_filelist"
esle #如果没有链接文件,则从tmp中去除用户需要保留的文件
	cat $1/$1"_filelist_tmp" | sort | uniq -c | grep '^[ \t ]*1' | sed 's/[ \t ]//g' |grep -v "用户需要保留的文件目录" > $1/$1"_filelist"
fi

#dirlist create #这里根据用户文件列表生成目录列表,以便用户查看
echo  >> $1/$1"_checklist"
cat $1/$1"_filelist" | awk -F '/' '{for (i=1;i<NF;i++){printf ("%s",$i"/")}{ print '\n' }}' |sort -u > $1/$1"_dirlist" 2> $1/$1"_errlist"

chown -R $1:group $1 #修改目录权限,让用户查看或修改

3、发送自动清理启动邮件,检索阶段结束

2-2、移动阶段(规则4)

这个阶段就是根据上个阶段生成的文件列表进行移动操作,由于代码较多,这里懒得打字改截图了 0.0!
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

2-3、删除阶段

这个阶段就简单了,先dwalk统计下数据,在drm删除就行了
在这里插入图片描述
查看删除总量:
在这里插入图片描述
这里可以看到最新一次删除的数据有160T左右

删除过程中,对存储造成了较大压力,减少并行度后有所缓解
在这里插入图片描述

3、待优化点

整个过程中还有一些待优化的点,目前没有找到好的解决办法:

  1. 单个用户文件过多,检索时长过大;目前文件数在一个亿以内的检索时间还可以接受,但是部分用户数据量达到了十几亿,这种目前只能让用户自己管理
  2. mv操作时最后的mvscript是将所有单个目录的移动操作放到一个脚本里后台执行,目前负载最多能hold 1万左右;更多的话就不行了,另外这种才做比较low,后续得想办法优化;比如加个判断,如果目录下所有文件都需要mv,则mv整个目录;这个现在还没想好怎么弄
  3. 整个流程还不够自动化,后续可以考虑进行封装
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值