【k8s安装redis】k8s安装单机版redis实现高性能高可用

发布于:2024-07-06 ⋅ 阅读:(33) ⋅ 点赞:(0)

简介

本文将根据在k8s环境中搭建【伪】单机模式的redis实例。由于共享存储的io性能比较低,所以将共享存储用于数据备份,而采用hostpath的形式进行redis数据的存储,这样有助于提高redis的io性能,本文将讲解如何在一个pod内用两个container作为redis的主从形式来实现单机版、高可用的redis。

一.条件及环境说明:

k8s版本k8s-1.29.4,环境搭建在电信机房,共计六个节点,每个节点有一块非系统盘的ssd盘挂载到/data/路径。有NAS共享存储,该共享存储是使用的阿里云NAS,走专线使用,专线带宽500Mb。

二.需求说明:

  • 搭建redis实例:可单机,可主从。
  • 高可用:有一个k8s节点死掉之后也不长时间影响使用。
  • 高性能:需要高iO,采用共享存储或者是ceph的分布式存储,读写iO会打很大的折扣。
  • 数据安全:在发生切换以后,数据要尽可能的保证完整
  • 安装简单、管理维护容易

三.实现原理及说明

1.将redis搭建成主从模式,主redis的数据读写落在本地ssd磁盘,从redis的数据数据落在外挂的共享nas存储。
2.然后创建一个statefulset的配置,放置两个container,一个container 作为主redis,挂载到hostpath,以主机名创建目录,并存储rdb文件。另外一个container 作为从redis,挂载nas路径也以主机名创建目录,并存储rdb文件。
3.调整从redis的数据持久化参数save,将数据落盘时间调整到较小的参数,这样保证更新的数据尽快存储到rdb文件。
4.在pod每次发生调度或者重启时,将nas存储的rdb文件拷贝到hostpath路径再启动redis。

注:这样做是让主redis实现高性能的处理业务数据,从redis就负责数据持久化,可能存在如下的问题:1.当主的读写数据io太高时,从redis由于是挂载nas,数据落盘时间会更长一些。

四.详细步骤

4.1.创建configmap 配置文件

配置包含三个文件主redis的配置文件,从redis的配置文件,以及一个根据执行角色执行不同操作的简单脚本,具体配置如下:
redis-master:conf 主redis配置文件,内存配置成256M,配置端口为6379,配置密码:redis#123,存储路径是/data/redis。
redis.conf:从redis配置文件,内存配置成256M,配置端口为6380,配置密码:redis#123,存储路径是/data/redis-2,并配置从6379的端口同步数据,将存储时间调整成60s以内有10个数据变动就进行存储落盘。
run.sh:主要作用就是判断角色并根据主机名创建目录,然后软连接到存储目录。这一步主要是将各自服务的redis数据存放到自己的目录,当创建新的redis的时候不会导致节点上的目录冲突。

apiVersion: v1
kind: ConfigMap
metadata:
  name: defaultapp-redis-standalone-config
  namespace: default
  labels:
    appname: default-app
    app: defaultapp-redis-standalone-config
data:
  redis-master.conf: |
    port 6379
    maxmemory 256mb
    requirepass redis#123
    dir /data/redis
  redis.conf: |
    port 6380
    maxmemory 256mb
    requirepass redis#123
    save 3600 1 300 5 60 10
    dir /data/redis-2
    replicaof 127.0.0.1 6379
    masterauth redis#123
  run.sh: |
    #!/bin/sh
    role=$1
    hname=$(hostname)
    if [ $role == "master" ];then
        echo "run redis master"
        ls /etc/redis/ -l
        [ -d /home/redis/$hname ] || mkdir -p /home/redis/$hname
        [ -d /data ] || mkdir /data
        ln -s /home/redis/$hname /data/redis
        if [ -f /home/redis-2/$hname/dump.rdb ];then
                cp -vf /home/redis-2/$hname/dump.rdb /data/redis/
        else
                echo "[info] no bak dump.rdb"
        fi
        redis-server /etc/redis/redis-master.conf
    else
        echo "run redis slave"
        ls /etc/redis/ -l
        [ -d /home/redis-2/$hname ] || mkdir -p /home/redis-2/$hname
        [ -d /data ] || mkdir /data
        ln -s /home/redis-2/$hname /data/redis-2
        redis-server /etc/redis/redis.conf
    fi
