一种磁盘上循环覆盖文件策略
2023-12-21 18:14:04
1. 前言
实际开发中经常需要存储数据, 无论是存储日志,还是二进制数据(图片,雷达数据或视频文件等), 不能一直存,是否存在一种策略:
当磁盘空间不足时,优先删除最开始写入的数据呢?
循环覆盖的策略应该有很多,这篇文章抛砖引玉,希望更多个伙伴给出更好的方案出来!
2. 软件设计流程思路
这里只提供思路,具体实现按照客户需求做多样化,最好写个抽象基类出来,后续可以多态各种需求。
- 初始化(挂载点/循环覆盖阈值T, 每次覆盖后预留一定的比例,比如覆盖阈值75,当使用率到了75后,删除的比例为5,那么删除后比例为70,)
- 策略有很多,看客户需求:
- 按照比例删除, 比如超过阈值,删掉{超过部分+一定过度,大概为5%~10%比例均可}。
- 按照时间删除,比如超过比例,删除掉最早日期的数据,如果日期内数据小,会导致删除频率高,这里多考量下多目录多文件情况下的事件复杂度(目录遍历) && CPU占用比例实际等,是否影响到系统性能。
- 组合删除。
- 空闲删除,某种方式设备休眠时做删除动作{主业务不启用等}。
- 策略有很多,看客户需求:
- 线程监测{按照比例删除流程}
- 监测
磁盘分区
当前使用比例。 - 比较使用比例和循环覆盖阈值T, 当大于阈值比例时, 计算需要删除的比例DT, 通过(总大小乘 DT )计算删除的数据大小。
- 对磁盘文件做递归查询,将非目录文件部署到数组中(std::vector>。
- 通过文件属性拿到写操作的时间戳, 通过STL的算法sort按照时间戳做降序/升序排序,得到 std::vector{sort}的数组。
- 开始删除文件,这里需要注意std::vector<> erase坑。
- 每次删除成功记录实际删除的大小。
- 通过这个实际删除大小和理论删除对比,如果{>=}就停止, 调试线程开始。
- 因为目录中的文件可能都删除了,所以需要检测空目录的情况,当有空目录就删除。
- 监测
3. 模拟测试
3.1 分区准备工作
- 通过fdisk工具分区,假设我们分1个区域/dev/mmcblk1p1
- 格式化
mkfs.ext4 /dev/mmcblk1p1
- 挂载 mount -t ext4 /dev/mmcblk1p1 /mywork
3.2 模拟写数据
- 格式化后分区大小为0
- 使用dd命令写操作, 如下是写的一个自动化写数据elf文件源码
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
int main(int argc, char *argv[])
{
if(argc < 5){
printf("Usage: ./a.out <创建文件数量> <创建文件大小MB> <创建文件间隔 S> <拷贝目录绝对路径>\n");
return -1;
}
std::string strcmd("");
int nFileCount = atoi(argv[1]);
int nFileSize = atoi(argv[2]);
int nTimeSpan = atoi(argv[3]);
std::string dir = argv[4];
printf("创建文件数量:%d, 创建文件大小为:%d, 创建文件间隔:%d 拷贝的目录:%s\n", nFileCount, nFileSize, nTimeSpan, dir.c_str());
for(int i = 0; i < nFileCount; ++i){
strcmd =std::string( "dd if=/dev/zero of=") + dir + "/"+std::to_string(time(0))+"_"+std::to_string(i+1)+".file bs=1048576 count=" + std::to_string(nFileSize);
printf("cmd:%s\n", strcmd.c_str());
FILE * fp = popen(strcmd.c_str(), "r");
if(nullptr == fp){
printf("pipe error .\n");
exit(127);
}
printf("create %02d , size:%d MB\n", i+1, nFileSize);
fclose(fp); fp = 0;
sleep(nTimeSpan);
}
return 0;
}
运行日志如下:
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141122_91.file bs=1048576 count=100
create 91 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.40722 s, 30.8 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141125_92.file bs=1048576 count=100
create 92 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.47826 s, 30.1 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141129_93.file bs=1048576 count=100
create 93 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.28752 s, 31.9 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141132_94.file bs=1048576 count=100
create 94 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.49482 s, 30.0 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141136_95.file bs=1048576 count=100
create 95 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.62826 s, 28.9 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141139_96.file bs=1048576 count=100
create 96 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.27876 s, 32.0 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141143_97.file bs=1048576 count=100
create 97 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.32141 s, 31.6 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141146_98.file bs=1048576 count=100
create 98 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.30286 s, 31.7 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141149_99.file bs=1048576 count=100
create 99 , size:100 MB
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.28151 s, 32.0 MB/s
cmd:dd if=/dev/zero of=/home/ubuntu/pic/6/1703141152_100.file bs=1048576 count=100
create 100 , size:100 MB
3.3 测试
- 开启一个窗口对分区写文件,执行
a.out 100 512 0.5 $PWD/2
, 命令行的含义上面的代码有解释。 - 当模拟写的过程中,磁盘使用率越来越大。当到阈值T时,会对最早写的数据做删除动作,直到删除了
超出阈值+一定的缓冲,一般给5%~10%足够
。 - 进入到目录中,确认目录中文件是否是先删除时间戳最早的文件。
文章来源:https://blog.csdn.net/nc_linux/article/details/135132222
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!