【云原生】k8s之存储卷

news2024/11/26 16:51:38

内容预知

 前言

1.emptyDir存储卷 

 2.hostPath存储卷

 3.nfs共享存储卷

 4. PVC 和 PV的静态存储卷

4.1 pv和pvc的介绍 

4.2 pvc 和pv的创建过程及销毁过程

 4.3 对pv的操作指导

4.4 静态创建pv和pvc资源由pod运用过程

步骤一:在NFS主机上创建共享目录,并且进行exportfs发布 

步骤二:在master主机编写pv资源创建yaml 

步骤三:创建pvc资源,并且设置匹配绑定相应的pv 

步骤四:创建pod,挂载共享卷,并且进行共享目录写入测试 

 5. StorageClass + nfs-client-provisioner搭建动态创建pv

5.1  StorageClass + nfs-client-provisioner的理解

5.2 具体的操作运用 

 步骤一:在stor01节点上安装nfs,并配置nfs服务

步骤二:创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限和动态规则 

步骤三:使用 Deployment 来创建 NFS Provisioner 

步骤四:创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联 

步骤五: 创建 PVC 和 Pod 测试


 前言

容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。 

 

1.emptyDir存储卷 

 当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除。

 emptyDir可实现Pod中的容器之间共享目录数据,但是emptyDir卷不能持久化数据,会随着Pod生命周期结束而一起删除。

 

创建步骤演示:

 

mkdir /opt/volumes
cd /opt/volumes

vim pod-emptydir.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-emptydir
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: nginx:1.14
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
	#定义容器挂载内容
    volumeMounts:
	#使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷
    - name: html
	  #挂载至容器中哪个目录
      mountPath: /usr/share/nginx/html/
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
	  #在容器内定义挂载存储名称和挂载路径
      mountPath: /data/
    command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
  #定义存储卷
  volumes:
  #定义存储卷名称  
  - name: html
    #定义存储卷类型
    emptyDir: {}
	
	
kubectl apply -f pod-emptydir.yaml

 

 

 

上面定义了2个容器,其中一个容器是输入日期到index.html中,然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。 

 

 

 

 2.hostPath存储卷

hostPath卷将 node 节点的文件系统中的文件或目录挂载到集群中。
hostPath可以实现持久存储,但是在node节点故障时,也会导致数据的丢失 

把Node节点上的目录/文件挂载到容器中,可实现持久化数据存储。但是存储空间会受到Node节点的单机限制,Node节点故障数据就会丢失,且Pod不能实现跨节点共享数据 

创建步骤演示:

 

//在 node01 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'this is node01' > /data/pod/volume1/index.html

//在 node02 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'this is node02' > /data/pod/volume1/index.html

//创建 Pod 资源
vim pod-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
	#定义容器挂载内容
    volumeMounts:
	#使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷
    - name: html
	  #挂载至容器中哪个目录
      mountPath: /usr/share/nginx/html
	  #读写挂载方式,默认为读写模式false
	  readOnly: false
  #volumes字段定义了paues容器关联的宿主机或分布式文件系统存储卷
  volumes:
    #存储卷名称
    - name: html
	  #路径,为宿主机存储路径
      hostPath:
	    #在宿主机上目录的路径
        path: /data/pod/volume1
		#定义类型,这表示如果宿主机没有此目录则会自动创建
        type: DirectoryOrCreate


kubectl apply -f pod-hostpath.yaml

 

 3.nfs共享存储卷

 

使用nfs服务将共享存储设备空间挂载到容器中,可实现持久化数据存储,且Pod能实现跨节点共享数据 

具体实验操作步骤:

//在stor01节点上安装nfs,并配置nfs服务
mkdir /data/volumes -p
chmod 777 /data/volumes

vim /etc/exports
/data/volumes 192.168.73.0/24(rw,no_root_squash)

systemctl start rpcbind
systemctl start nfs

showmount -e
Export list for stor01:
/data/volumes 192.168.73.0/24


//master节点操作
vim pod-nfs-vol.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-nfs
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
    - name: html
      nfs:
        path: /data/volumes
        server: stor01


kubectl apply -f pod-nfs-vol.yaml

 

 4. PVC 和 PV的静态存储卷

