K8S对接Ceph分部署存储

news/2024/9/18 12:24:29/ 标签: kubernetes, ceph, 容器

文章目录

    • 一、Ceph理论知识
      • 1、Ceph简介
      • 2、Ceph分布式存储的优点
      • 3、Ceph核心组件
    • 二、部署Ceph高可用集群
      • 1、服务器环境信息
      • 2、部署前环境准备工作
      • 3、部署Ceph监控服务Monitor
      • 4、激活Ceph存储服务OSD
    • 三、K8S对接Ceph存储
      • 1、K8S对接Ceph RBD实现数据持久化
      • 2、基于Ceph RBD生成PV
      • 3、基于Storageclass动态生成PV
      • 4、K8S对接CephFS实现数据持久化
    • 四、所遇问题记录
      • 1、激活OSD失败

一、Ceph理论知识

1、Ceph简介

Ceph 是一个开源的分布式存储系统,用于提供高性能、高可靠性的对象存储、块存储和文件系统,它通过去中心化的架构,自动处理数据复制和恢复,旨在提供弹性扩展和容错能力。Ceph官方网址:

Ceph包含一下几种存储类型:

(1)块存储(RBD):

  • 用途: 提供了高性能的块级存储,类似于传统的磁盘驱动器。通常用于虚拟机的存储或数据库的存储。

  • 接口: 通过 Ceph 的 RADOS(Reliable Autonomic Distributed Object Store)接口提供块设备。

  • 架构: 在 Ceph 集群中,每个块设备映射到一个 RADOS 对象,支持动态分配和快照功能。

  • 扩展性: 可以根据需求动态增加或减少存储容量。

  • 缺点:块设备具有优异的读写性能,但不能多处挂载同时读写,目前主要用在OpenStack上作为虚拟磁盘。

  • 总结:块设备可理解成一块硬盘,用户直接使用不含文件系统的块设备,也可以将其格式化成特定的文件系统,由文件系统来组织管理存储空间,从而为用户提供丰富而友好的数据操作支持。

(2)文件系统(CephFS):

  • 用途: 提供一个完整的分布式文件系统,用于支持标准的文件操作和目录结构,适用于需要 POSIX 兼容的应用程序。
  • 接口: 提供标准的 POSIX 文件系统接口,允许通过传统的文件系统工具和应用程序访问存储的数据。
  • 架构: CephFS 构建在 Ceph 的对象存储之上,通过元数据服务器(MDS)来管理文件和目录的元数据。
  • 扩展性: 支持横向扩展,能够处理大量的文件和目录操作。
  • 缺点:文件系统接口读写性能较块设备接口差,但具有优异的共享性。

(3)对象存储(Object Gateway):

  • 用途: 主要用于存储大量的非结构化数据,如照片、视频、备份和日志文件。

  • 接口: 提供了兼容 Amazon S3 和 OpenStack Swift 的 RESTful API,方便与现有的云服务和应用程序集成。

  • 架构: 数据以对象的形式存储,每个对象由数据、元数据和唯一标识符(Object ID)组成。

  • 扩展性: 对象存储可以通过增加更多的存储节点来横向扩展,适合大规模数据存储需求。

问题:有了块设备接口存储和文件系统接口存储,为什么还整个对象存储呢?

答:Ceph的块设备存储具有优异的存储性能但不具有共享性,而Ceph的文件系统具有共享性然而性能较块设备存储差,为什么不权衡一下存储性能和共享性,整个具有共享性而存储性能好于文件系统存储的存储呢,对象存储就这样出现了。

2、Ceph分布式存储的优点

  • 弹性扩展: 可以无缝添加更多的存储节点,以支持增长的存储需求,而不会影响系统的性能。
  • 高可用性: 数据自动复制到多个节点,确保在硬件故障时数据不会丢失。
  • 高性能:读写速度快。
  • 去中心化: 没有单点故障,提升了系统的可靠性和容错能力。
  • 灵活性: 支持对象存储、块存储和文件系统等多种存储类型,满足不同的需求。

