Ceph分布式存储系统优化分析

        Ceph支持多种存储访问接口,现有的多种性能测试工具都可用于Ceph的性能测试,如测试块接口性能的fio,iometer等;测试CephFS接口的filebench,fio等;测试对象接口的cosbench等。Ceph有专用的基准测试集CBT,其包含radosbench,librbdfio,kvmrbdfio和rbdfio。radosbench基准测试使用ceph common软件包附带的rados二进制文件,通过对象接口来访问Ceph集群。剩下的3个工具都是测试块存储性能的。

  • librbdfio基准模块通过用户态librbd库来测试RBD的块存储性能。

  • kvmrbdfio基准测试要求在使用CBT之前创建虚拟机实例,并挂载RBD块设备。

  • rbdfio基准测试使用内核进行驱动并将其映射到块设备的RBD块设备上。Teuthology是一个Ceph自动化测试的框架,可以在指定节点运行测试用例,也可以用于性能的测试。

        对Ceph系统进行持续的性能监控可以了解集群运行状况,及早发现性能瓶颈。Ceph提供了命令行接口输出性能相关的统计数据。OSD以PG为单位收集性能数据并定期发给Monitor节点。Monitor节点汇总性能数据并同步至其他Monitor节点。我们也提出了一种针对Ceph存储系统层进行分层性能监测和采集的框架,以及一种通过Ceph电文来分析系统性能和瓶颈的方法。

1、Ceph存储系统的特点和挑战

本节总结了Ceph分布式存储系统的特点和面临的挑战。

(1)Ceph存储系统的优点

  • 1)高性能。针对并发量大的异步IO场景,随着集群规模的扩大,Ceph可提供近线性的性能增长。

  • 2)高可扩展性。Ceph通过CRUSH算法来实现数据寻址。这种方法避免了元数据访问的瓶颈,使集群的存储容量可以轻易扩展至PB级,甚至EB级。

  • 3)统一存储,适用范围广。Ceph支持块、文件和对象存储,可满足多种不同的需求。底层的RADOS可扩展并支持不同类型的存储服务。

  • 4)支持范围广。自2012年起,Linux内核开始支持Ceph,目前Ceph可以在几乎所有主流的Linux发行版和其他类UNIX系统上运行。自2016年起,Ceph开始支持ARM架构,同时也可适用于移动、低功耗等领域,其应用场景覆盖了当前主流的软硬件平台。

(2)Ceph面临的挑战

  • 1)Ceph底层采用定长的对象存储,为了保证对象级别的原子性,底层存储引擎的写放大问题严重影响了性能。

  • 2)Ceph的数据分布算法CRUSH在实际环境中存在一些问题,包括扩容时数据迁移不可控、数据分布不均衡等。这些问题影响了Ceph性能的稳定性。

  • 3)Ceph对新型存储介质的支持较差。在使用高速存储介质时,软件造成的时延比硬件导致的时延高出数十倍。社区也在开发面向新型存储介质的存储引擎。

  • 4)Ceph的架构复杂,抽象层次多,时延较大。虽然Ceph采用面向对象的设计思想,但其代码内对象间的耦合严重,导致不同版本间的接口不兼容。针对不同版本的性能优化技术和方法也互相不兼容。

  • 5)Ceph是一个通用的分布式存储系统,可应用于云计算、大数据和高性能计算等领域。针对不同的访问负载特征,Ceph还有较大的性能提升和优化空间。

        Ceph是一个通用的分布式文件系统,适用于不同的场景。内部机制的优化对所有的场景都会产生性能的提升,但是优化的难度和复杂度也最高。

2、存储引擎的优化

        在分布式存储系统中,数据被分散在大量的存储服务器上,大部分分布式存储系统都直接使用本地文件系统来存储数据,如HDFS、,Lustre等。高性能、高可靠的分布式存储系统离不开高效、一致、稳定、可靠的本地文件系统。Ceph存储引擎的优化,参考“Ceph分布式存储系统架构研究综述”。

