K8S对接ceph的RBD块存储

1 PG数量限制问题

1.1 原因分析

1.还是老样子,先创建存储池,在初始化为rbd。

[root@ceph141~]# ceph osd pool create wenzhiyong-k8s 128 128
Error ERANGE:  pg_num 128 size 3 for this pool would result in 295 cumulative PGs per OSD
(2067 total PG replicas on 7 'in' root OSDs by crush rule) which exceeds the mon_max_pg_per_osd value
of 250

意思说:创建1个存储池wenzhiyong-k8s且指定PG数量是128,副本3个;将会产生128*3=384个PG

但是集群中每个OSD最多只能有250个PG。我是7个OSD,所以集群最大OSD数量是250*7=1750个

目前集群有多个PG了呢?可以通过ceph osd pool ls detail命令查看并累加得出:1 + 16 + 32 + 32 + 32 + 32 + 32 + 32 + 32 + 32 + 256 + 32 = 561;但是因为3副本机制,所以当前集群的PG数量还要再乘3为1683个,再加上即将创建的384个PG很明显是超过集群的最大PG1750的

在这里插入图片描述

1.2 故障解决方式

  • 上策,增加OSD数量。说白了,就是加设备,加机器。
  • 中策,调大OSD存储PG的上限,可以临时解决,治标不治本,因为随着PG数量增多,会给该磁盘添加I/O压力。
  • 下策,创建存储池时指定略少的PG数量。如:ceph osd pool create wenzhiyong-k8s 2 2
  • 下下策,删除没有用的存储池,已释放PG数量。也可以临时解决,但是要确定的确是没有用的数据,再做操作。

1.临时修改,修改完后可能需要重启集群才能生效。但实测后发现没用

[root@ceph141~]# ceph tell osd.* injectargs --mon-max-pg-per-osd 500
osd.0: {}
osd.0: mon_max_pg_per_osd = '' (not observed, change may require restart) osd_delete_sleep = '' osd_delete_sleep_hdd = '' osd_delete_sleep_hybrid = '' osd_delete_sleep_ssd = '' osd_max_backfills = '' osd_pg_delete_cost = '' (not observed, change may require restart) osd_recovery_max_active = '' osd_recovery_max_active_hdd = '' osd_recovery_max_active_ssd = '' osd_recovery_sleep = '' osd_recovery_sleep_hdd = '' osd_recovery_sleep_hybrid = '' osd_recovery_sleep_ssd = '' osd_scrub_sleep = '' osd_snap_trim_sleep = '' osd_snap_trim_sleep_hdd = '' osd_snap_trim_sleep_hybrid = '' osd_snap_trim_sleep_ssd = '' 
osd.1: {}
...
[root@ceph141~]# ceph osd pool create wenzhiyong-k8s 128 128
Error ERANGE:  pg_num 128 size 3 for this pool would result in 295 cumulative PGs per OSD (2067 total PG replicas on 7 'in' root OSDs by crush rule) which exceeds the mon_max_pg_per_osd value of 250[root@ceph141~]# systemctl reboot docker

2.永久修改方式,/etc/ceph/ceph.conf

[osd]
mon_max_pg_per_osd = 100

最终选择了指定少量的存储池

1.创建K8S特用的存储池
[root@ceph141~]# ceph osd pool create wenzhiyong-k8s 2 2
pool 'wenzhiyong-k8s' created2.创建镜像块设备文件
[root@ceph141 ~]# rbd create -s 5G wenzhiyong-k8s/nginx-web
[root@ceph141 ~]# 
[root@ceph141 ~]# rbd -p wenzhiyong-k8s ls 
nginx-web
[root@ceph141 ~]# 
[root@ceph141 ~]# rbd -p wenzhiyong-k8s info nginx-web
rbd image 'nginx-web':size 5 GiB in 1280 objectsorder 22 (4 MiB objects)snapshot_count: 0id: 12214b350eaa5block_name_prefix: rbd_data.12214b350eaa5format: 2features: layering, exclusive-lock, object-map, fast-diff, deep-flattenop_features: flags: create_timestamp: Fri Aug 23 16:34:00 2024access_timestamp: Fri Aug 23 16:34:00 2024modify_timestamp: Fri Aug 23 16:34:00 20243.ceph集群将ceph管理员的秘钥环keyring拷贝到所有的worker节点
[root@ceph141 ~]# scp /etc/ceph/ceph.client.admin.keyring  10.0.0.231:/etc/ceph/
[root@ceph141 ~]# scp /etc/ceph/ceph.client.admin.keyring  10.0.0.232:/etc/ceph/
[root@ceph141 ~]# scp /etc/ceph/ceph.client.admin.keyring  10.0.0.233:/etc/ceph/