3、Ceph核心组件

  • Monitors:监视器,负责维护集群状态的映射,包括监视器映射,管理器映射,OSD映射和CRUSH映射。这些映射是Ceph守护进程相互协调所需的关键集群状态。监视器还负责管理守护进程和客户端之间的身份验证。冗余和高可用性通常至少需要三个监视器。
  • Managers:负责跟踪运行时指标和Ceph集群的当前状态,包括存储利用率,当前性能指标和系统负载。 Ceph Manager守护进程还托管基于python的模块来管理和公开Ceph集群信息,包括基于Web的Ceph Dashboard和REST API。高可用性通常至少需要两名Managers。
  • Ceph OSD:负责存储数据,处理数据复制,恢复,重新平衡,并通过检查其他Ceph OSD守护进程来获取心跳,为Ceph监视器和管理器提供一些监视信息。冗余和高可用性通常至少需要3个Ceph OSD。
  • MDS:元数据服务器,代表Ceph文件系统存储元数据(即,Ceph块设备和Ceph对象存储不使用MDS)。 Ceph元数据服务器允许POSIX文件系统用户执行基本命令(如ls,find等),而不会给Ceph存储集群带来巨大负担。

二、部署Ceph高可用集群

1、服务器环境信息

注意:由于我本次仅仅只是实验所以我把Ceph集群与K8S集群部署到了一起,如果生产环境需要多申请三台服务器,单独部署Ceph集群!

序号IP地址主机名磁盘安装服务别名
116.32.15.200master-1sdb-20GK8S-Master、cephceph-deployK8S管理节点、Ceph管理节点
216.32.15.201node-1sdb-20GK8S-Node-1、ceph
316.32.15.202node-2sdb-20GK8S-Node-2、ceph

2、部署前环境准备工作

PS:所有主机中执行

1、配置阿里云Ceph安装源

cat >>  /etc/yum.repos.d/ceph.repo  << EOF
[Ceph] 
name=Ceph packages for \$basearch
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/x86_64/ 
enabled=1 
gpgcheck=0 
type=rpm-md 
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc 
priority=1
[Ceph-noarch] 
name=Ceph noarch packages 
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/noarch/ 
enabled=1 
gpgcheck=0 
type=rpm-md 
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc 
priority=1 
[ceph-source]
name=Ceph source packages 
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/SRPMS/ 
enabled=1 
gpgcheck=0 
type=rpm-md 
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc 
priority=1
EOF

2、安装基础包,平时排查问题需要用到

yum install -y yum-utils device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel  python-devel epel-release openssh-server socat  ipvsadm conntrack ntpdate telnet deltarpm

3、添加hosts本地解析

vim /etc/hosts16.32.15.200 master-1
16.32.15.201 node-1
16.32.15.202 node-2

4、修改主机名(对应主机执行)

hostnamectl set-hostname master-1 && bash
hostnamectl set-hostname node-1 && bash
hostnamectl set-hostname node-2 && bash

5、配置内网免密登入

ssh-keygenssh-copy-id master-1
ssh-copy-id node-1
ssh-copy-id node-2

6、配置NTP时间同步

yum -y install ntpdate
ntpdate ntp1.aliyun.com

添加定时任务,每天凌晨1点自动同步时间

echo "0 1 * * * ntpdate ntp1.aliyun.com" >> /var/spool/cron/root

3、部署Ceph监控服务Monitor

1、安装ceph-deploy(Ceph管理节点执行)

yum install python-setuptools  ceph-deploy -y

2、安装ceph(所有主机执行)

yum install ceph ceph-radosgw  -y

3、查看ceph版本

ceph --version

4、创建Monitor(Ceph管理节点执行)

创建一个目录,用于保存 ceph-deploy 生成的配置文件信息的

