Redis中的集群处理

Redis 主从复制详解

        主从复制是 Redis 中重要的高可用性机制。它的核心作用是复制数据,将主节点的数据备份到一个或多个从节点,以达到数据冗余和读写分离的目的。

为什么需要主从复制?

        Redis 是一个单线程的数据库,它只能在一个实例中一次性处理一个写请求。当 Redis 服务器需要处理大量的读写请求时,单节点性能会成为瓶颈。通过主从复制,我们可以增加多个从节点,分担读请求的压力,这样不仅提高了数据的可用性,还能提升读性能。

主从复制的基本角色

  1. 主节点(Master):主节点是负责数据写操作的节点。所有的写请求、数据更改都会发送到主节点来处理。
  2. 从节点(Slave):从节点负责接收主节点的数据副本,更新自己本地的数据以保持和主节点同步。它只接受读请求,不处理写请求,避免了数据不一致的风险。

        在主从架构中,主节点可以连接多个从节点,这些从节点的作用主要是提供读请求服务,从而减轻主节点的负担。

主从复制的详细工作流程

  1. 初次连接和全量同步

    • 从节点启动后,配置主节点地址,并通过命令 slaveof <master_ip> <master_port> 来连接主节点。
    • 一旦连接建立,从节点会请求主节点发送所有数据以完成初始同步。这时主节点会生成一个 数据快照(RDB),并将快照文件传输到从节点。
    • 从节点收到快照后,将自己现有的数据清空,加载主节点传来的快照数据,确保与主节点完全一致。
  2. 增量复制

    • 初次全量同步完成后,从节点会进入增量复制模式。主节点的每一次数据写操作(如设置、更新、删除数据等),都会以指令的方式发送到从节点,从节点逐一执行这些指令来保持数据同步。
    • 增量复制的机制确保了主从数据一致性,减小了数据同步的压力,不需要每次都进行全量传输。
  3. 断开连接与重连

    • 如果主从节点之间的网络短暂断开,再重新连接时,Redis 会自动从 断开位置 开始恢复同步,不需要重新全量同步。
    • Redis 主从复制的这种机制减少了重传数据的开销,并且大大提高了复制的效率。

故障恢复与数据一致性

        在主从复制中,如果主节点出现故障,从节点不会自动成为主节点。Redis 的基本主从复制架构下,故障恢复通常需要手动干预,手动将一个从节点设为新的主节点,再让其他从节点重新复制新主节点的数据。

        Redis 默认采用 异步复制,即主节点在更新数据后,不会等待从节点的响应。虽然这提升了效率,但也意味着在主节点崩溃的瞬间,可能存在一些数据在从节点中还没来得及同步。哨兵模式和集群模式在一定程度上可以弥补这一缺陷。

主从复制的应用场景与优缺点

  • 读写分离:在主从架构中,主节点负责写请求,从节点负责读请求,这样就能扩展从节点数量以分担更多的读请求压力,实现更高的读性能。

  • 数据备份:主从复制是 Redis 中最简单的灾备方案。即使主节点宕机,从节点也可以保留最新的数据副本,保障数据不会完全丢失。

  • 局限性

    • 手动故障恢复:主从复制下如果主节点宕机,从节点不会自动升为主节点。要实现自动故障转移,可以使用哨兵模式。
    • 一致性问题:因为异步复制,主节点崩溃时可能会丢失一些数据。

Redis 哨兵模式详解

        哨兵模式是 Redis 为了实现主从复制架构下的自动故障恢复机制而设计的。哨兵模式的主要作用是监控 Redis 主从节点的状态,并在主节点发生故障时自动进行故障转移,让系统恢复正常运行。

哨兵模式的核心功能

  1. 监控(Monitoring):哨兵会不断检查主节点和从节点是否运行正常。
  2. 自动故障转移(Automatic Failover):当检测到主节点宕机,哨兵会自动从从节点中选出一个新的主节点,确保 Redis 集群正常运作。
  3. 通知(Notification):哨兵可以将故障切换的消息通知给客户端,让客户端可以连接新的主节点。

        通过这三个功能,哨兵模式可以自动化地监控和管理 Redis 集群,提升集群的可用性和自动恢复能力。

