爱奇艺大数据离在线混部

混部作为一种提高资源利用率、降低成本的的方案,被业界普遍认可。爱奇艺在云原生化与降本增效的过程中,成功将大数据离线计算、音视频内容处理等工作负载与在线业务进行了混部,并且取得了阶段性收益。本文重点以大数据为例,介绍从 0 到 1 落地混部体系的实践过程。

01

   背景

爱奇艺大数据支持了公司内运营决策、用户增长、广告分发、视频推荐、搜索、会员等重要场景,为业务提供数据驱动引擎。随着业务需求的增长,计算需要的资源量与日俱增,成本管控和资源供给面临着较大的压力。

爱奇艺大数据计算分为离线计算、实时计算两条数据处理链路,其中:

  • 离线计算包括以 Spark 为主的数据处理、以 Hive 为主的小时级乃至天级别的数仓构建及对应的报表查询分析,这类计算多在每天凌晨开始启动计算前一天的数据,在上午结束。每天 0 - 8 点是计算资源需求的高峰期,集群总资源往往不足,任务经常排队、积压,而白天则出现较大空闲导致资源浪费。

  • 实时计算包括 Kafka + Flink 为代表的实时数据流处理,具有比较稳定的资源需求。

为了均衡大数据资源利用,我们将离线计算、实时计算进行混部,一定程度上缓解了白天资源空闲浪费情况,但仍无法有效地削峰填谷,大数据计算资源总体利用情况仍表现出“白天低谷、凌晨高峰”的潮汐现象,如图 1 所示。

e9ff45f0e36396a8d4e75eb834d049b2.png

图 1. 大数据计算集群一天内 CPU 使用变化情况

爱奇艺在线业务则面临另一个问题:服务质量与资源利用率之间的平衡。在线业务主要服务于爱奇艺视频播放等场景,午间和晚间观看视频的用户比较多,资源使用情况具备“白天高峰、凌晨低谷”的潮汐现象(如图 2 所示)。为保证高峰期间的服务质量,在线业务通常会预留较多资源,使得资源利用率非常不理想。

dee4370587e91fe562950a1fb84765dc.jpeg

图 2. 在线业务集群一天内 CPU 使用变化情况

为提高利用率,爱奇艺自研的上一代容器平台采用了 CPU 静态超售策略,该方式虽然对提升利用率有明显效果,但是受限于内核能力等因素,无法避免单机上业务之间偶发的资源竞争问题,也导致了在线业务服务质量不稳定,这个问题始终无法得到妥善解决。

随着云原生化推进,爱奇艺容器平台逐渐转型到 Kubernetes(下文简称“K8s”) 技术栈。最近几年,K8s 社区陆续出现多个混部相关的开源项目,业界也有一些混部实践 [1]。在此背景下,计算平台团队将工作方向由“静态超售”调整到“动态超售 + 混部”。

大数据作为最典型的离线业务,是尝试落地混部的先行者。一方面,大数据有着较大体量,以及较稳定的计算资源需求;另一方面,大数据业务与在线业务在很多维度都能达到互补的效果,通过混部能充分提高资源利用率。

基于上述分析,爱奇艺计算平台团队与大数据团队开始了混部的探索。

02

   混部方案设计

爱奇艺大数据体系基于开源的 Apache Hadoop 生态构建,采用了 YARN 作为计算资源调度系统,而在线业务构建在 K8s 上,如何打通两套不同的资源调度体系,是混部方案首先需要解决的。

业界通常有两种混部方案:

  • 方案一:直接将大数据作业(Spark、Flink 等,不支持 MapReduce)跑在 K8s 上,使用其原生的调度器

  • 方案二:将 YARN 的 NodeManager(下文简称“NM”)运行在 K8s 上,大数据作业仍通过 YARN 来调度

