主頁 >  其他 > k8s實戰案例之部署redis單機和redis cluster

k8s實戰案例之部署redis單機和redis cluster

2023-06-07 08:07:54 其他

1、在k8s上部署redis單機

1.1、redis簡介

redis是一款基于BSD協議,開源的非關系型資料庫(nosql資料庫),作者是意大利開發者Salvatore Sanfilippo在2009年發布,使用C語言撰寫;redis是基于記憶體存盤,而且是目前比較流行的鍵值資料庫(key-value database),它提供將記憶體通過網路遠程共享的一種服務,提供類似功能的還有memcache,但相比 memcache,redis 還提供了易擴展、高性能、具備資料持久性等功能,主要的應用場景有session共享,常用于web集群中的tomcat或PHP中多web服務器的session共享;訊息佇列,ELK的日志快取,部分業務的訂閱發布系統;計數器,常用于訪問排行榜,商品瀏覽數等和次數相關的數值統計場景;快取,常用于資料查詢、電商網站商品資訊、新聞內容等;相對memcache,redis支持資料的持久化,可以將記憶體的資料保存在磁盤中,重啟redis服務或者服務器之后可以從備份檔案中恢復資料到記憶體繼續使用;

1.2、PV/PVC 及 Redis 單機

由于redis的資料(主要是redis快照)都存放在存盤系統中,即便redis pod掛掉,對應資料都不會丟;因為在k8s上部署redis單機,redis pod掛了,k8s會將對應pod重建,重建時會把對應pvc掛載至pod中,加載快照,從而使得redis的資料不被pod的掛掉而丟資料;

1.3、構建redis鏡像

root@k8s-master01:~/k8s-data/dockerfile/web/magedu/redis# ll
total 1784
drwxr-xr-x  2 root root    4096 Jun  5 15:22 ./
drwxr-xr-x 11 root root    4096 Aug  9  2022 ../
-rw-r--r--  1 root root     717 Jun  5 15:20 Dockerfile
-rwxr-xr-x  1 root root     235 Jun  5 15:21 build-command.sh*
-rw-r--r--  1 root root 1740967 Jun 22  2021 redis-4.0.14.tar.gz
-rw-r--r--  1 root root   58783 Jun 22  2021 redis.conf
-rwxr-xr-x  1 root root      84 Jun  5 15:21 run_redis.sh*
root@k8s-master01:~/k8s-data/dockerfile/web/magedu/redis# cat Dockerfile 
#Redis Image
# 匯入自定義centos基礎鏡像
FROM harbor.ik8s.cc/baseimages/magedu-centos-base:7.9.2009 
# 添加redis原始碼包至/usr/local/src
ADD redis-4.0.14.tar.gz /usr/local/src
# 編譯安裝redis
RUN ln -sv /usr/local/src/redis-4.0.14 /usr/local/redis && cd /usr/local/redis && make && cp src/redis-cli /usr/sbin/ && cp src/redis-server  /usr/sbin/ && mkdir -pv /data/redis-data 
# 添加redis組態檔
ADD redis.conf /usr/local/redis/redis.conf 
# 暴露redis服務埠
EXPOSE 6379

#ADD run_redis.sh /usr/local/redis/run_redis.sh
#CMD ["/usr/local/redis/run_redis.sh"]
# 添加啟動腳本
ADD run_redis.sh /usr/local/redis/entrypoint.sh
# 啟動redis
ENTRYPOINT ["/usr/local/redis/entrypoint.sh"]
root@k8s-master01:~/k8s-data/dockerfile/web/magedu/redis# cat build-command.sh 
#!/bin/bash
TAG=$1
#docker build -t harbor.ik8s.cc/magedu/redis:${TAG} .
#sleep 3
#docker push  harbor.ik8s.cc/magedu/redis:${TAG}

