云原生+AI,把卫星遥感虐的死去活来

2021-09-14

在Docker容器技术即将统治世界的趋势下,作为地理遥感领域的AI处理解译平台,华为云GeoGenius空天地平台,早已开始全面的云原生方向转型。本文总结大规模遥感影像处理在云原生平台的落地经验,期间各种性能并发等场景优化经验有不少借鉴意义,与各遥感同行分享。

本文作者:唐盛军,华为云城市智能体架构师,拥有多年开发经验,先后从事:网络协议识别&解析、业务控制网关等网络协议相关工作;13年开始转战云计算,熟悉OpenStack,CloudFoundry,Docker,Kubernetes实现原理,精通常见的物理&云网络技术。目前负责容器业务产品化,如:遥感,基因,大数据,AI等
AI牛啊,云原生牛啊,所以1+1>2?

遥感影像,作为地球自拍照,能够从更广阔的视角,为人们提供更多维度的辅助信息,来帮助人类感知自然资源、农林水利、交通灾害等多领域信息。

AI技术,可以在很多领域超过人类,关键是它是自动的,省时又省力。可显著提升遥感影像解译的工作效率,对各类地物元素进行自动化的检测,例如建筑物,河道,道路,农作物等。能为智慧城市发展&治理提供决策依据。

云原生技术,近年来可谓是一片火热。易构建,可重复,无依赖等优势,无论从哪个角度看都与AI算法天生一对。所以大家也可以看到,各领域的AI场景,大都是将AI推理算法运行在Docker容器里面的。AI+云原生这么6,那么强强联手后,地物分类、目标提取、变化检测等高性能AI解译不就手到擒来?我们也是这么认为的,所以基于AI+Kubernetes云原生,构建了支持遥感影像AI处理的空天地平台。详见:ttps://www.huaweicloud.com/product/geogenius.html

不过理想是好的,过程却跟西天取经一般,九九八十一难,最终修成正果。

业务场景介绍

遇到问题的业务场景叫影像融合(Pansharpen),也就是对地球自拍照进行“多镜头合作美颜”功能。(可以理解成:手机的多个摄像头,同时拍照,合并成一张高清彩色大图)。

所以业务简单总结就是:读取2张图片,生成1张新的图片。该功能我们放在一个容器里面执行,每张融合后的结果图片大约5GB。

问题的关键是,一个批次业务量需要处理的是3000多张卫星影像,所以每批任务只需要同时运行完成3000多个容器就OK啦。云原生YYDS!

业务架构图示

为了帮助理解,这里分解使用云原生架构实现该业务场景的逻辑图如下:

在云上,原始数据,以及结果数据,一定是要存放在对象存储桶里面的。因为这个数据量,只有对象存储的价格是合适的。(对象存储,1毛钱/GB。文件存储则需要3毛钱/GB)

因为容器之间是互相独立无影响的,每个容器只需要处理自己的那幅影像就行。例如1号容器处理 1.tif影像;2号容器处理2.tif影像;依次类推。

所以管理程序,只需要投递对应数量的容器(3000+),并监控每个容器是否成功执行完毕就行(此处为简化说明,实际业务场景是一个pipeline处理流程)。那么,需求已经按照云原生理想的状态分解,咱们开始起(tang)飞(keng)吧~

注:以下描述的问题,是经过梳理后呈现的,实际问题出现时是互相穿插错综复杂的。

K8s死掉了

当作业投递后,不多久系统就显示作业纷纷失败。查看日志报调用K8s接口失败,再一看,K8s的Master都已经挂了。。。

K8s-Master处理过程,总结版:

1. 发现Master挂是因为CPU爆了

2. 所以扩容Master节点(此处重复N次);

3. 性能优化:扩容集群节点数量;

4. 性能优化:容器分批投放;

5. 性能优化:查询容器执行进度,少用ListPod接口;

详细版:

看监控Master节点的CPU已经爆掉了,所以最简单粗暴的想法就是给Master扩容呀,嘎嘎的扩。于是从4U8G * 3 一路扩容一路测试一路失败,扩到了32U64G * 3。可以发现CPU还是爆满。看来简单的扩容是行不通了。

3000多个容器,投给K8s后,大量的容器都处于Pending状态(集群整体资源不够,所以容器都在排队呢)。而正在Pending的Pod,K8s的Scheduler会不停的轮训,去判断能否有资源可以给它安排上。所以这也会给Scheduler巨大的CPU压力。扩容集群节点数量,可以减少排队的Pod数量。

另外,既然排队的太多,不如就把容器分批投递给K8s吧。于是开始分批次投递任务,想着别一次把K8s压垮了。每次投递数量,减少到1千,然后到500,再到100。