经过慎重的考虑,我们选择了方案二,主要的原因有以下两点:

  1. 目前公司内绝大多数大数据计算作业的调度是基于 YARN 的,YARN 具有强大的调度功能(多租户多队列、机架感知)、优秀的调度性能(5k+ 容器/s)和完善的安全机制(Kerberos、Delegation Tokens),支持 MapReduce、Spark、Flink 等几乎所有大数据计算框架。爱奇艺大数据团队从 2014 年引入 YARN 开始,围绕其构建了一系列平台,用于开发、运维、计算治理等,为公司内部用户提供了便捷的大数据开发流程。因此与 YARN API 的兼容性是混部方案选型的重要考虑点之一

  2. K8s 虽有批处理调度器,但还不够成熟,且调度性能存在瓶颈(<1k 容器/s),还不足以支撑大数据场景需求

K8s 层面,双方需要有一套标准的接口来管理和使用混部资源。社区中有很多优秀项目,如阿里巴巴开源的 Koordinator [2]、腾讯开源的 FinOps 项目 Crane [3]、字节跳动开源的项目 Katalyst [4] 等。其中,Koordinator 与龙蜥操作系统(爱奇艺正在尝试的 CentOS 替代者之一)拥有“天然”的适配能力,可以协作实现在线业务负载监测、空闲的资源超分、任务分级调度、在离线工作负载 QoS 保障等,契合爱奇艺需求。

基于上述技术选型,我们通过深度改造,将 YARN NM 容器化后运行在 K8s Pod 中,并可实时感知 Koordinator 动态变化的超分计算资源,从而实现自动的横向及纵向扩缩容,最大化利用混部资源。

03

   混部调度策略演进

大数据和在线业务的混部经历了多个阶段的技术演进,下文我们将详细介绍。

阶段一:夜间分时复用

为了快速验证方案,我们首先完成了 NM  on K8s Pod 的容器化改造(该阶段尚未采用 Koordinator),作为弹性节点扩容到已有的 Hadoop 集群。在大数据层面,这些 K8s NM 与其他物理机上的 NM 一起由 YARN 统一调度。这些弹性节点每天定时启停,只在 0 - 9 点之间运行。

在这个阶段,我们完成了 20 多项改造,下面列举 5 个主要的改造点:

改造点 1:固定 IP 池

传统 NM 部署在物理机上,机器的 IP 和域名固定,在 YARN ResourceManager(下文简称“RM”) 上配置节点白名单(slaves 文件)以允许该节点加入集群。同时 YARN 集群通过 Kerberos 来实现安全认证,在部署前需要在 Kerberos KDC 生成 keytab 文件,并分发到 NM 节点上。

为了适配 YARN 的白名单、安全认证机制,自建集群我们使用了自研的静态 IP 功能,每一个静态 IP 会有对应的 K8s StaticIP 资源,以记录 Pod 和 IP 的对应关系,同时基于公有云集群我们也会部署自研的 StaticIP CRD, 并针对每一个静态 IP 创建 StaticIP 资源,从而对 YARN 提供用法与自建集群一致的固定 IP 池。基于固定 IP 池内 IP 为其提前创建好 DNS 记录、keytab 文件,这样在 NM 启动时便可快速获取所需的配置。

改造点 2:Elastic YARN Operator

为了让用户对引入弹性节点无感知,我们将弹性 NM 加入到已有的 Hadoop YARN 集群。考虑到后期混部动态感知资源的复杂性,我们选择了自研 Elastic YARN Operator,用于更好地管理弹性 NM 的生命周期。

在这一阶段,Elastic YARN Operator 支持的策略有:

  • 按需启动:应对离线任务的突发流量,包括寒暑假、节假日、重要活动等场景

  • 周期性上下线:利用在线服务每天凌晨的资源利用率低谷期,运行大数据任务

改造点 3:Node Label - 弹性与固定资源隔离

由于 Flink 等大数据实时流计算任务是 7x24 小时不间断常驻运行的,对 NM 的稳定性的要求比批处理更高,弹性 NM 节点的缩容或资源量调整会使得流计算任务重启,导致实时数据波动。为此,我们引入了 YARN Node Label 特性 [5],将集群分为固定节点(物理机 NM)和弹性节点(K8s NM)。批处理任务可以使用任意节点,流任务则只能使用固定节点运行。

此外,批处理任务容错的基础在于 YARN Application Master 的稳定性。我们的解决方案是,给 YARN 新增了一个配置,用于设置 Application Master 默认使用的 label,确保 Application Master 不被分配到弹性 NM 节点上。这一功能已经合并到社区:YARN-11084、YARN-11088 。