nerdctl build -t  harbor.ik8s.cc/magedu/redis:${TAG} .
nerdctl push harbor.ik8s.cc/magedu/redis:${TAG}
root@k8s-master01:~/k8s-data/dockerfile/web/magedu/redis# cat run_redis.sh 
#!/bin/bash
# Redis啟動命令
/usr/sbin/redis-server /usr/local/redis/redis.conf
# 使用tail -f 在pod內部構建守護行程
tail -f  /etc/hosts
root@k8s-master01:~/k8s-data/dockerfile/web/magedu/redis# grep -v '^#\|^$' redis.conf 
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 5 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error no
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis-data
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass 123456
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
slave-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
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 no
lua-time-limit 5000
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
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
root@k8s-master01:~/k8s-data/dockerfile/web/magedu/redis# 

1.3.1、驗證rdis鏡像是否上傳至harbor?

1.4、測驗redis 鏡像

1.4.1、驗證將redis鏡像運行為容器,看看是否正常運行?

1.4.2、遠程連接redis,看看是否可正常連接?

能夠將redis鏡像運行為容器,并且能夠通過遠程主機連接至redis進行資料讀寫,說明我們構建的reids鏡像沒有問題;

1.5、創建PV和PVC

1.5.1、在nfs服務器上準備redis資料存盤目錄

root@harbor:~# mkdir -pv /data/k8sdata/magedu/redis-datadir-1
mkdir: created directory '/data/k8sdata/magedu/redis-datadir-1'
root@harbor:~# cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
#               to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#
/data/k8sdata/kuboard *(rw,no_root_squash)
/data/volumes *(rw,no_root_squash)
/pod-vol *(rw,no_root_squash)
/data/k8sdata/myserver *(rw,no_root_squash)
/data/k8sdata/mysite *(rw,no_root_squash)

/data/k8sdata/magedu/images *(rw,no_root_squash)
/data/k8sdata/magedu/static *(rw,no_root_squash)


/data/k8sdata/magedu/zookeeper-datadir-1 *(rw,no_root_squash)
/data/k8sdata/magedu/zookeeper-datadir-2 *(rw,no_root_squash)
/data/k8sdata/magedu/zookeeper-datadir-3 *(rw,no_root_squash)


/data/k8sdata/magedu/redis-datadir-1 *(rw,no_root_squash) 

root@harbor:~# exportfs -av
exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/kuboard".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [2]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volumes".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [3]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/pod-vol".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [4]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/myserver".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [5]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/mysite".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [7]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/images".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [8]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/static".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [11]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/zookeeper-datadir-1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [12]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/zookeeper-datadir-2".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [13]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/zookeeper-datadir-3".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [16]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis-datadir-1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exporting *:/data/k8sdata/magedu/redis-datadir-1
exporting *:/data/k8sdata/magedu/zookeeper-datadir-3
exporting *:/data/k8sdata/magedu/zookeeper-datadir-2
exporting *:/data/k8sdata/magedu/zookeeper-datadir-1
exporting *:/data/k8sdata/magedu/static
exporting *:/data/k8sdata/magedu/images
exporting *:/data/k8sdata/mysite
exporting *:/data/k8sdata/myserver
exporting *:/pod-vol
exporting *:/data/volumes
exporting *:/data/k8sdata/kuboard
root@harbor:~# 

1.5.2、創建pv

root@k8s-master01:~/k8s-data/yaml/magedu/redis/pv# cat redis-persistentvolume.yaml     
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-datadir-pv-1
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /data/k8sdata/magedu/redis-datadir-1 
    server: 192.168.0.42
root@k8s-master01:~/k8s-data/yaml/magedu/redis/pv# 

1.5.3、創建pvc

root@k8s-master01:~/k8s-data/yaml/magedu/redis/pv# cat redis-persistentvolumeclaim.yaml 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-datadir-pvc-1 
  namespace: magedu
spec:
  volumeName: redis-datadir-pv-1 
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
root@k8s-master01:~/k8s-data/yaml/magedu/redis/pv# 

1.6、部署redis服務

root@k8s-master01:~/k8s-data/yaml/magedu/redis# cat redis.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: devops-redis 
  name: deploy-devops-redis
  namespace: magedu
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: devops-redis
  template:
    metadata:
      labels:
        app: devops-redis
    spec:
      containers:
        - name: redis-container
          image: harbor.ik8s.cc/magedu/redis:v4.0.14 
          imagePullPolicy: Always
          volumeMounts:
          - mountPath: "/data/redis-data/"
            name: redis-datadir
      volumes:
        - name: redis-datadir
          persistentVolumeClaim:
            claimName: redis-datadir-pvc-1 

