OpenKruise v0.8.0 核心能力解读:管理 Sidecar 容器的利器

简介: OpenKruise 是阿里云开源的云原生应用自动化管理套件,也是当前托管在 Cloud Native Computing Foundation (CNCF) 下的 Sandbox 项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,是阿里内部生产环境大规模应用的基于 Kubernetes 之上的标准扩展组件,也是紧贴上游社区标准、适应互联网规模化场景的技术理念与最佳实践。

 

前言

OpenKruise 是阿里云开源的云原生应用自动化管理套件,也是当前托管在 Cloud Native Computing Foundation (CNCF) 下的 Sandbox 项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,是阿里内部生产环境大规模应用的基于 Kubernetes 之上的标准扩展组件,也是紧贴上游社区标准、适应互联网规模化场景的技术理念与最佳实践。

OpenKruise 在 2021 年 3 月 4 日发布了最新的 v0.8.0版本(ChangeLog),其中增强了 SidecarSet 的能力,特别是对日志管理类 Sidecar 有了更加完善的支持。

背景

Sidecar 是云原生中一种非常重要的容器设计模式,它将辅助能力从主容器中剥离出来成为单独的 sidecar 容器。在微服务架构中,通常也使用 sidecar 模式将微服务中的配置管理、服务发现、路由、熔断等通用能力从主程序中剥离出来,从而极大降低了微服务架构中的复杂性。随着 Service Mesh 的逐步风靡,sidecar 模式也日益深入人心,在阿里巴巴集团内部也大量使用 sidecar 模式来管理诸如运维、安全、消息中间件等通用组件。

在 Kubernetes 集群中,Pod 不仅可以实现主容器与 sidecar 容器的构建,同时提供了许多功能强大的 workload(例如:deployment、statefulset)来对 Pod 进行管理、升级。但是随着 Kubernetes 集群上的业务日益增多,sidecar 容器的种类与规模也随之日益庞大,对线上 sidecar 容器的管理和升级成为了愈发繁杂的工作:

  • 业务 Pod 里面包含了运维、安全、代理等多个 sidecar 容器,业务线同学不仅要完成自身主容器的配置,而且还需要熟悉这些 sidecar 容器的配置,这不仅增加了业务同学的工作量,同时也无形增加了 sidecar 容器配置的风险。
  • sidecar 容器的升级需要连同业务主容器一起重启(deployment、statefulset 等 workload 基于 Pod 销毁、重建的模式,来实现 Pod 的滚动升级),推动和升级支撑着线上数百款业务的 sidecar 容器,必然存在着极大的业务阻力。
  • 作为 sidecar 容器的提供者对线上诸多各种配置以及版本的 sidecar 容器没有直接有效的升级手段,这对 sidecar 容器的管理意味着极大的潜在风险。

阿里巴巴集团内部拥有着百万级的容器数量连同上面承载的上千个业务,因此,sidecar 容器的管理与升级也就成为了亟待完善的主题。因此,我们总结了内部许多 sidecar 容器的通用化需求,并将其沉淀到 OpenKruise 上面,最终抽象为 SidecarSet 作为管理和升级种类繁多 sidecar 容器的利器。

OpenKruise SidecarSet

SidecarSet 是 OpenKruise 中针对 sidecar 抽象出来的概念,负责注入和升级 Kubernetes 集群中的 sidecar 容器,是 OpenKruise 的核心 workload 之一。它提供了非常丰富的功能,用户使用 SidecarSet 可以非常方便实现 sidecar 容器的管理。主要特性如下:

  • 配置单独管理:为每一个 sidecar 容器配置单独的 SidecarSet 配置,方便管理。
  • 自动注入:在新建、扩容、重建 pod 的场景中,实现 sidecar 容器的自动注入。
  • 原地升级:支持不重建 pod 的方式完成 sidecar 容器的原地升级,不影响业务主容器,并包含丰富的灰度发布策略

注意:针对 Pod 中包含多个容器的模式,其中对外提供主要业务逻辑能力的容器称之为 主容器,其它一些如日志采集、安全、代理等辅助能力的容器称之为 Sidecar 容器。例如:一个对外提供 web 能力的 pod,nginx 容器提供主要的 web server 能力即为主容器,logtail 容器负责采集、上报 nginx 日志即为 Sidecar 容器。本文中的 SidecarSet 资源抽象也是为解决 Sidecar 容器的一些问题。