哨兵模式的工作原理

1. 哨兵节点的结构

        哨兵模式的核心是多个哨兵节点(Sentinel Nodes),它们可以作为一个“哨兵集群”共同工作。每个哨兵节点会监控 Redis 主节点和从节点的状态,并定期交换信息,以确保判断准确。一般来说,部署多个哨兵节点可以提高监控的可靠性。

2. 节点监控和故障判断

  • 主从节点的心跳检测:哨兵节点定期向主节点和从节点发送PING信号,检查节点的响应是否正常。
  • 下线判断:如果一个 Redis 节点在指定时间内没有响应,哨兵会标记该节点为主观下线。这时,其他哨兵节点也会进行检测,若都认定该节点宕机,则将其标记为客观下线,进入故障转移流程。

3. 故障转移(Failover)

当哨兵确认主节点已客观下线,会启动故障转移

  1. 选举新主节点:哨兵会从原主节点的从节点中选择一个节点作为新的主节点。这一过程基于优先级最新数据同步状态等标准来选择。
  2. 重新配置复制关系:选定新的主节点后,哨兵会将其他从节点重新配置为新主节点的从节点,以确保数据继续同步。
  3. 通知客户端:故障转移完成后,哨兵会通知客户端连接新的主节点,使客户端不受主节点故障的影响。

哨兵模式的优缺点

优点

  • 自动化故障恢复:当主节点出现故障时,哨兵能自动选出新的主节点,恢复集群功能。
  • 提高可用性:通过自动化监控和通知机制,系统整体可靠性提升。

缺点

  • 部署和管理复杂:哨兵模式比单纯的主从复制架构复杂,配置和监控上需要投入更多的精力。
  • 数据一致性:同样存在一定的数据丢失风险,因为哨兵转移的过程仍基于主从复制的异步复制机制。

哨兵模式的应用场景

        哨兵模式适用于对高可用性要求较高的生产环境,特别是在主节点宕机需要自动恢复的情况。哨兵模式结合主从复制,实现了自动化的容错机制,是 Redis 中常见的分布式部署模式之一。

Redis 切片集群模式的详解

        切片集群模式(Sharded Cluster)是 Redis 中一种分布式架构设计,用来扩展 Redis 的存储容量和处理能力。该模式通过将数据拆分成若干部分,并分布到多个节点中,既解决了单节点内存上限的限制,又提升了并发性能。

哈希槽与数据分片机制

        Redis 切片集群中最核心的概念是 哈希槽(Hash Slot)。了解哈希槽的工作机制有助于理解 Redis 集群如何在多个节点间管理数据:

  1. 哈希槽的设计

    • Redis 集群中有 16384 个哈希槽(编号 0 到 16383),这些槽是数据在集群中的基本分片单位。
    • 每个节点会分配若干个哈希槽,负责这些哈希槽中的数据存储与管理。
  2. 数据的哈希计算

    • 当客户端存储数据时,Redis 会对数据键进行哈希计算。计算方法是将键值通过 CRC16 哈希算法生成一个数值,再对 16384 取模得到一个哈希槽编号。
    • 这个哈希槽编号决定了数据被存放的节点。例如,如果键 "user:1000" 的哈希槽编号是 125,则 Redis 集群会将该键值对放入负责槽 125 的节点上。
  3. 哈希槽的动态分配

    • 集群启动时会根据节点的数量,将哈希槽平均分配到每个节点。
    • 随着集群节点的增减,Redis 可以重新分配哈希槽,通过 再平衡操作 将部分哈希槽移动到新节点,从而均衡各节点的数据量。

节点角色与数据同步

        Redis 切片集群中的每个节点都有明确的角色,主要包括主节点从节点

  1. 主节点(Master)

    • 每个主节点负责存储一部分哈希槽中的数据,是数据存取的核心节点。
    • 主节点直接处理读写请求,并负责将数据同步给其从节点。
  2. 从节点(Slave)

    • 从节点作为主节点的备份节点,保持与主节点的数据一致性。
    • 当主节点发生故障时,集群会将其中一个从节点提升为主节点,保证集群的高可用性。
    • 从节点主要用于数据冗余和高可用,不直接参与写请求。

