k8s1.20版本部署Redis集群(三主三从)——2023.05

news2024/11/24 12:37:53

文章目录

    • 一、准备工作
    • 二、逻辑图
    • 三、部署Redis集群
      • 1. 安装NFS服务
      • 2. 修改API配置
      • 3. 创建持久卷PVC
      • 4. 创建Redis服务
      • 4. 组建Redis集群
      • 5. 验证集群

一、准备工作

  1. 主机规划
节点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

注意:本文采用三主三从集群模式。redis集群至少要有6个节点,由于资源限制无法部署那么多node节点,所以6个pod都只能跑在node1节点上。

  1. 版本介绍
服务版本
centos7.9
Rancher(单节点)2.5.12
kubernetes1.20.15
Redis7.0.11

二、逻辑图

在这里插入图片描述
本次创建6个Redis服务,并使用configmap持久化redis配置文件;需要注意的是,本文没有使用传统的pv,pvc方式做持久化数据存储,而是使用storageclass调用provisioner,自动给pod创建的pvc分配pv并绑定,从而达到持久化存储的效果。
简单直观看下图:
在这里插入图片描述

接下来我们就一起来部署redis集群吧!

概念解释:
Provisioner:Provisioner是StorageClass中必须的一个资源,它是存储资源自动调配器,可以将其看作是后端存储驱动。对于NFS类型,K8S没有提供内部Provisioner,但可以使用外部的Provisioner。Provisioner必须符合存储卷的开发规范(CSI)。本文档中使用NFS提供的Provisioner。

三、部署Redis集群

1. 安装NFS服务

NFS Server IP(服务端):192.168.2.251
NFS Client IP(客户端):192.168.2.245

  1. NFS Server端安装NFS
    操作主机:NFS、Rancher|192.168.2.251
# 1.安装nfs与rpc
yum install -y nfs-utils rpcbind
# 查看是否安装成功
rpm -qa | grep nfs
rpm -qa | grep rpcbind

在这里插入图片描述

# 2.创建共享存储文件夹,并授权
mkdir -p /nfs/k8s_data
chmod 777 /nfs/k8s_data/

# 3.配置nfs
vim /etc/exports
/nfs/k8s_data 192.168.2.0/24(rw,no_root_squash,no_all_squash,sync)
注:
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 服务端的匿名用户
# 4.启动服务
systemctl start nfs
systemctl start rpcbind
#添加开机自启
systemctl enable nfs
systemctl enable rpcbind

# 5.配置生效
exportfs -r

# 6.查看挂载情况
showmount -e localhost
#输出下面信息表示正常
Export list for localhost:
/nfs/k8s_data 192.168.2.0/24
  1. NFS Client安装NFS
    操作主机:除了NFS server,其他所有主机
yum -y install nfs-utils

2. 修改API配置

Kubernetes v1.20 (opens new window)开始,默认停用了 metadata.selfLink 字段,并计划在 1.21 版本中删除该字段,然而,部分应用仍然依赖于这个字段,例如 nfs-client-provisioner。如果仍然要继续使用这些应用,将需要重新启用该字段。

由于我们后面要使用nfs-client-provisioner,所以,如果你的Kubernetes版本是1.20.x版本,需要提前修改api 配置,重启metadata.selfLink字段。

# 添加方式:
vim /etc/kubernetes/manifests/kube-apiserver.yaml

# 把下面配置增加进去
--feature-gates=RemoveSelfLink=false

在这里插入图片描述

如果没有修改配置,后面我们查看nfs-client-provisioner服务日志时,可能会出现报错:unexpected error getting claim reference: selfLink was empty, can’t make reference,就是由于没有开启这个字段导致的。

3. 创建持久卷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/
参考文章:https://dongweizhen.blog.csdn.net/article/details/130651727?spm=1001.2014.3001.5502

所以这里使用了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	

4. 创建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配置文件。
!!!再次提示:创建前,需要把配置文件中的注释都删除掉,要不然会报错wrong number of arguments

