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

为什么rsync能够快速删除400000文件?

为什么80%的码农都做不了架构师?>>>   hot3.png

背景 Quora上一篇文章★How can someone rapidly delete 400,000 files?提到通过rsync能够快速删除大量文件,之后在Linux技巧:一次删除一百万个文件的最快方法这篇文章里做了一个详细的评测,对于rm/find/rsync等诸多方法的性能做了对比。

对于出现性能的差异,应该属于预料中的结果。为了验证这个现象,我模拟了Quora原提问的要求,创建了40万个文件,分别用rm和rsync进行删除操作,对syscall做统计。为了简化条件,这写文件全部是空文件(使用包含内容的文件对结果不会造成明显差异,有兴趣可以重试一下)。

统计syscall使用了dtruss工具,这是MacOSX上提供的syscall调试工具,基于DTrace。Linux上可以使用SystemTap来代替。

验证测试步骤 第一步,创建测试文件

mkdir tmp/; seq 1 400000 | xargs -I{} touch tmp/file_{} 创建的目录文件大小约为13M。这个大小指的是目录文件,不包含目录中文件,要注意。

$ ls -dl tmp/ drwxr-xr-x 56513 lax wheel 13062562 6 13 16:18 tmp-test-rsync 第二步,使用dtruss执行rm命令测试

$sudo dtruss -c 'rm -rf tmp-test-rm/'

CALL COUNT __mac_syscall 1 audit_session_self 1 bsdthread_register 1 exit 1 fstatfs64 1 getaudit_addr 1 getegid 1 rmdir 1 shared_region_check_np 1 thread_selfid 1 __sysctl 2 close 2 close_nocancel 2 csops 2 getpid 2 ioctl 2 issetugid 2 open 2 open_nocancel 2 pread 2 geteuid 3 fchdir 4 mprotect 8 stat64 34 mmap 93 munmap 184 madvise 205 getdirentries64 2659 lstat64 311901 unlink 400000 第三步,使用dtruss执行rsync命令测试

$sudo dtruss -c 'rsync -a --delete empty/ tmp/'

CALL COUNT __mac_syscall 1 __pthread_canceled 1 audit_session_self 1 bsdthread_register 1 exit 1 fcntl_nocancel 1 fork 1 fstatfs64 1 getaudit_addr 1 getegid 1 getrlimit 1 getuid 1 ioctl 1 lstat64 1 shared_region_check_np 1 shm_open 1 sigprocmask 1 sigreturn 1 thread_selfid 1 umask 1 __sysctl 2 chdir 2 csops 2 getdirentries64 2 getpid 2 lseek 2 pread 2 socketpair 2 fstat64 3 munmap 3 open_nocancel 3 close 4 close_nocancel 4 geteuid 4 issetugid 4 open 4 wait4 6 read_nocancel 7 write 7 mprotect 8 read 10 sigaction 10 fcntl 11 mmap 13 select 21 stat64 35 现象分析 rm rm命令大量调用了lstat64和unlink,可以推测删除每个文件前都从文件系统中做过一次lstat操作。 lstat64的次数低于文件总数,还有另外的原因,之后会在另一篇文章中说明。 getdirentries64这个调用比较关键。 过程:正式删除工作的第一阶段,需要通过getdirentries64调用,分批读取目录(每次大约为4K),在内存中建立rm的文件列表;第二阶段,lstat64确定所有文件的状态;第三阶段,通过unlink执行实际删除。这三个阶段都有比较多的系统调用和文件系统操作。 rsync rsync所做的系统调用很少。 没有针对单个文件做lstat和unlink操作。 命令执行前期,rsync开启了一片共享内存,通过mmap方式加载目录信息。 只做目录同步,不需要针对单个文件做unlink。 另外,在其他人的评测里,rm的上下文切换比较多,会造成System CPU占用较多——对于文件系统的操作,简单增加并发数并不总能提升操作速度。

总结 把文件系统的目录与书籍的目录做类比,rm删除内容时,将目录的每一个条目逐个删除(unlink),需要循环重复操作很多次;rsync删除内容时,建立好新的空目录,替换掉老目录,基本没开销。

结论:频繁做减法不如直接从头来过。

转载于:https://my.oschina.net/panzhc/blog/175687

相关文章:

  • 全键盘操作Windows
  • Android中的后台邮件发送
  • 在Eclispe中新建了一个web项目,没有出现web.xml的原因
  • 样式规则的选择器
  • PostgreSQL安装详细步骤(windows)
  • c++策略模式(Strategy Method)
  • Data Domain和Avamar到底有什么不同呢?
  • pl/sql programming 03 语言基础
  • 【mysql基础】mysql学习笔记-2-存储引擎
  • 如何形成高端战力
  • java acm输入输出
  • Exchange210中的Rpc Client Access server属性
  • mysql5.5 主从复制 (触发器,函数,存储引擎,事件处理)说明
  • jstack dump日志文件详解
  • list模块
  • Angular2开发踩坑系列-生产环境编译
  • C学习-枚举(九)
  • Fundebug计费标准解释:事件数是如何定义的?
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Java编程基础24——递归练习
  • Logstash 参考指南(目录)
  • MobX
  • python 装饰器(一)
  • QQ浏览器x5内核的兼容性问题
  • SpringBoot几种定时任务的实现方式
  • Spring核心 Bean的高级装配
  • 基于HAProxy的高性能缓存服务器nuster
  • 力扣(LeetCode)21
  • 目录与文件属性:编写ls
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 使用docker-compose进行多节点部署
  • 提醒我喝水chrome插件开发指南
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • $$$$GB2312-80区位编码表$$$$
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (办公)springboot配置aop处理请求.
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (七)Knockout 创建自定义绑定
  • (四)库存超卖案例实战——优化redis分布式锁
  • (五)IO流之ByteArrayInput/OutputStream
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转)一些感悟
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .mysql secret在哪_MySQL如何使用索引
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET 使用 XPath 来读写 XML 文件
  • .Net 应用中使用dot trace进行性能诊断
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?