在 Redis 集群中,一个主节点可以有多个从节点,这些从节点会实时同步主节点的数据,确保在主节点故障时能快速恢复服务。

节点间的通信与集群管理

        为了保证数据分片、节点状态和故障转移的协调,Redis 切片集群中的各节点通过 集群总线(Cluster Bus) 相互通信。这种机制使集群能够高效地检测故障、完成哈希槽分配,并执行故障转移。

  1. 集群总线协议

    • Redis 使用 Gossip 协议 在节点之间传播消息。这种协议在分布式系统中很常见,通过定期交换状态信息,节点能够彼此检测是否存活。
    • 每个节点会定期向其他节点发送“PING”消息,如果其他节点正常运行会返回“PONG”消息;如果某个节点长时间未回复,集群会认为该节点可能故障。
  2. 集群配置文件

    • 每个节点在启动时会生成一个集群配置文件(nodes.conf),记录自身节点信息和所有其他节点的状态、哈希槽分配信息等。
    • 这个配置文件会自动更新,确保集群内所有节点都共享相同的集群结构,防止出现不一致的情况。
  3. 节点加入与移除

    • 当新节点加入时,集群会自动重新分配部分哈希槽给新节点,确保数据负载均衡。
    • 节点移除也会触发哈希槽的重新分配,Redis 会将移除节点负责的哈希槽和数据转移到其他节点。

故障转移机制

        Redis 切片集群内置了自动故障转移机制,确保即使某个主节点出现故障,集群仍能持续服务。

  1. 故障检测

    • 通过集群总线协议,节点会定期检查其他节点的状态。当主节点未能在规定时间内响应“PING”请求,其他节点会将其标记为“主观下线”。
    • 如果多个节点都认为该主节点失联,这个主节点会被标记为“客观下线”。
  2. 选举新主节点

    • 当主节点被判定为“客观下线”后,集群会启动故障转移流程。集群中的其他节点会在从节点中选出一个新的主节点。
    • 选举过程遵循 Redis 的故障转移规则:优先选择数据同步状态最新的从节点,确保数据最少丢失。
    • 选定的新主节点会接管故障主节点的哈希槽,并将自己作为客户端的新访问路径。
  3. 数据恢复和通知

    • 新主节点选定后,集群会自动通知客户端更新连接信息,以连接到新的主节点,确保数据访问正常。
    • Redis 切片集群中的客户端通常可以感知到主节点切换,并自动重试连接到新的主节点,以便读取或写入数据。

切片集群的优缺点分析

优点

  • 高可用性和自动恢复:内置的故障转移和从节点选举机制可以有效提升集群的稳定性,即使主节点宕机也能迅速恢复。
  • 弹性扩展:Redis 切片集群可以根据需求增加或减少节点数量,通过哈希槽的动态分配实现负载均衡,适应业务变化。
  • 高并发读写能力:数据分片在多个节点上处理读写请求,极大提升了并发性能。

缺点

  • 数据一致性问题:由于 Redis 默认采用异步复制,主节点故障时可能导致部分数据未同步到从节点,存在一定的数据丢失风险。
  • 运维复杂性:切片集群的配置、监控和维护较为复杂,尤其是在节点、哈希槽分配以及故障恢复等方面需要专业的运维支持。
  • 网络开销:节点之间的频繁通信需要一定的网络开销,在大规模集群中可能成为性能瓶颈。

切片集群的典型应用场景

切片集群广泛应用于高并发访问、大规模数据存储的场景,例如:

  • 社交平台:支持用户状态、消息流等高并发的读写需求。
  • 实时分析:用于处理高频数据访问场景,比如电商系统的用户行为分析。
  • 缓存和会话存储:将会话数据分散存储在集群中,保证高可用性和快速响应。

        这样,Redis 切片集群能够适应复杂的分布式环境需求,为系统提供灵活、可靠的缓存解决方案。