---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: devops-redis
  name: srv-devops-redis
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 6379 
    targetPort: 6379
    nodePort: 36379 
  selector:
    app: devops-redis
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
root@k8s-master01:~/k8s-data/yaml/magedu/redis# 

上述報錯說我們的服務埠超出范圍,這是因為我們在初始化k8s集群時指定的服務埠范圍;

1.6.1、修改nodeport埠范圍

編輯/etc/systemd/system/kube-apiserver.service,將其--service-node-port-range選項指定的值修改即可;其他兩個master節點也需要修改哦

1.6.2、多載kube-apiserver.service,重啟kube-apiserver

root@k8s-master01:~# systemctl daemon-reload                 
root@k8s-master01:~# systemctl restart kube-apiserver.service
root@k8s-master01:~# 

再次部署redis

1.7、驗證redis資料讀寫

1.7.1、連接k8s任意節點的36376埠,測驗redis讀寫資料

1.8、驗證redis pod 重建對應資料是否丟失?

1.8.1、查看redis快照檔案是否存盤到存盤上呢?

root@harbor:~# ll /data/k8sdata/magedu/redis-datadir-1
total 12
drwxr-xr-x 2 root root 4096 Jun  5 16:29 ./
drwxr-xr-x 8 root root 4096 Jun  5 15:53 ../
-rw-r--r-- 1 root root  116 Jun  5 16:29 dump.rdb
root@harbor:~# 

可以看到剛才我們向redis寫入資料,對應redis在規定時間內發現key的變化就做了快照,因為redis資料目錄時通過pv/pvc掛載的nfs,所以我們在nfs對應目錄里時可以正常看到這個快照檔案的;

1.8.2、洗掉redis pod 等待k8s重建redis pod

1.8.3、驗證重建后的redis pod資料

可以看到k8s重建后的redis pod 還保留著原有pod的資料;這說明k8s重建時掛載了前一個pod的pvc;

2、在k8s上部署redis集群

2.1、PV/PVC及Redis Cluster-StatefulSet

redis cluster相比redis單機要稍微復雜一點,我們也是通過pv/pvc將redis cluster資料存放在存盤系統中,不同于redis單機,redis cluster對存入的資料會做crc16計算,然后和16384做取模計算,得出一個數字,這個數字就是存入redis cluster的一個槽位;即redis cluster將16384個槽位,平均分配給集群所有master節點,每個master節點存放整個集群資料的一部分;這樣一來就存在一個問題,如果master宕機,那么對應槽位的資料也就不可用,為了防止master單點故障,我們還需要對master做高可用,即專門用一個slave節點對master做備份,master宕機的情況下,對應slave會接管master繼續向集群提供服務,從而實作redis cluster master的高可用;如上圖所示,我們使用3主3從的redis cluster,redis0,1,2為master,那么3,4,5就對應為0,1,2的slave,負責備份各自對應的master的資料;這六個pod都是通過k8s集群的pv/pvc將資料存放在存盤系統中;

2.2、創建PV

2.2.1、在nfs上準備redis cluster 資料目錄

root@harbor:~# mkdir -pv /data/k8sdata/magedu/redis{0,1,2,3,4,5}
mkdir: created directory '/data/k8sdata/magedu/redis0'
mkdir: created directory '/data/k8sdata/magedu/redis1'
mkdir: created directory '/data/k8sdata/magedu/redis2'
mkdir: created directory '/data/k8sdata/magedu/redis3'
mkdir: created directory '/data/k8sdata/magedu/redis4'
mkdir: created directory '/data/k8sdata/magedu/redis5'
root@harbor:~# tail -6 /etc/exports 
/data/k8sdata/magedu/redis0 *(rw,no_root_squash)
/data/k8sdata/magedu/redis1 *(rw,no_root_squash)
/data/k8sdata/magedu/redis2 *(rw,no_root_squash)
/data/k8sdata/magedu/redis3 *(rw,no_root_squash)
/data/k8sdata/magedu/redis4 *(rw,no_root_squash)
/data/k8sdata/magedu/redis5 *(rw,no_root_squash)
root@harbor:~# exportfs  -av
exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/kuboard".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [2]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/volumes".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [3]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/pod-vol".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [4]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/myserver".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [5]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/mysite".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [7]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/images".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [8]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/static".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [11]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/zookeeper-datadir-1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [12]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/zookeeper-datadir-2".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [13]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/zookeeper-datadir-3".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [16]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis-datadir-1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [18]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis0".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [19]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis1".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [20]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis2".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [21]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis3".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [22]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis4".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: /etc/exports [23]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/data/k8sdata/magedu/redis5".
  Assuming default behaviour ('no_subtree_check').
  NOTE: this default has changed since nfs-utils version 1.0.x