# 创建configmap
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 
# 查看状态:
kubectl get sts,pvc,pv

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

4. 组建Redis集群

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

1. 自动组建集群
这种方式,Redis会自动分配主节点和从节点,不需要手工指定。

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.

2. 手动组建集群
查看下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

5. 验证集群

使用下面这条命令验证集群状态,注意–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.

参考文章:
部署Redis7.0集群6节点三主三从(完整版)
Redis6节点集群搭建
K8s搭建nfs-storageclass
K8s搭建nfs-storageclass
Kuboard官网文档
Kubernetes官网文档

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

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

相关文章

【MySQL】-- 库的操作

目录 库的操作 显示数据库 创建数据库 创建数据库案例 删除数据库 删除数据库案例 字符集和校验规则 字符集 校验规则 小结 查看数据库支持的字符集 查看数据库支持的校验规则 校验规则对数据库的影响 不区分大小写 区分大小写 进行查询 结果排序 修改数据库…

我爱我家联合第四范式发布房产经纪大模型

5月15日&#xff0c;在我爱我家年度品牌战略发布会上&#xff0c;我爱我家联合第四范式发布“房产经纪大模型”&#xff0c;将大模型能力用于提升行业生产力的原点&#xff1a;赋能经纪人。本次发布的房产经纪大模型1.0版本已经具备了合格经纪人的基本能力&#xff0c;‍‍‍‍…

leetcode 不同路径详解

文章目录 62 . 不同路径题目详情动态规划之带备忘录实现Java完整代码 63. 不同路径 II题目详情动态规划之带备忘录实现Java完整代码 62 . 不同路径 题目详情 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只…

JavaSE进阶(二)—— 面向对象进阶(包、权限修饰符、抽象类、多态)

目录 一、包 1. 什么是包 2. 导包 二、权限修饰符 1. 什么是权限修饰符 2. 权限修饰符的分类和具体作用范围 3. 学完权限修饰符需要具备如下能力 三、final 1. final的作用 2. final修饰变量的注意 四、常量 1. 常量概述和基本作用 1.1 常量做信息配置的原理、优…

【操作系统】I/O管理

文章目录 I/O设备的基本概念和分类I/O设备的分类 I/O控制器I/O设备的组成I/O控制器的组成I/O控制器的两种寄存器编址方式 I/O控制方式程序直接控制方式中断驱动方式DMA方式通道控制方式 I/O软件的层次结构用户层软件设备独立性软件六大功能逻辑设备表—LUT 设备驱动程序中断处理…

免交互的使用

免交互的使用 一、免交互二、小实验三、利用脚本完成的小实验三、Expect 一、免交互 Here Document 免交互 使用I/O重定向的方式将命令列表提供给交互式程序或命令&#xff0c;比如ftp、cat或者read命令。 免交互时标准输入的一种替代品可以帮助脚本开发人员不必使用临时文件来…

MySQL查询练习题

一&#xff0e;编程题 有三张表&#xff0c;结构如下&#xff1a; Student(学号StuId,姓名StuName,性别StuSex,出生年月StuBirth) Course(课程号CouId,课程名CouName,授课教师CoouTeacher) SC(学号StuId,课程号CouId,成绩Score,授课教师CouTeacher) 用标准SQL语句完成下列操作…

第六章 介绍Productions - 其他Production 选项

文章目录 第六章 介绍Productions - 其他Production 选项用户门户工作流业务活动监控Alerts发布和订阅消息传递Message Bank 第六章 介绍Productions - 其他Production 选项 本章概述了与制作相关的其他选项。 用户门户 与 Studio 和管理门户等后端工具不同&#xff0c;用户…

免交互 (Here Document)

目录 免交互 (Here Document) 语法格式&#xff1a; 注意事项&#xff1a; 支持变量替换 多行注释 Expect 基本命令: interact 嵌入执行模式 实现 ssh 自动登录 免交互 (Here Document) 使用I/O重定向的方式将命令列表提供给交互式程序或命令&#xff0c;比如 ftp、c…