3、网络通信的优化

        在分布式存储系统中,节点间需要通过网络通信来交换状态和数据。Ceph有3种类型的通信模式,分别是Simple,Async和XIO。Simple线程模式对每个网络连接都创建了两个线程,分别用于接收和发送。Ceph集群中OSD、Monitor节点及客户端之间都需要建立连接。随着集群规模的增长,创建的连接数和线程数会呈指数级增长,需要消耗更多的CPU和内存资源。在内存有限的情况下,Simple模式将导致大量线程的频繁切换以致内存耗尽。Async模式将连接和线程分开,通过线程池管理来维护线程的使用,用户可设置线程池中线程的数量。这是目前被广泛采用的方式,自2017年发布Kraken版本后,这已经成为默认的通信模式。XIO模式使用了开源的网络通信库accelio来实现,现今仍处于实验阶段。目前针对网络通信优化的研究都是基于Async通信模式实现的。

        Async模式使用线程池,可兼顾资源和性能的平衡,但早期其设计是基于循环的简单调度方案,未考虑传输数据大小和线程负载。这种早期设计会导致工作线程负载不平衡,在高负荷情况下产生一些性能问题。Han等提出了一种用于Ceph文件系统的动态消息感知通信的调度程序,以解决工作线程调度不平衡的问题,从而提高性能。他提出的调度算法根据传入消息的类型来平衡工作线程的工作量,同时避免了工作线程之间不必要的连接转换。

        一方面,该算法将低优先级消息(例如来自心跳连接的消息)分配给特定线程,以免干扰其他高优先级消息。另一方面,高优先级消息被平均分配给每个工作线程,以平衡线程之间的工作负载。同时其使用遗传算法(GA)来使不必要的连接转换最小化。测试结果表明,在相同的客户端工作负载下,该方法比原始Asyncmessenger的性能高出12.5%,在客户端的随机工作负载下,其性能比原始Asyncmessenger高出24%。

        优化Asyncmessenger还可以通过将多个工作线程分配给单个连接来处理来自该连接的流量。但是,由于多个线程争用访问连接中的共享资源,这种映射结构会引起与锁定维护有关的另一种开销。

        Ceph的Luminous版本将Async网络通信模型作为默认的通信方式。虽然Async实现了IO的多路复用,使用共享的线程池来实现异步发送和接收任务,但是如何平衡Async工作线程的负载也是一个值得关注的问题。下表总结了几种常见的算法的优化方案。

图片

        RDMA是一种低延迟、高性能的网络传输协议,已被广泛应用于高性能计算环境中。为了在Ceph中利用RDMA以实现高速的数据传输,开发社区提出了两种方案。

        第一种方案是降低Ceph对网络层状态的要求,减少Messenger需要实现的逻辑。现在的XioMessenger规定的语义和策略过于复杂,使用新的网络协议实现的难度大;减少Messenger的逻辑则需要增加上层的逻辑。

        第二种方案是基于目前的AsyncMessenger的框架,扩展出支持RDMA的网络后端而无需关心上层的会话逻辑。国内的XSKY公司和Mellanox公司合作提出了基于AsyncMessenger的网络通信引擎。这种修改使用RDMA的双边通信机制,性能提升有限。并且在当前版本的代码实现中,RDMA只可用于客户端与服务器之间、服务器与服务器之间的通信,不能在两个网络中同时被应用,这也限制了该方案的应用。

 

4、数据放置方法的优化

        经典Ceph存储系统在副本模式下选择存储节点时,仅以节点存储容量为唯一选择条件,并没有考虑到网络和节点的负载状况,这影响了系统在网络性能差和节点高负载的情况下的读写性能。为解决这些问题,文献设计了基于软件定义网络技术的Ceph存储系统模型和存储节点选择策略,首先利用软件定义网络技术实时获取网络和负载状况,以简化网络配置和减小测量开销,然后通过建立并求解出综合考虑了多种因素的多属性决策数学模型来确定存储节点的位置。

        在实际环境中对设计的存储节点选择方法进行读写操作的测试,结果表明,与现有的CRUSH算法相比,提出的存储节点选择方法可以在保持与原有Ceph系统相同的写操作性能的同时,针对4KB对象的100%读操作的响应时间比原有的Ceph集群的缩短了10ms左右,针对4096KB对象的100%读操作响应时间相对缩短了120ms左右。这种方法需要获取网络的实时性能以用于数据放置策略的调整,引入了网络负载采集的开销,在大规模集群场景下应用受限。并且由于该方法会频繁更新CRUSH算法的参数,其读取性能会有所下降。