exporting *:/data/k8sdata/magedu/redis5
exporting *:/data/k8sdata/magedu/redis4
exporting *:/data/k8sdata/magedu/redis3
exporting *:/data/k8sdata/magedu/redis2
exporting *:/data/k8sdata/magedu/redis1
exporting *:/data/k8sdata/magedu/redis0
exporting *:/data/k8sdata/magedu/redis-datadir-1
exporting *:/data/k8sdata/magedu/zookeeper-datadir-3
exporting *:/data/k8sdata/magedu/zookeeper-datadir-2
exporting *:/data/k8sdata/magedu/zookeeper-datadir-1
exporting *:/data/k8sdata/magedu/static
exporting *:/data/k8sdata/magedu/images
exporting *:/data/k8sdata/mysite
exporting *:/data/k8sdata/myserver
exporting *:/pod-vol
exporting *:/data/volumes
exporting *:/data/k8sdata/kuboard
root@harbor:~# 

2.2.2、創建pv

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# cat pv/redis-cluster-pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-cluster-pv0
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: 192.168.0.42
    path: /data/k8sdata/magedu/redis0 

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-cluster-pv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: 192.168.0.42
    path: /data/k8sdata/magedu/redis1 

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-cluster-pv2
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: 192.168.0.42
    path: /data/k8sdata/magedu/redis2 

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-cluster-pv3
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: 192.168.0.42
    path: /data/k8sdata/magedu/redis3 

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-cluster-pv4
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: 192.168.0.42
    path: /data/k8sdata/magedu/redis4 

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-cluster-pv5
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: 192.168.0.42
    path: /data/k8sdata/magedu/redis5 
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# 

2.3、部署redis cluster

2.3.1、基于redis.conf檔案創建configmap

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# cat redis.conf 
appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# 

2.3.2、創建configmap

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# kubectl create cm redis-conf --from-file=./redis.conf -n magedu 
configmap/redis-conf created
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# kubectl get cm -n magedu 
NAME               DATA   AGE
kube-root-ca.crt   1      35h
redis-conf         1      6s
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# 

2.3.3、驗證configmap

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# kubectl describe cm redis-conf -n magedu 
Name:         redis-conf
Namespace:    magedu
Labels:       <none>
Annotations:  <none>

Data
=https://www.cnblogs.com/qiuhom-1874/archive/2023/06/06/===
redis.conf:
----
appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379


BinaryData
====

Events:  
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster#

2.3.4、部署redis cluster

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# cat redis.yaml 
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: magedu
  labels:
    app: redis
spec:
  selector:
    app: redis
    appCluster: redis-cluster
  ports:
  - name: redis
    port: 6379
  clusterIP: None
  
---
apiVersion: v1
kind: Service
metadata:
  name: redis-access
  namespace: magedu
  labels:
    app: redis
