当前位置: 首页 > article >正文

【数据库知识】Mysql进阶-高可用MHA(Master High Availability)方案

mysql高可用MHA(Master High Availability)方案

    • 集群部署模式下的高可用方案
      • 一、高可用架构原理
        • 1. 核心组件
        • 2. 故障切换流程
      • 二、详细部署步骤 (3节点集群)
        • 1. 环境准备
        • 2. 节点配置(以 node1 为例)
        • 3. 初始化集群
        • 4. 部署MySQL Router
      • 三、关键配置说明
        • 1. Group Replication 参数
        • 2. MySQL Router 配置
      • 四、故障切换机制详解
        • 1. 故障检测
        • 2. 切换流程
        • 3. 网络分区处理
      • 五、验证与监控
        • 1. 集群状态检查
        • 2. 故障模拟测试
      • 六、生产环境注意事项
    • 主从模式下的高可用方案
      • 一、高可用架构核心原理
      • 二、主流高可用方案
        • 方案1:MHA(Master High Availability)
        • 方案2:Keepalived + VIP
        • 方案3:ProxySQL中间件
    • 关联知识

集群部署模式下的高可用方案

以下是 MySQL 8.x 高可用集群的部署方案及原理详解,以 InnoDB Cluster(基于MySQL Group Replication和MySQL Router)为核心实现:

一、高可用架构原理

1. 核心组件
组件作用
Group Replication基于Paxos协议的多主/单主同步复制,实现数据一致性
MySQL Router提供读写分离和故障转移的中间件
MySQL Shell管理集群的自动化工具
2. 故障切换流程
App Router Primary Secondary Group 写请求 路由到主节点 响应 返回结果 主节点宕机 检测到Primary离线 选举新Primary 自动切换路由 新写请求 路由到新主 App Router Primary Secondary Group

二、详细部署步骤 (3节点集群)

1. 环境准备
# 所有节点执行
systemctl stop firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
yum install -y mysql-server mysql-shell mysql-router
2. 节点配置(以 node1 为例)
# /etc/my.cnf (所有节点)
[mysqld]
# 通用配置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid# Group Replication 配置
server_id = 1  # 每个节点唯一
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_checksum = NONE
log_bin = mysql-bin
log_slave_updates = ON
binlog_format = ROW
master_info_repository = TABLE
relay_log_info_repository = TABLE
transaction_write_set_extraction = XXHASH64# Group Replication 核心参数
plugin_load_add = 'group_replication.so'
group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"  # UUID
group_replication_start_on_boot = OFF
group_replication_local_address = "node1:33061"  # 内部通信端口
group_replication_group_seeds = "node1:33061,node2:33061,node3:33061"
3. 初始化集群
# 在第一个节点(node1)执行
mysqlsh
\connect root@node1
dba.configureInstance('root@node1', {password: 'StrongPass123!'})
dba.createCluster('myCluster')
\sql SET PERSIST group_replication_bootstrap_group=ON;
\js cluster = dba.getCluster()
cluster.addInstance('root@node2:3306', {password: 'StrongPass123!'})
cluster.addInstance('root@node3:3306', {password: 'StrongPass123!'})
4. 部署MySQL Router
# 任一节点执行
mysqlrouter --bootstrap root@node1:3306 --directory /opt/mysqlrouter --user=mysql
systemctl start mysqlrouter

三、关键配置说明

1. Group Replication 参数
参数说明
group_replication_consistency一致性级别(EVENTUAL/BEFORE/…)
group_replication_flow_control流量控制防止节点过载
group_replication_exit_state_action节点退出时的行为(ABORT_SERVER/OFFLINE_MODE)
2. MySQL Router 配置
# /opt/mysqlrouter/mysqlrouter.conf
[DEFAULT]
logging_folder = /var/log/mysqlrouter
runtime_folder = /var/run/mysqlrouter
data_folder = /opt/mysqlrouter/data[routing:rw]
bind_address = 0.0.0.0
bind_port = 6446
destinations = metadata_cache://myCluster/default?role=PRIMARY[routing:ro]
bind_address = 0.0.0.0
bind_port = 6447
destinations = metadata_cache://myCluster/default?role=SECONDARY