cd /etc/ceph
ceph-deploy new master-1 node-1 node-2

查看当前生成的文件:

ls -1 /etc/cephceph.conf   				# Ceph配置文件
ceph-deploy-ceph.log		# 日志文件
ceph.mon.keyring			# Monitor密钥

5、修改ceph配置文件(Ceph管理节点执行)

vim /etc/ceph/ceph.conf[global]
fsid = 8797ef39-fcb3-4e82-bf49-a068cfc72eae
mon_initial_members = master-1, node-1, node-2
mon_host = 16.32.15.200,16.32.15.201,16.32.15.202
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
# 新增配置如下:
osd_pool_default_size = 2               # 2个osd也能达到active+clean状态
mon clock drift allowed = 0.500         # 监视器间允许的时钟漂移量默认值0.05
mon clock drift warn backoff = 10       # 时钟偏移警告的退避指数。默认值5

注意:Ceph对每个mon之间的时间同步延时默认要求在0.05s之间,这个时间有的时候太短了。所以如果ceph集群如果出现clock问题就检查ntp时间同步或者适当放宽这个误差时间。

6、配置初始Monitor、收集所有的密钥(Ceph管理节点执行)

cd /etc/ceph
ceph-deploy mon create-initial

等待收集完成后,查看收集到的key