2RBD作为volumes

2.1 基于keyring的方式

cat > 03-rdb-admin-keyring.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-volume-rbd-admin-keyring
spec:replicas: 1selector:matchLabels:apps: ceph-rbdtemplate:metadata:labels:apps: ceph-rbdspec:volumes:- name: datarbd:monitors:- 10.0.0.141:6789- 10.0.0.142:6789- 10.0.0.143:6789# 指定存储池pool: wenzhiyong-k8s# 指定块设备镜像image: nginx-web# 指定文件系统,目前仅支持: "ext4", "xfs", "ntfs"。fsType: xfs# 块设备是否只读,默认值为false。readOnly: false# 指定连接ceph集群的用户,若不指定,默认为adminuser: admin# 指定ceph秘钥环的路径,默认值为: "/etc/ceph/keyring"keyring: "/etc/ceph/ceph.client.admin.keyring"containers:- name: c1image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1volumeMounts:- name: datamountPath: /wenzhiyong-dataports:- containerPort: 80
---apiVersion: v1
kind: Service
metadata:name: svc-rbd
spec:type: NodePortselector:apps: ceph-rbdports:- protocol: TCPport: 80targetPort: 80nodePort: 30033
EOF

1.运用K8S配置文件进入容器测试

/wenzhiyong-data # cd /
/ # rm -rf /wenzhiyong-data/
rm: can't remove '/wenzhiyong-data': Resource busy/ # df -h | grep wen
/dev/rbd0                 5.0G     68.1M      4.9G   1% /wenzhiyong-data
/ # ls -l /dev/rbd0 
ls: /dev/rbd0: No such file or directory/ # umount /wenzhiyong-data/
umount: can't unmount /wenzhiyong-data: Operation not permitted/ # rm -rf /wenzhiyong-data/
rm: can't remove '/wenzhiyong-data': Resource busy

2.查看该pod调度到了worker232节点

[root@master23104-cephfs]# kubectl get pods -o wide
NAME                                               READY   STATUS    RESTARTS   AGE     IP            NODE     
deploy-volume-rbd-admin-keyring-6b94f8cc86-nnpjd   1/1     Running   0          6m37s   10.100.2.45   worker232

3.在worker232节点查看,这个rbd挂载给了pod使用

[root@worker232~]# ll /dev/rbd*
brw-rw---- 1 root disk 252, 0 Nov  8 22:38 /dev/rbd0/dev/rbd:
total 0
drwxr-xr-x 2 root root 60 Nov  8 22:38 wenzhiyong-k8s/[root@worker232~]# df -h | grep rbd
/dev/rbd0       5.0G   69M  5.0G   2% /var/lib/kubelet/plugins/kubernetes.io/rbd/mounts/wenzhiyong-k8s-image-nginx-web

4.删除该应用后,worker232的挂载也随之消失

[root@worker232~]# df -h | grep rbd
[root@worker232~]#

2.2 基于秘钥的方式

1.获取ceph集群的admin账号的key信息并经过base64编码

[root@worker232~]# awk '/key/ {printf "%s", $NF}' /etc/ceph/ceph.client.admin.keyring | more 
AQAlsChnHubLJRAAH2s3vhyGrxgba8anloPDtg==
[root@worker232~]# awk '/key/ {printf "%s", $NF}' /etc/ceph/ceph.client.admin.keyring | base64 
QVFBbHNDaG5IdWJMSlJBQUgyczN2aHlHcnhnYmE4YW5sb1BEdGc9PQ==

