Native cloud era, two programs easily accelerate one million mirrors

 

With the expansion of the cluster size, you ever due to distribution problems plagued the mirror? Depending on the scene, we use a different image distribution method:

 

 

  • CNCF / containerd remote file system snapshot in a remote storage mirroring program directly, the container engine reads image content over a network, to distribute almost no time.

 

 

You will find the second approach relies on network stability. This article summarizes how the dynamic images of the contents read request is loaded from the remote to the local storage of the image as a trade-off, and how to choose a mirror image.

 

Background

 

 

When a small business, a single machine may be a single vessel deployment; but the business volume, and when divided into a plurality of applications, it is necessary to deploy multiple applications on the same machine; a plurality of applications at this time dependent It is a more difficult problem. And run multiple applications at the same time, it has also been interfering with each other.

 

At first, you can use virtual machines to achieve, so that each application a virtual machine, basically there is no dependency conflicts, but the virtual machine still have a slow start, the space occupied by a series of problems and large.

 

As technology behind, with lxc technology, which allows applications to run in a separate namespace, to achieve the operating mode isolation applications.

 

Here you can see the virtual machine to solve the problem of static isolation, lcx solve the isolation problem running state, while Docker is running while addressing the state of isolation and static two problems, so get close friends.

 

Docker core

 

Docker's three core: mirrors, containers, warehouse. Before Docker containers have different implementations, such as lxc. Mirroring and warehouse Docker's great innovation. Mirroring is an entity, centralized storage warehouse its center, and the container is running when the mirror.

 

Docker by mirroring, for example, can be magically achieve: the development of students for development testing (eg ubuntu) in your favorite platform above, and the node is actually deployed, it may be redhat / centos server.

 

 

Docker is a mirror-based, so there must be a mirror runtime container, and the container and can generate an image by docker commit. But the first image come from? May be introduced by docker import / load manner. And the image may be uploaded via the direction docker push / pull to the center of the mirror, or downloaded from a mirror image center.

 

Mirroring

 

Docker provides a docker build mechanism, easy to create images. Imagine, no docker build mechanisms to mirror the following steps:

 

  • A container starting from a base image;
  • Execute corresponding commands in a container, such as installing a package, add a file and the like;
  • Use Docker commit command to commit the container just a mirror image;
  • If there are other steps to be done, it is necessary to start the new image in a container, then the commit, until all operations.

 

With docker build mechanism, requires only a dockerfile, the above steps will then Docker automation, and finally generate a target image.

 

container

Is a detailed look at how the mirror, the mirror layer by layer, the design, all the mirror layers are read-only, linux by aufs / overlayfs manner to a mirror mount on the host, viewed from above, the top layer is a writable layer container, the container all write operations are written to run above this layer, while the lower layer is a read-only image layer.

 

Large-scale cluster slow image download

 

Docker's registry or on other sites to see, like busybox, nginx, mysql, etc. are not large mirror, which is tens to hundreds of M M look.

 

But Ali Baba's image generally have 3 ~ 4G, there are many reasons for such a large mirror, such as:

 

  • Group uses a model rich container, which is a virtual machine similar way to develop a more friendly developers can do development on previous experience, does not require much learning costs, which leads to the base image group has 2 ~ 3G;
  • The Group's business development are used in a distributed manner, dependent on a number of middleware, and middleware version due to reasons not fully unified, every middleware has hundreds of M; plus the java business package itself is not small, so generally 3 ~ 4G is normal;
  • 集团有上十万的物理机,上面运行着上百万的容器,每天有着上千次发布。可以想像一下,就单单把镜像从镜像中心下载到物理机上面,每天消耗的带宽是巨大的。

 

这就导致一个问题:镜像中心很有可能被打爆

 

这种情况在集团出现多次,在打爆的情况下,当前的镜像拉取被阻塞,同时又有更多的镜像拉取请求上来,导致镜像中心严重超负荷运行,并且致使问题越来越严重,可能会导致整个系统奔溃。因此,必须解决镜像下载导致的问题。

 

蜻蜓架构

 

 