1. Sidecar logging architectures

应用日志可以让你了解应用内部的运行状况,日志对调试问题和监控集群活动非常有用。应用容器化后,最简单且最广泛采用的日志记录方式就是写入标准输出和标准错误。

但是,在当前分布式系统、大规模集群的时代下,上述方案还不足以达到生产环境的标准。首先,对于分布式系统而言,日志都是分散在单个容器里面,没有一个统一汇总的地方。其次,如果发生容器崩溃、Pod 被驱逐等场景,会出现日志丢失的情况。因此,需要一种更加可靠,独立于容器生命周期的日志解决方案。

Sidecar logging architectures 是将 logging agent 放到一个独立的 sidecar 容器中,通过共享日志目录的方式,实现容器日志的采集,然后存储到日志平台的后端存储。

 

阿里巴巴以及蚂蚁集团内部同样也是基于这种架构实现了容器的日志采集,下面我将介 绍OpenKruise SidecarSet 如何助力 Sidecar 日志架构在 Kubernetes 集群中的大规模落地实践

2. 自动注入

OpenKruise SidecarSet 基于 Kubernetes AdmissionWebhook 机制实现了 sidecar 容器的自动注入,因此只要将 sidecar 配置到 SidecarSet 中,不管用户用 CloneSet、Deployment、StatefulSet 等任何方式部署,扩出来的 Pod 中都会注入定义好的 sidecar 容器

 

Sidecar 容器的所有者只需要配置自身的 SidecarSet,就可以在业务无感知的情况下完成 sidecar 容器的注入,这种方式极大的降低了 sidecar 容器使用的门槛,也方便了 sidecar 所有者的管理工作。为了满足 sidecar 注入的多种场景,SidecarSet 除 containers 之外还扩展了如下字段:

# sidecarset.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:name: test-sidecarset
spec:# 通过selector选择podselector:matchLabels:app: web-server# 指定 namespace 生效    namespace: ns-1    # container definitioncontainers:- name: logtailimage: logtail:1.0.0# 共享指定卷volumeMounts:- name: web-logmountPath: /var/log/web # 共享所有卷shareVolumePolicy: disabled# 环境变量共享transferEnv:- sourceContainerName: web-server# TZ代表时区,例如:web-server容器中存在环境变量 TZ=Asia/ShanghaienvName: TZ volumes:- name: web-logemptyDir: {}
  • Pod 选择器支持 selector 来选择要注入的 Pod,如示例中将选择 labels[app] = web-server 的 pod,将 logtail 容器注入进去,也可以在所有的 pod 中添加一个 labels[inject/logtail] = true 的方式,来实现全局性的 sidecar 注入。namespace:sidecarSet 默认是全局生效的,如果只想对某一个 namespace 生效,则配置该参数。
  • 数据卷共享共享指定卷:通过 volumeMounts 和 volumes 可以完成与主容器的特定卷的共享,如示例中通过共享 web-log volume 来达到日志采集的效果。共享所有卷:通过 shareVolumePolicy = enabled | disabled 来控制是否挂载 pod 主容器的所有卷卷,常用于日志收集等 sidecar,配置为 enabled 后会把应用容器中所有挂载点注入 sidecar 同一路经下(sidecar 中本身就有声明的数据卷和挂载点除外)。
  • 环境变量共享:可以通过 transferEnv 从其它容器中获取环境变量,会把名为 sourceContainerName 容器中名为 envName 的环境变量拷贝到本 sidecar 容器,如示例中日志 sidecar 容器共享了主容器的时区 TZ,这在海外环境中尤其常见。

注意:Kubernetes 社区对于已经创建的 Pod 不允许修改 container 数量,所以上述注入能力只能发生在 Pod 创建阶段,对于已经创建的 Pod 需要通过重建的方式来注入。

3. 原地升级

SidecarSet 不仅实现 sidecar 容器的注入,而且复用了 OpenKruise 中原地升级的特性,实现了在不重启 Pod 和主容器的前提下单独升级 sidecar 容器的能力。由于这种升级方式基本上能做到业务方无感知的程度,所以 sidecar 容器的升级已不再是上下交困的难题,从而极大解放了 sidecar 的所有者,提升了 sidecar 版本迭代的速度。

 

