空中加油: Harbor 2.1的非阻塞垃圾回收
题图摄于温哥华港
注:微信公众号不按照时间排序,请关注“亨利笔记”,并加星标置顶,以免错过更新。
本文介绍 Harbor 2.1 的非阻塞镜像垃圾回收功能,可以一边进行正常的镜像管理任务,一边默默地执行垃圾回收任务,如同飞机的空中加油,无需中断飞行。部分内容节选自最新出版的《Harbor权威指南》(详情参见文末),相关作者为 Harbor 开源项目维护者王岩,欢迎扫码或点击“阅读原文”购买。
垃圾回收(Garbage Collection)是计算机系统常见的一种资源管理方式,由John McCarthy 在 1959 年发明并在 Lisp 语言中应用。对,就是那位大名鼎鼎的、提出了人工智能概念并被誉为“人工智能之父”的 John McCarthy。
顾名思义,垃圾回收是指把系统中不再使用的资源(即垃圾)释放并且使其可被重新使用。程序员在 Java、Python、Go 等现代编程语言中可能都了解过垃圾回收的概念,即释放程序中不再使用的数据所占用的内存,从而腾出空间存放其他数据。垃圾回收由语言的运行时(runtime)在后台来处理,对程序员一般是透明的,程序员写代码的时候无需(或者无法)干预垃圾回收的过程。这样的设计避免了程序员去关注复杂的内存管理机制。
当然,垃圾回收也有个很大的不足之处:一般需要有阻塞的时间,就是不定期地暂停前台程序的执行,来处理后台的垃圾回收工作。取决于需要回收的垃圾数量,暂停程序的执行可能会持续比较长的时间,因此,对响应时间敏感的应用这个矛盾尤为突出。为此,人们设计了多种垃圾回收的执行方式,如并发回收、分代回收等,目的是减少程序执行“骤停”的时间或频率。
Harbor 作为镜像等云原生制品的仓库,为了释放不再使用的镜像所占的存储空间,也需要定期进行垃圾回收工作。 在 Harbor 2.0 及之前的版本中,垃圾回收一直是阻塞式的。也就是说,在 Harbor 系统执行垃圾回收任务时,系统处于只读状态,只能拉取而不能推送镜像。在部分用户的生产环境下,阻塞式的垃圾回收是不能被接受的,这会造成系统从几分钟到几十小时的阻塞状态。虽然建议用户定制周期垃圾回收任务在非工作日的夜间执行,但是并不能从根本上解决问题。
造成垃圾回收任务阻塞和执行时间较长的主要原因有如下两个。
1.层(layer)文件的引用计数
在阻塞式的垃圾回收任务中使用的是Docker Distribution(下简称Distribution)自带的垃圾回收功能,实现流程大致如下。
(1)遍历文件系统,得到每一个共享层文件的引用数量。当一个层文件的引用数量为0时,即为待删除层文件。
(2)在得到所有待删除的层文件后,调用存储系统的删除接口,依次删除层文件。
在计算层文件引用计数的过程中,如果此时用户正在上传镜像,则垃圾回收可能会删除正在上传的层文件,从而破坏镜像。因此,在垃圾回收任务执行时需要阻塞镜像的推送。
同时,因为 Distribution 并没有使用数据库记录层文件的引用关系,所以需要遍历整个存储系统的路径来获取每一个层文件的引用计数。这种遍历方式造成了很大的时间开销,并且所需时间随着层文件数量的增加而线性增加。
2.云存储的使用
在层文件引用关系的遍历和层文件的删除过程中,需要调用存储系统的接口来实现。如果用户使用云存储(如S3)作为存储系统,则存储系统接口调用的时间开销会比本地存储增加很多。
基于以上情况,Harbor 2.1 实现了非阻塞式的垃圾回收功能。该功能的目的是去除垃圾回收任务执行时的系统阻塞,同时提高垃圾回收任务的运行效率,使得 Harbor 可以一边进行正常的镜像管理任务,一边默默地执行垃圾回收任务,如同飞机的空中加油,无需中断飞行。本文将简要介绍非阻塞式的垃圾回收方案的基本思想。
1.Artifact(制品)数据库
在 Harbor 2.0 中,在用户成功推送一个镜像后,Harbor系统会完整记录这个镜像的信息,如下图所示。
从上图可以看出,一个镜像的层文件和其引用关系都被记录在 Artifact 数据库中。同时,在一个镜像被删除后,其层文件的引用关系也被删除。这样一来非阻塞式垃圾回收任务可以通过数据库计算出存储系统中所有层文件的引用计数。当任何一个层文件的引用计数为都0时,该层文件即待删除层文件。相比存储系统的遍历,数据库的计算可以节省大量时间开销。
2.层文件和清单文件删除API
通过数据库得到待删除层文件后,下一步就是将其删除。Distribution 并没有提供删除层文件和清单(manifest)文件的 API,而是暴露公有函数供其自身的垃圾回收任务使用。在非阻塞垃圾回收任务实现中,需要引用 Distribution 的代码来实现层文件和清单文件的删除 API,而删除 API 仅供非阻塞垃圾回收任务使用,不暴露给用户,如下图所示。
3.非阻塞
非阻塞式垃圾回收的核心是在垃圾回收任务运行时,不阻塞用户的镜像等 Artifact的推送。为了达到此目的,这里引入了状态控制和时间窗口机制,下面以镜像为例加以说明。
1)状态控制
在层文件的数据库表中加入了版本和状态列,层文件的每一次状态改变都会增加版本,这样可以通过版本来实现乐观锁。当非阻塞垃圾回收任务执行删除时,会尝试将待删除的层文件标记为“deleting”状态。如果该待标记的层文件刚好被Docker 客户端正在推送的镜像引用,则非阻塞垃圾回收任务的“deleting”标记将会失败。原因是 Docker 客户端在推送过程中发起的 HEAD Blob 请求被 Harbor 中间件拦截,中间件会增加层文件的版本。而非阻塞垃圾回收任务在更新层文件状态为“deleting”时,层文件的版本已经不符合数据库里的最新版本信息,导致更新失败,如下图所示。
2)时间窗口
在推送 Docker 客户端的过程中,Docker 客户端首先会推送层文件,而此时的层文件在系统中的引用计数为0,只有当清单文件推送成功后,Harbor 才会建立引用关系,使得这些层文件的引用计数非0。为保证在非阻塞垃圾回收任务执行中,用户正在推送的层文件不被删除,需要引入时间窗口概念。在层文件的数据库表中加入更新时间列,非阻塞垃圾回收仅作用于更新时间早于非阻塞垃圾回收起始时间两小时的层文件。在时间窗口内推送的层文件都会被保留,如下图所示。
在 Harbor 2.1 推出了非阻塞垃圾回收之后,解决了镜像运维的一个痛点,得到许多用户的点赞,有用户发出了“期待已久”的感叹。正如上期文章所说,这又是运维工程师一个保护”发际线“的功能,快来试试吧,欢迎留言告诉我们你使用的情况如何。
新书消息:
《Harbor权威指南》是第一本全面介绍 Harbor 云原生制品仓库的书籍,由 Harbor 开源项目维护者和贡献者倾力撰写,其中不乏 Harbor 项目的创始成员,甚至 Harbor 原型代码的设计者和编写者。很多用户关心的内容在本书有详尽讲解,如:Harbor 的架构原理;OCI 制品的支持方式;高可用制品仓库系统的设计要点;镜像等制品的扫描;制品的远程复制、权限和安全策略;备份与恢复策略;API 使用指南;成功案例;社区维护治理等,是Harbor用户和开发者非常理想的参考资料。
无论是对于Harbor的用户、开发者和贡献者,还是云原生软件开发工程师、测试工程师、运维工程师、IT架构师和IT技术经理,抑或是计算机相关学科的高校学生来说,本书都有非常重要的指导和参考价值。
扫码可直接在京东购买,或点击“阅读原文”购买:
要想了解云原生、区块链和人工智能等技术原理,请立即长按以下二维码,关注本公众号亨利笔记 ( henglibiji ),以免错过更新。
空中加油: Harbor 2.1的非阻塞垃圾回收相关推荐
- Java 理论与实践: 非阻塞算法简介——看吧,没有锁定!(转载)
简介: Java™ 5.0 第一次让使用 Java 语言开发非阻塞算法成为可能,java.util.concurrent 包充分地利用了这个功能.非阻塞算法属于并发算法,它们可以安全地派生它们的线程, ...
- 那些年让你迷惑的阻塞、非阻塞、异步、同步
点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 在IT圈混饭吃,不管你用什么编程语言.从事前端还是后端,阻塞.非阻塞.异步.同步这些概念,都需要清 ...
- Java 理论与实践: 非阻塞算法简介
在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情.Java 语言中主要的同步手段就是 synchronized 关键字(也称为内在锁),它强制实行互斥,确 ...
- 并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究
并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究 http://www.importnew.com/25668.html 一. 前言 常用的并发队列有阻塞队列和非阻塞队列 ...
- Java 理论与实践: 非阻塞算法简介--转载
在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情.Java 语言中主要的同步手段就是synchronized 关键字(也称为内在锁),它强制实行互斥,确保 ...
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...
- 面试必会系列 - 5.1 网络BIO、NIO、epoll,同步/异步模型、阻塞/非阻塞模型,你能分清吗?
本文已收录至 Github(MD-Notes),若博客中图片模糊或打不开,可以来我的 Github 仓库,包含了完整图文:https://github.com/HanquanHq/MD-Notes,涵 ...
- 阻塞/非阻塞/同步/异步方法和多线程的关系?没有任何关系,俩不挨着
1.阻塞非阻塞异步同步是针对方法说的,是评判一个方法运行状态的.和多线程完全两个级别. 2.阻塞非阻塞异步同步是针对方法说的,是评判一个方法运行状态的.和多线程完全两个级别. 3.阻塞非阻塞异步同步是 ...
- Java中的NIO非阻塞编程
在JDK1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞API.对于大多数应用来说,这样的API使用很方便,然而,一些对性能要求较高的应用,尤其是服务端应用,往往需要一个更为 ...
最新文章
- MongoDB(一):安装
- k8s安装工具:sealos设计原理及离线包结构分析
- listView无需适配器添加数据(写demo快速开发)entries属性的特殊用法
- springboot+jpa+mysql+redis+swagger整合步骤
- 终于有人把云计算、大数据和人工智能讲明白了! (2)
- linux开启多个matlab_Linux下启动Matlab
- python爬取全国真实地址_python爬虫学习之爬取全国各省市县级城市邮政编码
- 串口通讯---实现 PC 端之间串口连接传输文件
- VVC之SCC(一):IBC
- selected和checked区别
- 2cm有多长实物图_2cm 2cm有多长实物图
- 数据挖掘实战应用案例精讲-【概念篇】数据湖(补充篇)(Data Lake )
- AFM成像表面形貌和表面粗糙度
- Redirect 重定向
- Css3引用外部字体样式---博客园老牛大讲堂
- Idx推出AI系统检测糖尿病视网膜病变
- python gui编程for mac_Python IDE 开发软件-PyCharm pro for Mac
- Bugly 多渠道热更新解决方案
- springboot整合rocketMQ记录 实现发送普通消息,延时消息
- 笔记本电脑的S0-S5的状态