2.编写资源清单并把key封装为secret资源

cat > 04-rbd-admin-key.yaml << EOF
apiVersion: v1
kind: Secret
metadata:name: ceph-admin-secret
type: "kubernetes.io/rbd"
data:# 指定ceph的admin的KEY,将其进行base64编码,此处需要修改! key: QVFBbHNDaG5IdWJMSlJBQUgyczN2aHlHcnhnYmE4YW5sb1BEdGc9PQ==
# 注意,data如果觉得麻烦,可以考虑使用stringData
#stringData:
#  key: AQBeYMVm8+/UNhAAV8lxv/CvIm0Lyer1wSp9yA==
---apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-volume-rbd-secrets-keyring
spec:replicas: 1selector:matchLabels:apps: ceph-rbdtemplate:metadata:labels:apps: ceph-rbdspec:volumes:- name: datarbd:monitors:- 10.0.0.141:6789- 10.0.0.142:6789- 10.0.0.143:6789pool: wenzhiyong-k8simage: nginx-webfsType: xfsreadOnly: falseuser: adminsecretRef:# 指定用于存储ceph管理员的secret名称name: ceph-admin-secretcontainers:- name: c1image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v3volumeMounts:- name: datamountPath: /wenzhiyong-dataports:- containerPort: 80
EOF

现象和基于keyring的一样

3RBD结合动态存储类

01 SC

cat > 01-rbd-sc.yaml << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:# 指定集群的ID地址,需要改成自己的集群环境,通过ceph -s可以看到clusterID: 12fad866-9aa0-11ef-8656-6516a17ad6dd# 指定存储池pool: wenzhiyong-k8s# 镜像的特性imageFeatures: layeringcsi.storage.k8s.io/provisioner-secret-name: csi-rbd-secretcsi.storage.k8s.io/provisioner-secret-namespace: defaultcsi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secretcsi.storage.k8s.io/controller-expand-secret-namespace: defaultcsi.storage.k8s.io/node-stage-secret-name: csi-rbd-secretcsi.storage.k8s.io/node-stage-secret-namespace: default# 指定文件系统的类型csi.storage.k8s.io/fstype: xfs
# 定义回收策略
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:- discard
EOF

02 rbd secret

cat > csi-rbd-secret.yaml <<EOF
apiVersion: v1
kind: Secret
metadata:name: csi-rbd-secretnamespace: default
# 对于stringData和Data字段有所不同,无需进行base64编码,说白了就是原样输出。
stringData:# 指定用户名是admin,也可以自定义普通用户。userID: admin# 指定admin用户的key(注意要直接用ceph配置文件里面的秘钥)userKey: AQAlsChnHubLJRAAH2s3vhyGrxgba8anloPDtg==
EOF

03 rbd configmap

cat > ceph-config-map.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:name: ceph-config
data:# ceph集群的配置文件"/etc/ceph/ceph.conf",认证要求可以写成 cephx; fsid填写集群IDceph.conf: |[global]fsid = 12fad866-9aa0-11ef-8656-6516a17ad6ddmon_initial_members = ceph141, ceph142, ceph143mon_host = 10.0.0.141,10.0.0.142,10.0.0.143auth_cluster_required = cephxauth_service_required = cephxauth_client_required = cephx# 要求存在keyring这个key,值为空keyring: |
EOF

04 csi configmap

容器存储接口

cat > csi-config-map.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:name: ceph-csi-config
data:# clusterID可以通过"ceph -s"获取集群ID# monitors为你自己的ceph集群mon地址config.json: |-[{"clusterID": "12fad866-9aa0-11ef-8656-6516a17ad6dd","monitors": ["10.0.0.141:6789","10.0.0.142:6789","10.0.0.143:6789"]}]
EOF

05 csi-kms-config-map

cat > csi-kms-config-map.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:name: ceph-csi-encryption-kms-config
data:# 可以不创建这个cm资源,但是需要将csi-rbdplugin-provisioner.yaml和csi-rbdplugin.yaml中kms有关内容注释掉。#    - deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml  #    - deploy/rbd/kubernetes/csi-rbdplugin.yamlconfig.json: |-{}
EOF

