【云备份】服务端模块-热点管理

文章目录

0.回顾extern

extern cloudBackup::DataManager *_dataManager

extern 关键字用于声明一个全局变量或对象,而不定义它。这意味着 _dataManager 是一个指向 cloudBackup::DataManager 类型的指针,但它的定义(即实际内存分配)在其他地方,而不是在当前文件中

所以, 你可以理解为: 这行代码告诉编译器 _dataManager 是在其他文件中定义的,并且这个指针在另外文件中已经初始化过了。这样做的目的是让当前文件可以访问 _dataManager,尽管它的定义是在另一个文件中

也就是说, _dataManager在HotManager.hpp中进行声明, 说有一个_dataManager这个指针对象。 然后在test.cpp中进行定义。

在test.cpp中 定义一个全局的 _dataManager

1.介绍

服务器端的热点⽂件管理是对上传的⾮热点⽂件进⾏压缩存储,节省磁盘空间。

热点⽂件的判断在于上传⽂件的最后⼀次访问时间是否在热点判断时间之内,⽐如如果⼀个⽂件⼀天都没有被访问过我们就认为这是⼀个⾮热点⽂件,其实就是当前系统时间,与⽂件最后⼀次访问时间之间的时间差是否在⼀天之内的判断。

需要对上传的⽂件每隔⼀段时间进⾏热点检测,相当于遍历上传⽂件的存储⽂件夹,找出所有的⽂件,然后通过对逐个⽂件进⾏时间差的判断,来逐个进⾏热点处理。

将上传的⽂件存储位置与压缩后压缩⽂件的存储位置分开。这样在遍历上传⽂件夹的时候不⾄于将压缩过的⽂件⼜进⾏⾮热点处理了。

关键点:

上传⽂件有⾃⼰的上传存储位置,⾮热点⽂件的压缩存储有⾃⼰的存储位置

遍历上传存储位置⽂件夹,获取所有⽂件信息。

获取每个⽂件最后⼀次访问时间,进⽽完成是否热点⽂件的判断。

对⾮热点⽂件进⾏压缩存储,删除原来的未压缩⽂件。

2.实现思想

热点管理模块: 对服务器上备份的文件进行检测,哪些文件长时间没有被访问,则认为是非热点文件,则压缩存储,节省磁盘空间。

实现思路:

遍历所有的文件,检测文件的最后一次访问时间,与当前时间进行相减得到差值,这个差值如果大于设定好的非热点判断时间则认为是非热点文件,则进行压缩存放到压缩路径中,删除源文件。

法一:遍历数据管理模块中backupAInfo.dat

  1. 从数据管理模块中遍历所有的备份文件信息
  2. 遍历备份文件夹,获取所有的文件进行属性获取,最终判断

法二:直接遍历备份文件夹backupDir。

遍历文件夹,每次获取文件的最新数据进行判断,并且还可以解决数据信息缺漏的问题

  1. 遍历备份目录,获取所有文件路径名称
  2. 逐个获取最后一次访问时间与当前系统时间进行比较判断
  3. 对非热点文件进行压缩处理,删除源文件
  4. 修改数据管理模块对应的文件信息(压缩标志->true)

3.代码

cpp 复制代码
#ifndef __MY_HOT__
#define __MY_HOT__
#include <unistd.h>
#include <memory>
#include "dataManager.hpp"

//在多个文件中使用 _dataManager 确保它在每个文件中都被声明为extern 但只在一个源文件中被定义
//声明全局变量_dataManager 在其他文件中定义 
//extern cloudBackup::DataManager *_dataManager;
extern std::shared_ptr<cloudBackup::DataManager> _dataManager;

namespace cloudBackup
{
	class HotManager
	{
	private:
		std::string _backupDir; // 备份文件路径
		std::string _zipDir;	// 压缩文件路径
		std::string _zipSuffix; // 压缩文件后缀
		int _hotTime;			// 热点判定时间间隔

		// 热点文件-返回真
		bool isHot(const std::string &filename)
		{
			FileUtil fileUtil(filename);
			time_t last_atime = fileUtil.LastATime();
			time_t cur_time = time(NULL);
			if (cur_time - last_atime > _hotTime)
				return false;
			return true;
		}

	public:
		HotManager()
		{
			Config *config = Config::GetInstance();
			_backupDir = config->GetBackupDir();
			_zipDir = config->GetZipDir();
			_zipSuffix = config->GetZipSuffix();
			_hotTime = config->GetHotTime();

			//Q
			FileUtil tmp1(_backupDir);
			FileUtil tmp2(_zipDir);
			tmp1.CreateDirectory();
			tmp2.CreateDirectory();
		}

		// 死循环
		bool RunHotManager()
		{
			while (true)
			{
				// 1. 遍历备份目录 获取所有文件名
				FileUtil fileUtil(_backupDir);
				std::vector<std::string> array;
				fileUtil.ScanDirectory(&array);

				// 2. 遍历判断文件是否是热点文件
				for (auto &file : array)
				{
					if (isHot(file) == true) // 热点文件则不需要特别处理
						continue;
					// 3. 获取文件的备份信息
					BackupAInfo info;
					// 文件存在 但hashmap中没有备份信息 考虑差错:设置该文件的备份信息
					if (_dataManager->GetOneByFileName(file, &info) == false)
						info.NewBackupAInfo(file);

					// 3. 对非热点文件进行压缩处理
					FileUtil tmp(file);
					tmp.Compress(info._zipPath);

					// 4. 删除源文件 修改备份信息
					tmp.Remove();
					info._isZipped = true;
					_dataManager->Update_Table(info);
				}
				usleep(1000); // 避免空目录循环遍历 消耗cpu资源过高
			}
			return true;
		}
	};
}

#endif //__MY_HOT__

测试代码

cpp 复制代码
#include "fileUtil.hpp"
#include "jsonUtil.hpp"
#include "config.hpp"
#include "dataManager.hpp"
#include "hotManager.hpp"
// #include "service.hpp"
#include <thread>
using namespace std;

// 声明全局指针对象 如果声明为局部的
// 当出了作用域 生命周期截止 指针对象销毁 堆空间泄露
// cloudBackup::DataManager *_dataManager;
std::shared_ptr<cloudBackup::DataManager> _dataManager;
void HotTest()
{
	cloudBackup::HotManager hot;
	hot.RunHotManager();
}
int main(int argc, char *argv[])
{
	//_dataManager 的定义在程序其他部分尝试访问它之前就已经完成
	std::shared_ptr<cloudBackup::DataManager> ptr(new cloudBackup::DataManager());
	_dataManager = ptr;
	HotTest();

	return 0;
}

热点管理总结

对备份的文件进行检测,哪些文件长时间没有被访问,则认为是非热点文件,对其压缩存储,节省磁盘空间。

  1. 遍历备份目录 获取所有文件名
  2. 遍历判断文件是否是热点文件
  3. 对非热点文件进行压缩处理
  4. 删除源文件 修改备份信息