改造点 4:NM Graceful Decommission

我们采用了弹性节点固定时间上下线,来对在离线资源进行削峰填谷。弹性 NM 的上线由 YARN Operator 来启动,一旦启动完成,任务就可被调度上。弹性 NM 的下线则略微复杂些,因为任务仍然运行在上面,我们需要尽可能保证任务在下线的时间区间内已经结束。

例如我们周期性部署策略为:0 - 8 点弹性 NM 上线,8 - 9 点为下线时间区间,9 - 24 点为节点离线状态。通过使用 YARN graceful decommission [6] 的机制,将增量 container 请求避免分配到 decommissioning 的节点上,在下线时间区间内等待任务缓慢结束即可。

但是在我们集群中,批处理任务大部分是 Spark 3.1.1 版本,因为 Spark 申请的 YARN container 是作为 task 的 executor 来使用,在大部分情况下,1 个小时的下线区间往往是不够的。因此我们引入了 SPARK-20624 的一系列优化 [7],通过 executor 响应 YARN decommission 事件来将 executor 尽可能快速退出。

改造点 5:引入 Remote Shuffle Service - Uniffle

Shuffle 作为离线任务中的重要一环,我们采用 Spark ESS on NodeManager 的部署模式。但在引入弹性节点后,因为弹性 NM 生命周期短,无法保证在 YARN graceful decommmission 的时间区间内,任务所在节点的 shuffle 数据被消费完,导致作业整体失败。

基于这一点,我们引入了 Apache Uniffle (incubating) [8] 实现 remote shuffle service 来解耦 Spark shuffle 数据与 NM 的生命周期,NM 被转变为单纯的计算,不存储中间 shuffle 数据,从而实现 NM 快速平滑下线。

另外一方面,弹性 NM 挂载的云盘性能一般,无法承载高 IO 和高并发的随机读写,同时也会对在线服务产生影响。通过独立构建高性能 IO 的 Uniffle 集群,提供更快速的 shuffle 服务。

爱奇艺作为 Uniffle 的深度参与者,贡献了 100+ 改进和 30+ 特性,包括 Spark AQE 优化 [9] 、Kerberos 的支持 [10] 和超大分区优化 [11] 等。

阶段二:资源超分

在阶段一,我们仅使用 K8s 资源池剩余未分配资源实现了初步的混部。为了最大限度地利用空闲资源,我们引入 Koordinator 进行资源的超分配。

我们对弹性 NM 的资源容量采用了固定规格限制:10 核 batch-cpu、30 GB batch-memory(batch-cpu 和 batch-memory 是 Koordinator 超分出来的扩展资源),NM 保证离线任务使用的资源总量不会超过这些限制。

为了保证在线业务的稳定性,Koordinator 会对节点上离线任务能够使用的 CPU 进行压制 [12],压制结果由压制阈值和在线业务 CPU 实际用量(不是 request 请求)的差值决定,这个差值就是离线业务能够使用的最大 CPU 资源,由于在线业务 CPU 实际使用量不断变化,所以离线业务能够使用的 CPU 也在不断变化,如图 3 所示:

065afacc4c1ba89ef01457f7289cd451.png

图 3. Koordinator 资源分配策略

对离线任务的 CPU 压制保证了在线业务的稳定性,但是离线任务执行时间就会被拉长。如果某个节点上离线任务被压制程度比较严重,就可能会导致等待的发生,从而拖慢整体任务的运行速度。为了避免这种情况,Koordinator 提供了基于 CPU 满足度的驱逐功能 [13],当离线任务使用的 CPU 被压制到用户指定的满足度以下时,就会触发离线任务的驱逐。离线任务被驱逐后,可以调度到其他资源充足的机器上运行,避免等待。

在经过一段时间的测试验证后,我们发现在线业务运行稳定,集群 CPU 7 天平均利用率提升了 5%。但是节点上的 NM Pod 被驱逐的情况时有发生。NM 被驱逐之后,RM 不能及时感知到驱逐情况的发生,会导致失败的任务延迟重新调度。为了解决这个问题,我们开发了 NM 动态感知节点离线 CPU 资源的功能。