06 定义PVC

cat > pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: rbd-pvc01
spec:accessModes:- ReadWriteOnceresources:requests:storage: 2GistorageClassName: csi-rbd-sc
---apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: rbd-pvc02
spec:accessModes:- ReadWriteOnceresources:requests:storage: 4GistorageClassName: csi-rbd-sc
EOF

07 创建csi接口

需要这些文件,下载地址:https://github.com/ceph/ceph-csi/tree/release-v3.7/deploy/rbd/kubernetes

==注:==前面6步的文件需要先apply,否则这些pod无法创建

csi-config-map.yaml  csidriver.yaml  csi-nodeplugin-rbac.yaml
csi-provisioner-rbac.yaml  csi-rbdplugin-provisioner.yaml  csi-rbdplugin.yaml
[root@master231deploy]# kubectl get pods -o wide
NAME                                         READY   STATUS    RESTARTS   AGE   IP            NODE     
csi-rbdplugin-l24hj                          3/3     Running   0          30m   10.0.0.233    worker233
csi-rbdplugin-provisioner-5dfcf67885-8rk48   7/7     Running   0          30m   10.100.1.30   worker233
csi-rbdplugin-provisioner-5dfcf67885-9wznm   7/7     Running   0          30m   10.100.2.48   worker232
csi-rbdplugin-qz7k6                          3/3     Running   0          30m   10.0.0.232    worker232

08 查看rbd image和PVC的关联

1.在ceph集群可以看到有2个rbd image

[root@ceph141~]# rbd ls -p wenzhiyong-k8s
csi-vol-d33df512-9df7-11ef-85fc-4a89d731ca68
csi-vol-d33df570-9df7-11ef-85fc-4a89d731ca68
nginx-web
[root@ceph141~]# rbd info wenzhiyong-k8s/csi-vol-d33df512-9df7-11ef-85fc-4a89d731ca68
rbd image 'csi-vol-d33df512-9df7-11ef-85fc-4a89d731ca68':size 2 GiB in 512 objectsorder 22 (4 MiB objects)snapshot_count: 0id: 392f1fe374022block_name_prefix: rbd_data.392f1fe374022format: 2features: layeringop_features: flags: create_timestamp: Sat Nov  9 01:35:19 2024access_timestamp: Sat Nov  9 01:35:19 2024modify_timestamp: Sat Nov  9 01:35:19 2024
[root@ceph141~]# rbd info wenzhiyong-k8s/csi-vol-d33df570-9df7-11ef-85fc-4a89d731ca68
rbd image 'csi-vol-d33df570-9df7-11ef-85fc-4a89d731ca68':size 4 GiB in 1024 objectsorder 22 (4 MiB objects)snapshot_count: 0id: 392f182ce6323block_name_prefix: rbd_data.392f182ce6323format: 2features: layeringop_features: flags: create_timestamp: Sat Nov  9 01:35:19 2024access_timestamp: Sat Nov  9 01:35:19 2024modify_timestamp: Sat Nov  9 01:35:19 2024
24
[root@ceph141~]# rbd info wenzhiyong-k8s/csi-vol-d33df570-9df7-11ef-85fc-4a89d731ca68
rbd image 'csi-vol-d33df570-9df7-11ef-85fc-4a89d731ca68':size 4 GiB in 1024 objectsorder 22 (4 MiB objects)snapshot_count: 0id: 392f182ce6323block_name_prefix: rbd_data.392f182ce6323format: 2features: layeringop_features: flags: create_timestamp: Sat Nov  9 01:35:19 2024access_timestamp: Sat Nov  9 01:35:19 2024modify_timestamp: Sat Nov  9 01:35:19 2024

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

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

相关文章

Windows11安装Isaac Lab