什么是脑裂

  1. 脑裂的基本概念

    • 在分布式系统中,脑裂(Split-Brain)指的是集群中因为网络问题分成了多个彼此孤立的部分,每个部分都“以为”自己是唯一的集群在独立运行。
    • 比如,Redis 集群本来应该是多个节点协同工作,但在脑裂情况下,各节点会因为网络分区等原因变成互相隔离的小集群,各自处理自己的数据,不再同步。
  2. 脑裂在 Redis 中的影响

    • 当 Redis 发生脑裂,多个原本的主节点可能会在不同的隔离小集群中各自运作。因为这些小集群没有彼此的连接,每个小集群都认为自己是“唯一的集群”,导致多个主节点会同时处理读写请求。
    • 这样可能会造成数据不一致数据丢失。等网络恢复后,不同节点上存储的数据可能会互相冲突,导致应用无法正确使用这些数据。

Redis 防止脑裂的解决方案

        脑裂问题对于 Redis 这样的分布式系统来说是一个很大的风险。Redis 提供了一些方法来减少脑裂的影响,确保数据安全。下面是几种常见的解决方案:

使用 Redis 哨兵(Sentinel)监控节点状态

        Redis 的 Sentinel(哨兵)系统可以实时监控集群中每个节点的状态,当节点发生故障或出现脑裂情况时,哨兵会进行相应的操作,比如重新选举主节点。

  • 哨兵的工作机制

    • Sentinel 会周期性地向各个 Redis 节点发送“心跳”信号。如果哨兵在一定时间内没有收到某个节点的响应,它会判断该节点可能发生了问题(比如因为网络分区导致的脑裂)。
    • 如果哨兵认为某个主节点失效,它会在从节点中选出一个新的主节点,保证集群可以继续运行。
  • 解决脑裂的原理

    • 在脑裂情况下,即使主节点因为网络分区而被隔离,哨兵也能帮助协调集群状态,并在网络恢复后重新选举合适的主节点,确保集群数据尽可能一致。
    • 但注意,哨兵本身也依赖于网络,如果哨兵和 Redis 节点间的网络连接不稳定,哨兵可能会误判或未及时探测到脑裂。

设置 min-slaves-to-write 参数,增加写操作的安全性

Redis 提供了一个配置参数 min-slaves-to-write,可以强制要求主节点在写入数据时,必须至少有一定数量的从节点在线并同步成功,才能进行写操作。

  • 配置的作用

    • 当 Redis 集群设置了 min-slaves-to-write 参数后,如果主节点在某一时刻无法连接到足够数量的从节点,它会自动停止接收写请求。
    • 这种机制能有效减少数据不一致的风险,因为主节点在网络分区期间不会随意接受写入请求,避免了孤立节点和其他节点之间的数据冲突。
  • 解决脑裂的原理

    • min-slaves-to-write 确保写操作至少得到多个节点的确认,降低了数据丢失的可能性,即使发生脑裂,数据也不会随意写入,保持数据一致性。
    • 但该参数的设置也会影响写入性能,参数值越高,主节点要求的从节点确认越多,写入操作可能变得更慢。

强一致性协议(如 Raft)实现更严格的数据一致性

Redis 本身采用最终一致性模式(Eventual Consistency),在脑裂情况下可能会有数据不一致。如果业务对一致性要求很高,可以考虑使用 Raft、Paxos 等一致性协议。

  • 强一致性协议的工作原理

    • Raft 和 Paxos 等协议通过让节点间达成共识的方式来保证数据一致性,即在写入数据前,集群中的大部分节点必须同意该操作,才会最终写入数据。
    • 当节点发现网络分区后,会自动暂停操作,直到重新连接并达成共识,确保数据不冲突。
  • 优缺点

    • Raft 等协议能有效避免脑裂带来的数据冲突,但由于协议的复杂性和节点间的共识流程,系统性能会有所下降,特别是写操作的延迟会增加。

使用网络隔离检测工具预防脑裂

Redis 集群还可以借助网络隔离检测工具来预防脑裂。这些工具会持续监控集群节点间的网络连接情况,帮助管理员快速发现网络分区问题。

  • 网络检测的工作方式

    • 检测工具会对 Redis 集群的节点之间的网络状态进行实时监测,一旦发现某个节点的连接异常或者延迟增加,就会警告管理员。
    • 在网络异常期间,检测工具可以隔离有问题的节点,避免其处理写请求,防止数据冲突。
  • 预防脑裂的效果

    • 通过实时检测网络状态,提前识别网络分区问题,并在必要时停止特定节点的操作,可以有效降低脑裂发生的概率。