四、故障切换机制详解

1. 故障检测

• 心跳机制:节点间每1秒发送心跳包

• 超时判定:连续5次未收到响应视为节点故障(默认5秒)

2. 切换流程
  1. 故障确认:剩余节点通过多数派投票确认主节点失效

  2. 新主选举:基于以下优先级自动选举:
    • 节点权重(group_replication_member_weight

    • 数据最新的节点

    • 启动顺序

  3. 路由切换:MySQL Router 2秒内更新路由表

3. 网络分区处理

• 脑裂防护:采用 group_replication_unreachable_majority_timeout(默认3小时)

• 恢复策略:

# 被隔离节点恢复后执行
STOP GROUP_REPLICATION;
START GROUP_REPLICATION;

五、验证与监控

1. 集群状态检查
-- 查看集群成员
SELECT * FROM performance_schema.replication_group_members;-- 检查同步延迟
SHOW STATUS LIKE 'group_replication%delay';
2. 故障模拟测试
# 在Primary节点执行
systemctl stop mysqld# 观察自动切换
mysqlsh -e "dba.getCluster().status()"
  1. 监控指标
    | 指标 | 健康标准 |
    |-------------------------------|----------------------------|
    | group_replication_primary | 显示有效IP地址 |
    | group_replication_delay | 延迟 < 100ms |
    | group_replication_members | 存活节点数 ≥ (N/2 + 1) |

六、生产环境注意事项

  1. 网络要求:
    • 节点间RTT < 2ms

    • 使用10Gbps以上网络

    • 禁用UDP协议的ECN功能(避免数据包乱序)

  2. 安全配置:

    -- 创建专用账户
    CREATE USER 'cluster_admin'@'%' IDENTIFIED BY 'SecurePass!';
    GRANT ALL PRIVILEGES ON *.* TO 'cluster_admin'@'%' WITH GRANT OPTION;-- 启用SSL加密
    SET GLOBAL group_replication_ssl_mode = "REQUIRED";
    
  3. 备份策略:

    # 物理备份建议
    mysqlbackup --user=root --password=xxx --backup-dir=/backup --compress \
    --include-databases="mydb" --ssl-mode=REQUIRED
    

通过以上方案,MySQL集群可在30秒内完成自动故障转移,RPO=0(零数据丢失),RTO<60秒,满足金融级高可用要求。

主从模式下的高可用方案

以下是MySQL主从模式下实现高可用性的完整方案及原理详解,包含多种主流实现方式:

一、高可用架构核心原理

异步复制
健康检查
故障切换
应用层
VIP/Proxy
Master
Slave
监控节点

关键机制:

  1. 故障检测:通过心跳检测(2-5秒)判断主库状态
  2. 自动切换:VIP漂移或连接重定向到新主
  3. 数据一致性:确保切换后新主数据完整性
  4. 脑裂防护:使用多数派确认机制

二、主流高可用方案

方案1:MHA(Master High Availability)

部署步骤:

  1. 环境准备(所有节点):
# 安装Perl模块
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager# 下载MHA
wget https://github.com/yoshinorim/mha4mysql-manager/archive/refs/tags/v0.58.tar.gz
tar zxvf v0.58.tar.gz && cd mha4mysql-manager-0.58
perl Makefile.PL && make && make install
  1. 配置SSH互信:
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@master
ssh-copy-id -i ~/.ssh/id_rsa.pub root@slave1
  1. 配置文件:
# /etc/mha/app1.cnf
[server default]
manager_workdir=/var/log/mha/app1
manager_log=/var/log/mha/app1/manager.log
ssh_user=root
repl_user=repl
repl_password=Repl@1234[server1]
hostname=master
candidate_master=1[server2]
hostname=slave1
no_master=1
  1. 启动管理节点:
masterha_manager --conf=/etc/mha/app1.cnf

切换过程:

  1. 检测主库不可达(连续3次失败)
  2. 确认从库数据一致性
  3. 提升最优先从库为新主
  4. 修改其他从库指向新主
  5. 通知应用VIP切换
方案2:Keepalived + VIP

配置示例:

  1. Master节点keepalived.conf:
vrrp_script chk_mysql {script "/etc/keepalived/check_mysql.sh"interval 2weight 2
}vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.1.200/24}track_script {chk_mysql}
}
  1. 健康检查脚本:
#!/bin/bash
# /etc/keepalived/check_mysql.sh
if ! mysql -uroot -p$password -e "SELECT 1" >/dev/null 2>&1; thensystemctl stop keepalivedexit 1
fi
exit 0

切换特点:
• VIP漂移时间:3-5秒

• 需配合半同步复制使用

• 需要人工介入修复原主

方案3:ProxySQL中间件

架构实现:

App
ProxySQL
Master
Slave1
Slave2

关键配置:

-- 添加后端节点
INSERT INTO mysql_servers(hostgroup_id, hostname, port) 
VALUES 
(10, 'master', 3306),
(20, 'slave1', 3306),
(20, 'slave2', 3306);-- 配置读写分离规则
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup)
VALUES
(1, 1, '^SELECT', 20),
(2, 1, '.*', 10);-- 设置健康检查
UPDATE global_variables SET variable_value='2000' 
WHERE variable_name='mysql-monitor_slave_lag_when_null';LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

自动切换流程:

  1. 每1秒执行SELECT @@read_only检查
  2. 标记连续失败节点为OFFLINE_SOFT
  3. 自动将流量路由到新主
  4. 通过Galera或Group Replication同步配置

三、数据一致性保障

  1. 半同步复制配置
# master配置
[mysqld]
plugin_load = "rpl_semi_sync_master=semisync_master.so"
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000  # 1秒超时# slave配置
[mysqld]
plugin_load = "rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_slave_enabled = 1
  1. GTID模式启用