同时,查询Pod进度的时候,避免使用ListPod接口,改为直接查询具体的Pod信息。因为List接口,在K8s内部的处理会列出所有Pod信息,处理压力也很大。

这一套组合拳下来,Master节点终于不挂了。不过,一头问题按下去了,另一头问题就冒出来了。

容器跑一半,挂了

虽然Master不挂了,但是当投递1~2批次作业后,容器又纷纷失败。

容器挂掉的处理过程,总结版:

1. 发现容器挂掉是被eviction驱逐了;

2. Eviction驱逐,发现原因是节点报Disk Pressure(存储容量满了);

3. 于是扩容节点存储容量;

4. 延长驱逐容器(主动kill容器)前的容忍时间;

详细版:

(注:以下问题是定位梳理后,按顺序呈现给大家。但其实出问题的时候,顺序没有这么友好)

容器执行失败,首先想到的是先看看容器里面脚本执行的日志呗:结果报日志找不到~

于是查询Pod信息,从event事件中发现有些容器是被Eviction驱逐干掉了。同时也可以看到,驱逐的原因是 DiskPressure(即节点的存储满了)。

当Disk Pressure发生后,节点被打上了驱逐标签,随后启动主动驱逐容器的逻辑:

由于节点进入Eviction驱逐状态,节点上面的容器,如果在5分钟后,还没有运行完,就被Kubelet主动杀死了。(因为K8s想通过干掉容器来腾出更多资源,从而尽快退出Eviction状态)。

这里我们假设每个容器的正常运行时间为1~2个小时,那么不应该一发生驱动就马上杀死容器(因为已经执行到一半的容器,杀掉重新执行是有成本浪费的)。我们期望应该尽量等待所有容器都运行结束才动手。所以这个 pod-eviction-timeout 容忍时间,应该设置为24小时(大于每个容器的平均执行时间)。

Disk Pressure的直接原因就是本地盘容量不够了。所以得进行节点存储扩容,有2个选择:1)使用云存储EVS(给节点挂载云存储)。2)扩容本地盘(节点自带本地存储的VM)。

由于云存储(EVS)的带宽实在太低了,350MB/s。一个节点咱们能同时跑30多个容器,带宽完全满足不了。最终选择使用 i3类型的VM。这种VM自带本地存储。并且将8块NVMe盘,组成Raid0,带宽还能x8。

对象存储写入失败

容器执行继续纷纷失败。

容器往对象存储写入失败处理过程,总结版:

1. 不直接写入,而是先写到本地,然后cp过去。

2. 将普通对象桶,改为支持文件语义的并行文件桶。

详细版:

查看日志发现,脚本在生成新的影像时,往存储中写入时出错:

我们整集群是500核的规模,同时运行的容器数量大概在250个(每个2u2g)。这么多的容器同时往1个对象存储桶里面并发追加写入。这个应该是导致该IO问题的原因。

对象存储协议s3fs,本身并不适合大文件的追加写入。因为它对文件的操作都是整体的,即使你往一个文件追加写入1字节,也会导致整个文件重新写一遍。

最终这里改为:先往本地生成目标影像文件,然后脚本的最后,再拷贝到对象存储上。相当于增加一个临时存储中转一下。

在临时中转存储选择中,2种本地存储都试过:1)块存储带宽太低,350MB/s影响整体作业速度。2)可以选择带本地存储的VM,多块本地存储组成Raid阵列,带宽速度都杠杠滴。

同时,华为云在对象存储协议上也有一个扩展,使其支持追加写入这种的POSIX语义,称为并行文件桶。后续将普通的对象桶,都改为了文件语义桶。以此来支撑大规模的并发追加写入文件的操作。

K8s计算节点挂了

So,继续跑任务。但是这容器作业,执行又纷纷失败鸟~

计算节点挂掉,定位梳理后,总结版:

1. 计算节点挂掉,是因为好久没上报K8s心跳了。

2. 没上报心跳,是因为kubelet(K8s节点的agent)过得不太好(死掉了)。

3. 是因为Kubelet的资源被容器抢光了(由于不想容器经常oom kill,并未设置limit限制)

4. 为了保护kubelet,所有容器全都设置好limit。

详细版,直接从各类奇葩乱象等问题入手:

1) 容器启动失败,报超时错误。

2) 然后,什么PVC共享存储挂载失败:

3) 或者,又有些容器无法正常结束(删不掉)。

4) 查询节点Kubelet日志,可以看到充满了各种超时错误:

啊,这么多的底层容器超时,一开始感觉的Docker的Daemon进程挂了,通过重启Docker服务来试图修复问题。

后面继续定位发现,K8s集群显示,好多计算节点Unavailable了(节点都死掉啦)。

继续分析节点不可用(Unavailable),可以发现是Kubelet好久没有给Master上报心跳了,所以Master认为节点挂了。说明不仅仅是Docker的Daemon受影响,节点的Kubelet也有受影响。