5、配置参数性能调优

        Ceph存储系统的可配置参数有1500多个,参数的调整对系统性能有较大的影响。默认配置针对不同的硬件和应用通常不是最优配置。通过锁优化和系统参数调优技术使系统的吞吐率提升了1.6倍,但其并未讨论修改了哪些配置参数。虽有文献详细介绍了在全闪存环境下需要调整哪些参数(包括内核、文件系统、磁盘缓存、RADOS和RBD等),但是没有给出调整前后的性能对比。

        Intel开发并开源了一个性能优化工具CeTune,该工具可用于Ceph集群的部署、测试、分析和调优。该工具是一个交互性的调优工具,尚不能自动寻找最优配置。分布式存储系统的性能调优仍是一个具有挑战性的问题。参数组合导致问题解空间大,且参数之间会互相影响。在数据库领域已有一些利用机器学习和决策树的方法进行自动调优的成功案例,而在分布式存储系统领域,相关研究仍处于起步阶段。

面向特定硬件环境的优化

        随着3DXpoint和非易失内存等技术的发展与成熟,最快的存储介质性能已接近内存性能。使用新型存储器件的系统中软件已成为瓶颈。如图所示,HDD,SATASSD,NVMe NANDSSD,3 DXPointStorage,3DXPoint Memory系统中的软件造成的延迟分别是0,10%,20%,40%和90%。通过重构软件的体系结构来充分发挥高速存储介质的性能是目前的一个研究热点。

图片

5.1 固态存储

        固态存储设备相比磁盘设备,在性能、功耗和机架密度上具有显著的优势。SATA接口限制了固态存储设备的最大吞吐率。Intel提出的利用PCIE总线来访问固态存储的NVMe接口方法提供了通用的高速存取方案。使用NVMe的固态存储设备在吞吐量和延迟性能上比传统的磁盘高出1-2个数量级,因此在总的IO处理时间中,软件造成的延迟占据更大的比例。现有的存储系统为低速硬件设计了合并写、异步写等机制,但是这些机制并不适用于高速存储设备。随着存储设备性能的进一步提升,存储系统软件栈的性能和效率对存储系统的影响越来越大。存储系统因受制于低效冗余的软件栈而不能充分发挥硬件性能。

        SPDK是Intel提出的使用NVMeSSD作为后端存储的应用软件加速库。该软件库的核心是实现用户态、异步、无锁、轮询方式的NVMe驱动。虽然SPDK等新型驱动可以将NVMeSSD的性能最高提高6倍,但是在Ceph中直接使用SPDK却没有明显的性能提升。其主要原因在于在BlueStore的处理中有很多线程协作,线程间的互斥和切换开销较大。

        在Ceph中,OSD使用异步IO等待IO完成,多线程可以充分利用NVMeSSD多通道的特点来提升性能。由于一个OSD无法充分利用NVMeSSD的带宽,研究人员发现将NVMeSSD进行分区,然后在其上运行多个OSD可显著提高性能。图给出了一个NVMeSSD分别使用1个OSD、2个OSD和4个OSD时的性能,可以看到在1个SSD上运行4个OSD时的随机读,其IOPS增长很快但延迟增长缓慢。

        但是将SSD分区并同时支持多个OSD也有一些缺点,如降低了可靠性、小块随机写延迟增大、需要更多内存和CPU资源等。另一项对于随机写的测试结果如图所示,在1个SSD上运行2个OSD时的IOPS与运行4个OSD时的IOPS相近,且需要的CPU资源更少。使用多个OSD的提升效果与SSD的性能和CPU的性能相关,且需要占用较多的CPU和内存资源,对可用性也有影响,因此不适用于大规模生产环境。

图片

        除了NVMe以外,现在还有一些使用SATASSD来代替HDD的策略,但直接替换存储介质的性能提升有限。Ceph针对HDD设计了很多异步和调整写顺序的机制,但这些机制反而降低了SSD的性能。当使用Ceph集群和全闪存SSD进行4K随机写入/读取的性能测试时,随机写入性能也只能达到16KIOPS。当线程数增加到32个及以上时,IOPS几乎保持不变,且延迟急剧增加。随机读取时,当线程数少于32时,IOPS较低,且延迟较高。

 