1.1 下载文件 将 Isaac Lab 仓库克隆到您的工作空间&#xff1a; git clone https://github.com/isaac-sim/IsaacLab.git 1.2 创建Isaac Sim符号链接 F:cd IsaacLab 官方文档里路径/有问题&#xff0c;改成\&#xff09;&#xff1a; # 打开IsaacLab目录cd IsaacLab# 使用…

NES游戏机项目制作笔记(未完成)

24年12月1日晚记——在网上找项目学习的时候发现一个有意思的项目&#xff0c;准备靠这个应用一些STM32的高级功能。值得提醒的是——目的在于学习不可贪杯&#xff0c;注意效率 01 根据项目需求分析 为确保充分考虑每一个细节&#xff0c;并且让自己高效的完成项目制作&#…

ElasticSearch - 理解doc Values与Inverted Index倒排索引

文章目录 概述倒排索引&#xff1a;从图书馆的索引卡片谈起倒排索引的工作原理 docValues&#xff1a;从数据库的列式存储说起docValues的工作原理 docValues与倒排索引的对比两者的联系&#xff1a;组合使用&#xff0c;优化搜索与分析 小结 概述 在使用 Elasticsearch 进行大…

前端H5移动端基础框架模板 :Vue3 + Vite5 + Pinia + Vant4 + Sass + 附源码

技术栈选用 Vue3 Vite5 Pinia Vant4 Sass 源码地址&#xff1a; git clone https://gitee.com/gaiya001/h5-APP.git1. 1.vite.config.js文件配置 ** import { defineConfig } from vite // 导入 Vite 的配置函数 import vue from vitejs/plugin-vue // 导入 Vue 插件 i…

游戏引擎学习第36天

仓库 :https://gitee.com/mrxiao_com/2d_game 回顾之前的内容 在这个程序中&#xff0c;目标是通过手动编写代码来从头开始制作一个完整的游戏。整个过程不使用任何库或现成的游戏引擎&#xff0c;这样做的目的是为了能够全面了解游戏执行的每一个细节。开发过程中&#xff0…

C++小碗菜之五:GDB调试工具

“程序员不是编写代码的人&#xff0c;而是调试错误的人。” – 约翰本尼斯&#xff08;John Bennet&#xff09; 目录 前言 在虚拟机中安装 GDB GDB调试的实战演练 创建示例代码 例子&#xff1a; 使用 GDB 调试 编译代码 启动 GDB 设置断点 运行程序 打印变量值 …

【软件测试面试题】测试理论/基础面试(持续更新)

Hi&#xff0c;大家好。最近很多朋友都在说今年的互联网行情不好&#xff0c;面试很难&#xff0c;不知道怎么复习&#xff0c;我最近总结了一份在软件测试面试中比较常见的测试理论/基础面试面试题合集&#xff0c;希望对大家有帮助。建议点赞收藏再阅读&#xff0c;防止丢失&…

(css)element中el-select下拉框整体样式修改

(css)element中el-select下拉框整体样式修改 重点代码&#xff08;颜色可行修改&#xff09; // 修改input默认值颜色 兼容其它主流浏览器 /deep/ input::-webkit-input-placeholder {color: rgba(255, 255, 255, 0.50); } /deep/ input::-moz-input-placeholder {color: rgba…

十一、容器化 vs 虚拟化-Docker

文章目录 前言一、Docker 介绍1. 简介2. 应用场景3. 特点4. Docker和虚拟机之间的区别5. 解决痛点1. 解决依赖兼容2. 解决操作系统环境差异3. 小结 二、Docker 架构三、工作流程五、Docker 核心组件及其工作机制1. Docker 客户端&#xff08;Docker Client&#xff09;2. Docke…

游戏引擎学习第38天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾上次的内容。 我们之前讨论了将精灵放在屏幕上&#xff0c;但颜色错误的问题。问题最终查明是因为使用了一个调整工具&#xff0c;导致文件的字节顺序发生了变化。重新运行“image magic”工具对一些大图像进行重新处理后&am…

Docker 安装Nginx与配置Nginx