阶段三:从夜间分时复用到全天候实时弹性

与其触发 Koordinator 的驱逐操作,不如让 NM 主动感知节点上离线资源的变化,在离线资源充足时,调度较多任务,离线资源不足时,停止调度任务,甚至主动杀死一些离线 container 任务,避免 NM 被 Koordinator 驱逐。

根据这个思路,我们通过 YARN Operator 动态感知节点所能利用的资源,来纵向伸缩 NM 可用资源量。分两步实现:1)提供离线任务 CPU 压制指标;2)让 NM 感知 CPU 压制指标,采取措施。如图 4 所示:

9d5009ba6c111fd99b4ae4a1435d4970.png

图 4. NM 动态感知资源

CPU 压制指标

Koordinator 的 Koordlet 组件,运行于 K8s 的节点上,负责执行离线任务 CPU 压制、Pod 驱逐等操作,它以 Prometheus 格式提供了 CPU 压制指标,经过采集后就可以通过 Prometheus 对外提供。CPU 压制指标默认每隔 1 秒更新 1 次,会随着在线业务负载的变化而变化,波动较大。而 Prometheus 的指标抓取周期一般都大于 1 秒,这会造成部分数据的丢失,为了平滑波动,我们对 Koordlet 进行了修改,提供了 1 min、5 min、10 min CPU 压制指标的均值、方差、最大值和最小值等指标供 NM 选择使用。

YARN Operator 动态感知和纵向伸缩

在 NM 常驻的部署模式下,YARN Operator 提供了新的策略。通过在 YARN Operator 接收到当前部署的节点 10 min 内可利用的资源指标,用来决策是否对所在宿主机上的 NM 进行纵向伸缩。

对于扩容,一旦超过 3 核,则向 RM 进行节点的资源更新。扩容过程如图 5 所示:

e4c67f05ec7ac54c17a6f4b3ca733fa4.png

图 5. NM 动态扩容资源

缩容的话,如果抑制率控制在 10% 以内的波动,我们默认忽略。一旦超过阈值,则会触发缩容操作,分为两个步骤:1)更新节点在 RM 上的可用资源,用来堵住增量的 container 分配需求;2)将缩容请求下发给 NM 的 guarder sidecar 容器,来对部分资源超用的 container 的平滑和强制下线,避免因占用过多 CPU 资源导致整个 NM 被驱逐。

guarder 在拿到目标可用资源后,会对当前所有的 YARN container 进程进行排序,包括框架类型、运行时长、资源使用量三者,决策拿到要 kill 的进程。在 kill 前,会进行 SIGPWR 信号的发送,用来平滑下线任务,Spark Executor 接收到此信号,会尽可能平滑退出。缩容过程如图 6 所示:

f3176bf64751cff208b7a8b24e4efac8.png

图 6. NM 动态缩容资源

通常节点的资源量变动幅度不是很大,且 NM 可使用的资源量维持在较高的水平(平均有 20 core),部分 container 的存活周期为 10 秒级,因此很快就能降至目标可用资源量值。涉及到变动幅度频繁的节点,通过 guarder 的平滑下线和 kill 决策,container 失败数非常低,从线上来看,按天统计平均 force kill container 数目为 5 左右,guarder 发送的平滑下线信号有 500+,可以看到效果比较好。

在离线 CPU 资源感知功能全面上线后,NM Pod 被驱逐的情况基本消失。因此,我们逐步将混部时间由凌晨的 0 点至 8 点,扩展到全天 24h 运行,并根据在线业务负载分布情况,在一天的不同时段采用不同的 CPU 资源超分比,从而实现全天候实时弹性调度策略。伴随着全天 24h 的稳定运行,集群 CPU 利用率再度提升了 10%。从线上混部 K8s 集群来看(如图 7 所示),弹性 NM 的 vcore 使用资源量(绿线)也是动态贴合可超分的资源(黄线)。

e9fa46733b43b495a6a123b9cf7519c4.png

图 7. 混部资源分配及使用情况

阶段四:提升资源超分率