5.2 非易失内存

        存储是数据密集型系统中最慢的组件。尽管基于NVMe的固态驱动器提供了更快、更持久的存储,IO性能已大大提高,但其仍然比系统中的其他组件慢。随着NVDIMM产品的出现,可字节寻址的非易失性存储器将提供与内存相近的IO性能。

        Intel将Client端的NVM作为缓存,提出了3个优化方案,大大提升了块存储接口的访问性能。

  • 方案一提出由于Ceph快照中的父对象是只读的,Client端将其缓存在本地SSD中以提高读取性能。但该方案仅缓存特定的不变对象,不具有通用性。

  • 方案二利用Client端的NVM实现了一个写回缓存,写入NVM的数据并将其不定期刷新至OSD中。该方案性能提升的效果明显,能将99.99%的写入延迟缩短到1/10以下。但是因为在客户端发生故障时,保存在NVM中的数据没有写入Ceph后端的OSD,所以会造成数据不一致。

  • 为了解决这个问题,方案三通过RDMA技术为Client节点和OSD节点的NVM空间建立镜像,以避免因Client故障导致的数据丢失。复制写日志机制将数据同时持久化至Client和OSD的NVM中,当Client不发生故障时,OSD仅提供镜像空间,无需额外的CPU等资源。基于客户端的缓存性能提升明显,但为每个客户端配置NVM和RDMA的成本较高,且该方案并未充分利用OSD端的NVM特性。

5.3 混合存储

        在Ceph集群中可以使用SSD作为保存日志或缓存来提高访问性能。Ceph支持使用高速存储设备作为缓存来加速IO性能。目前有两种不同的缓存实现方式:1)在OSD内部使用缓存;2)将高性能节点组成缓存层。

        根据第一种方案,在使用FileStore时,文件系统可以识别并使用异构来存储介质,并将其中的SSD作为缓存,其架构如图7(a)所示。这种方案可以依赖已有的缓存工具(如dm-cache,bcache,FalshCache)来实现该功能,也可以使用现有的多种缓存控制方法。其中,dm-cache作为linux内核的一部分,采用devicemapper机制以允许用户建立混合卷;bcache是linux内核块层缓存,使用SSD作为HDD硬盘的缓存,从而起到加速作用;FlashCache可智能缓存最近读取过的用户数据或元数据,从而加快数据访问。

图片

        第二种方案的实现方式是将独立的设备或节点组成缓存池,在慢速节点保存冷数据,在高性能节点保存热数据。在这种方案中,高速节点被组织成为缓存层,该缓存层也是一个RADOS池,不仅具有持久化的能力,还具有独立的CRUSH策略。该层以下是基于HDD的RADOS池,其可以采用三副本的ReplicatePG作为后端,也可以采用Erasurecoded作为后端。

6、未来展望

        针对前面提到的不同的性能优化方法,本节从Ceph内部机制优化、基于新型硬件和面向不同负载优化这3个方面对性能优化问题的未来研究方向进行了展望。

6.1 Ceph内部机制的优化

        Ceph发展至今,其规模和复杂性不断增大。数据分发、元数据管理和对象一致性保证等方面的逻辑复杂,目前的多线程和加锁机制效率较低。采用新的内存分配机制和高效KV数据来管理子系统可能对性能有所提升。目前内置的性能采集机制不完善,采集内容和方法、性能数据分析这两方面都有改进的空间。

6.2 基于新型特定硬件的优化

        随着新型存储介质的发展,NVM和3D XpointSSD等介质的访问性能比传统HDD提升了2-4个数量级。存储系统优化需通过结合硬件特征来重构存储系统的体系结构,删除冗余抽象和功能,并重新分配软硬件的功能。存储软件中针对传统硬件的优化方法可能会降低性能,如异步写、随机写合并等。SSD的文件转换层的垃圾回收、空间映射与管理功能也可移至软件实现。多种不同性能的介质也将长期共存于存储系统中,根据数据冷热和介质特性自适应实现高性价比的数据分布也是一个研究方向。Ceph虽然已支持RDMA协议,但是双边操作方式性能的提升有限,设计新的通信机制、采用单边操作可进一步提高性能。

 6.3 面向应用场景的自适应优化

        Ceph应用场景众多,不同应用的访问特征和数据分布差异较大。在不同的负载情况下,基于人工制定的存储优化方案不能满足要求。根据不同应用负载的自适应优化技术也是一个挑战,其研究内容包括利用访问标签来实现不同应用的性能服务质量保证以及性能隔离、利用机器学习技术自动寻找最优配置,以及动态的数据预取和迁移。