注意:Kubernetes 社区对于已经创建的 Pod 只允许修改 container.image 字段,因此对于 sidecar 容器的修改包含除 container.image 的其它字段,则需要通过 Pod 重建的方式,不能直接原地升级。

为了满足一些复杂的 sidecar 升级场景,SidecarSet 除了原地升级以外,还提供了非常丰富的灰度发布策略。

4. 灰度发布

灰度发布应该算是日常发布中最常见的一种手段,它能够比较平滑的完成 sidecar 容器的发布,尤其是在大规模集群的场景下,强烈建议使用这种方式。下面是首批暂停后续基于最大不可用滚动发布的例子,假设一个有 1000 个 pod 需要发布:

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:name: sidecarset
spec:# ...updateStrategy:type: RollingUpdatepartition: 980maxUnavailable: 10%

上述配置首先发布(1000 - 980)= 20 个 pod 之后就会暂停发布,业务可以观察一段时间发现 sidecar 容器正常后,调整重新 update SidecarSet 配置:

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:name: sidecarset
spec:# ...updateStrategy:type: RollingUpdatemaxUnavailable: 10%

这样调整后,对于余下的 980 个 pod,将会按照最大不可用的数量(10% * 1000 = 100)的顺序进行发布,直到所有的 pod 都发布完成。

Partition 的语义是保留旧版本 Pod 的数量或百分比,默认为 0。这里的 partition 不表示任何 order 序号。如果在发布过程中设置了 partition:

  • 如果是数字,控制器会将 (replicas - partition) 数量的 Pod 更新到最新版本。
  • 如果是百分比,控制器会将 (replicas * (100% - partition)) 数量的 Pod 更新到最新版本。

MaxUnavailable 是发布过程中保证的,同一时间下最大不可用的 Pod 数量,默认值为 1。用户可以将其设置为绝对值或百分比(百分比会被控制器按照 selected pod 做基数来计算出一个背后的绝对值)。

注意:maxUnavailable 和 partition 两个值是没有必然关联。举例:

  • 当 {matched pod}=100,partition=50,maxUnavailable=10,控制器会发布 50 个 Pod 到新版本,但是发布窗口为 10,即同一时间只会发布 10 个 Pod,每发布好一个 Pod 才会再找一个发布,直到 50 个发布完成。
  • 当 {matched pod}=100,partition=80,maxUnavailable=30,控制器会发布 20 个 Pod 到新版本,因为满足 maxUnavailable 数量,所以这 20 个 Pod 会同时发布。

5. 金丝雀发布

对于有金丝雀发布需求的业务,可以通过 strategy.selector 来实现。方式:对于需要率先金丝雀灰度的 pod 打上固定的 labels[canary.release] = true,再通过
strategy.selector.matchLabels 来选中该 pod。

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:name: sidecarset
spec:# ...updateStrategy:type: RollingUpdateselector:matchLabels:- canary.release: truemaxUnavailable: 10%  

上述配置只会发布打上金丝雀 labels 的容器,在完成金丝雀验证之后,通过将 updateStrategy.selector 配置去掉,就会继续通过最大不可用来滚动发布。

6. 打散发布

SidecarSet 对于 pod 的升级顺序,默认按照如下规则:

  • 对升级的 pod 集合,保证多次升级的顺序一致
  • 选择优先顺序是(越小优先级越高):unscheduled < scheduled, pending < unknown < running, not-ready < ready, newer pods < older pods。

除了上述默认发布顺序之外,scatter 打散策略允许用户自定义将符合某些标签的 Pod 打散到整个发布过程中。比如,对于像 logtail 这种全局性的 sidecar container,一个集群当中很可能注入了几十个业务 pod,因此可以使用基于 应用名 的方式来打散 logtail 的方式进行发布,实现不同应用间打散灰度发布的效果,并且这种方式可以同最大不可用一起使用。

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:name: sidecarset
spec:# ...updateStrategy:type: RollingUpdate# 配置pod labels,假设所有的pod都包含labels[app_name]scatterStrategy:- key: app_namevalue: nginx- key: app_namevalue: web-server- key: app_namevalue: api-gatewaymaxUnavailable: 10%  

注意:当前版本必须要列举所有的应用名称,我们将在下个版本支持只配置 label key 的智能打散方式。