为了提供更多的离线资源,我们开始逐步调高 CPU 资源的超分比,而 NM Pod 被驱逐的情况再次发生了,这一次的原因是内存驱逐。我们将物理机器的内存超分比设置为 90%,从集群总体情况看,物理机器上的内存资源比较充足,刚开始我们只关注了 CPU 资源,没有关注内存资源。而 NM 的 CPU 和内存按照 1:4 的比例来使用,随着 CPU 超分比的提高,YARN 任务需要的内存也在提升,最终当 K8s 节点内存使用量超过设定的阈值时,就会触发 Koordinator 的驱逐操作。

经过观察,我们发现内存驱逐在某些节点上发生的概率特别高,这些节点的内存比其他节点内存小,而 CPU 数量是相同的,因此这些节点在 CPU 超分比相同的情况下,更容易因为内存原因被驱逐,它们能提供的离线内存更少。因此,guarder 容器也需要感知节点的离线内存资源用量,并根据资源用量采取相应的措施,这个过程与 CPU 离线资源的感知一样的,不再赘述。

内存感知功能上线后,我们又逐步提升了 CPU 的超分比,当前在线业务集群的 CPU 利用率已经提升到全天平均 40%+、夜间 58% 左右。

e10dc4d1c1088ba23f1b60ea10e64192.jpeg

图 8. 混部集群 CPU 利用率


04

   效果

通过大数据离线计算与在线业务的混部,我们将在线业务集群 CPU 平均利用率从 9% 提升到 40%+,在不增加机器采购的同时满足了部分大数据弹性计算的资源需求,每年节省数千万元成本。

同时,我们也将这套框架应用到大数据 OLAP 分析场景,实现了 Impala/Trino on K8s 弹性架构,满足数据分析师日常动态查询需求,支持了寒暑假、春晚直播、广告 618 与双 11 等重要活动期间临时大批量资源扩容需求,保障了广告、BI、会员等数据分析场景的稳定、高效。


05

   未来计划

当前,大数据离在线混部已稳定运行一年多,并取得阶段性成果,未来我们将基于这套框架进一步推进大数据云原生化:

  1. 完善离在线混部可观测性:建立精细化的 QoS 监控,保障在线服务、大数据弹性计算任务的稳定性。

  2. 加大离在线混部力度:K8s 层面,继续提高宿主机资源利用率,提供更多的弹性计算资源供大数据使用。大数据层面,进一步提升通过离在线混部框架调度的弹性计算资源占比,节省更多成本。

  3. 大数据混合云计算:目前我们主要使用爱奇艺内部的 K8s 进行混部,随着公司混合云战略的推进,我们计划将混部推广到公有云 K8s 集群中,实现大数据计算的多云调度。

  4. 探索云原生的混部模式:尽管复用 YARN 的调度器能让我们快速利用混部资源,但它也带来了额外的资源管理和调度开销。后续我们也将探索云原生的混部模式,尝试将大数据的计算任务直接使用 K8s 的离线调度器进行调度,进一步优化调度速度和资源利用率。


参考资料

[1] 一文看懂业界在离线混部技术. https://www.infoq.cn/article/knqswz6qrggwmv6axwqu

[2] Koordinator: QoS-based Scheduling for Colocating on Kubernetes. https://koordinator.sh/

[3] Crane: Cloud Resource Analytics and Economics in Kubernetes clusters. https://gocrane.io/

[4] Katalyst: a universal solution to help improve resource utilization and optimize the overall costs in the cloud. https://github.com/kubewharf/katalyst-core

[5] Apache Hadoop YARN - Node Labels. https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/NodeLabel.html

[6] Apache Hadoop YARN - Graceful Decommission of YARN Nodes. https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/GracefulDecommission.html

[7] Apache Spark - Add better handling for node shutdown. https://issues.apache.org/jira/browse/SPARK-20624

[8] Apache Uniffle: Remote Shuffle Service. https://uniffle.apache.org/

[9] Apache Uniffle - Support getting memory data skip by upstream task ids. https://github.com/apache/incubator-uniffle/pull/358

[10] Apache Uniffle - Support storing shuffle data to secured dfs cluster. https://github.com/apache/incubator-uniffle/pull/53

