1.思路来源
某机关单位所使用的某达OA系统,基于Windows server服务器安装,其电子邮件功能使用得非常频繁,由于其工作性质的原因,邮件中的附件往往非常大,经常给服务器撑爆,以往处理方式是发现系统使用异常后手动将数月前的文件移动到其他磁盘去,当然这也会导致移走的文件就无法从OA平台上面下载了,若实在是有需要时,就依据文件名从服务器中手动的拷贝出来,这种的使用体验感非常不好,OA厂家也无法给出较好的解决方法。
单位领导咨询到我,让我找找有没有未使用、硬盘比较大、性能比较好的服务器,当作新OA服务器。当我了解到文件的存储逻辑后,想到无论怎样磁盘终将会有满的时候,又看到机房有许多旧的某康存储设备,于是给出建议使用存储设备挂载到服务器上,用作扩展存储(本身支持SAN协议,挂载上去之后跟本地磁盘无区别),让OA厂家将附件的存储路径修改至新挂载的位置。
修改后测试并未发现有何不妥,业务均正常,遂汇报此方案更改成功。过了一段时间,大家都需要报材料,用户并发量上来了,反应OA打不开/非常卡,于是都认为是我建议使用的存储设备导致的。
听到此消息时很无奈,好心办了坏事,但逻辑上说不通啊,去看了存储的读写、网络性能等,占用都是非常低的,再看了一下服务器的读写,发现了速度非常低,测试了一下拷贝大文件,速度也非常慢,并且会导致服务器变卡,拷贝完成后恢复正常,结合他们平时使用平台时也会卡顿的情况分析,这显然不符合服务器的正常逻辑,我再去跟领导汇报,认为这是服务器硬盘原因导致的(机械硬盘,使用了3-4年左右),演示了这个服务器拷贝文件的时候会卡,其他服务器拷贝文件的时候就是正常的(能说通就没找工具检测),建议换硬盘或换服务器,又去机房找了一番,找到一台闲置的服务器,固态盘、双CPU,性能是足够了,让他们找人重装系统后OA厂家迁移了平台,使用就变得非常流畅了,下午看了用户并发量,同时在线200-300人,但也再也没人反应OA卡的情况。
5块固态盘做RAID5后,存储空间也有限,按照往月数据量,大概6个月时间也会存储满的,领导又想把存储路径修改到存储设备上去,以便扩展存储空间,但是由于之前的怀疑,我就拒绝了,免得后期出现问题再找我。
我先是使用了文件同步工具,将本地磁盘的文件单向同步到存储设备挂载的磁盘,这样满的时候他们直接删除旧的文件即可,数据也不会丢失,再想的是大不了写个脚本,定期删除文件,就不用手动去删了。尽管他们之前就是这样操作的,但这样还是会导致用户的使用感不好,删掉的文件没办法再直接从OA平台上下载,遂想出了以下方式。
2.理论依据
在以往维护Linux系统时,日常升级程序时报错了,升级的逻辑是停止程序→备份程序→替换程序,查询日志显示备份程序出错,去对应的路径查看发现是程序路径下存在一个失效的软链接,删除了即可。出于好奇就去了解了一下软链接是啥,了解完后知识点+1。
于是乎联想到这个OA服务器是否能使用此方式迁移文件?这里就把服务器本地磁盘的存放的数据叫做热数据,存储设备挂载的磁盘叫做冷数据。
热数据保存3个月,而冷数据一直在单向同步热数据:那这样就是3个月前的数据只存在于冷数据中,3个月内的数据即存在与热数据又存在于冷数据中。再将冷数据通过软链接的形式放在热数据的路径下,因为从使用层面上来说软链接与原始文件并没有任何区别,就相当于是复制了一份。即使存储设备坏了,但近3个月的数据还是存放在服务器中,服务器坏了跟我就没关系了。
而该OA系统,附件是存放在按“年月”来命名文件夹中,例如2024年3月份产生的附件就存放在 2403 文件夹内,通过判断文件夹名称就能知道文件是什么时候的了。
3.方案实现
1).单向备份
要想使文件从磁盘D自动定期同步到存储设备挂载的磁盘F上去,最好的方式就是使用现成的同步软件,我使用的是Goodsync( https://www.52pojie.cn/thread-1731991-1-1.html 机关单位是涉密的内网环境,征求了领导意见,就直接使用了非官方版,请支持正版!),具体使用教程就不详述了,我创建的是“从左往右备份(单向)”,取消勾选触发删除,由于后期会在左边的文件创建软链接,但这个又是不需要同步备份的,故需要在过滤器的排出项中添加 issymlink (官方文档地址https://www.goodsync.com/manual#filters ),以便在同步时能排除软链接,同步周期设定的是每日凌晨。
2).文件对比
上述操作能实现文件的自动同步,理论上不存在失败的情况,但以防万一,加入了校验功能,直接获取原始文件夹下指定月份文件夹的大小,与备份路径下对应的文件夹的大小进行对比,对比一致就可以浅显的认为文件都已经备份过来了,就可以执行删除操作,获取文件夹的总大小可使用如下代码:
import os
def fileSize(path_add):#获取文件夹大小
try:
size = 0
# 遍历并装载第一层的文件和文件夹
list = os.listdir(path_add)
for i in list:
# 拼接成完整的绝对路径
pathfile = os.path.join(path_add,i)
if os.path.isfile(pathfile):
# print(i," is FILE")
#print(pathfile)
size += os.path.getsize(pathfile)
# 文件夹 OR NOT
elif os.path.isdir(pathfile):
# print(i," is FOLDER")
#print(pathfile)
T,s = fileSize(pathfile)
size += s
return True,size
except Exception:
return False,str(sys.exc_info()[1])
调用fileSize函数传入文件夹路径即可返回总大小。为了严谨起见还可以通过递归获取文件的md5值进行对比判定文件是否一致,但这对比非常耗费时间,就不采用此严谨的方式。
参考链接:https://www.cnblogs.com/chengd/p/7298874.html
3).删除原始文件
有了2)的判断,证明文件已经备份成功,就可以大胆的执行删除操作,代码如下:
import shutil,os
def delete(path):#删除文件夹
try:
#os.removedirs(path)
shutil.rmtree(path)
return True,f"成功删除文件夹 {path}!"
except OSError as e:
return False,f"删除文件夹 {path} 失败: {e}"
调用 delete 函数传入文件夹路径即可实现删除指定文件夹操作。
4).创建软链接
通过3)的删除,才能创建一个与原文件夹同名的软链接,创建软链接代码如下:
import os
def symlink(source_file, target_link):#创建软链接(源路径、目标路径)
try:
# 创建软链接
os.symlink(source_file, target_link)
#print("成功创建软链接")
return True,f'成功创建软链接{target_link}!'
except OSError as e:
#print(f"创建软链接失败: {e}")
return False,f"创建软链接失败: {e}"
特别注意!此执行此需要管理员权限!!!
5).文件夹日期判断
由于文件夹是按日期命名,符合"%y%m"
规则,直接将文件夹名称转换为时间戳格式,再与当前时间戳进行对比,就能知道文件夹建立多久、是否过期了,代码如下:
import os,time
def outdate(path):
Filelist = os.listdir(path)#获取路径下的文件夹名,列表形式
for i in Flist:
try:
struct_time = time.strptime(i, "%y%m")#格式化时间
timestamp = time.mktime(struct_time)+10000#转换成时间戳并加上10000秒,这10000秒就是设定的过期时间
if timestamp < time.time():#如果文件夹名的时间+1000秒后比现在的时间小,表示已经过期了,例如120秒过期,现在是12:30,文件名对应的日期是12:29,12:29+120秒等于12:31,12:31>12:30的,证明文件没有过期
Newlist.append(i)#将过期的文件名放入Newlist列表中,后续在此列表操作就行
except Exception:
print ("此目录不满足规范"+ str(sys.exc_info()[1]))
print ("获取到的:"+str(Filelist)+",过滤后的:"+str(Newlist))
return Newlist
6).整体逻辑
将上述4个函数通过组合、增加判断、循环等就能实现完整的功能,我是打包成exe文件后,通过任务计划程序定时实现,不同的现场有不同的需求,我的代码并不能匹配每一个现场,故此处只分享逻辑和关键代码,不提供完整源码和成品软件,有需要的自行完善,有疑问共同探讨!
4.展望
以上介绍的方式已成功实现,运行数月无任何问题。
其实使用软链接的方式来迁移C盘安装的软件至其他磁盘,解放C盘空间,完全也是可以的
占用空间大的都是软件的安装目录,例如MS office的安装目录在C:\Program Files\Microsoft Office
,在完全退出MS office的情况下(建议在安全模式或PE下的cmd执行,某些程序手动很难完全退出),直接把"Microsoft Office" 整个文件夹复制到其他磁盘(这儿就复制到D:\Program Files\Microsoft Office
),再彻底删除C:\Program Files\
下的"Microsoft Office"文件夹,使用(管理员运行cmd执行)
mklink /d "C:\Program Files\Microsoft Office" "D:\Program Files\Microsoft Office"
这样建立软链接后就可以了,亦可在Python中使用4)中的函数(也要管理员权限运行)来创建软链接,理论上任何软件在彻底退出程序后都能使用这个方式无损的迁移安装路径,从而达到解放C盘的目的。
软链接相关介绍
https://www.cnblogs.com/cnxkey/articles/7658462.html
https://www.cnblogs.com/Naylor/p/7597869.html
https://www.jianshu.com/p/b1614a073087