7. 实践

阿里巴巴以及蚂蚁集团内部已经大规模的使用 SidecarSet 来管理 sidecar 容器,下面我将通过日志采集 Logtail sidecar 来作为一个示例。

  • 基于 sidecarSet.yaml 配置文件创建 SidecarSet 资源。
# sidecarset.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:name: logtail-sidecarset
spec:selector:matchLabels:app: nginxupdateStrategy:type: RollingUpdatemaxUnavailable: 10%containers:- name: logtailimage: log-service/logtail:0.16.16# when recevie sigterm, logtail will delay 10 seconds and then stopcommand:- sh- -c- /usr/local/ilogtail/run_logtail.sh 10livenessProbe:exec:command:- /etc/init.d/ilogtaild- statusresources:limits:memory: 512Mirequests:cpu: 10mmemory: 30Mi##### share this volume    volumeMounts:- name: nginx-logmountPath: /var/log/nginxtransferEnv:- sourceContainerName: nginxenvName: TZ volumes:- name: nginx-logemptyDir: {}
  • 基于 pod.yaml 创建 Pod。
apiVersion: v1
kind: Pod
metadata:labels:# matches the SidecarSet's selectorapp: nginx name: test-pod
spec:containers:- name: nginximage: log-service/docker-log-test:latestcommand: ["/bin/mock_log"]args: ["--log-type=nginx", "--stdout=false", "--stderr=true", "--path=/var/log/nginx/access.log", "--total-count=1000000000", "--logs-per-sec=100"]volumeMounts:- name: nginx-logmountPath: /var/log/nginxenvs:- name: TZvalue: Asia/Shanghaivolumes:- name: nginx-logemptyDir: {}    
  • 创建这个 Pod,你会发现其中被注入了 logtail 容器:
$ kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
test-pod   2/2     Running   0          118s$ kubectl get pods test-pod -o yaml |grep 'logtail:0.16.16'image: log-service/logtail:0.16.16
  1. 此时,SidecarSet status 被更新为:
$ kubectl get sidecarset logtail-sidecarset -o yaml | grep -A4 status
status:matchedPods: 1observedGeneration: 1readyPods: 1updatedPods: 1
  • 更新 sidecarSet 中 sidecar container 的 image logtail:0.16.18。
$ kubectl edit sidecarsets logtail-sidecarset# sidecarset.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:name: logtail-sidecarset
spec:containers:- name: logtailimage: log-service/logtail:0.16.18
  • 此时,发现 pod 中的 logtail 容器已经被更新为了 logtail:0.16.18 版本,并且 pod 以及其它的容器没有重启。
$ kubectl get pods |grep test-pod
test-pod                            2/2     Running   1          7m34s$ kubectl get pods test-pod -o yaml |grep 'image: logtail:0.16.18'image: log-service/logtail:0.16.18$ kubectl describe pods test-pod
Events:Type    Reason     Age                 From               Message----    ------     ----                ----               -------Normal  Killing    5m47s               kubelet            Container logtail definition changed, will be restartedNormal  Pulling    5m17s               kubelet            Pulling image "log-service/logtail:0.16.18"Normal  Created    5m5s (x2 over 12m)  kubelet            Created container logtailNormal  Started    5m5s (x2 over 12m)  kubelet            Started container logtailNormal  Pulled     5m5s                kubelet            Successfully pulled image "log-service/logtail:0.16.18"

总结

本次 OpenKruise v0.8.0 版本的升级,SidecarSet 特性主要是完善了日志管理类 Sidecar 场景的能力,后续我们在持续深耕 SidecarSet 稳定性、性能的同时,也将覆盖更多的场景,比如下一个版本将会增加针对 Service Mesh 场景的支持。同时,我们也欢迎更多的同学参与到 OpenKruise 社区来,共同建设一个场景更加丰富、完善的 K8s 应用管理、交付扩展能力,能够面向更加规模化、复杂化、极致性能的场景。

作者:赵明山(立衡)

原文链接

本文为阿里云原创内容,未经允许不得转载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/514066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

请把ios文件解压出来是什么意思_【张小亮】最新版本行会3。中文版本。解压即玩。...

