pv和pvc
一、PV和PVC详解
当前,存储的方式和种类有很多,并且各种存储的参数也需要非常专业的技术人员才能够了解。在Kubernetes集群中,放了方便我们的使用和管理,Kubernetes提出了PV和PVC的概念,这样Kubernetes集群的管理人员就可以将注意力集中到Kubernetes集群中来,而无需操心后端的存储设备。
pv : 相当于磁盘分区
pvc: 相当于磁盘请求
PersistentVolumeClaim(PVC)是用户存储的请求
PVC的使用逻辑:在pod中定义一个存储卷(该存储卷类型为PVC),
定义的时候直接指定大小,pvc必须与对应的pv建立关系,
pvc会根据定义去pv申请,而pv是由存储空间创建出来的。
pv和pvc是kubernetes抽象出来的一种存储资源。
PV : 持久化卷的意思,是对底层的共享存储的一种抽象
PVC(Persistent Volume Claim)是持久卷请求于存储需求的一种声明(PVC其实就是用户向kubernetes系统发出的一种资源需求申请。)

从上图可以看出,底层的存储可以使各种类型,包括NFS、Ceph、CIFS等等,而Kubernetes会把这些存储统一抽象为PV。PV,即Persistent Volume,是集群中配置的存储资源。PVC,即Persistent Volume Claim,是用户存储的请求,通常我们在一个Pod中定义一个存储卷,定义的时候会指定该存储卷的相关信息,比如空间大小、可读可写等属性。但是PVC并不是真正的存储空间,Pod的PVC和PV之间必须建立某种联系,这样才能使得Pod可以调用实际存储空间。
kind: PersistentVolume
metadata:name: pv2
apiVersion: v1
spec:nfs: # 存储类型,与底层真正存储对应capacity: # 存储能力,目前只支持存储空间的设置storage: 2GiaccessModes: # 访问模式storageClassName: # 存储类别persistentVolumeReclaimPolicy: # 回收策略
使用了PV和PVC之后,工作可以得到进一步的细分:
存储:存储工程师维护
PV: kubernetes管理员维护
PVC:kubernetes用户维护
二、PV和PVC生命周期
实际上,不管是PV,还是PVC,都遵循以下生命周期:
2.1 Provisioning
Provisioning,即配置阶段。一般而言,PV的提供方式有两种——静态和动态。
所谓静态提供,就是Kubernetes管理员创建多个PV,这些PV的存储空间等属性已经确定,并且已经和真实的存储设备进行了关联。Pod中的PVC可以根据需要请求这些PV。
所谓动态提供,需要依托与StorageClass的支持,这时Kubernetes会尝试为PVC来动态的创建PV。这样做的好处是避免出现这种情况:部分PVC被分配给了远远超出其资源需求的PV、或者说系统存在很多资源较少的PV,但是一个资源需求很高的PVC缺无法被满足的情况。
2.2 Binding
在动态配置的情况下,用户创建或者已经创建了具有特定数量的PVC后,PVC与PV绑定的过程。
如果没有满足PVC请求需求的PV,那么PVC将无法被创建,因此造成的结果就是相应的Pod也不会被创建。
2.3 Using
即PVC与PC绑定后,Pod对存储空间的使用过程。
2.4 Releasing
当Pod被删除或者对该PV的资源使用结束后,Kubernetes就会删除该PVC对象,相应的也会回收PV资源,这时的PV就会处于这种状态。但是此时的PV还需要处理完毕之前的Pod在该存储卷上存储信息后才能够被使用。
2.5 Reclaiming
PV的回收策略对被释放的PV的处理过程。
2.6 Recycling
根据配置,有时PV会被执行擦除操作,删除掉该存储空间上的所有信息,并且该存储资源也可以被再次使用。
三、访问模式
3.1 PV 的访问模式(accessModes)
模式 | 解释 |
ReadWriteOnce (RWO) | 可读可写,但只支持被单个节点挂载。 |
ReadOnlyMany (ROX) | 只读,可以被多个节点挂载。 |
ReadWriteMany (RWX) | 多路可读可写。这种存储可以以读写的方式被多个节点共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是 NFS。在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。 |
3.2 PV的回收策略(persistentVolumeReclaimPolicy)
策略 | 解释 |
Retain | 不清理,保留Volume (需要手动清理) |
Recycle | 删除数据,即rm -rf /thevolumel*(只有NFS和HostPath支持) |
Delete | 删除存储资源,比如删除AWS EBS卷(只有AWS EBS,GCE PD,Azure Disk和Cinder支持) |
3.3 PV的状态
状态 | 解释 |
Available | 可用 |
Bound | 已经分配给PVC |
ReleasedPVC | 解绑但还未执行回收策略 |
Failed | 发生错误 |
四、实验验证
4.1 安装nfs
# 1、创建目录
[root@k8s ~]# mkdir /root/data/{pv1,pv2,pv3} -pv# 2、暴露服务
[root@k8s ~]# vim /etc/exports
/root/data/pv1 192.168.223.0/24(rw,sync,no_root_squash)
/root/data/pv2 192.168.223.0/24(rw,sync,no_root_squash)
/root/data/pv3 192.168.223.0/24(rw,sync,no_root_squash)# 3、重启服务
[root@k8s ~]# systemctl restart nfs
4.2 创建pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: pv1
spec:capacity:storage: 10GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retain #回收策略storageClassName: nfs #类别名字nfs: #nfs存储path: /root/data/pv1 #nfs挂载路径server: 192.168.15.30 #对应的nfs服务器[root@k8s pv]# kubectl apply -f pv.yaml
persistentvolume/pv1 created
[root@k8s pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 10Gi RWX Retain Available nfs 4s
4.3 PVC
PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息。下面是资源清单文件:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvcnamespace: dev
spec:accessModes: # 访问模式selector: # 采用标签对PV选择storageClassName: # 存储类别resources: # 请求空间requests:storage: 5Gi
PVC 的关键配置参数说明:
访问模式(accessModes)
用于描述用户应用对存储资源的访问权限
选择条件(selector)
通过Label Selector的设置,可使PVC对于系统中己存在的PV进行筛选
存储类别(storageClassName)
PVC在定义时可以设定需要的后端存储的类别,只有设置了该class的pv才能被系统选出
资源请求(Resources )
描述对存储资源的请求
4.4 实验
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc1namespace: dev
spec:accessModes: - ReadWriteManyresources:requests:storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc2namespace: dev
spec:accessModes: - ReadWriteManyresources:requests:storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc3namespace: dev
spec:accessModes: - ReadWriteManyresources:requests:storage: 1Gi # 如果pvc大于pv,则绑定不上
# 1、创建pvc
[root@k8s ~]# kubectl create -f pvc.yaml
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
persistentvolumeclaim/pvc3 created
# 2、查看pvc
[root@k8s ~]# kubectl get pvc -n dev -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
pvc1 Bound pv1 1Gi RWX 15s Filesystem
pvc2 Bound pv2 2Gi RWX 15s Filesystem
pvc3 Bound pv3 3Gi RWX 15s Filesystem
# 3、查看pv
[root@k8s k8s]# kubectl get pv -n dev
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWX Retain Bound dev/pvc1 4m25s
pv2 2Gi RWX Retain Bound dev/pvc2 4m25s
pv3 3Gi RWX Retain Bound dev/pvc3
创建pods.yaml, 使用pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /root/data/pv2 #路径和地址全部指向nfs机器
server: 192.168.223.30
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv3
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /root/data/pv3
server: 192.168.223.30
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: none #无头service
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet #一个接着一个创建
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: "nfs"
resources:
requests:
storage: 1Gi
[root@k8s pv]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pv3 1Gi RWX nfs 10s
www-web-1 Bound pv2 2Gi RWX nfs 4s
[root@k8s pv]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 17s
web-1 1/1 Running 0 11s
web-2 0/1 Pending 0 5s
[root@k8s pv]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 28s
web-1 1/1 Running 0 22s
web-2 0/1 Pending 0 16s
[root@k8spv]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 29s
web-1 1/1 Running 0 23s
效果测试
#查看pv2的存储
[root@k8s pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv2 2Gi RWX Retain Bound default/www-web-1 nfs 93s
pv3 1Gi RWX Retain Bound default/www-web-0 nfs 93s
[root@k8s pv]# kubectl describe pv pv2
Name: pv2
Labels: <none>
Annotations: pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs
Status: Bound
Claim: default/www-web-1
Reclaim Policy: Retain
Access Modes: RWX
VolumeMode: Filesystem
Capacity: 2Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 192.168.223.30
Path: /root/data/pv2
ReadOnly: false
Events: <none>
#进入挂载目录创建index.html文件
[root@k8s pv]# cd /root/data/pv2
[root@k8s pv2]# ls
[root@k8s pv2]# vim index.html
[root@k8s pv2]# cat index.html
aaaaaa
[root@k8s pv2]# chmod 777 index.html
[root@k8s pv2]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv2 2Gi RWX Retain Bound default/www-web-1 nfs 4m20s Filesystem
pv3 1Gi RWX Retain Bound default/www-web-0 nfs 4m20s Filesystem
[root@k8s pv2]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-0 1/1 Running 0 4m14s 10.150.2.120 k8s-node-02 <none> <none>
web-1 1/1 Running 0 4m8s 10.150.1.96 k8s-node-01 <none> <none>
web-2 0/1 Pending 0 4m2s <none> <none> <none> <none>
[root@k8s pv2]# curl 10.150.1.96
aaaaaa
statefulset访问的名称一样,当删除pod的时候 ,名称不变。地址会变。例如web-1一样。
[root@k8s pv2]# kubectl delete pods web-1
pod "web-1" deleted
[root@k8s pv2]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 9m26s
web-1 1/1 Running 0 58s
web-2 0/1 Pending 0 9m14s
[root@k8s pv2]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-0 1/1 Running 0 9m35s 10.150.2.120 k8s-node-02 <none> <none>
web-1 1/1 Running 0 67s 10.150.1.97 k8s-node-01 <none> <none>
web-2 0/1 Pending 0 9m23s <none> <none> <none> <none>
#新的IP地址访问,一样可以访问到
[root@k8s-master-01 pv2]# curl 10.150.1.97
aaaaaa
[root@k8s-master-01 pv2]#
其余pv类似
五、关于statefulset
匹配 Pod name(网络标识)的模式为: (statefulset 名称)-(序号),比如上面的示例: web-0,web-1,web-2
StatefulSet为每个Pod副本创建了一个DNS域名,这个域名的格式为: $(podname).(headlessserver name),也就意味着服务间是通过Pod域名来通信而非Pod lP,因为当Pod所在Node发生故障时,Pod会被飘移到其它Node 上,Pod IP会发生变化,但是Pod域名不会有变化
tatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN为: (servicename).(namespace).svc.cluster.local,其中,"cluster.local”指的是集群的域名
根据volumeClaimTemplates,为每个Pod创建一个pvc, pvc的命名规则匹配模式:(volumeClaimTemplates.name)-(pod_name),比如上面的volumeMounts.name=www,Podname=web-[0-2],因此创建出来的PVC是www-web-0、www-web-1、www-web-2
删除Pod不会删除其pvc,手动删除pvc将自动释放pv
[root@k8s pv2]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-pd 1/1 Running 0 14s
web-0 1/1 Running 0 16m
web-1 1/1 Running 0 8m16s
web-2 0/1 Pending 0 16m
[root@k8s pv2]# kubectl exec -it test-pd -- sh
/ # ping web-0.nginx
ping: bad address 'web-0.nginx'
/ # ping web-0.nginx
PING web-0.nginx (10.150.2.120): 56 data bytes
64 bytes from 10.150.2.120: seq=0 ttl=64 time=4.891 ms
64 bytes from 10.150.2.120: seq=1 ttl=64 time=0.209 ms
64 bytes from 10.150.2.120: seq=2 ttl=64 time=0.196 ms
64 bytes from 10.150.2.120: seq=3 ttl=64 time=0.131 ms
64 bytes from 10.150.2.120: seq=4 ttl=64 time=0.128 ms
5.1 statefulset的启停顺序
有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态。
有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。
有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。
5.2 StatefulSet使用场景:
稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现。稳定的网络标识符,即Pod重新调度后其PodName和HostName不变。
有序部署,有序扩展,基于init containers来实现。
有序收缩。
[root@k8s pv2]# kubectl get pods -o wide -n kube-system
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-f68b4c98f-nkqlm 1/1 Running 2 22d 10.150.0.7 k8s-master-01 <none> <none>
coredns-f68b4c98f-wzrrq 1/1 Running 2 22d 10.150.0.6 k8s-master-01 <none> <none>
etcd-k8s-master-01 1/1 Running 3 22d 192.168.223.30 k8s-master-01 <none> <none>
kube-apiserver-k8s-master-01 1/1 Running 3 22d 192.168.223.30 k8s-master-01 <none> <none>
kube-controller-manager-k8s-master-01 1/1 Running 4 22d 192.168.223.30 k8s-master-01 <none> <none>
kube-flannel-ds-8zj9t 1/1 Running 1 11d 192.168.223.30 k8s-node-01 <none> <none>
kube-flannel-ds-jmq5p 1/1 Running 0 11d 192.168.223.30 k8s-node-02 <none> <none>
kube-flannel-ds-vjt8b 1/1 Running 4 11d 192.168.223.30 k8s-master-01 <none> <none>
kube-proxy-kl2qj 1/1 Running 2 22d 192.168.223.30 k8s-master-01 <none> <none>
kube-proxy-rrlg4 1/1 Running 1 22d 192.168.223.9 k8s-node-01 <none> <none>
kube-proxy-tc2nd 1/1 Running 0 22d 192.168.223.10 k8s-node-02 <none> <none>
kube-scheduler-k8s-master-01 1/1 Running 4 22d 192.168.223.30 k8s-master-01 <none> <none>
[root@k8s-master-01 pv2]# dig -t A nginx.default.svc.cluster.local. @10.150.0.7; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.8 <<>> -t A nginx.default.svc.cluster.local. @10.244.0.7
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26852
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx.default.svc.cluster.local. INA;; ANSWER SECTION:
nginx.default.svc.cluster.local. 30 INA10.111.55.241;; Query time: 7 msec
;; SERVER: 10.150.0.7#53(10.150.0.7)
;; WHEN: 一 08月 06 00:00:38 CST 2021
;; MSG SIZE rcvd: 107
删除对应的pod、svc、statefulset、pv、pvc
[root@k8s pv]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-pd 1/1 Running 0 18m
web-0 1/1 Running 0 34m
web-1 1/1 Running 0 26m
web-2 0/1 Pending 0 34m[root@k8s pv]# kubectl delete -f pod.yaml
service "nginx" deleted
statefulset.apps "web" deleted[root@k8s pv]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-pd 1/1 Running 0 18m
web-0 0/1 Terminating 0 35m
web-1 0/1 Terminating 0 26m[root@k8s pv]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d[root@k8s pv]# kubectl delete statefulsets.apps --all
No resources found
[root@k8s pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv2 2Gi RWX Retain Bound default/www-web-1 nfs 35m
pv3 1Gi RWX Retain Bound default/www-web-0 nfs 35m[root@k8s pv]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pv3 1Gi RWX nfs 35m
www-web-1 Bound pv2 2Gi RWX nfs 35m
www-web-2 Pending nfs 35m
[root@k8s pv]# kubectl delete pvc --all
persistentvolumeclaim "www-web-0" deleted
persistentvolumeclaim "www-web-1" deleted
persistentvolumeclaim "www-web-2" deleted#查看pv显示release状态
[root@k8s pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv2 2Gi RWX Retain Released default/www-web-1 nfs 36m
pv3 1Gi RWX Retain Released default/www-web-0 nfs 36m#编辑pv2的yaml格式、因为 claimRef的显示所以一直显示release的状态,可以通过edit修改pv2的yaml,删除对应的claimRef的那一段[root@k8s pv]# kubectl edit pv pv2 -o yaml# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: PersistentVolume
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"name":"pv2"},"spec":{"accessModes":["ReadWriteMany"],"capacity":{"storage":"2Gi"},"nfs":{"path":"/root/data/pv2","server":"192.168.15.31"},"persistentVolumeReclaimPolicy":"Retain","storageClassName":"nfs"}}pv.kubernetes.io/bound-by-controller: "yes"creationTimestamp: "2021-12-26T15:34:19Z"finalizers:- kubernetes.io/pv-protectionname: pv2resourceVersion: "501755"uid: 7b9f8b31-f111-4064-9ec7-d06e55f6bebd
spec:accessModes:- ReadWriteManycapacity:storage: 2GiclaimRef:apiVersion: v1kind: PersistentVolumeClaimname: www-web-1namespace: defaultresourceVersion: "498363"uid: 7d47eaf8-8bed-40fc-b790-18e93a8a0398nfs:path: /root/data/pv2
"/tmp/kubectl-edit-euy6w.yaml" 37L, 1260C
#这时候发现状态已经为 Available状态
[root@k8s pv]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv2 2Gi RWX Retain Available nfs 44m
pv3 1Gi RWX Retain Released default/www-web-0 nfs 44m

相关文章:

pv和pvc
一、PV和PVC详解当前,存储的方式和种类有很多,并且各种存储的参数也需要非常专业的技术人员才能够了解。在Kubernetes集群中,放了方便我们的使用和管理,Kubernetes提出了PV和PVC的概念,这样Kubernetes集群的管理人员就…...

k8s篇之Pod 干预与 PDB
文章目录自愿干预和非自愿干预PDBPDB 示例分离集群所有者和应用程序所有者角色如何在集群上执行中断操作自愿干预和非自愿干预 Pod 不会消失,除非有人(用户或控制器)将其销毁,或者出现了不可避免的硬件或软件系统错误。 我们把这…...

Django学习17 -- ManytoManyField
1. ManyToManyField (参考:Django Documentation Release 4.1.4) 类定义 class ManyToManyField(to, **options)使用说明 A many-to-many relationship. Requires a positional argument: the class to which the model is related, which w…...

既然有MySQL了,为什么还要有Redis?
目录专栏导读一、同样是缓存,用map不行吗?二、Redis为什么是单线程的?三、Redis真的是单线程的吗?四、Redis优缺点1、优点2、缺点五、Redis常见业务场景六、Redis常见数据类型1、String2、List3、Hash4、Set5、Zset6、BitMap7、Bi…...

RSTP基础要点(上)
RSTP基础RSTP引入背景STP所存在的问题RSTP对于STP的改进端口角色重新划分端口状态重新划分快速收敛机制:PA机制端口快速切换边缘端口的引入RSTP引入背景 STP协议虽然能够解决环路问题,但是由于网络拓扑收敛较慢,影响了用户通信质量ÿ…...

Linux操作系统学习(信号处理)
文章目录进程信号信号的产生方式(信号产生前)1. 硬件产生2.调用系统函数向进程发信号3.软件产生4.定位进程崩溃的代码(进程异常退出产生信号)信号保存的方式(信号产生中)获取pending表&&修改block表…...

CopyOnWriteArrayList 源码解读
一、CopyOnWriteArrayList 源码解读 在 JUC 中,对于 ArrayList 的线程安全用法,比较推崇于使用 CopyOnWriteArrayList ,那 CopyOnWriteArrayList是怎么解决线程安全问题的呢,本文带领大家一起解读下 CopyOnWriteArrayList 的源码…...
方法
方法方法(函数)一、课前问答二、方法和函数三、方法的参数3.1 单个参数3.2 多个参数四、方法的返回值五、方法的多级调用六、递归方法(函数) 一、课前问答 1、break和continue的区别 2、嵌套循环的执行流程 3、二进制有哪些运算&…...

C/C++实现发送邮件功能(附源码)
C++常用功能源码系列 本文是C/C++常用功能代码封装专栏的导航贴。部分来源于实战项目中的部分功能提炼,希望能够达到你在自己的项目中拿来就用的效果,这样更好的服务于工作实践。 专栏介绍:专栏讲本人近10年后端开发常用的案例,以高质量的代码提取出来,并对其进行了介绍。…...

Java虚拟机JVM-运行时数据区域说明
及时编译器 HotSpot虚拟机中含有两个即时编译器,分别是编译耗时短但输出代码优化程度较低的客户端编译器(简称为C1)以及编译耗时长但输出代码优化质量也更高的服务端编译器(简称为C2),通常它们会在分层编译…...

修复电子管
年前在咸鱼捡漏买到了10根1G4G电子管,这是一种直热三极管,非常的少见。买回来的时候所有的灯丝都是通的,卖家说都是新的,库存货,但是外观实在是太糟糕了,看着就像被埋在垃圾场埋了几十年的那种,…...

【Java】反射机制和代理机制
目录一、反射1. 反射概念2. 反射的应用场景3. 反射机制的优缺点4. 反射实战获取 Class 对象的四种方式二、代理机制1. 代理模式2. 静态代理3. 动态代理3.1 JDK动态代理机制1. 介绍2.JDK 动态代理类使用步骤3. 代码示例3.2 CGLIB 动态代理机制1.介绍2.CGLIB 动态代理类使用步骤3…...

synchronized底层
Monitor概念一、Java对象头二、Monitor2.1、Monitor—工作原理2.2、Monitor工作原理—字节码角度2.2、synchronized进阶原理(优化)2.3、synchronized优化原理——轻量级锁2.4、synchronized优化原理——锁膨胀2.5、synchronized优化原理——自旋优化2.6、…...

数据结构:复杂度的练习(笔记)
数据结构:复杂度的练习(笔记) 例题一: 可以先给数组排序,然后再创建一个i值,让他循环一次一次,遍历这个排序后的数组,但如果用qsort函数进行排序,时间复杂度就和题目要求…...
JAVA练习69- 从前序与中序遍历序列构造二叉树
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 提示:这里可以添加本文要记录的大概内容: 3月5日练习内容 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目-从…...

brew安装问题
最近使用mac安装了Python和PyCharm,使用python中的绘制图像的turtle库后,执行报错: import _tkinter # If this fails your Python may not be configured for Tk ModuleNotFoundError: No module named _tkinter 查询后需在mac 命令行执行&…...

【数据挖掘与商务智能决策】第一章 数据分析与三重工具
numpy基础 numpy与数组 import numpy as np # 用np代替numpy,让代码更简洁 a [1, 2, 3, 4] # 创建列表a b np.array([1, 2, 3, 4]) #从列表ach print(a) print(b) print(type(a)) #打印a类型 print(type(b)) #打印b类型[1, 2, 3, 4] [1 2 3 4] <class ‘list’>…...

计算机底层:BDC码
计算机底层:BDC码 BDC码的作用: 人类喜欢十进制,而机器适合二进制,因此当机器要翻译二进制给人看时,就会进行二进制和十进制的转换,而常规的转换法(k*位权)太麻烦。因此就出现了不同…...

【C++】平衡二叉搜索(AVL)树的模拟实现
一、 AVL树的概念 map、multimap、set、multiset 在其文档介绍中可以发现,这几个容器有个共同点是:其底层都是按照二叉搜索树来实现的,但是二叉搜索树有其自身的缺陷,假如往树中插入的元素有序或者接近有序,二叉搜索树…...

[2019红帽杯]childRE
题目下载:下载 参考:re学习笔记(24)BUUCTF-re-[2019红帽杯]childRE_Forgo7ten的博客-CSDN博客 这道题涉及到c函数的修饰规则,按照规则来看应该是比较容易理解的。上面博客中有总结规则,可以学习一下。 载…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...