阿里云异构计算云服务器GPU、FPGA和EAIS详解

阿里云阿里云异构计算主要包括GPU云服务器、FPGA云服务器和弹性加速计算实例EAIS&#xff0c;随着人工智能技术的发展&#xff0c;越来越多的AI计算都采用异构计算来实现性能加速&#xff0c;阿里云异构计算云服务研发了云端AI加速器&#xff0c;通过统一的框架同时支持了Tenso…

量化数据运算

量化数据运算 文章目录 量化数据运算量化数据乘积仿射映射量化的矩阵运算矩阵表示 矩阵CAB量化方式表示 矩阵CAB 代码展示基于仿射映射量化的矩阵乘法矩阵乘法计算API通过仿射映射量化形式计算两个矩阵的乘法**欢迎关注公众号【三戒纪元】** 量化数据乘积 使用记号&#xff08…

【Java代码审计】XSS漏洞产生原理及其修复

XSS漏洞代码审计 前言XSS漏洞原理1、反射型XSS反射型XSS漏洞审计 2、存储型XSS存储型XSS审计 漏洞修复 前言 笔者已经很长时间没有写过笔记力&#xff0c;经过一年的摸爬滚打也算是走到了代码审计这一关&#xff0c;这些日子也还在为项目和hw周旋&#xff0c;上周终于面试完&a…

今年是很惨,但有人怒砍一大把Offer...

300万字&#xff01;全网最全大数据学习面试社区等你来&#xff01; 今天的主人公是一个应届生&#xff0c;同时也是我在训练营辅导的一名同学&#xff0c;在整体经济下行&#xff0c;互联网见顶的情况拿到包括腾讯、蚂蚁、B站等多家互联网大厂Offer。 下面是我站在求职者角度提…

DDL语句DQL语句

SQL学习笔记 DDL语句--操作数据表 /* 快捷键: insert键 在插入 和 替换模式之间切换 ctrl 字母z 撤销上一步操作 tab 往后缩进(默认4个空格) shift tab 往前缩进(默认4个空格) …

基于Java+SpringBoot+Vue学生信息管理设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

重磅发布:《AI产品经理的实操手册(2023版)》

今天是咱们社群“AI产品经理大本营”六周年活动的最后一天&#xff0c;正式发布这份大家和我都非常期待的重磅干货——《AI产品经理的实操手册&#xff08;2023版&#xff09;》 上周发布的“AI季度资料包&#xff08;2023Q2&#xff09;”&#xff0c;适合对AI初步感兴趣的产品…

《统计学习方法》——隐马尔可夫模型(中)

概率计算算法 直接计算法 给定模型 λ ( A , B , π ) \lambda(A,B,\pi) λ(A,B,π)和观测序列 O ( o 1 , o 2 , ⋯ , o T ) O(o_1,o_2,\cdots,o_T) O(o1​,o2​,⋯,oT​)&#xff0c;计算观测序列 O O O出现的概率 P ( O ∣ λ ) P(O|\lambda) P(O∣λ)。最直接的方法就是…

『python爬虫』23. selenium之窗口切换与iframe(保姆级图文)

目录 1. 窗口切换2. 抓取拉勾网职务信息2.1 拉勾网查看职务详情与价格2.2 完整代码 3. iframe的处理总结 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 1. 窗口切换 窗口句柄的定义&#xff1a;WebDriver对象有wi…

肝一肝设计模式【八】-- 外观模式

系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 肝一肝设计模式【三】-- 原型模式 传送门 肝一肝设计模式【四】-- 建造者模式 传送门 肝一肝设计模式【五】-- 适配器模式 传送门 肝一肝设计模式【六】-- 装饰器模式 传送门 肝…

Windows本地快速搭建SFTP文件服务器,并端口映射实现公网远程访问

文章目录 1. 搭建SFTP服务器1.1 下载 freesshd服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内网连接测试成功 3 使用cpolar内网穿透3.1 创建SFTP隧道3.2 查看在线隧道列表 4. 使用SFTP客户端&#xff0…