[11] Apache Uniffle - Huge partition optimization. https://github.com/apache/incubator-uniffle/issues/378

[12] Koordinator - CPU Suppress. https://koordinator.sh/docs/user-manuals/cpu-suppress/

[13] Koordinator - Eviction Strategy based on CPU Satisfaction. https://koordinator.sh/docs/user-manuals/cpu-evict/

700634db9afed707dbd32356f950df3d.jpeg

也许你还想看

爱奇艺大数据加速:从Hive到Spark SQL

  后Hadoop时代,爱奇艺如何有效整合大数据和AI平台?

  爱奇艺大数据生态的实时化建设

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

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

相关文章

HDFS、MapReduce原理--学习笔记

1.Hadoop框架 1.1框架与Hadoop架构简介 &#xff08;1&#xff09;广义解释 从广义上来说&#xff0c;随着大数据开发技术的快速发展与逐步成熟&#xff0c;在行业里&#xff0c;Hadoop可以泛指为&#xff1a;Hadoop生态圈。 也就是说&#xff0c;Hadoop指的是大数据生态圈整…

多线程(初阶)

文章目录 一、认识线程&#xff08;Thread&#xff09;1.1 概念1.1.1 什么是线程1.1.2 为什么要有线程1.1.3 进程和线程的区别&#xff08;重要&#xff09;1.1.4 Java的线程和操作系统线程的关系 1.2 第一个多线程 程序1.3 创建线程&#xff08;重要&#xff09;1.3.1 继承 Tr…

iframe渲染后端接口文件和实现下载功能

一&#xff1a;什么是iframe&#xff1f; 1、介绍 iframe 是HTML 中的一种标签&#xff0c;全称为 Inline Frame&#xff0c;即内联框架。它可以在网页中嵌入其他页面或文档&#xff0c;将其他页面的内容以框架的形式展示在当前页面中。iframe的使用方式是通过在HTML文档中插入…

Linux_安装docker

安装包管理工具yum-utils&#xff0c;并设置docker储存库&#xff08;如果已有&#xff0c;不用安装&#xff09; # 安装包管理工具 sudo yum install -y yum-utils # 安装docker储存库 sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/cen…

react之基于@reduxjs/toolkit使用react-redux

react之基于reduxjs/toolkit使用react-redux 一、配置基础环境二、使用React Toolkit 创建 counterStore三、为React注入store四、React组件使用store中的数据五、实现效果六、提交action传递参数七、异步状态操作 一、配置基础环境 1.使用cra快速创建一个react项目 npx crea…

python图

有向图&#xff1a;图中的每条边都有方向的图叫有向图。此时&#xff0c;边的两个顶点有次序关系&#xff0c;有向边 < u,v>成为从顶点u到顶点v的一条弧&#xff0c;u成为弧尾&#xff08;始点&#xff09;&#xff0c;v成为弧头&#xff08;终点&#xff09;&#xff0c…

我叫:选择排序【JAVA】

1.我是个啥子&#xff1f;&#xff1f; 选择式排序&#xff1a;属于内部排序法,从欲排序的数据中,按指定的规则选出某一元素&#xff0c;再依规定交换位置后达到排序的目的。 2.我的思想 基本思想:第一次从arr[0]~arr[n-1]中选取最小值&#xff0c;与arr[0]交换&#xff0c;第…

【C++】类和对象(7)--友元, static成员

目录 一 友元 1 友元概念 2 友元函数 3 友元类 二 static成员 1 概念 2 用法 3 static成员特性 4 例题 一 友元 1 友元概念 友元提供了一种突破封装的方式&#xff0c;有时提供了便利。但是友元会增加耦合度&#xff0c;破坏了封装&#xff0c;所以 友元不宜多用。 …

2023年高压电工证考试题库及高压电工试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年高压电工证考试题库及高压电工试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机出的高压…

【碰碰球】弹珠游戏-微信小程序项目开发流程详解

还记得小时候玩过的弹珠撞击游戏不&#xff0c;这里把它的实现原理通俗易懂地讲一下&#xff0c;看看怎样实现一个碰碰球(弹珠)小游戏&#xff0c;除了个人玩法&#xff0c;也可以双人玩哦&#xff0c;与打乒乓球一样的&#xff0c;可练习临场反应。 创建项目 打开微信开发者…