4.2.创建StatefulSet 配置

为什么不用deployment是因为存储路径是根据主机名的目录,deployment的主机名每次重启都会变动,所以才采用statefuleset。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: defaultapp-redis-standalone
  namespace: default
  labels:
    appname: default-app
    app: defaultapp-redis-standalone
spec:
  serviceName: "defaultapp-redis-standalone"
  replicas: 1
  selector:
    matchLabels:
      app: defaultapp-redis-standalone
  template:
    metadata:
      labels:
        app: defaultapp-redis-standalone
    spec:
      containers:
      - name: redis-master
        image: xxx-registry-vpc.cn-shenzhen.cr.aliyuncs.com/public/redis:7.2.5-alpine3.20
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh","/etc/redis/run.sh"]
        args: ["master"]
        ports:
          - containerPort: 6379
        volumeMounts:
        - name: redis-config-volume
          mountPath: /etc/redis/
        - name: redis-data
          mountPath: /home/redis
        - name: redis-backup
          mountPath: /home/redis-2
          readOnly: false
      - name: redis-slave
        image: xxx-registry-vpc.cn-shenzhen.cr.aliyuncs.com/public/redis:7.2.5-alpine3.20
        imagePullPolicy: IfNotPresent
        ports:
          - containerPort: 6380
        command: ["/bin/sh","/etc/redis/run.sh"]
        args: ["slave"]
        volumeMounts:
        - name: redis-config-volume
          mountPath: /etc/redis/
        - name: redis-data
          mountPath: /home/redis
        - name: redis-backup
          mountPath: /home/redis-2
          readOnly: false
      restartPolicy: Always
      volumes:
        - name: redis-data
          hostPath:
            path: /data/redis_data
            type: ""
        - name: redis-config-volume
          configMap:
            name: defaultapp-redis-standalone-config
        - name: redis-backup
          nfs:
           server: xxxx-mxx.cn-shenzhen.nas.aliyuncs.com
           path: /backup/redis
4.3.创建service headless 配置

创建无头服务,集群内调用可以采用无头服务的名称进行调用。

apiVersion: v1
kind: Service
metadata:
  name: defaultapp-redis-standalone
  namespace: default
  labels:
    appname: default-app
    app: defaultapp-redis-standalone
spec:
  ports:
  - port: 6379
  clusterIP: None
  selector:
    app: defaultapp-redis-standalone

如果需要对k8s集群外提供访问可以创建成service服务并配置LoadBalancer或者NodePort的形式。

apiVersion: v1
kind: Service
metadata:
  name: defaultapp-redis-standalone-external
  namespace: default
  labels:
    appname: default-app
    app: defaultapp-redis-standalone
spec:
  ports:
  - port: 6379
  type: LoadBalancer
  selector:
    app: defaultapp-redis-standalone

五.安装说明

  • 需要先在k8s的节点创建/data/redis_data的路径来存放数据。
  • 需要挂载一个共享存储,或者有一个公共路径存放备份文件的地方。
  • 使用配置前将配置中的defaultapp替换成自己需要的命名。
  • 配置中的镜像地址采用了私有的镜像地址,镜像是dockerhub上下载的redis:7.2.5-alpine3.20镜像到私有镜像仓库的,如果能直通外网的k8s可以直接用redis:7.2.5-alpine3.20。否则配置一个可以通的镜像地址。
  • redis.conf或redis-master.conf中的密码redis#123替换成自己的密码。
  • 复制配置时注意缩进字符,有不明白的配置欢迎私信

网站公告

今日签到

点亮在社区的每一天
去签到