7、结束语

        本文介绍了Ceph分布式存储系统的发展历史和特点,并从内部优化机制、面向硬件设备和应用场景这3个方面梳理了现有的性能优化方法。作为一个开源的统一存储系统,Ceph提供了高性能、高可扩展性和高可用的块、文件和对象存取功能。Ceph的特点使之被广泛应用于云计算、高性能计算和大数据处理领域。目前,Ceph的性能优化研究工作虽然有一定的进展,但仍有很多问题尚未完全解决。

作者:张 晓、张思蒙、石佳、董聪、李战怀

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

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

相关文章

【数据结构与算法】十大经典排序算法-插入排序

🌟个人博客:www.hellocode.top 🏰Java知识导航:Java-Navigate 🔥CSDN:HelloCode. 🌞知乎:HelloCode 🌴掘金:HelloCode ⚡如有问题,欢迎指正&#…

第57步 深度学习图像识别:CNN可视化(Pytorch)

基于WIN10的64位系统演示 一、写在前面 由于不少模型使用的是Pytorch,因此这一期补上基于Pytorch实现CNN可视化的教程和代码,以SqueezeNet模型为例。 二、CNN可视化实战 继续使用胸片的数据集:肺结核病人和健康人的胸片的识别。其中&…

问DAO成都丨CyberDAO共识会议在成都圆满落幕

过往匆匆,唯有共识绵延;未来已来,愿与智者同谋。2023年8月9日至8月10日,CyberDAO共识会议在成都市大邑县顺利召开,吸引了上百名Web3.0与元宇宙爱好者参与本次会议。CyberDAO大中华区运营团队合伙人JR、漫威、安祈、可乐…

【Rust】Rust学习 第十一章编写自动化测试

Rust 是一个相当注重正确性的编程语言,不过正确性是一个难以证明的复杂主题。Rust 的类型系统在此问题上下了很大的功夫,不过它不可能捕获所有种类的错误。为此,Rust 也在语言本身包含了编写软件测试的支持。 编写一个叫做 add_two 的将传递…

[C++ 网络协议编程] TCP/IP协议