集团开发了蜻蜓(Dragonfly 这套 P2P 下载系统。上面是蜻蜓的架构图,蜻蜓可以分为三层,最上层是一个配置中心,中间是超级节点,下面就是运行容器的物理节点。

 

配置中心管理整个蜻蜓集群,当物理节点上有镜像要下载时,它通过 dfget 命令向超级节点发出请求,而向哪些超级节点发出请求是由配置中心配置的。

 

以下图为例:

 

 

当下载一个文件时,物理节点发送了一个 dfget 请求到超级节点,超级节点会检查自身是否有这部分数据,如果有,则直接把数据传送给物理节点;否则会向镜像中心发出下载请求,这个下载请求是分块的,这样,只有下载失败的块需要重新下载,而下载成功的块,则不需要。

 

更为重要的是,如果是两个或更多物理节点请求同一份数据,那么蜻蜓收到请求后,只会往镜像中心发一个请求,极大地降低了镜像中心的压力。

 

关于 P2P,也就是说如果一个节点有了另一个节点的数据,为了减少超级节点的压力,两个节点可以完成数据的互传。这样更高效地利用了网络带宽。

 

蜻蜓效果

 

 

从上面的蜻蜓效果图可以看到:

 

随着镜像拉取的并发量越来越大,传统方式所消耗的时间会越来越多,后面的线条越来越陡;但是蜻蜓模式下,虽然耗时有增加,但只是轻微增加。效果还是非常明显的。

 

蜻蜓里程碑

 

 

应该说,集团内是先有蜻蜓,后面才有 docker 的。原因是集团在全面 docker 之前,使用了 t4 等技术,不管哪种技术,都需要在物理机上面下载应用的包,然后把应用跑起来。

 

所以,从里程碑上看,2015 年 6 月就已经有了蜻蜓 p2p 了,随着集团全面 Docker 化,在 2015 年 9 月,蜻蜓提供了对 Docker 镜像的支持,后面的几个时间点上,可以看到蜻蜓经受了几次双 11 的考验,并且经过软件迭代,在 2017 年 11 月的时候实现了开源。

 

现在蜻蜓还在不断演化,比如说全部使用 golang 重写,解决 bug,提供更多能力集,相信蜻蜓的明天更美好。

 

蜻蜓也不能完美解决的问题——镜像下载

 

蜻蜓在集团取得了极好的效果,但是并不能解决所有问题,比如我们就遇到了以下比较突出的问题:

 

  • 镜像下载导致业务抖动

 

在实践中,上线的业务运行经常有抖动的现象,分析其中原因,有部分业务抖动时,都在做镜像下载。

 

分析原因发现:镜像层采用的是 gzip 压缩算法。这一古老的算法,是单线程运行,并且独占一个 CPU,更要命的是解压速度也很慢,如果几个镜像层同时展开的话,就要占用几个 CPU,这抢占了业务的 CPU 资源,导致了业务的抖动。

 

  • 应用扩容要更好的时效性

 

平时应用发布、升级时,只需要选择在业务低峰,并且通过一定的算法,比如只让 10% 左右的容器做发布、升级操作,其它 90% 的容器还给用户提供服务。这种不影响业务、不影响用户体验的操作,对于时效性要求不高,只要在业务高峰来临前完成操作即可,所以耗时一两个小时也无所谓。

 

假设遇到大促场景,原计划 10 个容器可以服务 100 万用户,但是,突然来了 300 万用户,这时所有用户的体验将会下降,这时就需要通过扩容手段来增加服务器数量,此时对容器扩出来有着极高的时效要求。

 

  • 如何而对云环境

 

现在所有公司都在上云,集团也在上云阶段,但云上服务器的一些特性与物理机还是有些差别,对镜像来讲感受最深的就是磁盘 IO 了,原来物理机的 SSD 磁盘,IO 可以达到 1G 以上,而使用 ECS 后,标准速度是 140M,速度只有原来的十分之一。

 

Gzip 优化

 

对于 gzip 的问题,通过实测及数据分析,如上图所示:

 

1 与 2 下载的是同一个镜像层,只是 1 下载的是一个 gzip 格式的,而 2 下载的是一个没有压缩的镜像层。可以看到 2 因为下载的数据量要大很多,所以下载的时间要长许多,但是 1 中将 400M 的 gzip 还原成 1G 的原始数据却又消耗了太多时间,所以最终两者总体时效是差不多的。

 

并且由于去掉 gzip,镜像下载不会抢占业务的 CPU 资源。自从上了这一方案后,业务抖动的次数明显减少了许多。

 

在蜻蜓的章节,镜像下载是镜像层从超级节点到物理机,在这一过程中,蜻蜓有一个动态压缩能力,比如使用更好的 lz4 算法,即达到了数据压缩的效果,又不会造成业务抖动。这就是图 3,整体上这一点在集团的应用效果很不错。

 

远程盘架构

 

 

解决了镜像下载对业务的干扰后,扩容、云环境的问题还没有解决。这时远程盘就派上用场了。

 

从上面的架构图看,集团有一套镜像转换机制,将原始的镜像层放在远端服务器上,第一个层都有一个唯一的远程盘与之对应。然后镜像中保存的是这个远程盘的 id,这样做下来,远程盘的镜像可以做到 kB 级别。对于 kB 级别的镜像,下载耗时在 1~2 秒之间。

 

通过远程盘,解决了镜像下载的问题,同时由于远程盘放在物理机同一个机房,容器运行时读取镜像数据,相当于从远程盘上面读取数据,因为在同一个机房,当然不能跟本地盘比,但是效果可以与云环境的云盘性能相媲美。

 

远程盘的问题

 

远程盘虽然解决了镜像下载的问题,但是所有镜像的数据都是从远程盘上读取,消耗比较大的网络带宽。当物理机上环境比较复杂时,远程盘的数据又不能缓存在内存时,所有数据都要从远端读取,当规模上来后,就会给网络带来不小的压力。

 

另外一个问题是,如果远程盘出现问题,导致 IO hang,对于容器进程来讲,就是僵尸进程,而僵尸进程是无法杀死的。对于应用来讲,一个容器要么是死,要么是活,都好办,死的了容器上面的流量分给活着的容器即可,但对于一个僵尸容器,流量没法摘除,导致这部分业务就受损了。

 

最后,远程盘因为要服务多台物理机,必然要在磁盘 IO 上面有比较好的性能,这就导致了成本较高。

 

DADI

 

 

针对上述问题,集团采用的 DADI 这一项技术,都是对症下药:

 

  • 使用 P2P 技术

 

远程盘是物理机所有数据都要从远程盘上读,这样会导致对远程盘机器的配置较高的要求,并且压力也很大。

 

而通过 P2P 手段,可以将一部分压力分担掉,当一台机器已经有另一台需要的数据时,它俩之间可以完成数据互传。

 

  • 高效压缩算法

 

同样是解决网络带宽的问题,远程盘对应的数据都是没有压缩的,传输会占用比较多的带宽。

 

而 DADI 则在传输过程中,跟蜻蜓一样,对数据进行压缩,减少网络压力。

 

  • 本机缓存

 

这个是核心买点了,当容器启动后,DADI 会把整个镜像数据拉取到本地,这样即使网络有问题,也不会导致容器进程僵尸,解决了业务受损的问题。

Guess you like

Origin www.cnblogs.com/alisystemsoftware/p/11263262.html