-- 所有节点执行
SET GLOBAL gtid_mode = ON;
SET GLOBAL enforce_gtid_consistency = ON;-- my.cnf配置
[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON

四、异常处理机制

  1. 脑裂防护措施
# 切换前状态检查脚本
CURRENT_MASTER=$(mysql -h vip -P 3306 -uroot -p$pass -e "SELECT @@server_id" -sN)
if [ "$CURRENT_MASTER" != "$EXPECTED_MASTER" ]; thenecho "Split brain detected!" >&2exit 1
fi
  1. 数据补偿机制
-- 使用pt-table-checksum校验数据一致性
pt-table-checksum --replicate=test.checksums u=root,p=password,h=vip-- 使用pt-table-sync修复差异
pt-table-sync --execute --sync-to-master h=slave1,D=test,t=users

五、监控指标建议

监控项预警阈值检测方法
主从延迟> 60秒SHOW SLAVE STATUS
主库可用性连续3次失败mysqladmin ping
半同步ACK等待> 500msStatus变量监控
复制线程状态Not runningSHOW PROCESSLIST
磁盘空间使用率> 85%df -h

六、方案对比选型

方案切换时间数据一致性复杂度适用场景
MHA10-30s强一致中小规模生产环境
Keepalived3-5s最终一致简单主从架构
ProxySQL1-2s最终一致读写分离复杂架构
Orchestrator5-10s强一致大规模跨机房部署

推荐组合:
金融场景:MHA + 半同步复制 + ProxySQL
互联网场景:Orchestrator + 异步GTID + 读写中间件

通过以上方案,MySQL主从架构可实现99.95%以上的可用性,RTO(恢复时间目标)控制在30秒以内,RPO(数据恢复点目标)趋近于零。

关联知识

【分布式技术】分布式共识算法Paxos

相关文章:

【数据库知识】Mysql进阶-高可用MHA(Master High Availability)方案

mysql高可用MHA&#xff08;Master High Availability&#xff09;方案 集群部署模式下的高可用方案一、高可用架构原理1. 核心组件2. 故障切换流程 二、详细部署步骤 (3节点集群)1. 环境准备2. 节点配置&#xff08;以 node1 为例&#xff09;3. 初始化集群4. 部署MySQL Route…...

Web 架构之会话保持深度解析

文章目录 一、引言二、会话保持的基本概念2.1 什么是会话2.2 为什么需要会话保持 三、会话保持的常见实现方式3.1 基于客户端的会话保持3.1.1 Cookie 方式3.1.2 URL 重写方式 3.2 基于服务器端的会话保持3.2.1 负载均衡器会话保持3.2.2 会话共享 四、会话保持可能遇到的问题及解…...

微信小程序仿淘宝拍照/照片点位识图、点位裁剪生图、图片裁剪组件、图片点位框选、裁剪生成图片,canvasToImg

实现效果 效果&#xff1a; 1.微信小程序仿淘宝拍照/照片点位识图、根据点位裁剪生图、图片可裁剪、图片高度可控 2.识别点位自动生成标准构图方案&#xff0c;支持手动微调实现像素级精准裁剪 3.可以根据接口识别的点位信息实现拍照/相册图片特征点自动识别并裁剪 实现步骤 …...

attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作获取第二维度,第三维度

attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作获取第1 维度,第二维度 attention_weights = torch.ones_like(prompt_embedding[:, :, 0]) 这行代码的作用是创建一个与 prompt_embedding[:, :, 0] 形状相同且所有元素都为 1 的张量,它用于初始化…...

Rust入门之高级Trait

Rust入门之高级Trait - 本文源码 引言 前面学习了迭代器&#xff08;Iterators&#xff09;&#xff0c;Iterator源码中就用到了关联类型的功能。关联类型就属于高级trait的内容&#xff0c;这次我们学习一下高级trait&#xff0c;了解关联类型等知识。关联类型看似和泛型相…...

从 Set、Map 到 WeakSet、WeakMap 的进阶之旅

在 ES5 时代&#xff0c;JavaScript 的数据结构主要依赖于两种类型&#xff1a;数组和对象。然而&#xff0c;随着应用规模的增长和复杂性上升&#xff0c;传统的数据结构越来越难以满足开发需求。比如&#xff0c;需要一个能自动去重的集合、一个支持任意类型键名的字典、一个…...

TTL (Time-To-Live) 解析

文章目录 TTL (Time-To-Live) 解析&#xff1a;网络与Java中的应用一、TTL的定义二、TTL在网络中的应用1. **路由和数据包的生命周期**2. **DNS中的TTL**3. **防止环路** 三、TTL在Java中的应用1. **缓存管理**2. **Java中的ThreadLocal**3. **网络通信中的TTL** 四、TTL的注意…...

Qt/C++开发监控GB28181系统/录像文件查询/录像回放/倍速播放/录像文件下载

一、前言 搞定了实时预览后&#xff0c;另一个功能就是录像回放&#xff0c;录像回放和视频点播功能完全一致&#xff0c;唯一的区别就是发送点播的sdp信息中携带了开始时间和结束时间&#xff0c;因为是录像文件&#xff0c;所以有这个时间&#xff0c;而实时视频预览这个对应…...

季报中的FPGA行业:U型反转,春江水暖

上周Lattice,AMD两大厂商相继发布2025 Q1季报,尽管恢复速度各异,但同时传递出FPGA行业整体回暖的复苏信号。 5月5日,Lattice交出了“勉强及格”的答卷,报告季度营收1亿2000万,与华尔街的预期基本相符。 对于这家聚焦在中小规模器件的领先厂商而言,按照其CEO的预期,长…...

嵌入式机器学习平台Edge Impulse图像分类 – 快速入门

陈拓 2025/05/08-2025/05/11 1. 简介 官方网址 https://edgeimpulse.com/ 适用于任何边缘设备的人工智能&#xff1a; Gateways - 网关 Sensors & Cameras - 传感器和摄像头 Docker Containers - Docker容器 MCUs, NPUs, CPUs, GPUs 构建数据集、训练模型并优化库以…...

web 自动化之 yaml 数据/日志/截图

文章目录 一、yaml 数据获取二、日志获取三、截图 一、yaml 数据获取 需要安装 PyYAML 库 import yaml import os from TestPOM.common import dir_config as Dir import jsonpathclass Data:def __init__(self,keyNone,file_name"test_datas.yaml"):file_path os…...

ARMV8 RK3399 u-boot TPL启动流程分析 --start.S

上电后运行的第一支文件&#xff1a;arch/arm/cpu/armv8/start.S CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK1 #include <asm/arch/boot0.h> 跳转到 arch/arm/include/asm/arch-rockchip/boot0.h CONFIG_SPL_BUILD1 b 1f ROCKCHIP_EARLYRETURN_TO_BROMno TINY_FRAMEWORKno …...

zst-2001 上午题-历年真题 计算机网络(16个内容)

网络设备 计算机网络 - 第1题 ac 计算机网络 - 第2题 d 计算机网络 - 第3题 集线器不能隔离广播域和冲突域&#xff0c;所以集线器就1个广播域和冲突域 交换机就是那么的炫&#xff0c;可以隔离冲突域&#xff0c;有4给冲突域&#xff0c;但不能隔离广播域&#xf…...

使用termius连接腾讯云服务器

使用termius连接腾讯云服务器 1.下载termius termius官网 安装配置教程 这里安装的window版本> 默认安装到C盘&#xff0c;不建议修改路径 可以选择谷歌登录&#xff0c;也可以不登录&#xff0c;软件是免费的&#xff0c;试用的是付费版本&#xff0c;不需要点 2.配置 这里…...

redis 命令大全整理

http://doc.redisfans.com/ 原网址 Redis 命令分类 Key(键) Key(键)命令 exists/del/keys/type/scanobject/move/dump/migratettl/pttl/persist/expireat/pexpireat/expire/pexpirerename/renamenxsort/randomkey/restoreexists 语法:exists key [key ...] 检查一个或多…...

实景三维建模软件应用场景(众趣科技实景三维建模)

实景三维建模软件应用场景概述 实景三维建模软件&#xff0c;作为数字化时代的重要工具&#xff0c;不仅能够真实、立体、时序化地反映和表达物理世界&#xff0c;还为国家的基础设施建设和数字化发展提供了有力的支撑。 在测绘与地理信息领域&#xff0c;实景三维建模软件是构…...

Mac M系列 安装 jadx-gui

安装 Homebrew在终端中执行以下命令&#xff08;需管理员密码&#xff09;&#xff1a; 安装 Homebrew&#xff08;官方源&#xff09; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"国内用户可用镜像源加速&…...

软考 系统架构设计师系列知识点之杂项集萃(56)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;55&#xff09; 第91题 商业智能关注如何从业务数据中提取有用的信息&#xff0c;然后采用这些信息指导企业的业务开展。商业智能系统主要包括数据预处理、建立&#xff08;&#xff09;、数据分…...

Ubuntu20.04 搭建Kubernetes 1.28版本集群

环境依赖 以下操作,无特殊说明,所有节点都需要执行 安装 ssh 服务安装 openssh-server复制代码 sudo apt-get install openssh-server修改配置文件复制代码 vim /etc/ssh/sshd_config找到配置项 复制代码 LoginGraceTime 120 PermitRootLogin prohibit-password StrictModes…...

【Linux】基础指令(Ⅱ)

目录 1. mv指令 2. cat指令 3.echo指令 补&#xff1a;输出重定向 4. more指令 5. less指令 6. head指令和tail指令 7.date指令 时间戳&#xff1a; 8. cal指令 9. alias指令 10.grep指令 1. mv指令 语法&#xff1a;mv [选项]... 源文件/目录 目标文件/目录 …...

RAG之大规模解析 PDF 文档全流程实战

PDF 文档在商业、学术和政府领域无处不在,蕴含着大量宝贵信息。然而,从 PDF 中提取结构化数据却面临着独特的挑战,尤其是在处理数千甚至数百万个文档时。本指南探讨了大规模解析 PDF 的策略和工具。 PDF解析挑战 PDF 的设计初衷是为了提供一致的视觉呈现,而非数据提取。这…...

vue-ganttastic甘特图label标签横向滚动固定方法

这个甘特图之前插件里&#xff0c;没有找到能固定label标签在屏幕上的办法&#xff0c;用css各种办法都没有实现&#xff0c;所以我我直接手写定位&#xff0c;用js监听滚动条滚动的距离&#xff0c;然后同步移动甘特图label标签&#xff0c;造成一种定位的错觉&#xff0c;以下…...

AcroForm JavaScript Promise 对象应用示例: 异步加载PDF文件

这段代码演示了在Adobe Acrobat DC Pro 的 JavaScript 环境中如何使用 Promise 对象处理异步操作。具体功能是&#xff1a; 定义了一个loadFile函数&#xff0c;模拟异步加载PDF文件的操作使用Promise对象封装异步操作&#xff0c;提供成功(resolve)和失败(reject)两种状态通过…...

MySQL 8.0 OCP 1Z0-908 题目解析(2)

题目005 Choose two. Which two actions can obtain information about deadlocks? □ A) Run the SHOW ENGINE INNODB MUTEX command from the mysql client. □ B) Enable the innodb_status_output_locks global parameter. □ C) Enable the innodb_print_all_deadlock…...