spec:
  type: NodePort
  selector:
    app: redis
    appCluster: redis-cluster
  ports:
  - name: redis-access
    protocol: TCP
    port: 6379
    targetPort: 6379
    nodePort: 36379

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  namespace: magedu
spec:
  serviceName: redis
  replicas: 6
  selector:
    matchLabels:
      app: redis
      appCluster: redis-cluster
  template:
    metadata:
      labels:
        app: redis
        appCluster: redis-cluster
    spec:
      terminationGracePeriodSeconds: 20
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - redis
              topologyKey: kubernetes.io/hostname
      containers:
      - name: redis
        image: redis:4.0.14
        command:
          - "redis-server"
        args:
          - "/etc/redis/redis.conf"
          - "--protected-mode"
          - "no"
        resources:
          requests:
            cpu: "500m"
            memory: "500Mi"
        ports:
        - containerPort: 6379
          name: redis
          protocol: TCP
        - containerPort: 16379
          name: cluster
          protocol: TCP
        volumeMounts:
        - name: conf
          mountPath: /etc/redis
        - name: data
          mountPath: /var/lib/redis
      volumes:
      - name: conf
        configMap:
          name: redis-conf
          items:
          - key: redis.conf
            path: redis.conf
  volumeClaimTemplates:
  - metadata:
      name: data
      namespace: magedu
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# 

上述配置清單,主要用sts控制器創建了6個pod副本,每個副本都使用configmap中的組態檔作為redis組態檔,使用pvc模板指定pod在k8s上自動關聯pv,并在magedu名稱空間創建pvc,即只要k8s上有空余的pv,對應pod就會在magedu這個名稱空間按pvc模板資訊創建pvc;當然我們可以使用存盤類自動創建pvc,也可以提前創建好pvc,一般情況下使用sts控制器,我們可以使用pvc模板的方式來指定pod自動創建pvc(前提是k8s有足夠的pv可用);

應用配置清單部署redis cluster

使用sts控制器創建pod,pod名稱是sts控制器的名稱-id,使用pvc模板創建pvc的名稱為pvc模板名稱-pod名稱,即pvc模板名-sts控制器名-id;

2.4、初始化redis cluster

2.4.1、在k8s上創建臨時容器,安裝redis cluster 初始化工具

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# kubectl run -it ubuntu1804 --image=ubuntu:18.04 --restart=Never -n magedu bash
If you don't see a command prompt, try pressing enter.
root@ubuntu1804:/#
root@ubuntu1804:/# apt update
# 安裝必要工具
root@ubuntu1804:/# apt install python2.7 python-pip redis-tools dnsutils iputils-ping net-tools
# 更新pip
root@ubuntu1804:/# pip install --upgrade pip
# 使用pip安裝redis cluster初始化工具redis-trib
root@ubuntu1804:/# pip install redis-trib==0.5.1
root@ubuntu1804:/#

2.4.2、初始化redis cluster

root@ubuntu1804:/# redis-trib.py create \
 `dig +short redis-0.redis.magedu.svc.cluster.local`:6379 \
 `dig +short redis-1.redis.magedu.svc.cluster.local`:6379 \
 `dig +short redis-2.redis.magedu.svc.cluster.local`:6379 

在k8s上我們使用sts創建pod,對應pod的名稱是固定不變的,所以我們初始化redis 集群就直接使用redis pod名稱就可以直接決議到對應pod的IP地址;在傳統虛擬機或物理機上初始化redis集群,我們可用直接使用IP地址,原因是物理機或虛擬機IP地址是固定的,在k8s上pod的IP地址是不固定的;

2.4.3、給master指定slave

  • 給redis-0指定slave為 redis-3
root@ubuntu1804:/# redis-trib.py replicate \
 --master-addr `dig +short redis-0.redis.magedu.svc.cluster.local`:6379 \
 --slave-addr `dig +short redis-3.redis.magedu.svc.cluster.local`:6379

  • 給redis-1指定slave為 redis-4
root@ubuntu1804:/# redis-trib.py replicate \
 --master-addr `dig +short redis-1.redis.magedu.svc.cluster.local`:6379 \
 --slave-addr `dig +short redis-4.redis.magedu.svc.cluster.local`:6379

  • 給redis-2指定slave為 redis-5
root@ubuntu1804:/# redis-trib.py replicate \
--master-addr `dig +short redis-2.redis.magedu.svc.cluster.local`:6379 \
--slave-addr `dig +short redis-5.redis.magedu.svc.cluster.local`:6379

2.5、驗證redis cluster狀態

2.5.1、進入redis cluster 任意pod 查看集群資訊

2.5.2、查看集群節點