总结

        在 Redis 集群中,脑裂问题是导致数据丢失和集群不一致的主要风险之一。我们可以通过以下几种方案来降低脑裂的影响:

  1. 哨兵监控:Sentinel 通过监控节点状态,自动进行主从切换,减小脑裂带来的数据丢失风险。
  2. 写入条件限制:设置 min-slaves-to-write 参数,确保写入操作得到多个节点的确认。
  3. 一致性协议:使用 Raft 等一致性协议来保证集群的严格一致性。
  4. 网络隔离检测:通过检测工具预防网络分区,及时隔离故障节点。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML之列表学习记录

练习题&#xff1a; 图所示为一个问卷调查网页&#xff0c;请制作出来。要求&#xff1a;大标题用h1标签&#xff1b;小题目用h3标签&#xff1b;前两个问题使用有序列表&#xff1b;最后一个问题使用无序列表。 代码&#xff1a; <!DOCTYPE html> <html> <he…

【ElasticSearch】定位分片不分配

记录遇到的es集群分片不分配的情况--待补全 定位分片不分配的原因 定位分片不分配的原因 在shell客户端执行如下的语句&#xff1a; curl -X GET "http://192.168.0.209:9200/_cat/shards?v&hindex,shard,prirep,state,unassigned.reason"集群中各分片的状态都…

10款PDF合并工具讲解与推荐!!!

在现在的大环境下&#xff0c;PDF文件因其跨平台、格式固定等优势&#xff0c;成为了我们工作和学习中不可或缺的一部分。是最常用的文档格式之一。然而&#xff0c;面对多个PDF文件需要合并成一个的场景&#xff0c;如何选择一款高效、易用的PDF合并工具就显得尤为重要。今天&…

「QT」窗口类 之 QWidget 窗口基类

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「QT」QT5程序设计&#x1f4da;全部专栏「Win」Windows程序设计「IDE」集成开发环境「UG/NX」BlockUI集合「C/C」C/C程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「UG/NX」NX定制…

【机器学习】如何配置anaconda环境(无脑版)

马上就要上机器学习的实验&#xff0c;这里想写一下我配置机器学习的anaconda环境的二三事 一、首先&#xff0c;下载安装包&#xff1a; Download Now | Anaconda 二、打开安装包&#xff0c;一直点NEXT进行安装 这里要记住你要下载安装的路径在哪&#xff0c;后续配置环境…

【3D Slicer】的小白入门使用指南四

开源解剖影像浏览工具Open Anatomy Browser使用及介绍 和3D slicer米有太大关系,该工具是网页版影像数据的浏览工具(可以简单理解为网页版的3D slicer) 介绍 ● 开放解剖(OA)浏览器是由神经影像分析中心开发的,基于网络浏览器技术构建的图谱查看器。 ● OA浏览器将解剖模…

Unity使用PS合并贴图

前言 使用PBR渲染&#xff0c;金属工作流时&#xff0c;默认使用一个金属度贴图&#xff0c;其中r通道保存金属度&#xff0c;a通道保存光滑度&#xff0c;g通道和b通道没使用&#xff1b; 我们很可能使用Occlusion Map&#xff0c;使用其中的g通道保存Occlusion 信息。单独使用…

Linux中.NET读取excel组件,不会出现The type initializer for ‘Gdip‘ threw an exception异常

组件&#xff0c;可通过nuget安装&#xff0c;直接搜名字&#xff1a; ExcelDataReader using ConsoleAppReadFileData.Model; using ExcelDataReader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Task…

Qt_day4_Qt_UI设计

目录 Qt_UI设计 1. Designer 设计师&#xff08;掌握&#xff09; 2. Layout 布局&#xff08;重点&#xff09; 2.1 基本使用 2.2 高级用法 2.3 代码布局&#xff08;了解&#xff09; 3. Designer与C的关系&#xff08;熟悉&#xff09; 4. 基本组件&#xff08;掌握…

Axure网络短剧APP端原型图,竖屏微剧视频模版40页