4.1 pv和pvc的介绍 

 

 PV 全称叫做 Persistent Volume,持久化存储卷。它是用来描述或者说用来定义一个存储卷的,这个通常都是由运维工程师来定义。

PVC 的全称是 Persistent Volume Claim,是持久化存储的请求。它是用来描述希望使用什么样的或者说是满足什么条件的 PV 存储。

PVC 的使用逻辑:在 Pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候直接指定大小,PVC 必须与对应的 PV 建立关系,PVC 会根据配置的定义去 PV 申请,而 PV 是由存储空间创建出来的。PV 和 PVC 是 Kubernetes 抽象出来的一种存储资源。


PV是集群中的资源。 PVC是对这些资源的请求,也是对资源的索引检查。 

 

4.2 pvc 和pv的创建过程及销毁过程

 

 PV和PVC之间的相互作用遵循这个生命周期:


Provisioning(配置)---> Binding(绑定)---> Using(使用)---> Releasing(释放) ---> Recycling(回收)

 

 ●Provisioning,即 PV 的创建,可以直接创建 PV(静态方式),也可以使用 StorageClass 动态创建
●Binding,将 PV 分配给 PVC
●Using,Pod 通过 PVC 使用该 Volume,并可以通过准入控制StorageProtection(1.9及以前版本为PVCProtection) 阻止删除正在使用的 PVC
●Releasing,Pod 释放 Volume 并删除 PVC
●Reclaiming,回收 PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除

根据这 5 个阶段,PV 的状态有以下 4 种:
●Available(可用):表示可用状态,还未被任何 PVC 绑定
●Bound(已绑定):表示 PV 已经绑定到 PVC
●Released(已释放):表示 PVC 被删掉,但是资源尚未被集群回收
●Failed(失败):表示该 PV 的自动回收失败

 

 一个PV从创建到销毁的具体流程如下:

  1. 一个PV创建完后状态会变成Available,等待被PVC绑定。
  2. 一旦被PVC邦定,PV的状态会变成Bound,就可以被定义了相应PVC的Pod使用。
  3. Pod使用完后会释放PV,PV的状态变成Released。
  4. 变成Released的PV会根据定义的回收策略做相应的回收工作。有三种回收策略,Retain、Delete和Recycle。Retain就是保留现场,K8S集群什么也不做,等待用户手动去处理PV里的数据,处理完后,再手动删除PV。Delete策略,K8S会自动删除该PV及里面的数据。Recycle方式,K8S会将PV里的数据删除,然后把PV的状态变成Available,又可以被新的PVC绑定使用。 

 

 4.3 对pv的操作指导

kubectl explain pv    #查看pv的定义方式
FIELDS:
	apiVersion: v1
	kind: PersistentVolume
	metadata:    #由于 PV 是集群级别的资源,即 PV 可以跨 namespace 使用,所以 PV 的 metadata 中不用配置 namespace
	  name: 
	spec
	
kubectl explain pv.spec    #查看pv定义的规格
spec:
  nfs:(定义存储类型)
    path:(定义挂载卷路径)
    server:(定义服务器名称)
  accessModes:(定义访问模型,有以下三种访问模型,以列表的方式存在,也就是说可以定义多个访问模式)
    - ReadWriteOnce          #(RWO)存储可读可写,但只支持被单个 Pod 挂载
	- ReadOnlyMany           #(ROX)存储可以以只读的方式被多个 Pod 挂载
	- ReadWriteMany          #(RWX)存储可以以读写的方式被多个 Pod 共享
#nfs 支持全部三种;iSCSI 不支持 ReadWriteMany(iSCSI 就是在 IP 网络上运行 SCSI 协议的一种网络存储技术);HostPath 不支持 ReadOnlyMany 和 ReadWriteMany。
  capacity:(定义存储能力,一般用于设置存储空间)
    storage: 2Gi (指定大小)
  storageClassName: (自定义存储类名称,此配置用于绑定具有相同类别的PVC和PV)
  persistentVolumeReclaimPolicy: Retain    #回收策略(Retain/Delete/Recycle)
