Kubernets1.20部署Redis7.0集群6节点三主三从(完整版)-2023.5.13

news2025/1/20 14:55:45

目录

    • 一、产品选型
    • 二、草图
    • 三、部署
      • 1、安装NFS服务
        • 1)NFS Server端安装NFS
        • 2)创建NFS 共享点
        • 3)启动rpcbind、nfs服务
        • 4)验证服务配置
      • 2、创建持久卷PVC
        • 1)创建ServiceAccount账号
        • 2)创建provisioner
        • 3)创建StorageClass
      • 3、创建Redis服务
        • 1)创建redis配置文件
        • 2)创建statefulset类型的Redis集群
      • 4、检查服务
        • 问题:修改K8s1.20版本的API配置
      • 5、组建Redis集群
        • 1)自动组建集群
        • 1)手动组建集群
      • 6、验证集群

一、产品选型

主要服务和版本

服务版本
Rancher (单节点)2.5.12
Redis7.0.11
Kubernetes1.20.15
CentOS7.9

主机规划

节点IP
k8s-master1192.168.2.245
k8s-master2192.168.2.246
k8s-master3192.168.2.247
k8s-node1192.168.2.248
NFS、Rancher192.168.2.251

二、草图

在这里插入图片描述

三、部署

1、安装NFS服务

1)NFS Server端安装NFS

操作主机:NFS、Rancher|192.168.2.251

yum -y install nfs-utils rpcbind

2)创建NFS 共享点

vim /etc/exports
/nfs/k8s_data 192.168.2.0/24(rw,no_root_squash,no_all_squash,sync)

创建目录

/nfs/k8s_data
注:
rw read-write 读写
ro read-only 只读
sync 请求或写入数据时,数据同步写入到NFS server的硬盘后才返回。数据安全,但性能降低了
async 优先将数据保存到内存,硬盘有空档时再写入硬盘,效率更高,但可能造成数据丢失。
root_squash 当NFS 客户端使用root用户访问时,映射为NFS 服务端的匿名用户
no_root_squash 当NFS 客户端使用root 用户访问时,映射为NFS服务端的root 用户
all_squash 不论NFS 客户端使用任何帐户,均映射为NFS 服务端的匿名用户

3)启动rpcbind、nfs服务

systemctl start nfs
systemctl start rpcbind
#添加开机自启
systemctl enable nfs
systemctl enable rpcbind

4)验证服务配置

exportfs -r
#无返回表示服务正常

查看挂载情况

showmount -e localhost
#输出下面信息表示正常
Export list for localhost:
/nfs/k8s_data 192.168.2.0/24

5)安装NFS client端
操作主机:除了NFS server,其他所有主机

yum -y install nfs-utils

2、创建持久卷PVC

当有很多的数据卷需要创建或者管理时,Kubernetes解决这个问题的方法是提供动态配置PV的方法,可以自动创建PV。管理员可以部署PV配置器(provisioner),然后定义对应的StorageClass,这样开发者在创建PVC的时候就可以选择需要创建存储的类型,PVC会把StorageClass传递给PV provisioner,由provisioner自动创建PV。

参考k8s官网:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#provisioner
参考Github开源组件:https://github.com/kubernetes-retired/external-storage/blob/master/nfs-client/deploy/

所以这里使用了StorageClass的类型当做就持久化方案

1)创建ServiceAccount账号

vim nfs-serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
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"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

创建资源

kubectl create -f nfs-serviceaccount.yaml

2)创建provisioner

(也可称为供应者、置备程序、存储分配器)
vim nfs-client-provisioner.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner				#这个serviceAccountName就是上面创建ServiceAccount账号
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME			#PROVISIONER_NAME的值就是本清单的顶部定义的name
              value: nfs-client-provisioner
            - name: NFS_SERVER					#这个NFS_SERVER参数的值就是nfs服务器的IP地址
              value: 192.168.2.251
            - name: NFS_PATH					#这个NFS_PATH参数的值就是nfs服务器的共享目录
              value: /nfs/k8s_data
      volumes:
        - name: nfs-client-root
          nfs:									#这里就是配置nfs服务器的ip地址和共享目录
            server: 192.168.2.251
            path: /nfs/k8s_data

