存储系统01——存储系统框架
存储系统
- 存储系统框架
- 存储系统模块
- 存储系统调用过程
存储系统框架
存储系统包括:配置信息config、存储管理datamanager、服务器service
存储系统模块
- 配置信息模块config
根据storage.conf文件中对应字段内容进行解析,包含:IP、端口号、存储路径、已存储文件信息info等;
{"server_port" : 8081,"server_ip" : " ", "download_prefix" : "/download/", //文件下载的前缀,即url中将包含该字符串,如/download/index.html"deep_storage_dir" : "./deep_storage/", # 压缩存储的路径 "low_storage_dir" : "./low_storage/", # 普通存储的路径"bundle_format":4, #压缩存储的文件类型,由选择的压缩格式确定"storage_info" : "./storage.data" #已存储文件的信息
}
config通过读取.conf文件的配置信息,并保存在Config类中;该模块使用懒汉单例模式,通过static Config *GetInstance()
获取全局唯一单例,并提供多个get接口获取config信息。
GetInstance()
使用双重检查锁定(Double-Checked Locking),避免每次访问资源时都进行加锁操作,降低锁带来的性能开销。
public:// 获取单例类对象static Config *GetInstance(){if (_instance == nullptr){_mutex.lock();if (_instance == nullptr){_instance = new Config();}_mutex.unlock();}return _instance;}
- 存储管理模块datamanager
存储管理模块实现了一个DataManager类,用于管理存储文件storage_info的属性信息,包含:初始化读取Get*()、插入Insert()、更新Update()等功能;
管理的StorageInfo信息为以下结构体内容:
(永久化保存的.data文件为JSON格式,读取、保存操作前需要进行序列化、反序列化)
typedef struct StorageInfo{ time_t mtime_; // 文件的最后修改时间time_t atime_; // 文件的最后访问时间size_t fsize_; // 文件的大小std::string storage_path_; // 文件存储路径std::string url_; // 请求URL中的资源路径bool NewStorageInfo(const std::string &storage_path){.........mtime_ = f.LastAccessTime();atime_ = f.LastModifyTime();fsize_ = f.FileSize();storage_path_ = storage_path;storage::Config *config = storage::Config::GetInstance();........return true;}} StorageInfo;
初始化DataManager类时,调用InitLoad()
从文件读取数据并进行反序列化;
DataManager类使用哈希表table_管理存储信息;哈希表key = URL、value = StorageInfo结构体
;
std::unordered_map<std::string, StorageInfo> table_;
- 服务端http通信模块service
服务端http通信模块是基于libevent库
的一个服务器,通过在libevent
中注册一个事件evhttp_new
后进行事件循环dispatch
,当事件触发后,通过在回调函数GenHandler
中判断请求并执行对应业务;
整个事件启动伪代码如下:
// 初始化环境
event_base *base = event_base_new();
...
// http 服务器,创建evhttp上下文
evhttp *httpd = evhttp_new(base);
...
// 设定回调函数
evhttp_set_gencb(httpd, GenHandler, NULL);
...
// 启动事件循环,开始处理事件
event_base_dispatch(base)
...
存储系统调用过程
服务器启动过程:
- 首先实例化
DataManager类
,获取已经存储的文件信息列表; - 实例化
service类
,调用RunMoudle()
函数启动服务器(evhttp事件循环
); - 客户端建立连接后,服务端根据不同请求(
upload、download、showlist
)触发事件的回调函数执行不同的任务。
(用户刷新前端界面时,后端返回新的index.html
中的文件内容给浏览器)