#Retain(保留):当删除与之绑定的PVC时候,这个PV被标记为released(PVC与PV解绑但还没有执行回收策略)且之前的数据依然保存在该PV上,但是该PV不可用,需要手动来处理这些数据并删除该PV。
#Delete(删除):删除与PV相连的后端存储资源(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)
#Recycle(回收):删除数据,效果相当于执行了 rm -rf /thevolume/* (只有 NFS 和 HostPath 支持)

kubectl explain pvc   #查看PVC的定义方式
KIND:     PersistentVolumeClaim
VERSION:  v1
FIELDS:
   apiVersion	<string>
   kind	<string>  
   metadata	<Object>
   spec	<Object>

#PV和PVC中的spec关键字段要匹配,比如存储(storage)大小、访问模式(accessModes)、存储类名称(storageClassName)
kubectl explain pvc.spec
spec:
  accessModes: (定义访问模式,必须是PV的访问模式的子集)
  resources:
    requests:
      storage: (定义申请资源的大小)
  storageClassName: (定义存储类名称,此配置用于绑定具有相同类别的PVC和PV)

 

 

4.4 静态创建pv和pvc资源由pod运用过程

 

 如图所示我们将选择一台k8s集群之外的服务器作为NFS共享存储服务器,并且按照图中的规格

创建pv,再由k8s集群创建pv资源和pvc资源,最后将其挂载在pod上进行使用

 

步骤一:在NFS主机上创建共享目录,并且进行exportfs发布 

 

#创建共享目录
mkdir -p /data/vulumes/v{1..5}
#进行exports共项目录的编辑
vim /etc/exports
/data/vulumes/v1 192.168.73.0/24(rw,sync,no_root_squash)
/data/vulumes/v2 192.168.73.0/24(rw,sync,no_root_squash)
/data/vulumes/v3 192.168.73.0/24(rw,sync,no_root_squash)
/data/vulumes/v4 192.168.73.0/24(rw,sync,no_root_squash)
/data/vulumes/v5 192.168.73.0/24(rw,sync,no_root_squash)
#发布共享目录
exportfs -avf

 

步骤二:在master主机编写pv资源创建yaml 

 

showmounte -e 192.168.73.108

 

vim pv-demo.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/vulumes/v1
    server: 192.168.73.108
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0002
spec:
  capacity:
    storage: 2Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/vulumes/v2
    server: 192.168.73.108
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 2Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/vulumes/v3
    server: 192.168.73.108
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0004
spec:
  capacity:
    storage: 4Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/vulumes/v4
    server: 192.168.73.108
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0005
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/vulumes/v5
    server: 192.168.73.108

kubectl apply -f pv-demo.yaml

 

 

步骤三:创建pvc资源,并且设置匹配绑定相应的pv 

 

vim pvc-demo.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi

kubectl apply -f pvc-demo.yaml

 

步骤四:创建pod,挂载共享卷,并且进行共享目录写入测试 

 

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myapp
      image: nginx:1.14
      volumeMounts:
      - mountPath: "/usr/share/nginx/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

kubectl apply -f pod-demo.yaml 

 

 

 

 

 

 

 5. StorageClass + nfs-client-provisioner搭建动态创建pv

5.1  StorageClass + nfs-client-provisioner的理解


上面介绍的PV和PVC模式是需要运维人员先创建好PV,然后开发人员定义好PVC进行一对一的Bond,但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,Kubernetes提供一种自动创建PV的机制,叫StorageClass,它的作用就是创建PV的模板。

创建 StorageClass 需要定义 PV 的属性,比如存储类型、大小等;另外创建这种 PV 需要用到的存储插件,比如 Ceph 等。 有了这两部分信息,Kubernetes 就能够根据用户提交的 PVC,找到对应的 StorageClass,然后 Kubernetes 就会调用 StorageClass 声明的存储插件,自动创建需要的 PV 并进行绑定。
Kubernetes 本身支持的动态 PV 创建不包括 NFS,所以需要使用外部存储卷插件分配PV。详见:https://kubernetes.io/zh/docs/concepts/storage/storage-classes/