ls -1 /etc/ceph/*.keyring

4、激活Ceph存储服务OSD

注意:以下操作均在,Ceph管理节点执行!!

1、准备OSD

cd /etc/ceph/ceph-deploy osd prepare master-1:/dev/sdb
ceph-deploy osd prepare node-1:/dev/sdb 
ceph-deploy osd prepare node-2:/dev/sdb

2、激活OSD

ceph-deploy osd activate master-1:/dev/sdb1
ceph-deploy osd activate node-1:/dev/sdb1
ceph-deploy osd activate node-2:/dev/sdb1

3、查看OSD状态

ceph-deploy osd list master-1 node-1 node-2

三、K8S对接Ceph存储

注意1:在K8S集群中如果使用Ceph存储,需要再K8S各个节点中安装ceph-common工具,安装命令如下:

yum install ceph-common -y

注意2:如果K8S集群和Ceph集群不在相同服务器中,需要把Ceph集群中的 /etc/ceph 目录拷贝到K8S各个节点下!!

1、K8S对接Ceph RBD实现数据持久化

PS:以下操作均在,Ceph管理节、K8S管理节点中执行!!

1、创建RBD

ceph osd pool create k8srbd 16
rbd create rbda -s 1024 -p k8srbd			
rbd feature disable  k8srbd/rbda object-map fast-diff deep-flatten   # 禁用无用特性

2、查看RBD状态信息

ceph osd pool ls				# 列出所有pool
ceph osd pool stats k8srbd		# 查看状态

3、创建Pod,使用RBD挂载

apiVersion: v1
kind: Pod
metadata:name: test-rbd
spec:containers:- image: nginxname: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: testrbdmountPath: /optvolumes:- name: testrbdrbd:monitors: # 监视器IP:Port- '16.32.15.200:6789'- '16.32.15.201:6789'- '16.32.15.202:6789'pool: k8srbd # pool名称image: rbda # image名称fsType: xfsreadOnly: falseuser: adminkeyring: /etc/ceph/ceph.client.admin.keyring

3、执行apply并查看Pod状态

kubectl apply -f pod.yaml
kubectl get pods

注意:RBD类型只能挂载一个,如果再创建一个Pod,使用相同的RBD,则会创建失败!

2、基于Ceph RBD生成PV

PS:以下操作均在,Ceph管理节、K8S管理节点中执行!!

1、创建Ceph secret对象

Secret对象用于K8S Volume插件访问Ceph集群,获取client.admin的keyring值,(ceph管理节点):

ceph auth get-key client.admin | base64
QVFDVHljbG1hU3JnSnhBQSt0eUpmcVRjNEs2SHdrZUcxdjJVblE9PQ==

2、创建Ceph的Secret资源(K8S Master节点操作):

apiVersion: v1
kind: Secret
metadata:name: ceph-secret
data:key: QVFBWk0zeGdZdDlhQXhBQVZsS0poYzlQUlBianBGSWJVbDNBenc9PQ==
kubectl apply -f ceph-secret.yaml

3、创建pool池

ceph osd pool create k8srbd1 16
rbd create rbda -s 1024 -p k8srbd1
rbd feature disable k8srbd1/rbda object-map fast-diff deep-flatten

4、创建PV、PVC

apiVersion: v1
kind: PersistentVolume
metadata:name: ceph-pv
spec:capacity:storage: 1GiaccessModes:- ReadOnlyManyrbd:monitors:- '16.32.15.200:6789'- '16.32.15.201:6789'- '16.32.15.202:6789'pool: k8srbd1image: rbdauser: adminsecretRef:name: ceph-secretfsType: xfsreadOnly: falsepersistentVolumeReclaimPolicy: Recycle
---
kind: PersistentVolumeClaim 
apiVersion: v1 
metadata:   name: ceph-pvc 
spec:   accessModes:     - ReadOnlyMany   resources:     requests:       storage: 1Gi
kubectl apply -f ceph-pv-pvc.yaml

查看PVC是否绑定PV:

kubectl get pvc ceph-pvc

在这里插入图片描述

5、创建Deployment资源,使用PVC

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:selector:matchLabels:app: nginxreplicas: 2template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80volumeMounts:- mountPath: "/ceph-data"name: ceph-datavolumes:- name: ceph-datapersistentVolumeClaim:claimName: ceph-pvc
kubectl apply -f deployment.yaml

注意:Ceph RBD块存储能在同一个Node上跨pod以使用ReadWriteOnce共享挂载,但不支持跨Node使用。

问题:结合Ceph RBD共享挂载的特性,发现一个问题:

由于Deployment触发更新,为了保证服务的可用性,Deployment要先创建一个Pod并运行正常之后,再去删除老Pod。而如果新创建的Pod和老Pod不在一个node,就会导致此故障。

解决办法:

  • 使用能支持跨node和pod之间挂载的共享存储,例如CephFS,GlusterFS等。
  • 给Node添加Label,只允许Deployment所管理的Pod调度到一个固定的Node上。(不建议,Node节点宕机,服务也就宕机了)

3、基于Storageclass动态生成PV

注意:K8S1.20版本之后如果需要使用自动生成PV,需要修改kube-apiserver配置,进行兼容:

vim /etc/kubernetes/manifests/kube-apiserver.yaml
# 添加这一行:
- --feature-gates=RemoveSelfLink=false

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

重启kubelet生效

systemctl restart kubelet

注意:我这边两套集群v1.26.2版本修改此配置后,导致集群起不来,而v1.23.0版本修改后可以正常启动,建议现在测试环境添加此配置,如果没有问题,在添加生产环境!!

1、执行赋权操作(所有K8S集群、Ceph集群中执行)

chmod 777  -R  /etc/ceph/*
mkdir /root/.ceph/
cp -ar /etc/ceph/ /root/.ceph/
cp -ar /etc/ceph/* /root/.ceph/

2、创建RBD的供应商Provisioner

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: rbd-provisioner
rules:- apiGroups: [""]resources: ["persistentvolumes"]verbs: ["get", "list", "watch", "create", "delete"]- apiGroups: [""]resources: ["persistentvolumeclaims"]verbs: ["get", "list", "watch", "update"]- apiGroups: ["storage.k8s.io"]resources: ["storageclasses"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["events"]verbs: ["create", "update", "patch"]- apiGroups: [""]resources: ["services"]resourceNames: ["kube-dns","coredns"]verbs: ["list", "get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: rbd-provisioner
subjects:- kind: ServiceAccountname: rbd-provisionernamespace: default
roleRef:kind: ClusterRolename: rbd-provisionerapiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: rbd-provisioner
rules:
- apiGroups: [""]resources: ["secrets"]verbs: ["get"]
- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: rbd-provisioner
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: rbd-provisioner
subjects:
- kind: ServiceAccountname: rbd-provisionernamespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:name: rbd-provisioner
spec:selector:matchLabels:app: rbd-provisionerreplicas: 1strategy:type: Recreatetemplate:metadata:labels:app: rbd-provisionerspec:containers:- name: rbd-provisionerimage: quay.io/xianchao/external_storage/rbd-provisioner:v1imagePullPolicy: IfNotPresentenv:- name: PROVISIONER_NAMEvalue: ceph.com/rbdserviceAccount: rbd-provisioner
---
apiVersion: v1
kind: ServiceAccount
metadata:name: rbd-provisioner
kubectl apply -f rbd-provisioner.yaml

3、创建Ceph Secret

ceph osd pool create k8srbd2 16
ceph auth get-key client.admin | base64
apiVersion: v1
kind: Secret
metadata:name: ceph-secret-1
type: "ceph.com/rbd"
data:key: QVFDVHljbG1hU3JnSnhBQSt0eUpmcVRjNEs2SHdrZUcxdjJVblE9PQ== 
kubectl apply -f ceph-secret-1.yaml

4、创建Storageclass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: k8s-rbd
provisioner: ceph.com/rbd # 与provisioner对应
parameters:monitors: 16.32.15.200:6789,16.32.15.201:6789,16.32.15.202:6789adminId: adminadminSecretName: ceph-secret-1pool: k8srbd2     userId: adminuserSecretName: ceph-secret-1fsType: xfsimageFormat: "2"imageFeatures: "layering"
kubectl apply -f storageclass.yaml

4、创建PVC,自动生成PV

kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: rbd-pvc
spec:accessModes:- ReadWriteOncevolumeMode: Filesystemresources:requests:storage: 1GistorageClassName: k8s-rbd
kubectl apply -f rbd-pvc.yaml
kubectl get pvc

5、创建Pod,挂载PVC

apiVersion: v1
kind: Pod
metadata:labels:test: rbd-podname: ceph-rbd-pod
spec:containers:- name: ceph-rbd-nginximage: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: ceph-rbdmountPath: /mntreadOnly: falsevolumes:- name: ceph-rbdpersistentVolumeClaim:claimName: rbd-pvc
kubectl apply -f pod-sto.yaml

4、K8S对接CephFS实现数据持久化

PS:以下操作均在,Ceph管理节、K8S管理节点中执行!!

1、创建MDS

ceph-deploy mds create  master-1 node-1 node-2

2、创建存储池

一个CephFS至少要求两个librados存储池,一个为data,一个为metadata。当配置这两个存储池时,需要注意以下两点:

  • 为metadata pool设置较高级别的副本级别,因为metadata的损坏可能导致整个文件系统不用。
  • 建议metadata pool使用低延时存储,比如SSD,因为metadata会直接影响客户端的响应速度。
ceph osd pool create cephfs_data 128
ceph osd pool create cephfs_metadata 128

pg_num 取值是强制性的,因为不能自动计算。下面是几个常用的值:

  • 少于 5 个 OSD 时可把 pg_num 设置为 128
  • OSD 数量在 5 到 10 个时,可把 pg_num 设置为 512
  • OSD 数量在 10 到 50 个时,可把 pg_num 设置为 4096

当OSD 数量大于 50 时,得理解权衡方法、以及如何自己计算 pg_num 取值

自己计算 pg_num 取值时可借助 pgcalc 工具

随着 OSD 数量的增加,正确的 pg_num 取值变得更加重要,因为它显著地影响着集群的行为、以及出错时的数据持久性(即灾难性事件导致数据丢失的概率)

3、创建文件系统

ceph fs new k8sfs cephfs_metadata cephfs_data

4、查看

ceph fs ls              # 查看创建后的cephfs
ceph mds stat           # 查看mds节点状态
ceph -s					# 查看集群信息

5、创建目录,将CephFS挂载到此目录

cat /etc/ceph/ceph.client.admin.keyring |grep key|awk -F" " '{print $3}' > /etc/ceph/admin.secret
mkdir /data/ceph_data -p
mount -t ceph 16.32.15.201:6789:/ /data/ceph_data -o name=admin,secretfile=/etc/ceph/admin.secret
df -hT /data/ceph_data

6、在CephFS挂载目录中,创建子目录,作为存储挂载

mkdir -p /data/ceph_data/qinzt
chmod 0777 /data/ceph_data/qinzt

7、创建Secret,用于K8S连接Ceph

将/etc/ceph/ceph.client.admin.keyring里面的key的值转换为base64,否则会有问题

cat /etc/ceph/ceph.client.admin.keyring|awk NR==2'{print $NF}'|base64
QVFCbExNcG11Q215TEJBQVdWTzlEY2h1T2Zham5GQWxmV1dESFE9PQo=
apiVersion: v1
kind: Secret
metadata:name: cephfs-secret
data:key: QVFCbExNcG11Q215TEJBQVdWTzlEY2h1T2Zham5GQWxmV1dESFE9PQo=
kubectl apply -f cephfs-secret.yaml

8、创建PV、PVC

apiVersion: v1
kind: PersistentVolume
metadata:name: cephfs-pv
spec:capacity:storage: 1GiaccessModes:- ReadWriteManycephfs:monitors:     - '16.32.15.200:6789'- '16.32.15.201:6789'- '16.32.15.202:6789'path: /qinzt  # 挂载目录(Ceph根下的qinzt目录 > /data/ceph_data/qinzt)user: adminreadOnly: falsesecretRef:name: cephfs-secretpersistentVolumeReclaimPolicy: Recycle
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: cephfs-pvc
spec:accessModes:- ReadWriteManyvolumeName: cephfs-pvresources:requests:storage: 1Gi
kubectl apply -f cephfs-pv-pvc.yaml
kubectl get pvc cephfs-pvc

9、创建Pods,挂载CephFS

apiVersion: apps/v1
kind: Deployment
metadata:name: cephfs-deployment
spec:replicas: 3selector:matchLabels:app: nginxenv: devtemplate:metadata:labels:app: nginxenv: devspec:containers:- image: nginxname: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: cephfsmountPath: /mntvolumes:- name: cephfspersistentVolumeClaim:claimName: cephfs-pvc
kubectl apply -f cephfs-deployment.yaml

10、验证,Pod中创建文件,本地查看是否存在

# 进入Pod1创建5个文件
kubectl exec -it cephfs-deployment-6f66847599-2hd9s -- /bin/bash
touch pod1{1..5}.txt /mnt/# 进入Pod2查看创建的文件
kubectl exec -it cephfs-deployment-6f66847599-cggzm -- /bin/bash
ls /mnt/*# 查看本地目录
ls /data/ceph_data/qinzt/
pod11.txt  pod12.txt  pod13.txt  pod14.txt  pod15.txt

通过验证,可以确认容器内挂载目录是共享的,并且Pod写入的数据已经存储到了CephFS中了

四、所遇问题记录

1、激活OSD失败

报错信息:ERROR: error creating empty object store in /var/lib/ceph/tmp/mnt.QdHa3y: (13) Permission denied

解决方案:

chown ceph:ceph /dev/sdb*

http://www.ppmy.cn/news/1516019.html

相关文章

在编程学习的道路上,面对Bug和复杂算法时,我们常常会感到挫折和困惑。以下是一些克服这些挑战的有效方法:

在编程学习的道路上&#xff0c;面对Bug和复杂算法时&#xff0c;我们常常会感到挫折和困惑。以下是一些克服这些挑战的有效方法&#xff1a; 系统化问题解决&#xff1a; 遇到Bug时&#xff0c;首先要从整体入手&#xff0c;系统地分析问题。例如&#xff0c;可以通过逐步调试…

2024年Intellij IDEA快捷键总结

目录 编辑与格式化&#xff1a; 导航与跳转&#xff1a; 重构&#xff1a; 查找与替换&#xff1a; 调试 其他常用&#xff1a; 使用快捷键的好处&#xff1a; 快捷键功能描述 编辑与格式化&#xff1a; CtrlX删除当前行或选中的文本CtrlD复制当前行或选中的文本到下一行…

iPhone13手机照片被误删,有什么方法可以恢复吗?

在日常使用手机时&#xff0c;我们可能因为误操作、手机崩溃、或者其他原因&#xff0c;导致iPhone13手机中的照片丢失。遇到这种情况&#xff0c;手机误删照片如何恢复&#xff1f;在本文中&#xff0c;我们将分享3个妙招&#xff0c;帮助您恢复iPhone13上误删的照片。 一、通…

Flask restful 前后端分离和 restful 定义

Flask restful 前后端分离和 restful 定义 前后端分离RESTful API总结在Web开发中,前后端分离(Frontend and Backend Separation)和RESTful API(Representational State Transfer 应用程序接口)是两个重要的概念,特别是在构建大型或复杂的Web应用程序时。Flask作为一个轻…

解锁C#性能监控:内置性能计数器全解析

标题&#xff1a;解锁C#性能监控&#xff1a;内置性能计数器全解析 摘要 性能计数器是衡量和监控应用程序性能的重要工具。在C#中&#xff0c;.NET框架提供了一套完整的性能计数器类库&#xff0c;使得开发者能够轻松地收集和分析应用程序的运行时数据。本文将详细介绍如何在…

【第一章概述—计算机中的数制】非十进制数到十进制数的转换,八进制转十进制,16进制转十进制。十进制转8进制,十进制转16进制

将非十进制数转换为十进制数或将十进制数转换为其他进制数&#xff0c;具体步骤如下&#xff1a; 八进制&#xff08;Octal&#xff09;转换为十进制&#xff08;Decimal&#xff09; 八进制转十进制&#xff1a; 每个八进制位乘以其对应的权重&#xff1a; 从右到左&#x…

Python爬虫—常用的网络爬虫工具推荐

以下列举几个常用的网络爬虫工具 1. 八爪鱼&#xff08;Bazhuayu&#xff09; 简介&#xff1a; 八爪鱼是一款面向非技术用户的桌面端爬虫软件&#xff0c;以其可视化操作和强大的模板库而受到青睐。它支持从各种网站上抓取数据&#xff0c;包括文本、图片、文档等&#xff…

MySQL对JSON数据类型的处理

MySQL从5.7版本开始提供了对JSON数据类型的支持&#xff0c;‌使得MySQL能够直接存储和管理JSON格式的数据。‌这使得在数据库中处理JSON数据变得更为方便和高效。‌以下是一些常用的处理JSON数据的函数和操作&#xff1a;‌ 1.‌创建JSON列 CREATE TABLE my_table (id INT A…

uniapp-:class内使用函数报错及解决方法

在开发时&#xff0c;需要根据状态动态的去渲染颜色&#xff0c;这个时候就用到了 :class :class"hColor(2,item, index)" 在vue内开发时&#xff0c;此代码片段可以正常使用 在uniapp内开发时&#xff0c;相同代码报错&#xff0c;因为在uniapp内 :class不支持直接…

优化学习管理:Moodle和ONLYOFFICE文档编辑器的完美结合

目录 前言 一、什么是 Moodle 1、简单快速插入表单字段 3、免费表单模板库 4、开启无缝协作 三、在Moodle中集成ONLYOFFICE文档 四、在Moodle安装使用ONLYOFFICE 1、下载安装 2、配置服务器 3、在Moodle中使用ONLYOFFICE 文档活动 五、未来展望 写在最后 前言 在当今教育科技飞…

启动kafka

启动 kafka 启动 kafka 使用 zookeeper # 启动 zookeeper ./zookeeper-server-start.sh ../config/zookeeper.properties & # 启动 kafka ./kafka-server-start.sh ../config/server.properties &# 关闭 kafka ./kafka-server-stop.sh ../config/server.properties# …

一款人性化的终端用户界面工具

A collection of human friendly terminal user interface. 截图 历史文件预览 注意: find file 依赖 fzf. file browser依赖 ranger / lf / … 安装 git clone https://github.com/StubbornVegeta/StartUp ~/.config/ cd ~/.config/StartUp ./install.sh用法 . $HOME/.…

人员离岗识别摄像机

一种通过摄像技术来监测和识别工作场所员工离开工作岗位的设备。该摄像机能够准确识别员工的面部特征&#xff0c;并通过算法识别出员工是否离开了工作岗位&#xff0c;从而提高工作场所的管理效率。摄像机采用高清摄像头和人脸识别技术&#xff0c;能够精准识别出员工的面部特…

自制电路图为何无法驱动ESP01S?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

jmeter——添加测试片段

问&#xff1a;为什么要添加测试片段&#xff1f; 答&#xff1a;在测试的过程中&#xff0c;有可能遇到这一个测试需要上一个测试为前提的情况&#xff0c;例如&#xff1a;登录之后才能下单&#xff0c;所以先要进行登录&#xff0c;因此就用到【测试片段】。 1、右键【测试…

【论文阅读】A Closer Look at Parameter-Efficient Tuning in Diffusion Models

Abstract 大规模扩散模型功能强大&#xff0c;但微调定制这些模型&#xff0c;内存和时间效率都很低。 本文通过向大规模扩散模型中插入小的学习器(称为adapters)&#xff0c;实现有效的参数微调。 特别地&#xff0c;将适配器的设计空间分解为输入位置、输出位置、函数形式的…

免费高画质提取PPT/Word/Excel中的图片工具

下载地址&#xff1a;https://pan.quark.cn/s/134ccc35b8a2 软件简介&#xff1a; 好不容易搞到一个几十上百MB的ppt&#xff0c;想导出里面的图片进行二次加工&#xff0c;却被ppt超低画质的图片另存为功能劝退&#xff0c;明知里面全是高清图片&#xff0c;走时却是两手空空…

倒计时7天!MoonBit 游戏挑战赛即将开启!

基于 Wasm4 框架的 MoonBit 游戏开发指南 MoonBit 即将面向全国举办“编程创新挑战赛”&#xff0c;并包含游戏赛道。本教程将介绍本次比赛中使用的框架 Wasm4&#xff0c;以及如何使用 MoonBit 在 Wasm4 框架中编写游戏。相关赛事详情见文末。 如果你曾访问过 mooncakes 或我们…

MySQL——连接查询(2)内连接

内连接(Inner Join)又称简单连接或自然连接&#xff0c;是一种常见的连接查询。内连接使用比较运算符对两个表中的数据进行比较&#xff0c;并列出与连接条件匹配的数据行&#xff0c;组合成新的记录&#xff0c;也就是说在内连接查询中&#xff0c;只有满足条件的记录才能出现…

苍穹外卖-day05(SpringBoot+SSM的企业级Java项目实战)

苍穹外卖-day05 课程内容 Redis入门 Redis数据类型 Redis常用命令 在Java中操作Redis 店铺营业状态设置 功能实现&#xff1a;营业状态设置 效果图&#xff1a; 选择营业中&#xff0c;客户可在小程序端下单&#xff1a; 选择打烊中&#xff0c;客户无法在小程序端下单&…