文章目录 前言 1.什么是nginx2.为什么使用nginx3.高并发4.Nginx特点&#xff1a; 一、docker安装nginx二、Nginx配置简介 1.文件讲解2.nginx.conf3.default.conf 三、nginx负载均衡 1.配置服务器列表地址2.多集群策略 2.1 权重配置2.2 ip_hash2.3 least_conn2.4 fair2.5 url_h…

qwen2.5 模型JSON格式化输出案例

这篇不是通过prompt提示去实现,是用vllm、ollama推理框架支持;这里也给出个prompt实现的案例参考 1、 vllm推理 参考:https://docs.vllm.ai/en/latest/usage/structured_outputs.html 模型vllm运行: 用的Qwen/Qwen2.5-3B-Instruct模型 vllm serve ./qwen2_5 --host 0.0…

黑马商城微服务复习(6)

MQ高级 1. 消息可靠性2. 发送者的可靠性1. 发送者问题2. 生产者重试机制3. 生产者确认机制4. MQ可靠性5. 消费者的可靠性 3. 延迟消息1. 定义2. 死信交换机 1. 消息可靠性 发送消息时丢失&#xff1a; 生产者发送消息时连接MQ失败生产者发送消息到达MQ后未找到Exchange生产者发…

UE5.5 Geometry库平面切割原理分析

平面切割--FMeshPlaneCut 平面定义: 面上一个点 法线 算法流程如下 求几何体所有顶点和面的有向距离(Signs) Sign计算&#xff1a; float Sign (VertexPos - PlaneOrigin).Dot(PlaneNormal); 遍历所有几何体所有交叉边, 进行SplitEdge 对于位于切割面两侧的交叉边(Sign…

TMS Software:TMS BIZ产品——TMS XData

TMS XData 用于多层REST/JSON HTTP/HTTPS应用服务器开发和ORM远程处理的Delphi框架。 TMS扩展数据可同时用于以下框架&#xff1a; VCLWEBFMX TMS XData可同时用于以下操作系统/浏览器&#xff1a; TMS XData可同时用于以下IDE&#xff1a; 功能概述 基于REST/JSON架构风格的…

优化移动端H5:常见问题与解决方案

移动端H5开发中的“坑”与解决方案 本文介绍了开发中遇到的几个关于移动端H5开发中的小问题&#xff0c;以及解决的方法。 一、iOS滑动不流畅问题 在iOS设备上&#xff0c;H5页面的滑动效果有时会出现不流畅的情况&#xff0c;特别是在页面高度超过一屏时。这通常是由于iOS的…

【论文速读】| AttackQA:利用微调及开源大语言模型辅助网络安全运营的数据集的开发与应用

基本信息 原文标题: AttackQA: Development and Adoption of a Dataset for Assisting Cybersecurity Operations Using Fine-Tuned and Open-Source LLMs 原文作者: Varun Badrinath Krishna 作者单位: SambaNova Systems 关键词: 网络安全、检索增强生成&#xff08;RAG&…

Ubuntu24.04配置STMTrack

项目地址&#xff1a;https://github.com/fzh0917/STMTrack 一、安装 CUDA 参考链接&#xff1a; Ubuntu24.04配置DINO-Tracker Ubuntu多CUDA版本安装及切换 由于之前在其他项目中已经安装了 CUDA12.1&#xff0c;这次需要安装另一个版本。 1. 查看安装版本 按照 requireme…

服务器数据恢复—热备盘上线过程中硬盘离线导致raid5阵列崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; 两组分别由4块SAS接口硬盘组建的raid5阵列&#xff0c;两组raid5阵列划分LUN并由LVM管理&#xff0c;格式化为EXT3文件系统。 服务器故障&#xff1a; RAID5阵列中一块硬盘未知原因离线&#xff0c;热备盘自动激活上线替换离线硬盘。在热备盘上…

【Java学习笔记】Map接口和常用方法

一、 Map接口实现类的 特点[很实用] key是自己存的java对象 value是一个固定的 //当有相同的 k ,就等价于替换. 二、 Map常用方法 &#xff08;根据键–>k&#xff09; 三、Map接口遍历方法 package com.hspedu.map_; import java.util.*; /** * author 韩顺平 * ver…