【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件

问题场景&#xff1a; 提示&#xff1a;ipa是用于苹果设备安装的软件包资源 设备&#xff1a;iphone 13(未越狱) 安装包类型&#xff1a;ipa包 调试工具&#xff1a;hbuilderx 问题描述 提要&#xff1a;ios包无法安装 uniapp导出ios包无法安装 相信有小伙伴跟我一样&…...

【嵌入模型与向量数据库】

目录 一、什么是向量&#xff1f; 二、为什么需要向量数据库&#xff1f; 三、向量数据库的特点 四、常见的向量数据库产品 FAISS 支持的索引类型 vs 相似度 五、常见向量相似度方法对比 六、应该用哪种 七、向量数据库的核心逻辑 &#x1f50d; 示例任务&#xff1a;…...

【东枫科技】使用LabVIEW进行NVIDIA CUDA GPU 开发

文章目录 工具包 CuLab - LabVIEW 的 GPU 工具包特性和功能功能亮点类似 LabVIEW 的 GPU 代码开发支持的功能数值类型和维数开发系统要求授权售价 工具包 CuLab - LabVIEW 的 GPU 工具包 CuLab 是一款非常直观易用的 LabVIEW 工具包&#xff0c;旨在加速 Nvidia GPU 上的计算密…...

基于策略的强化学习方法之策略梯度(Policy Gradient)详解

在前文中&#xff0c;我们已经深入探讨了Q-Learning、SARSA、DQN这三种基于值函数的强化学习方法。这些方法通过学习状态值函数或动作值函数来做出决策&#xff0c;从而实现智能体与环境的交互。 策略梯度是一种强化学习算法&#xff0c;它直接对策略进行建模和优化&#xff0c…...

1.Redis-key的基本命令

&#xff08;一&#xff09;Redis的基本类型 String&#xff0c;List&#xff0c;Set&#xff0c;Hash&#xff0c;Zset 三种特殊类型&#xff1a;geospatial&#xff08;地理空间数据&#xff09;、hyperloglog[基数估算&#xff08;去重计数&#xff09;]、bitmaps(位图&…...

JavaScript 中级进阶技巧之map函数

作为一名初级 JavaScript 开发者&#xff0c;你可能已经熟悉了基础语法、变量和简单的循环。但要从初级迈向中级&#xff0c;掌握一些高效、优雅的编码技巧是关键。其中&#xff0c;map 函数是中级开发者常用的工具&#xff0c;它不仅能简化代码&#xff0c;还能提升代码的可读…...