那什么情况会导致Kubelet,Docker这些主机进程都不正常呢?这个就要提到Kubernetes在调度容器时,所设计的Request和Limit这2个概念了。

Request是K8s用来调度容器到空闲计算节点上的。而Limit则会传递给Docker用于限制容器资源上限(触发上限容易被oom killer 杀掉)。前期我们为了防止作业被杀死,仅为容器设置了Request,没有设置Limit。也就是每个容器实际可以超出请求的资源量,去抢占额外的主机资源。大量容器并发时,主机资源会受影响。

考虑到虽然不杀死作业,对用户挺友好,但是平台自己受不了也不是个事。于是给所有的容器都加上了Limit限制,防止容器超限使用资源,强制用户进程运行在容器Limit资源之内,超过就Kill它。以此来确保主机进程(如Docker,Kubelet等),一定是有足够的运行资源的。

K8s计算节点,又挂了

于是,继续跑任务。不少作业执行又双叒失败鸟~

节点又挂了,总结版:

1. 分析日志,这次挂是因为PLEG(Pod Lifecycle Event Generator)失败。

2. PLEG异常是因为节点上面存留的历史容器太多(>500个),查询用时太久超时了。

3. 及时清理已经运行结束的容器(即使跑完的容器,还是会占用节点存储资源)。

4. 容器接口各种超时(cpu+memory是有limit保护,但是io还是会被抢占)。

5. 提升系统磁盘的io性能,防止Docker容器接口(如list等)超时。

详细版:

现象还是节点Unavailable了,查看Kubelet日志搜索心跳情况,发现有PLEG is not healthy 的错误:

于是搜索PLEG相关的Kubelet日志,发现该错误还挺多:

这个错误,是因为kubelet去list当前节点所有容器(包括已经运行结束的容器)时,超时了。

看了代码:

https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/pleg/generic.go#L203

kubelet判断超时的时间,3分钟的长度是写死的。所以当pod数量越多,这个超时概率越大。很多场景案例表明,节点上的累计容器数量到达500以上,容易出现PLEG问题。(此处也说明K8s可以更加Flexible一点,超时时长应该动态调整)。

缓解措施就是及时的清理已经运行完毕的容器。但是运行结束的容器一旦清理,容器记录以及容器日志也会被清理,所以需要有相应的功能来弥补这些问题(比如日志采集系统等)。

List所有容器接口,除了容器数量多,IO慢的话,也会导致超时。

这时,从后台可以看到,在投递作业期间,大量并发容器同时运行时,云硬盘的写入带宽被大量占用:

对存储池的冲击也很大:

这也导致了IO性能变很差,也会一定程度影响list容器接口超时,从而导致PLEG错误。

该问题的解决措施:尽量使用的带本地高速盘的VM,并且将多块数据盘组成Raid阵列,提高读写带宽。

这样,该VM作为K8s的节点,节点上的容器都直接读写本地盘,io性能较好。(跟大数据集群的节点用法一样了,强依赖本地shuffle~)。

在这多条措施实施后,后续多批次的作业都可以平稳的运行完。

总结:“AI+云原生”这条路

云原生是趋势,已经成为大家的共识,各领域也都开始以云原生为底座的业务尝试。AI是未来,这也是当前不可阻挡的力量。但是当AI踏上这条云原生的道路却不那么一帆风顺。至少可以看到,华为云的云原生底座(当然,也包括存储、网络等周边基础设施)还可以有更多的进步空间。

但是,大家也不用担心太多,因为当前华为云的空天地平台,在经历了多年的AI+云原生的积累,目前可以很稳定的处理PB级每日的遥感影像数据,支撑各类空基、天基、地基等场景,并且在该领域保持绝对领先的战斗值。虽然大家看到此间过程有点曲折,但是所有的困难都是涅槃的火种,克服过的困难都是今后可以对客户做的承诺。在这里可以很明确的告诉各位:AI+云原生=真香。

写这篇文章的目的,不是在阐述困难,而是为了总结分享。与同领域的人分享并促进遥感领域的快速发展,共同推动AI+云原生的落地。

(0)