集群節點資訊中記錄了master節點id和slave id,其中slave后面會對應master的id,表示該slave備份對應master資料;

2.5.3、查看當前節點資訊

127.0.0.1:6379> info
# Server
redis_version:4.0.14
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:165c932261a105d7
redis_mode:cluster
os:Linux 5.15.0-73-generic x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:8.3.0
process_id:1
run_id:aa8ef00d843b4f622374dbb643cf27cdbd4d5ba3
tcp_port:6379
uptime_in_seconds:4303
uptime_in_days:0
hz:10
lru_clock:8272053
executable:/data/redis-server
config_file:/etc/redis/redis.conf

# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:2642336
used_memory_human:2.52M
used_memory_rss:5353472
used_memory_rss_human:5.11M
used_memory_peak:2682248
used_memory_peak_human:2.56M
used_memory_peak_perc:98.51%
used_memory_overhead:2559936
used_memory_startup:1444856
used_memory_dataset:82400
used_memory_dataset_perc:6.88%
total_system_memory:16740012032
total_system_memory_human:15.59G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:2.03
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1685992849
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:245760
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0
aof_current_size:0
aof_base_size:0
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

# Stats
total_connections_received:7
total_commands_processed:17223
instantaneous_ops_per_sec:1
total_net_input_bytes:1530962
total_net_output_bytes:108793
instantaneous_input_kbps:0.04
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:1
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:853
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication
role:master
connected_slaves:1
slave0:ip=10.200.155.175,port=6379,state=online,offset=1120,lag=1
master_replid:60381a28fee40b44c409e53eeef49215a9d3b0ff
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1120
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1120

# CPU
used_cpu_sys:12.50
used_cpu_user:7.51
used_cpu_sys_children:0.01
used_cpu_user_children:0.00

# Cluster
cluster_enabled:1

# Keyspace
127.0.0.1:6379> 

2.5.4、驗證redis cluster讀寫資料是否正常?

2.5.4.1、手動連接redis cluster 進行資料讀寫

手動連接redis 集群master節點進行資料讀寫,存在一個問題就是當我們寫入的key經過crc16計算對16384取模后,對應槽位可能不在當前節點,redis它會告訴我們該key該在哪里去寫;從上面的截圖可用看到,現在redis cluster 是可用正常讀寫資料的

2.5.4.2、使用python腳本連接redis cluster 進行資料讀寫

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# cat redis-client-test.py
#!/usr/bin/env python
#coding:utf-8
#Author:Zhang ShiJie
#python 2.7/3.8
#pip install redis-py-cluster

import sys,time
from rediscluster import RedisCluster
def init_redis():
    startup_nodes = [
        {'host': '192.168.0.34', 'port': 36379},
        {'host': '192.168.0.35', 'port': 36379},
        {'host': '192.168.0.36', 'port': 36379},
        {'host': '192.168.0.34', 'port': 36379},
        {'host': '192.168.0.35', 'port': 36379},
        {'host': '192.168.0.36', 'port': 36379},
    ]
    try:
        conn = RedisCluster(startup_nodes=startup_nodes,
                            # 有密碼要加上密碼哦
                            decode_responses=True, password='')
        print('連接成功!!!!!1', conn)
        #conn.set("key-cluster","value-cluster")
        for i in range(100):
            conn.set("key%s" % i, "value%s" % i)
            time.sleep(0.1)
            data = https://www.cnblogs.com/qiuhom-1874/archive/2023/06/06/conn.get("key%s" % i)
            print(data)

        #return conn

    except Exception as e:
        print("connect error ", str(e))
        sys.exit(1)

init_redis()
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# 

運行腳本,向redis cluster 寫入資料

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# python redis-client-test.py
Traceback (most recent call last):
  File "/root/k8s-data/yaml/magedu/redis-cluster/redis-client-test.py", line 8, in <module>
    from rediscluster import RedisCluster
ModuleNotFoundError: No module named 'rediscluster'
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster#

這里提示沒有找到rediscluster模塊,解決辦法就是通過pip安裝redis-py-cluster模塊即可;

安裝redis-py-cluster模塊

