当前位置: 首页 > news >正文

一种磁盘上循环覆盖文件策略

目录标题

  • 1. 前言
  • 2. 软件设计流程思路
  • 3. 模拟测试
    • 3.1 分区准备工作
    • 3.2 模拟写数据
    • 3.3 测试

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%足够
  • 进入到目录中,确认目录中文件是否是先删除时间戳最早的文件。
http://www.lryc.cn/news/264330.html

相关文章:

  • elementui消息弹出框MessageBox英文内容不换行问题
  • WPF——样式和控件模板、数据绑定与校验转换
  • 服务器数据恢复-raid5故障导致上层分区无法访问的数据恢复案例
  • 石器时代H5小游戏架设教程
  • 计算机网络-网络协议
  • 多维时序 | MATLAB实现KOA-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测
  • 业务出海如何快速将站点搬迁到AWS云中?
  • ansible剧本playbook
  • .NET 中string类型的字符串内部化机制
  • 公共字段自动填充——后端
  • nginx upstream 6种负载均衡策略介绍
  • 基于Antd4 和React-hooks的项目开发
  • Spring中用到的设计模式
  • 常用网络接口自动化测试框架
  • 【重点】【贪心】55.跳跃游戏
  • 灰度化、二值化、边缘检测、轮廓检测
  • 基于JAVA的高校大学生创业管理系统 开源项目
  • 神经网络学习小记录76——Tensorflow2设置随机种子Seed来保证训练结果唯一
  • ai学习笔记-入门
  • workflow系列教程(5-1)HTTP Server
  • php-使用wangeditor实现富文本(完成图片上传)-npm
  • mysql查看数据库中所有的表的建表语句
  • 【Axure RP9】实现登入效验及实现左侧菜单栏跳转各页面
  • 76. 最小覆盖子串。优化官方题解!
  • 在国产GPU寒武纪MLU上快速上手Pytorch使用指南
  • 重生奇迹MU觉醒战士攻略
  • 美颜技术详解:深入了解视频美颜SDK的工作机制
  • 3D模型格式转换工具如何实现高性能数据转换?请看CAE系统开发实例!
  • 多级缓存:亿级流量的缓存方案
  • C语言——高精度乘法