目录 1. TCP/IP协议栈 2. TCP原理 2.1 TCP套接字中的I/O缓冲 2.2 TCP工作原理 2.2.1 三次握手(连接) 2.2.2 与对方主机的数据交换 2.2.3 四次握手(断开与套接字的连接) TCP(Transmission Control Protocol传输控…

无涯教程-Perl - ref函数

描述 如果EXPR为引用,则此函数返回真值;如果未提供EXPR,则为$_。返回的实际值还定义了引用所引用的实体的类型。 内置类型为- REFSCALARARRAYHASHCODEGLOBLVALUEIO::Handle 如果使用bless()函数为变量设置了祝福,则将返回新的数据类型。新的数据类型通常将是一个…

大数据-玩转数据-Flink 自定义Sink(Mysql)

一、说明 如果Flink没有提供给我们可以直接使用的连接器,那我们如果想将数据存储到我们自己的存储设备中,mysql 的安装使用请参考 mysql-玩转数据-centos7下mysql的安装 创建表 CREATE TABLE sensor (id int(10) ) ENGINEInnoDB DEFAULT CHARSETutf8二…

4个简化IT服务台任务的ChatGPT功能

最近几个月,ChatGPT 风靡全球,这是一个 AI 聊天机器人,使用户能够生成脚本、文章、锻炼图表等。这项技术在各行各业都有无穷无尽的应用,在本文中,我们将研究这种现代技术如何帮助服务台团队增强服务交付和客户体验。 什…

最佳实践:如何优雅地提交一个 Amazon EMR Serverless 作业?

《大数据平台架构与原型实现:数据中台建设实战》一书由博主历时三年精心创作,现已通过知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详…

章节7:XSS检测和利用

章节7&#xff1a;XSS检测和利用 测试payload <script>alert(XSS)</script> <script>alert(document.cookie)</script> ><script>alert(document.cookie)</script> ><script>alert(document.cookie)</script> &qu…

golang—面试题大全

目录标题 sliceslice和array的区别slice扩容机制slice是否线程安全slice分配到栈上还是堆上扩容过程中是否重新写入go深拷贝发生在什么情况下&#xff1f;切片的深拷贝是怎么做的copy和左值进行初始化区别slice和map的区别 mapmap介绍map的key的类型map对象如何比较map的底层原…

《Java极简设计模式》第03章:工厂方法模式(FactoryMethod)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 源码地址&#xff1a;https://github.com/binghe001/java-simple-design-patterns/tree/master/j…

腾讯云标准型CVM云服务器详细介绍

腾讯云CVM服务器标准型实例的各项性能参数平衡&#xff0c;标准型云服务器适用于大多数常规业务&#xff0c;例如&#xff1a;web网站及中间件等&#xff0c;常见的标准型云服务器有CVM标准型S5、S6、SA3、SR1、S5se等规格&#xff0c;腾讯云服务器网来详细说下云服务器CVM标准…

NAS搭建指南一——服务器的选择与搭建

一、服务器的选择 有自己的本地的公网 IP 的请跳过此篇文章按需求选择一个云服务器&#xff0c;目的就是为了进行 frp 的搭建&#xff0c;完成内网穿透我选择的是腾讯云服务器&#xff0c;我的配置如下&#xff0c;仅供参考&#xff1a; 4. 腾讯云服务器官网地址 二、服务器…

day9 10-牛客67道剑指offer-JZ66、19、20、75、23、76、8、28、77、78

文章目录 1. JZ66 构建乘积数组暴力解法双向遍历 2. JZ19 正则表达式匹配3. JZ20 表示数值的字符串有限状态机遍历 4. JZ75 字符流中第一个不重复的字符5. JZ23 链表中环的入口结点快慢指针哈希表 6. JZ76 删除链表中重复的结点快慢指针三指针如果只保留一个重复结点 7. JZ8 二…

gitblit-使用

1.登入GitBlit服务器 默认用户和密码: admin/admin 2.创建一个新的版本库 点击图中的“版本库”&#xff0c;然后点击图中“创建版本库” 填写名称和描述&#xff0c;注意名称最后一定要加 .git选择限制查看、克隆和推送勾选“加入README”和“加入.gitignore文件”在图中的1处…

使用IIS服务器部署Flask python Web项目

参考文章 ""D:\Program Files (x86)\Python310\python310.exe"|"D:\Program Files (x86)\Python310\lib\site-packages\wfastcgi.py"" can now be used as a FastCGI script processor参考文章 请求路径填写*&#xff0c;模块选择FastCgiModule&…

一键部署 Umami 统计个人网站访问数据

谈到网站统计&#xff0c;大家第一时间想到的肯定是 Google Analytics。然而&#xff0c;我们都知道 Google Analytics 会收集所有用户的信息&#xff0c;对数据没有任何控制和隐私保护。 Google Analytics 收集的指标实在是太多了&#xff0c;有很多都是不必要的&#xff0c;…

Multi-object navigation in real environments using hybrid policies 论文阅读

论文信息 题目&#xff1a;Multi-object navigation in real environments using hybrid policies 作者&#xff1a;Assem Sadek, Guillaume Bono 来源&#xff1a;CVPR 时间&#xff1a;2023 Abstract 机器人技术中的导航问题通常是通过 SLAM 和规划的结合来解决的。 最近…

优化堆排序(Java 实例代码)

目录 优化堆排序 Java 实例代码 src/runoob/heap/HeapSort.java 文件代码&#xff1a; 优化堆排序 上一节的堆排序&#xff0c;我们开辟了额外的空间进行构造堆和对堆进行排序。这一小节&#xff0c;我们进行优化&#xff0c;使用原地堆排序。 对于一个最大堆&#xff0c;首…