運行腳本連接redis cluster進行資料讀寫

連接redis pod,驗證資料是否正常寫入?


從上面的截圖可用看到三個reids cluster master pod各自都存放了一部分key,并非全部;說明剛才我們用python腳本把資料正常寫入了redis cluster;

驗證在slave 節點是否可用正常讀取資料?

從上面的截圖可以了解到在slave節點是不可以讀取資料;

到slave對應的master節點讀取資料

上述驗證說明了redis cluster 只有master可以讀寫資料,slave只是對master資料做備份,不可以在slave上讀寫資料;

2.6、驗證驗證redis cluster高可用

2.6.1、在k8s node節點將redis:4.0.14鏡像上傳至本地harbor

  • 修改鏡像tag
root@k8s-node01:~# nerdctl tag redis:4.0.14 harbor.ik8s.cc/redis-cluster/redis:4.0.14
  • 上傳redis鏡像至本地harbor
root@k8s-node01:~# nerdctl push harbor.ik8s.cc/redis-cluster/redis:4.0.14
INFO[0000] pushing as a reduced-platform image (application/vnd.docker.distribution.manifest.list.v2+json, sha256:1ae9e0f790001af4b9f83a2b3d79c593c6f3e9a881b754a99527536259fb6625) 
WARN[0000] skipping verifying HTTPS certs for "harbor.ik8s.cc" 
index-sha256:1ae9e0f790001af4b9f83a2b3d79c593c6f3e9a881b754a99527536259fb6625:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:5bd4fe08813b057df2ae55003a75c39d80a4aea9f1a0fbc0fbd7024edf555786: done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:191c4017dcdd3370f871a4c6e7e1d55c7d9abed2bebf3005fb3e7d12161262b8:   done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 1.4 s                                                                    total:  8.5 Ki (6.1 KiB/s)                                       
root@k8s-node01:~# 

2.6.2、修改redis cluster部署清單鏡像和鏡像拉取策略

修改鏡像為本地harbor鏡像和拉取策略是方便我們測驗redis cluster的高可用;

2.6.3、重新apply redis cluster部署清單

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# kubectl apply -f redis.yaml
service/redis unchanged
service/redis-access unchanged
statefulset.apps/redis configured
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# 

這里相當于給redis cluster更新,他們之間的集群關系還存在,因為集群關系配置都保存在遠端存盤之上;

  • 驗證pod是否都正常running?
  • 驗證集群狀態和集群關系

不同于之前,這里rdis-0變成了slave ,redis-3變成了master;從上面的截圖我們也發現,在k8s上部署redis cluster pod重建以后(IP地址發生變化),對應集群關系不會發生變化;對應master和salve一對關系始終只是再對應的master和salve兩個pod中切換,這其實就是高可用;

2.6.4、停掉本地harbor,洗掉redis master pod,看看對應slave是否會提升為master?

  • 停止harbor服務
root@harbor:~# systemctl stop harbor
  • 洗掉redis-3,看看redis-0是否會提升為master?

可用看到我們把redis-3洗掉(相當于master宕機)以后,對應slave提升為master了;

2.6.5、恢復harbor服務,看看對應redis-3恢復會議后是否還是redis-0的slave呢?

  • 恢復harbor服務
  • 驗證redis-3pod是否恢復?

再次洗掉redis-3以后,對應pod正常被重建,并處于running狀態;

  • 驗證redis-3的主從關系

可以看到redis-3恢復以后,對應自動加入集群成為redis-0的slave;

作者:Linux-1874 出處:https://www.cnblogs.com/qiuhom-1874/ 本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利.

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/554499.html

標籤:其他

上一篇:1.3. 資料型別與變數

下一篇:返回列表