前端面试:如何实现并发请求数量控制?

题目&#xff1a;实现一个并发请求函数concurrencyRequest(urls, maxNum) 要求如下&#xff1a; 要求最大并发数 maxNum;每当有一个请求返回&#xff0c;就留下一个空位&#xff0c;可以增加新的请求;所有请求完成后&#xff0c;结果按照 urls 里面的顺序依次打出&#xff1b;…

DE算法简介

文章目录 前言一、DE是什么&#xff1f;二、DE流程2.1 初始化种群2.2 变异&#xff08;差分操作&#xff09;2.3 交叉2.4 选择2.5 重复迭代 三、DE运行结果 前言 这两天看了DE算法&#xff0c;简单说下自己的认识 一、DE是什么&#xff1f; 百科定义&#xff1a;差分进化算…

Vue+ElementUI技巧分享:自定义表单项label的文字提示

文章目录 概要在表单项label后添加文字提示1. 使用 Slot 自定义 Label2. 添加问号图标与提示信息 slot的作用详解1. 基本用法2. 具名插槽 显示多行文字提示的方法1. 问题背景2. 实现多行内容显示3. 样式优化 结语 概要 在Vue和ElementUI的丰富组件库中&#xff0c;定制化表单是…

Linux进程间通信之匿名管道

文章目录 为什么要有进程间通信pipe函数共享管道原理管道特点管道的四种情况 管道的应用场景&#xff08;进程池&#xff09;ProcessPool.ccTask.hpp 为什么要有进程间通信 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享…

Vue3-自定义hook函数

Vue3-自定义hook函数 功能&#xff1a;可以将组合式API封装成一个函数&#xff0c;用于解决代码复用的问题。注意&#xff1a;需要在src文件夹下创建一个文件夹hooks&#xff0c;在里面放js文件&#xff0c;命名随意&#xff0c;主要是将setup函数中的代码放入js文件中。 // s…

Windows10下Maven3.9.5安装教程

文章目录 1.下载maven2.安装3.配置系统变量3.1.新建系统变量 MAVEN_HOME3.2.编辑系统变量Path 4.CMD命令测试是否安装成功5.配置maven本地仓库6.配置国内镜像仓库 1.下载maven 官网 https://maven.apache.org/download.cgi 点击下载。 2.安装 解压到指定目录 D:\installSoft…

计算机硬件的基本组成

一、冯诺依曼结构 存储程序&#xff1a; “存储程序”的概念是指将指令以二进制代码的形式事先输入计算机的主存储器&#xff0c;然后按其在存储器中的首地址执行程序的第一条指令&#xff0c;以后就按该程序的规定顺序执行其他指令&#xff0c;直至程序执行结束。 冯诺依曼计…

io多路复用:select、poll和epoll

1、为什么使用多路复用&#xff1a; 1.1单线程BIO监听socket 多路复用一般用于网络io当中&#xff0c;提到网络io我们肯定能想到socket。如果我们想要一个线程单纯的用向下文的方式监听很多个socket看他是否有事件发生&#xff0c;那这样是不可行。 但上一个socket1没有可读事…

Codewhisperer 使用评价

最近亚⻢逊推出了一款基于机器学习的 AI 编程助手 Amazon CodeWhisperer&#xff0c;可以实时提供代码建议。在编写代码时&#xff0c;它会自动根据现有的代码和注释给出建议。Amazon CodeWhisperer 与GitHub Copilot类似&#xff0c;主要的功能有: 代码补全注释和文档补全代码…

Banana Pi BPI-W3之RK3588安装Qt+opencv+采集摄像头画面.

场景&#xff1a;在Banana Pi BPI-W3 RK3588上做qt开发工作RK3588安装Qtopencv采集摄像头画面 2. 环境介绍 硬件环境&#xff1a; Banana Pi BPI-W3RK3588开发板、MIPI-CSI摄像头( ArmSoM官方配件 )软件版本&#xff1a; OS&#xff1a;ArmSoM-W3 Debian11 QT&#xff1a;QT5…