作品概况 页面数量&#xff1a;共 40 页 使用软件&#xff1a;Axure RP 9 及以上&#xff0c;非软件无源码 适用领域&#xff1a;短剧、微短剧、竖屏视频 作品特色 本作品为网络短剧APP的Axure原型设计图&#xff0c;定位属于免费短剧软件&#xff0c;类似红果短剧、河马剧场…

网安加·百家讲坛 | 仝辉:金融机构鸿蒙应用安全合规建设方案

作者简介&#xff1a;仝辉&#xff0c;北京娜迦信息科技发展有限公司攻防安全负责人&#xff0c;深耕移动应用安全领域十余年&#xff0c;获得过CISP、CISSP、OSCP、PMP、CCRC-CIASW等相关证书&#xff0c;参与多项移动应用安全标准起草&#xff0c;参与华为、平安集团、中国移…

C语言 strlen 函数 - C语言零基础入门教程

目录 一.strlen 函数简介二.strlen 函数实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.strlen 函数简介 在C 语言中&#xff0c;char 字符串也是一种非常重要的数据类型&#xff0c;我们可以使用 strlen 函数获取字符串长度&#xff1b;…

OceanStor Pacific系列 8.1.0 功能架构

功能架构 华为OceanStor Pacific系列提供基于三层的分布式存储架构&#xff0c;融合分布式文件、对象、大数据和块多个服务形态&#xff0c;支持文件、对象、大数据服务部署在一个集群&#xff0c;并统一管理。 华为OceanStor Pacific系列整体功能架构由存储接口层、存储服务…

Simulink中Matlab function使用全局变量

目录 一. 引言二. 普通Matlab function使用全局变量三. Simulink中的Matlab function使用全局变量四. 如何利用Matlab function的全局变量施加随机噪声 一. 引言 最近发现了之前仿真中的一个问题&#xff0c;记录一下备忘。 Matlab function中有时候需要用到全局变量&#xf…

react-markdown内容宽度溢出和换行不生效问题

情景复现&#xff1a; 解决办法&#xff0c;添加样式进行限制 /* index.css */ .markdown-container {word-break: break-word; /* 强制长单词断行 */white-space: pre-wrap; /* 保留空白符序列&#xff0c;但是正常地进行换行 */overflow-wrap: break-word; /* 在长单词或…

【C#设计模式(10)——装饰器模式(Decorator Pattern)】

前言 装饰器模式可以在运行时为对象添加额外的功&#xff0c;而无需修改原始对象的代码。这种方式比继承更加灵活。 代码 //蛋糕类&#xff08;抽象类&#xff09; public abstract class Cake {public abstract void Create(); } //奶油蛋糕类 public class CreamCake : Cak…

Diffusion Transformer模型结构解析(DiT、SD3、Flux)

Diffusion Transformer模型结构解析&#xff08;DiT、SD3、Flux&#xff09; 本文将通过 DiT、SD3、Flux 三个 DiT 相关工作&#xff0c;介绍 Diffusion 中的 Transformer 结构的应用与演进。注意 SD3 和 Flux 采用的 Flow Matching 的扩散模型形式化当然是很关键的改进&#…

给阿里云OSS绑定域名并启用SSL

为什么要这么做&#xff1f; 问题描述&#xff1a; 当用户通过 OSS 域名访问文件时&#xff0c;OSS 会在响应头中增加 Content-Disposition: attachment 和 x-oss-force-download: true&#xff0c;导致文件被强制下载而不是预览。这个问题特别影响在 2022/10/09 之后新开通 OS…

如何找到系统中bert-base-uncased默认安装位置

问题&#xff1a; 服务器中无法连接huggingface&#xff0c;故需要自己将模型文件上传 ubuntu 可以按照这个链接下载 Bert下载和使用&#xff08;以bert-base-uncased为例&#xff09; - 会自愈的哈士奇 - 博客园 里面提供了giehub里面的链接 GitHub - google-research/be…

【算法】区间DP

基本内容 [!NOte] 通过分治的思想实现DP数组 入门例子 NOI1995] 石子合并 - 洛谷 | 计算机科学教育新生态 题目要求&#xff1a;给定一圈石头数组&#xff0c;每个石头对应一个权重值&#xff0c;当两个石头合并时组成一个小石头堆&#xff0c;成本为两个石头权重值相加&#x…