电脑游戏目录【回复&#xff1a;电脑游戏】手机游戏目录【回复&#xff1a;手机游戏】【张小亮】最新版本行会3。中文版本。解压即玩。【名称】行会3【大小】4.12 GB【版本】v0.9.9【系统】电脑游戏【下载】本文中【往下滑】【安装】1。请下载【好压】这款解压软件进行解压。2。…

数据结构是如何装入 CPU 寄存器的?

作者|码农的荒岛求生来源|码农的荒岛求生有同学问了这样一个问题&#xff1a;既然CPU内部的寄存器数量有限&#xff0c;容量有限&#xff0c;那么我们使用的庞大的数据结构是怎样装入寄存器供CPU计算的呢&#xff1f;这篇文章就为你讲解一下这个问题。内存与数据真正有用的程序…

基于WASM的无侵入式全链路A/B Test实践

简介&#xff1a; 我们都知道&#xff0c;服务网格(ServiceMesh)可以为运行其上的微服务提供无侵入式的流量治理能力。通过配置VirtualService和DestinationRule&#xff0c;即可实现流量管理、超时重试、流量复制、限流、熔断等功能&#xff0c;而无需修改微服务代码。 本文所…

网易游戏基于 Flink 的流式 ETL 建设

简介&#xff1a; 网易游戏流式 ETL 建设实践及调优经验分享&#xff5e; 网易游戏资深开发工程师林小铂为大家带来网易游戏基于 Flink 的流式 ETL 建设的介绍。内容包括&#xff1a; 专用 ETLEntryX 通用 ETL调优实践未来规划 一. 业务背景 网易游戏 ETL 服务概况 网易游戏的…

potplayer 多个进程_创建守护进程的步骤

什么是守护进程&#xff1f;答&#xff1a;守护进程是后台运行的、系统启动是就存在的、不予任何终端关联的&#xff0c;用于处理一些系统级别任务的特殊进程。实现思路&#xff1a;实现一个守护进程&#xff0c;其实就是将普通进程按照上述特性改造为守护进程的过程。需要注意…

mysql 走索引 很慢_MySQL优化:为什么SQL走索引还那么慢?

背景2019-01-11 9:00-10:00 一个 MySQL 数据库把 CPU 打满了。硬件配置&#xff1a;256G 内存&#xff0c;48 core分析过程接手这个问题时现场已经不在了&#xff0c;信息有限&#xff0c;所以我们先从监控系统中查看一下当时的状态。从 PMM 监控来看&#xff0c;这个 MySQL 实…

华为徐直军:以持续创新加快数字化发展

【中国 深圳】2021年9月23日&#xff0c;华为全联接大会以线上形式举行&#xff0c;今年的全联接大会以“深耕数字化”为主题&#xff0c;汇聚了业界思想领袖&#xff0c;商业精英&#xff0c;技术大咖&#xff0c;生态伙伴等&#xff0c;探讨如何深入业务场景&#xff0c;把数…

大型 Web 应用插件化架构探索

简介&#xff1a; 随着 Web 技术的逐渐成熟&#xff0c;越来越多的应用架构趋向于复杂&#xff0c;例如阿里云等巨型控制台项目&#xff0c;每个产品下都有各自的团队来负责维护和迭代。不论是维护还是发布以及管控成本都随着业务体量的增长而逐渐不可控。在这个背景下微前端应…

高精地图技术专栏 | 基于空间连续性的异常3D点云修复技术

简介&#xff1a; 我们需要通过激光的内部机制和数据处理算法&#xff0c;将这些噪声恢复到它本来的位置。本文会从MTA问题产生的原理、激光应对MTA的内部机制、数据处理算法三方面来介绍高精资料处理是如何解决这个问题的。 1.背景 1.1 高精资料采集 高精采集车是集成了测绘…

pytorch 图像分割的交并比_「通知」《深度学习之图像识别》再版工作启动,欢迎指导和提建议...

不知不觉有三第一本书也上市超过1年半了&#xff0c;第一次写作略显稚嫩&#xff0c;许多细节处理不当&#xff0c;比如没有在印刷前核对公式&#xff0c;被删掉了参考文献影响读者阅读体验等。现在本书正式启动再版工作&#xff0c;注意不是重印&#xff0c;是再版。重印只是修…

mysql实例怎么复制_Mysql实例MySQL数据库复制概论