標籤雲
其他(160500) Python(38206) JavaScript(25478) Java(18205) C(15237) 區塊鏈(8270) C#(7972) AI(7469) 爪哇(7425) MySQL(7234) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4585) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1983) 功能(1967) HtmlCss(1952) Web開發(1951) C++(1932) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1879) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • k8s實戰案例之部署redis單機和redis cluster

    redis是一款基于BSD協議,開源的非關系型資料庫(nosql資料庫),作者是意大利開發者Salvatore Sanfilippo在2009年發布,使用C語言撰寫;redis是基于記憶體存盤,而且是目前比較流行的鍵值資料庫(key-value database),它提供將記憶體通過網路遠程共享的一種服... ......

    uj5u.com 2023-06-07 08:07:54 more
  • 1.3. 資料型別與變數

    ## 資料型別 在Java中,資料型別決定著一個資料的取值范圍和操作。Java中的資料型別主要分為兩類:基本資料型別和參考資料型別。 ### 基本資料型別 Java中的基本資料型別包括整型、浮點型、字符型和布爾型。 - 整型:byte、short、int、long。對應的取值范圍依次是-128~12 ......

    uj5u.com 2023-06-07 08:02:11 more
  • opennmmlab實戰營二期-mmpretrain代碼課課(五)

    # opennmmlab實戰營二期-mmpretrain代碼課課(五) [點我:視頻課程](https://www.bilibili.com/video/BV1Ju4y1Z7ZE/?share_source=copy_web&vd_source=ffcf9b861e082755b1f5504b717 ......

    uj5u.com 2023-06-07 07:56:43 more
  • ChatGPT玩法(二):AI玩轉Excel表格處理

    在線免費體驗ChatGpt:https://www.topgpt.one;你是否還在為記不住Excel的繁瑣函式和公式而苦惱?如果是這樣,那么不妨試試ChatExcel。即使你對函式一竅不通,也能輕松處理表格。只要你能清楚地描述你的需求,它就可以幫你搞定。此外,ChatExcel 的作者還制作了一張... ......

    uj5u.com 2023-06-07 07:56:30 more
  • 手把手教你用Stable Diffusion寫好提示詞

    Stable Diffusion 技術把 AI 影像生成提高到了一個全新高度,文生圖 Text to image 生成質量很大程度上取決于你的提示詞 Prompt 好不好。本文從“如何寫好提示詞”出發,從提示詞構成、調整規則和 chatGPT 輔助工具等角度,對文生圖的提示詞輸入進行歸納總結。 ......

    uj5u.com 2023-06-07 07:55:18 more
  • opennmmlab實戰營二期-mmpretrain代碼課課(五)

    # opennmmlab實戰營二期-mmpretrain代碼課課(五) [點我:視頻課程](https://www.bilibili.com/video/BV1Ju4y1Z7ZE/?share_source=copy_web&vd_source=ffcf9b861e082755b1f5504b717 ......

    uj5u.com 2023-06-07 07:54:46 more
  • 讀資料壓縮入門筆記04_統計編碼

    一種新的精確熵編碼方法,所得到的結果可以和最優熵任意接近,它的壓縮率與算術編碼接近,而性能則與哈夫曼編碼相當 ......

    uj5u.com 2023-06-07 07:54:13 more
  • ChatGPT玩法(二):AI玩轉Excel表格處理

    在線免費體驗ChatGpt:https://www.topgpt.one;你是否還在為記不住Excel的繁瑣函式和公式而苦惱?如果是這樣,那么不妨試試ChatExcel。即使你對函式一竅不通,也能輕松處理表格。只要你能清楚地描述你的需求,它就可以幫你搞定。此外,ChatExcel 的作者還制作了一張... ......

    uj5u.com 2023-06-07 07:47:36 more
  • 1.3. 資料型別與變數

    ## 資料型別 在Java中,資料型別決定著一個資料的取值范圍和操作。Java中的資料型別主要分為兩類:基本資料型別和參考資料型別。 ### 基本資料型別 Java中的基本資料型別包括整型、浮點型、字符型和布爾型。 - 整型:byte、short、int、long。對應的取值范圍依次是-128~12 ......

    uj5u.com 2023-06-07 07:43:30 more
  • SCM Manager XSS漏洞復現(CVE-2023-33829)

    SCM-Manager 是一款開源的版本庫管理軟體,同時支持 subversion、mercurial、git 的版本庫管理。該漏洞主要為攻擊者利用其多個功能的描述欄位的代碼缺陷,構造payload進行XSS攻擊。 ......

    uj5u.com 2023-06-07 07:43:17 more