创建资源

kubectl create -f nfs-client-provisioner.yaml

3)创建StorageClass

vim nfs-storageclass.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storageclass
provisioner: nfs-client-provisioner				#provisioner参数定义置备程序
reclaimPolicy: Retain							#回收策略,默认是Delete
parameters:
  archiveOnDelete: "false"

创建资源

kubectl create -f nfs-storageclass.yaml	

3、创建Redis服务

1)创建redis配置文件

这里使用的是k8s的configmap类型创建的
vim redis.conf

bind 0.0.0.0
protected-mode yes
port 6360											#redis端口,为了安全设置为6360端口
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no										#redis是否以后台模式运行,必须设置no
supervised no
pidfile /data/redis.pid								#redis的pid文件,放到/data目录下
loglevel notice
logfile /data/redis_log								#redis日志文件,放到/data目录下
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb									#这个文件会放在dir定义的/data目录
dir /data											#数据目录
masterauth iloveyou									#redis集群各节点相互认证的密码,必须配置和下面的requirepass一致
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
requirepass iloveyou								#redis的密码
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"						#这个文件会放在dir定义的/data目录
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
cluster-enabled yes									#是否启用集群模式,必须去掉注释设为yes
cluster-config-file nodes.conf						#这个文件会放在dir定义的/data目录
cluster-node-timeout 15000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

创建configmap
#创建cm,名称为redis-conf,key为redis.conf,value为上创建的redis.conf配置文件

kubectl create configmap redis-conf --from-file=redis.conf=redis.conf	

2)创建statefulset类型的Redis集群

这里使用statefulsets有状态应用来创建redis,创建sts有状态应用需要有一个headless service,同时在sts中挂载configmap卷,使用动态分配pv用于redis数据持久化
vim redis-cluster-sts.yaml

---
apiVersion: v1
kind: Service                                     #先创建一个无头service
metadata:
  labels:                                         #service本身的标签
    app: redis-svc
  name: redis-svc                                 #service的名称,下面创建的StatefulSet就要引用这个service名称
spec:
  ports:
  - port: 6360                                    #service本身的端口
    protocol: TCP
    targetPort: 6360                              #目标端口6360,redis默认端口是6379,这里为了安全改成了6360
  selector:
    app: redis-sts                                #标签选择器要与下面创建的pod的标签一样
  type: ClusterIP
  clusterIP: None                                 #clusterIP为None表示创建的service为无头service
---
apiVersion: apps/v1
kind: StatefulSet                                 #创建StatefulSet资源
metadata:
  labels:                                         #StatefulSet本身的标签
    app: redis-sts
  name: redis-sts                                 #资源名称
  namespace: default                              #资源所属命名空间
spec:
  selector:                                       #标签选择器,要与下面pod模板定义的pod标签保持一致
    matchLabels:
      app: redis-sts
  replicas: 6                                     #副本数为6个,redis集群模式最少要为6个节点,构成3主3从
  serviceName: redis-svc                          #指定使用service为上面我们创建的无头service的名称
  template:                     
    metadata:
      labels:                                     #pod的标签,上面的无头service的标签选择器和sts标签选择器都要与这个相同
        app: redis-sts
    spec:
#     affinity:
#       podAntiAffinity:                         #定义pod反亲和性,目的让6个pod不在同一个主机上,实现均衡分布,这里我的node节点不够,所以不定义反亲和性
#         preferredDuringSchedulingIgnoredDuringExecution:
#         - weight: 100
#           podAffinityTerm:
#             labelSelector:
#              matchExpressions:
#               - key: app
#                 operator: In
#                 values:
#                 - redis-sts
#             topologyKey: kubernetes.io/hostname
      containers:
      - name: redis                               #容器名称
        image: redis:latest                       #redis镜像
        imagePullPolicy: IfNotPresent             #镜像拉取策略
        command:                                  #定义容器的启动命令和参数
          - "redis-server"
        args:
          - "/etc/redis/redis.conf"
          - "--cluster-announce-ip"                              #这个参数和下面的这个参数
          - "$(POD_IP)"                                                  #这个参数是为了解决pod重启ip变了之后,redis集群状态无法自动同步问题
        env:
        - name: POD_IP                                                   #POD_IP值引用自status.podIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP   
        ports:                                    #定义容器端口
        - name: redis-6360                        #为端口取个名称为http
          containerPort: 6360                     #容器端口
        volumeMounts:                             #挂载点
        - name: "redis-conf"                      #引用下面定义的redis-conf卷
          mountPath: "/etc/redis"                 #redis配置文件的挂载点
        - name: "redis-data"                      #指定使用的卷名称,这里使用的是下面定义的pvc模板的名称
          mountPath: "/data"                      #redis数据的挂载点
        - name: localtime                                                 #挂载本地时间
          mountPath: /etc/localtime
          readOnly: true
      restartPolicy: Always
      volumes:
      - name: "redis-conf"                        #挂载一个名为redis-conf的configMap卷,这个cm卷已经定义好了
        configMap:
          name: "redis-conf"
          items:
            - key: "redis.conf"
              path: "redis.conf"
      - name: localtime                                                 #挂载本地时间
        hostPath:
          path: /etc/localtime
#          type: File
  volumeClaimTemplates:                           #定义创建pvc的模板
    - metadata:
        name: "redis-data"                        #模板名称
      spec:
        resources:                                #资源请求
          requests:
            storage: 100M                         #需要100M的存储空间
        accessModes:                            
        - ReadWriteOnce                           #访问模式为RWO
        storageClassName: "nfs-storageclass"      #指定使用的存储类,实现动态分配pv

创建资源

kubectl create -f  redis-cluster-sts.yaml 

4、检查服务

问题:修改K8s1.20版本的API配置

如果Kubernetes的版本是1.20.x以上的版本,我们查看nfs-client-provisioner服务日志,应该会出现报错:unexpected error getting claim reference: selfLink was empty, can’t make reference
解决方法:
1)二进制安装的集群:
在/etc/kubernetes/manifests/kube-apiserver.yaml的文件中添加:

--feature-gates=RemoveSelfLink=false

2)Rancher RKE工具安装或者其他工具
万变不离其宗,参考Rancher万金油法则,在Rancher上修改Kubernetes的API yaml文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
修改

  services:
    kube-api:
      extra_args:
        feature-gates: 'RemoveSelfLink=false'

在这里插入图片描述
最后点击保存,等到集群更新完成即可

kubectl get sts,pvc,pv

在这里插入图片描述
服务全部就绪,数据卷已绑定完成

5、组建Redis集群

这里介绍两种组建集群的方法,分为手动和自动,选择自己喜欢的一个方式操作
我使用了域名的方式让他们相互通信,这样可以避免pod被重启ip变化,导致集群出现问题
根据K8s机制,<pod-name>.<svc-name>.<namespace>.svc.cluster.local这个 DNS 记录,正是 Kubernetes 项目为 Pod 分配的唯一的可解析身份,这样Pod就可以通过名字编号进行区分了,并且可以相互访问。

1)自动组建集群

kubectl exec -it redis-sts-0 -- redis-cli -a iloveyou --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis-sts -o jsonpath='{range.items[*]}{.metadata.name}.redis-svc:6360 {end}')

输入yes,正式开始组建redis集群
最后返回:

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

1)手动组建集群

查看下Pod的信息

[root@k8s-master01 redis]# kubectl get pod  -l app=redis-sts
NAME          READY   STATUS    RESTARTS   AGE
redis-sts-0   1/1     Running   0          61m
redis-sts-1   1/1     Running   0          61m
redis-sts-2   1/1     Running   0          61m
redis-sts-3   1/1     Running   0          61m
redis-sts-4   1/1     Running   0          61m
redis-sts-5   1/1     Running   0          61m