相关推荐

  • 云原生时代需要什么样的存储系统

    本文介绍了目前云原生环境下,支持有状态应用的几种典型存储方案的特点,并对市场主流的云原生存储产品实际测试性能进行对比. 1现状 当前,云原生已经成为应用开发者在选择架构设计时的首选.云原生让应用开发者 ...

  • PolarDB是什么

    PolarDB 是阿里云自主研发的新一代关系型云原生数据库,既拥有分布式设计的低成本优势,又具有集中式的易用性.PolarDB 采用存储计算分离.软硬一体化设计,满足大规模应用场景需求. PolarD ...

  • 云原生,看这一篇就够了!

    CNCF,The Cloud Native Computing Foundation的缩写,云原生计算基金会.这是业界首个以云原生为主题的组织. 本文摘录自"云原生计算研究报告", ...

  • 7 个关键的数据库概念,人人都应该了解

    神译局23小时前 关注 关于数据库的知识有很多,所以让我们从基础开始 神译局是36氪旗下编译团队,关注科技.商业.职场.生活等领域,重点介绍国外的新技术.新观点.新风向. 编者按:对于最终用户来说,数 ...

  • Kubernetes设计与架构 中文翻译

    更多细节请参见:Architectural Roadmap(架构演进路线) 概述 Kubernetes是由谷歌开发的,为了在主机集群间的应用容器可以进行部署.动态伸缩.管理的一个生产级别的.开源的基础 ...

  • 一个优秀的云原生架构需要注意哪些地方

    本文整理自腾讯云容器产品,容器解决方案架构团队的陈浪交在 Techo 开发者大会云原生专题的分享内容--一个优秀的云原生架构需要注意哪些地方.本文将会给大家分享云原生架构的特点和以及实践过程中的一些注 ...

  • 你家的数据库“云原生”了吗?

    2020 年 9 月 16 日,云原生数据库厂商 Snowflake 在纽交所上市,总市值超 700 亿美元,成为有史以来规模最大的软件 IPO,"云原生数据库"一词也随之成为炙手 ...

  • 为什么说 Pulsar 是云原生的消息平台?

    企业中的不同的应用系统共同支撑起了业务的运行,在企业的发展过程中,总会有应用系统需要以设计时未曾想过的方式集成在一起.在过去二十年的实践当中,消息传递技术通过使用消息同步两个系统,同时又能够解耦消息的 ...

  • 《智慧农业》编委刘良云研究员:叶绿素荧光卫星遥感——原理与应用

    2019年5月18日,<智慧农业>编辑部举办的"2019智慧农业青年学术研讨会"上,编委刘良云研究员就"叶绿素荧光卫星遥感-原理与应用"做了精彩分享 ...

  • +AI+低代码+云原生,RPA到底要怎么走下去?

    " 大数据产业创新服务媒体 --聚焦数据 · 改变商业 卡罗尔·德韦克(Carol Dweck)的<终身成长>一书中讲到,人有两种思维模式:固定型思维模式和成长型思维模式. 固定 ...

  • AI 云原生浅谈:好未来 AI 中台实践

    前言 AI 时代的到来,给企业的底层 IT 资源的丰富与敏捷提出了更大的挑战.利用阿里云稳定.弹性的 GPU 云服务器,领先的 GPU 容器化共享和隔离技术,以及 K8S 集群管理平台,好未来通过云原 ...

  • 云原生数据中台技术与趋势解读

    数据中台发展至今,大体经历了 4 个重要阶段:数据库 - 数据仓库 - 大数据平台 - 数据中台.每次新的变革,都是为了解决上一阶段存在的问题. 当前,走向云原生成为数据中台的必然和必须. 云原生从何 ...

  • Azure上的Java:云原生身份验证

    API通常需要识别其调用方.它可以是调用API的Web应用程序,也可以是调用API的另一个API.识别API的调用者也称为身份验证.建立自己的身份验证框架可能很棘手.值得庆幸的是,不必建立自己的身份验 ...

  • 乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时

    TaylorShi dotNET跨平台 昨天 Dapr是一个由微软主导的云原生开源项目,国内云计算巨头阿里云也积极参与其中,2019年10月首次发布,到今年2月正式发布V1.0版本.在不到一年半的时间 ...

  • (40条消息) 云原生的 WebAssembly 能取代 Docker 吗?

    WebAssembly 是一个可移植.体积小.加载快并且兼容 Web 的全新格式.由于 WebAssembly 具有很高的安全性,可移植性,效率和轻量级功能,因此它是应用程序安全沙箱方案的理想选择.现 ...

  • 卫星遥感揭开近20年全球湖库水色变化规律,通过福莱尔水色计 (Forel-Ule scale)把全球海洋和内陆水体颜色分为从深蓝到红棕色的21个级别

    编者按:从古至今,人类从未停止过探索未知世界的脚步,认知世界的能力和手段与日俱增.中科院之声与中国科学院空天信息创新研究院联合开设"观天测地"专栏,为大家介绍天上地上探索的那些事儿 ...

  • 云原生/云计算发展白皮书(附下载)

    随着云计算发展成熟和企业需求推动,云原生技术和理念得到广泛接受,迎来快速发展.发展如火如荼的同时,云原生也面临不少挑战.譬如,传统行业对云原生价值认知模糊,企业云原生技术水平参差不齐,业内对云原生的定 ...