卷插件称为 Provisioner(存储分配器),NFS 使用的是 nfs-client,这个外部卷插件会使用已经配置好的 NFS 服务器自动创建 PV。
Provisioner:用于指定 Volume 插件的类型,包括内置插件(如 kubernetes.io/aws-ebs)和外部插件(如 external-storage 提供的 ceph.com/cepfs)。

 

5.2 具体的操作运用 

 

 步骤一:在stor01节点上安装nfs,并配置nfs服务

 

mkdir /opt/k8s
chmod 777 /opt/k8s/

vim /etc/exports
/opt/k8s 192.168.73.0/24(rw,no_root_squash,sync)

systemctl restart nfs

 

 

步骤二:创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限和动态规则
 

vim nfs-client-rbac.yaml
#创建 Service Account 账户,用来管理 NFS Provisioner 在 k8s 集群中运行的权限
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
---
#创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nfs-client-provisioner-clusterrole
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: ["list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
#集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: nfs-client-provisioner
  namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-clusterrole
  apiGroup: rbac.authorization.k8s.io


kubectl apply -f nfs-client-rbac.yaml

 

 

步骤三:使用 Deployment 来创建 NFS Provisioner 

vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
  containers:
  - command:
    - kube-apiserver
    - --feature-gates=RemoveSelfLink=false       #添加这一行
    - --advertise-address=192.168.73.105
......

kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system 
kubectl get pods -n kube-system | grep apiserver

 

 

 

 

#创建 NFS Provisioner
vim nfs-client-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner   	  #指定Service Account账户
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: nfs-storage       #配置provisioner的Name,确保该名称与StorageClass资源中的provisioner名称保持一致
            - name: NFS_SERVER
              value: stor01           #配置绑定的nfs服务器
            - name: NFS_PATH
              value: /opt/k8s          #配置绑定的nfs服务器目录
      volumes:              #申明nfs数据卷
        - name: nfs-client-root
          nfs:
            server: stor01
            path: /opt/k8s
	
	
kubectl apply -f nfs-client-provisioner.yaml 

 ​​​​​​​

 

 

步骤四:创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
 

vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client-storageclass
provisioner: nfs-storage     #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:
  archiveOnDelete: "false"   #false表示在删除PVC时不会对数据目录进行打包存档,即删除数据;为ture时就会自动对数据目录进行打包存档,存档文件以archived开头
  
  
kubectl apply -f nfs-client-storageclass.yaml

 

 

 

步骤五: 创建 PVC 和 Pod 测试

 

vim test-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-nfs-pvc
  #annotations: volume.beta.kubernetes.io/storage-class: "nfs-client-storageclass"     #另一种SC配置方式
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-client-storageclass    #关联StorageClass对象
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-storageclass-pod
spec:
  containers:
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command:
    - "/bin/sh"
    - "-c"
    args:
    - "sleep 3600"
    volumeMounts:
    - name: nfs-pvc
      mountPath: /mnt
  restartPolicy: Never
  volumes:
  - name: nfs-pvc
    persistentVolumeClaim:
      claimName: test-nfs-pvc      #与PVC名称保持一致
	  
	  
kubectl apply -f test-pvc-pod.yaml

 

nfs主机中: 

 

 

 

 

 

静态PV的使用:
1、准备好存储设备和共享目录
2、创建PV资源,配置存储卷类型、访问模式(RWX,RWO,ROX)、存储能力大小
3、创建PVC资源,配置请求PV资源的访问模式和存储大小,绑定PV(一个PV只能绑定一个PVC)
4、创建Pod资源挂载PVC,配置存储卷类型为persistentVolumeClaim,在容器配置中定义存储卷挂载内容


StorageClass 简称 SC 资源 实现动态创建 PV 资源
StorageClass :可以调用指定的存储卷插件(provisioner),根据PVC的请求内容动态创建PV资源,使PV与PVC绑定
provisioner :在存储设备上创建PV资源的卷所使用的目录,将PV与卷目录建立关联

StorageClass + nfs-client-provisioner 动态创建PV:
1、准备好NFS服务器和共享目录
2、创建service account服务账户和RBAC授权,使得sa服务账户具有对PV,PVC,SC等资源的操作权限
3、创建nfs-client-provisioner存储卷插件Pod,配置中使用之前授权过的sa服务账户,设置环境变量定义provisioner的名称及NFS服务器地址和共享目录路径
4、创建StorageClass资源,配置中使用之前定义provisioner的名称

------------- 以上过程是一劳永逸的,以后只需要创建PVC就可以动态生成相关PV资源 -------------
5、创建PVC资源,配置中关联StorageClass资源。创建PVC资源后会在NFS服务器上自动生成相关的PV使用的目录,目录名以<pvc的namespace_name>-<pvc_name>-<pv_name>格式命名
6、创建Pod资源,配置存储卷类型为persistentVolumeClaim,在容器配置中定义存储卷挂载内容

 

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

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

相关文章

采用rknn-toolkit导出rknn模型并部署在rock3a-rk3568芯片 上全流程

因工作需要&#xff0c;需要将目标检测模型 部署在开发板上。在走了很多弯路后 找到一个成功的案例并记载下来 这里说一下我现有的硬件设备 。 我是购买的RADXA的rock3a开发板 搭载的soc是rk3568 这是开发板的正面图&#xff0c;因为瑞芯微针对计算机视觉中的目标检测模型有一…

Java IO流 - 缓冲流的详细使用介绍

文章目录缓冲流缓冲流概述字节缓冲流字符缓存流缓冲流 缓冲流概述 缓冲流介绍: 缓冲流也称为高效流、或者高级流。之前学习的字节流和字符流可以称为原始流。 作用&#xff1a;缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能 缓冲流分为: 字节缓存输入流、字节…

做个测试工具

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

uniapp中引入vant Weapp

Vant Weapp官&#xff1a;https://vant-contrib.gitee.io/vant-weapp/#/home 步骤一&#xff1a;下载vant组件插件 从github上下载该插件https://github.com/youzan/vant-weapp 只要这个dist文件夹&#xff0c;把dist重命名为vant&#xff1b; 步骤二&#xff1a; 与pages…

301-295- 至少有 K 个重复字符的最长子串-0105

题解 本题使用分治策略,如果某个字符的出现次数小于k,则用它将数组分开,再把每个子数组组委参数递归执行.如果都大于k,则将该字符串的长度返回. 用一个字符分割,往深了分割各子字符串,这个字符分割完成,使用另一个字符进行分割,而不是一次用多个字符进行分割.这个题递归有些绕…

电脑怎么重装系统?小白也能轻松掌握这些方法

重新安装计算机系统有两种原因&#xff1a;一种是计算机系统可以正常使用&#xff0c;但是电脑比较卡&#xff0c;为了提高它的运行速度&#xff0c;所以想要通过重新安装系统来解决这个问题&#xff1b;另一种原因是计算机系统文件丢失&#xff0c;系统出现蓝屏&#xff0c;或…

MQ概念简介

队列管理器 队列管理器是MQ系统中最上层的一个概念&#xff0c;由它为我们提供基于队列的消息服务。 2) 消息 在MQ中&#xff0c;我们把应用程序交由MQ传输的数据定义为消息&#xff0c;我们可以定义消息的内容并对消息进行广义的理解&#xff0c;比如&#xff1a;用户的各种类…

机器学习100天(二十九):029 K折交叉验证

机器学习100天,今天讲的是:K 折交叉验证! 《机器学习100天》完整目录:目录 机器学习中,我们常会遇到一个问题,就是超参数的选择,超参数就是机器学习算法中的调优参数,比如上一节 K 近邻算法中的 K 值。K 折交叉验证就是帮助我们选择最优的超参数。 首先,介绍一下简…

FPGA并行计算可编程芯片

玩转Zynq可以使用Vivado创建一个FPGA工程。什么是FPGA前言自FPGA诞生以来&#xff0c;FPGA&#xff08;现场可编程门阵列&#xff09;就引起了人们的关注。在1980年代中期&#xff0c;Ross Freeman和他的同事从Zilog购买了该技术&#xff0c;并创建了Xilinx&#xff0c;目标是A…

基于Java+SpringBoot+vue+node.js实现自行车租赁平台管理系统

基于JavaSpringBootvuenode.js实现自行车租赁平台管理系统 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目录基于JavaSp…

netmap: UDP 协议栈的实现

文章目录1、获取以太网数据1.1、netmap 原理1.2、netmap 环境搭建2、udp 协议栈的实现2.1、以太网帧2.2、ip 协议2.3、udp 协议2.4、问题分析3、ARP 协议的实现4、icmp 协议的实现5、netmap 代码实现1、获取以太网数据 自定义协议栈&#xff0c;需要获取原始的以太网数据&…

第50问:从连接判断应用访问数据库的异常行为

问 我发现应用有一根访问数据库的连接有异常流量&#xff0c;如何判断是应用哪个逻辑导致了异常行为 实验 先起锅烧一个数据库实例&#xff1a; 我们用 mysqlslap 作为应用&#xff1a; 假设在 MySQL 中&#xff0c;我们认为这根连接有异常流量&#xff1a; 通过 ss 找到这根…

阿里一面 | 说说你对 MySQL 死锁的理解

1、什么是死锁&#xff1f; 死锁指的是在两个或两个以上不同的进程或线程中&#xff0c;由于存在共同资源的竞争或进程&#xff08;或线程&#xff09;间的通讯而导致各个线程间相互挂起等待&#xff0c;如果没有外力作用&#xff0c;最终会引发整个系统崩溃。 2、Mysql出现死…

cordova-Toast的使用 -官方插件和自定义插件

前言&#xff1a;cordova是使用前端技术来开发app,可以节省成本和快速发布。不需要了解原生app开发 加载web的方式&#xff0c;可以兼容生成Android、ios以及浏览器等各种平台的项目 前文&#xff1a;cordova开发流程 一、官方提示浮动框 cordova-plugin-x-toast 1.cordova pl…

二、GtkApplication and GtkApplicationWindow

1 GtkApplication 1.1 GtkApplication and g_application_run 人们编写编程代码来开发应用程序。什么是应用程序?应用程序是使用库运行的软件&#xff0c;其中包括操作系统、框架等。在GTK 4编程中&#xff0c;GTK应用程序是使用GTK库运行的程序(或可执行程序)。 编写GtkAp…

屏幕录制有快捷键吗?录屏快捷键ctrl加什么

我们日常使用的电脑是自带录屏功能&#xff0c;可以方便我们将玩游戏的精彩画面&#xff0c;或者是电影某个片段给录制下来。为了不错过这些精彩片段&#xff0c;可以使用录屏快捷键录制。那电脑录屏快捷键ctrl加什么&#xff1f;今天本文就简单地给大家介绍电脑录屏快捷键&…

【错误记录】IntelliJ IDEA 编译 Java 文件报错 ( 错误: 非法字符: ‘\ufeff‘ )

文章目录一、报错信息二、修改方案一、报错信息 报错信息 : D:\002_Project\003_Java_Work\Xxx\src\main\java\cn\Xxx.java:1: 错误: 非法字符: \ufeff &#xfeff;package xxx;出现该问题的原因是 IntelliJ IDEA 在创建文件时 , 为文件添加了 BOM 隐藏字符 , 这是 文件的 字…

(七)汇编语言——更灵活的定位内存地址的方法

目录 and和or ASCII码 [bxidata] SI和DI寄存器 [bxsi]和[bxdi] [bxsiidata]和[bxdiidata] 总结 例子&#xff08;双重循环的解决方案&#xff09; 我们知道&#xff0c;对于汇编来说&#xff0c;内存是极为重要的&#xff0c;所以&#xff0c;能精准且巧妙地定位内存地…

进程间通信——信号

目录 1 概念 2 信号类型 linux的基本信号类型 操作 常用的信号 3 怎么操作信号 signal kill raise alarm pause 注意 范例1&#xff08;自己用信号发送书写sleep函数实现定时炸弹&#xff09; 范例2&#xff08;用信号发送书写功能检测用户是否输入&#xff0c;如…

OAuth2.0协议流程与授权模式、协议流程

什么是OAuth2.0OAuth&#xff08;Open Authorization&#xff09;是一个关于授权&#xff08;authorization&#xff09;的开放网络标准&#xff0c;允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息&#xff0c;而不需要将用户名和密码提供给第三方移动应用或分…