手动创建redis集群的master节点,指定redis-sts-0、redis-sts-2、redis-sts-4的pod为master节点,同样适用DNS解析域名的方式

 kubectl exec -it redis-sts-0 -- redis-cli -a iloveyou --cluster create redis-sts-0.redis-svc:6360 redis-sts-2.redis-svc:6360 redis-sts-4.redis-svc:6360
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: 0708f2d7db318bc8651dd422d28627957756472d redis-sts-0.redis-svc:6360   #0708f2d7db318bc8651dd422d28627957756472d集群ID
   slots:[0-5460] (5461 slots) master
M: 0b5c2c8d2907dbb56c6e40baf0272917e59d960f redis-sts-2.redis-svc:6360   #同上
   slots:[5461-10922] (5462 slots) master
M: 8ace82454363dc760fe856712fc0fbb220b2e2d5 redis-sts-4.redis-svc:6360    # 同上
   slots:[10923-16383] (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes           #输入yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
..
>>> Performing Cluster Check (using node redis-sts-0.redis-svc:6360)
M: 0708f2d7db318bc8651dd422d28627957756472d redis-sts-0.redis-svc:6360
   slots:[0-5460] (5461 slots) master
M: 0b5c2c8d2907dbb56c6e40baf0272917e59d960f 10.42.2.38:6360
   slots:[5461-10922] (5462 slots) master
M: 8ace82454363dc760fe856712fc0fbb220b2e2d5 10.42.3.71:6360
   slots:[10923-16383] (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

为每一个master节点添加slave节点

# redis-sts-0 主   >>    redis-sts-1 从
kubectl exec -it redis-sts-0 -- redis-cli -a iloveyou --cluster add-node redis-sts-1.redis-svc:6360 redis-sts-0.redis-svc:6360 --cluster-slave --cluster-master-id 0708f2d7db318bc8651dd422d28627957756472d


# redis-sts-2 主   >>    redis-sts-3 从
kubectl exec -it redis-sts-0 -- redis-cli -a iloveyou --cluster add-node redis-sts-3.redis-svc:6360 redis-sts-2.redis-svc:6360 --cluster-slave --cluster-master-id 0b5c2c8d2907dbb56c6e40baf0272917e59d960f

# redis-sts-4 主   >>    redis-sts-5 从
kubectl exec -it redis-sts-0 -- redis-cli -a iloveyou --cluster add-node redis-sts-5.redis-svc:6360 redis-sts-4.redis-svc:6360 --cluster-slave --cluster-master-id 8ace82454363dc760fe856712fc0fbb220b2e2d5

注:
–cluster add-node 参数指定要加入的slave节点
–cluster-master-id 参数指定该slave节点对应的master节点的id

6、验证集群

使用下面这条命令验证集群状态,注意–cluster check 后面仅需指定任意一个节点ip即可,这里的range.items[0]就表示指定第一个redis-sts-0的ip,如下所示,集群状态正常

[root@k8s-master01 redis]# kubectl exec -it redis-sts-0 -- redis-cli -a iloveyou --cluster check  $(kubectl get pods -l app=redis-sts -o jsonpath='{range.items[0]}{.metadata.name}:6360 {end}')
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
redis-sts-0:6360 (0708f2d7...) -> 0 keys | 5461 slots | 1 slaves.
10.42.3.71:6360 (8ace8245...) -> 0 keys | 5461 slots | 1 slaves.
10.42.2.38:6360 (0b5c2c8d...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node redis-sts-0:6360)
M: 0708f2d7db318bc8651dd422d28627957756472d redis-sts-0:6360
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 8ace82454363dc760fe856712fc0fbb220b2e2d5 10.42.3.71:6360
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 0b5c2c8d2907dbb56c6e40baf0272917e59d960f 10.42.2.38:6360
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 9683517103c33656e8fb1b666064011d74addf52 10.42.1.16:6360
   slots: (0 slots) slave
   replicates 0b5c2c8d2907dbb56c6e40baf0272917e59d960f
S: 6f17691791b9755956868d14b7fc0e1c59bf4fb2 10.42.0.25:6360
   slots: (0 slots) slave
   replicates 8ace82454363dc760fe856712fc0fbb220b2e2d5
S: 22038a5bb2e31d385ce016ba1cd9d8f13eb4e0d8 10.42.0.24:6360
   slots: (0 slots) slave
   replicates 0708f2d7db318bc8651dd422d28627957756472d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

参考:
Redis6节点集群搭建
K8s搭建nfs-storageclass
K8s搭建nfs-storageclass

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

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

相关文章

vite入坑之路:react+vite动态导入报错@vite-ignore的解决方法

正常的动态组件导入方式 webpack搭建的项目&#xff0c;不管是react还是vue通常引入动态组件基本这么写&#xff1a; const url import(../pages/${locale}) // vite不支持or const url import(../pages/${locale}/index.jsx) // vite不支持这在vite架构中&#xff0c;一般…

Vue3+vite环境变量配置

在项目开发中&#xff0c;通常来说&#xff0c;不同的环境会有不同的请求api接口&#xff0c;这就需要修改配置&#xff0c;才能满足对应的环境。所以这里就使用了环境变量。环境变量就是在不同的环境中使用不同的变量值。 # 环境变量文件(.env) 在项目根目录&#xff08;和sr…

TCP协议和相关特性

1.TCP协议的报文结构 TCP的全称为&#xff1a;Transmission Control Protocol。 特点: 有连接可靠传输面向字节流全双工 下面是TCP的报文结构&#xff1a; 源端口和目的端口&#xff1a; 源端口表示数据从哪个端口传输出来&#xff0c;目的端口表示数据传输到哪个端口去。…

FPGA_学习_03_第一个FPGA程序流水灯

学习编程&#xff0c;最重要永远就是动手&#xff0c;本文将在开发板上实现FPGA的“Hello world”→流水灯。本文主要目的是熟悉在Vivado上从零到程序运行起来的基本开发流程。 1 硬件电路介绍 本人购买的开发板接在PL端的只有2个LED灯&#xff0c;刚好达到流水灯的最低要求。…

今年这情况,大家多一手准备吧......

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

ASEMI代理MAX5048BAUT+T原装ADI车规级MAX5048BAUT+T

编辑&#xff1a;ll ASEMI代理MAX5048BAUTT原装ADI车规级MAX5048BAUTT 型号&#xff1a;MAX5048BAUTT 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;SOT-23-6 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;6 工作温度:-40C~125C 类型&a…

npx下载构建nuxt3开发模板失败的解决方案

在搭建nuxt3项目开发的时候&#xff0c;安装nuxt3开发模板的时候&#xff0c;使用命令&#xff1a; npx nuxi init my-app 会出出现一下错误&#xff1a; This is related to npm not being able to find a file. 发生上述错误是因为您有一个未正确安装的依赖项。 以下是解决…

大央企的“中央厨房”,泰裤辣

本文来源&#xff1a;特大号 作者&#xff1a;特大妹 最近两年&#xff0c;大央企大国企在数字化转型中&#xff0c;特热衷成立“中央厨房”。 有的中央厨房&#xff0c;单独挂牌为“数科公司”&#xff0c;有的中央厨房&#xff0c;升级为集团数字化转型的一级部门。 把之前各…

“警”彩集结|北峰通信亮相11届警博会,多场景助力警务智能化

2023年5月11日-14日&#xff0c;第十一届中国国际警用装备博览会(警博会)在北京首钢会展中心隆重召开。“警博会”作为中国乃至亚太地区最具影响力、最权威的警用装备盛会&#xff0c;代表了中国警用装备行业的最高水平。北峰通信作为服务公共安全实战30余年的企业&#xff0c;…

软考A计划-真题-分类精讲汇总-第十二章(法律法规与标准化)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

Web渗透 不断更新

Web渗透 SQL注入一般注入步骤 文件上传漏洞过滤绕过空格绕过 针对Linux特定字符过滤绕过 针对Linux(例如&#xff1a;cat) 序列号unserialize SQL注入 一般注入步骤 注入点 --> 查询注入字段数 --> 查询注入回显位 --> 查询当前数据库信息 --> 查询数据库表 --&g…

MySQL基础(三十四)锁

1. 概述 在数据库中&#xff0c;除传统的计算资源&#xff08;如CPU、RAM、I/O等&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的 资源。为保证数据的一致性&#xff0c;需要对 并发操作进行控制&#xff0c;因此产生了 锁 。同时 锁机制 也为实现MySQL 的各…

HIT数据结构lab2-树型结构的建立与遍历

title: 数据结构lab2-树型结构的建立与遍历 date: 2023-05-16 11:42:26 tags: 数据结构与算法 哈尔滨工业大学计算机科学与技术学院 实验报告 课程名称&#xff1a;数据结构与算法 课程类型&#xff1a;必修 实验项目&#xff1a;树型结构的建立与遍历 实验题目&#xff1…

【目标检测】模型信息解析/YOLOv5检测结果中文显示

前言 之前写过一篇博文【目标检测】YOLOv5&#xff1a;标签中文显示/自定义颜色&#xff0c;主要从显示端解决目标中文显示的问题。 本文着重从模型角度&#xff0c;从模型端解决目标中文显示问题。 模型信息解析 正常情况下&#xff0c;可以直接加载模型打印信息&#xff0…

GPT专业应用:英语作文修改与解释

正文共 868 字&#xff0c;阅读大约需要 3 分钟 英语学习者/老师必备技巧&#xff0c;您将在3分钟后获得以下超能力&#xff1a; 快速修改英语作文 Beezy评级 &#xff1a;B级 *经过简单的寻找&#xff0c; 大部分人能立刻掌握。主要节省时间。 推荐人 | Kim 编辑者 | Linda …

字节外包做了5年软件测试,12月无情被辞,想给划水的兄弟提个醒

前言 先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成…

第45讲:Python集合对象生成式的概念以及应用案例

文章目录 1.什么是集合生成式3.使用集合生成式创建集合3.在集合生成式中使用if语句4.在集合生成式中使用嵌套for循环语句 集合的生成式和集合的非常类似&#xff0c;只是符号不同而已&#xff0c;集合的语法格式如下&#xff0c;可以看到只是和集合的符号不同&#xff1a; {集…

【Linux】Linux /proc/iomem与/proc/ioports

目录 1. 前言 2. /proc/iomem 2.1 简介 2.2 ioremap 2.3 mmap 3. struct resource 4. System RAM 4.1 System RAM 简介 4.2 page_is_ram 4.3 Kernel code、data、bss 5. /proc/ioports 6. /proc/iomem/与/proc/ioports/对比 6.1 API简介 6.3 源码解读 7.总结 8.…

再来跟我一起写 Makefile 沉痛悼念技术大牛左耳朵耗子(陈皓)

再来跟我一起写 Makefile 沉痛悼念技术大牛左耳朵耗子&#xff08;陈皓&#xff09; 左耳朵耗子redefence 左耳朵耗子 5 月 15 日早晨&#xff0c;一则意外消息打得我们猝不及防&#xff1a;MegaEase CEO、知名架构师、CSDN 资深博主&#xff08;https://blog.csdn.net/haoel&…

Java的继承与实现

一、Java的继承与实现 继承可以使用现有类的所有功能&#xff0c;并在无需重新编写原来的类的情况下对这些功能进行扩展。这种派生方式体现了传递性。 在Java中&#xff0c;除继承&#xff0c;还有一种体现传递性的方式叫实现。那么&#xff0c;这两者方式有何区别&#xff1f…