《Mysql实例MySQL数据库复制概论》要点&#xff1a;本文介绍了Mysql实例MySQL数据库复制概论&#xff0c;希望对您有用。如果有疑问&#xff0c;可以联系我们。导读&#xff1a;每当我们讨论一项(新的)领域技术的时候,最好的方式通常是首先抛出一些问题,这些问题大致分为三类&a…

app inventor离线版_百度要哭了!今日头条出了搜索引擎了,还做了APP

今天小编为大家送上几条新闻了&#xff1a;1 微软给Edge浏览器添加离线小游戏谷歌浏览器在不联网的情况下&#xff0c;会有一个小恐龙跳一跳的游戏&#xff0c;而最近换上chromium内核的edge&#xff0c;也添加了自己的离线小游戏。这是一款冲浪游戏&#xff0c;非常类似于微软…

打车业务下单高并发解决方案

简介&#xff1a; 打车业务下单高并发解决方案前言 在技术领域有一条准则&#xff0c;即不存在银弹技术。在实际工作中&#xff0c;通常无法通过几项简单的技术组合就解决实际业务中各种场景下的复杂问题。虽然追求架构的简单简洁也是架构师的目标之一。但必须认识到架构的简单…

Serverless 时代 DevOps 的最佳打开方式

简介&#xff1a; 传统软件开发过程中&#xff0c;开发和运维是极其分裂的两个环节&#xff0c;运维人员不关心代码是怎样运作的&#xff0c;开发人员也不知道代码是如何运行的。 作者 | 许成铭&#xff08;竞霄&#xff09; 来源 | 阿里巴巴云原生公众号 DevOps 简析 传统软…

2020 q5l使用手册电子版_关于2020下半年自考本科毕业生论文预答辩题目查询的通知...

一、对象&#xff1a;2020下半年获论文预答辩资格毕业生(名单见附件1)二、查询方法&#xff1a;请登录以下网址&#xff1a; 输入个人准考证和姓名&#xff0c;查询论文预答辩题目。三、相关要求1. 请将《自学考试本科毕业论文预答辩记录表》(见附件2)中个人相关信息以及预答辩…

现实版“奇异博士”?原来是这款神秘的“数学黑盒”

简介&#xff1a; 现实版“奇异博士”&#xff1f;原来是这款神秘的“数学黑盒”供稿团队&#xff1a;阿里云市场部在漫威电影《复联3》中&#xff0c;奇异博士预测到未来有1400多万种可能&#xff0c;而胜利却只有一种&#xff0c;这唯一的最优解成为他们战斗的希望。只可惜&a…

如何在Spring生态中玩转RocketMQ?

简介&#xff1a; RocketMQ作为业务消息的首选&#xff0c;在消息和流处理领域被广泛应用。而微服务生态Spring框架也是业务开发中最受欢迎的框架&#xff0c;两者的完美契合使得RocketMQ成为Spring Messaging实现中最受欢迎的消息实现。本文展示了5种在Spring生态中文玩转Rock…

enum 有什么好处_林卡尔|先买地板后装修的三大好处

【中华地板网】现在很多装饰公司和设计师&#xff0c; 提倡的装修新模式——“先定地板后装修”。 后装修并不是买完地板后再开工&#xff0c; 而是在开工之前&#xff0c; 先把地板风格、颜色、尺寸、价位定下&#xff0c; 然后让设计师根据地板进行其他设计。 那么这样做究竟…

华为推出业界首个分布式云原生产品:华为云UCS,持续创新,深耕数字化

华为面向ICT产业的全球年度旗舰活动——华为全联接2021拉开序幕。华为轮值董事长徐直军进行了“以持续创新加快数字化发展”的大会主题演讲。 本次大会围绕“深耕数字化”主题&#xff0c;探讨如何深入业务场景&#xff0c;把数字技术与行业知识深度结合&#xff0c;解决核心业…

Flink 必知必会经典课程四:Fault-tolerance in Flink

简介&#xff1a; 本文由 Apache Flink PMC , 阿里巴巴高级技术专家李钰分享&#xff0c;主要从有状态的流计算、全局一致性快照 、Flink的容错机制、Flink的状态管理 四个方面介绍 Flink 的容错机制原理。 作者 | 李钰 分享人&#xff1a;本文由 Apache Flink PMC , 阿里巴巴…