docker搭建redis哨兵集群和分片集群

news2024/11/24 8:59:50

搭建哨兵集群

环境准备拉取镜像

搭建目标 : 一主而从三哨兵集群

docker pull redis:6.2.6

创建文件夹及配置文件

我这里在/usr/local/docker/redis目录下

在 redis-master、redis-slave1、redis-slave2 下分别建立data、 redis.conf、 sentinel.conf

redis配置文件

在从节点上配置所属于哪个父集群(找爹行动)

  • replicaof 39.106.53.30 6379(redis5.0之后)
  • slaveof 39.106.53.30 6379(5.0之前的命令)
# master redis.conf
save 3600 1
save 300 100
save 60 10000

appendonly no

protected-mode no 
port 6379

# redis-slave1 redis.conf

save 3600 1
save 300 100

save 60 10000

appendonly no

bind 0.0.0.0

port 6380

protected-mode no 

replicaof 39.106.53.30 6379

# redis-slave2 redis.conf

save 3600 1
save 300 100

save 60 10000

appendonly no

bind 0.0.0.0

port 6381

protected-mode no 

replicaof 39.106.53.30 6379

 sentinel配置

# master 配置

port 26379
dir /tmp
sentinel monitor mymaster 39.106.53.30 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000

# slave1 配置

port 26380
dir /tmp
sentinel monitor mymaster 39.106.53.30  6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000


# slave2 配置

port 26381
dir /tmp
sentinel monitor mymaster 39.106.53.30  6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000

 编写docker-compose.yml

version: '3'
services:
  master:
    image: redis:6.2.6       
    container_name: redis-master
    command: redis-server /etc/redis/redis.conf 
    ports:
      - 6379:6379
    volumes:
    - /usr/local/docker/redis/redis-master/data:/data
    - /usr/local/docker/redis/redis-master/redis.conf:/etc/redis/redis.conf
  slave1:
    image: redis:6.2.6                
    container_name: redis-slave1
    volumes:
    - /usr/local/docker/redis/redis-slave1/data:/data
    - /usr/local/docker/redis/redis-slave1/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf 
    ports:
      - 6380:6380
    depends_on:
    - master
  slave2:
    image: redis:6.2.6                
    container_name: redis-slave2
    volumes:
    - /usr/local/docker/redis/redis-slave2/data:/data
    - /usr/local/docker/redis/redis-slave2/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf 
    ports:
      - 6381:6381
    depends_on:
    - master
  sentinel1:
    image: redis:6.2.6      
    container_name: redis-sentinel1
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    ports:
      - 26379:26379
    volumes:
    - /usr/local/docker/redis/redis-master/sentinel.conf:/usr/local/etc/redis/sentinel.conf
    depends_on:
    - master
    - slave1
    - slave2
  sentinel2:
    image: redis:6.2.6                
    container_name: redis-sentinel2          
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    ports:
      - 26380:26380
    volumes:
    - /usr/local/docker/redis/redis-slave1/sentinel.conf:/usr/local/etc/redis/sentinel.conf
    depends_on:
    - master
    - slave1
    - slave2
  sentinel3:
    image: redis:6.2.6               
    container_name: redis-sentinel3          
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    ports:
      - 26381:26381
    volumes:
    - /usr/local/docker/redis/redis-slave1/sentinel.conf:/usr/local/etc/redis/sentinel.conf
    depends_on:
    - master
    - slave1
    - slave2

 执行docker-compose

docker-compose up -d

查看集群信息 

 查看集群信息 info replication

测试数据同步

本次搭建的集群,在从节点是只读形式,只有主节点才能够写,在主节点写入 set test test 

set k v,查看所有从节点信息,在从节点中写,会提示只读副本

在主节点中写,发现在所有从节点中都存在数据,数据同步成功

主从集群同步原理

主从同步第一次同步是全量同步

master如何判断slave是不是第一次来同步数据:

Replication ld: 简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid

ofset:偏移量,随着记录在repl_bak_log中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的ofset如果slave的offset小于master的offset,说明slave数据落后于master,需要更新

因此slave做数据同步,必须向master声明自己的replication id 和offset,master才可以判断到底需要同步哪些数据

但如果slave重启后同步,则执行增量同步

repl_bak_log大小有上限,写满后会覆盖最早的数据。如果slave断开时间过久,导致尚未备份的数据被覆盖,则无法基于log做增量同步,只能再次全量同步

 全量同步流程

增量同步流程 

spring boot整合集群并配置读写分离

引入依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置集群

由于哨兵模式的节点不固定,所以配置哨兵集群,监听的redis集群由哨兵去找

server:
  port: 9000
spring:
  redis:
    sentinel:
      master: mymaster
      nodes:
        - 39.106.53.30:26379
        - 39.106.53.30:26380
        - 39.106.53.30:26381

测试集群同步

这里的ReadFrom是配置Redis的读取策略:

  • MASTER:从主节点读取.
  • MASTER PREFERRED:优先从master节点读取,master不可用才读取replica
  • REPLICA: 从slave (replica)节点读取
  • REPLICA PREFERRED: 优先从slave (replica)节点读取,所有的slave都不可用才读取master
package com.test.cluster.rediscluster;

import io.lettuce.core.ReadFrom;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class RedisClusterApplication {

    public static void main(String[] args) {
        SpringApplication.run(RedisClusterApplication.class, args);
    }

    @Bean
    public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){
        return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
    }

}

 编写controller

package com.test.cluster.rediscluster.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author sl
 */
@RestController
public class TestRedisSentinelController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/get/{key}")
    public String getKey(@PathVariable("key") String key){
        String s = redisTemplate.opsForValue().get(key);
        if(s!= null){
            return "获取"+  s  + "成功";
        }
        return "获取"+  key  + "失败";
    }

    @RequestMapping("set/{key}/{value}")
    public String setValue(@PathVariable("key")String key,@PathVariable("value") String value){
        redisTemplate.opsForValue().set(key,value);
        return "set" +  key  + "success";
    }


}

设置key http://localhost:9000/set/china/yyds ,在80和81中,可以查到china的值

搭建分片集群

redis 哨兵模式虽然提供了 redis⾼可⽤、高并发读的解决方案,但是在海量数据应用场景下,仍然存在海量数据存储问题和高并发写的问题。当只有⼀个 Master 对外提供服务时,如果数据量特别⼤,内存占⽤问题严重,数据的高并发写、数据备份和恢复都会⼤⼤降低效率,针对这些问题,redis 推出 Cluster 集群架构,该结构具有如下特点:

Redis Cluster 采用的去中心化的网络拓扑架构,没有中心节点,所有节点既是数据存储节点,也是控制节点

引入槽(slot)的概念,通过 CRC+hashslot 算法支持多个主节点(分片),每个主节点分别负责存储一部分数据,这样理论上可以支持无限主节点的水平扩容以便支持海量吞吐量

在 Cluster 集群里设置了 16384 个哈希槽(hash slot),在 master 节点上写键值对数据时,redis 先对每个键(key),用CRC16 算法对 key 进行运算,然后用 16384 对运算结果取模,余数作为插槽,每个槽在不同的节点下,形成了分片

内置类似哨兵的高可用机制,能够实现自动故障转移,保证每个主节点的高可用

创建文件和映射

创建6379-6384的文件夹,目录为data ,redis.conf

编写redis.conf

port 6379

daemonize no

cluster-enabled yes

# reids维护
cluster-config-file nodes_6379.conf

tcp-keepalive 300
timeout 0

appendonly yes

logfile "redis_6379.log"

bind 0.0.0.0

cluster-node-timeout 5000

protected-mode no 

cluster-announce-ip 39.106.53.30

cluster-announce-bus-port 16379

编写docker-compose

version: '3'
services:
  node1:
    image: redis:6.2.6
    container_name: redis-node1
    restart: always
    ports:
      - 6379:6379
      - 16379:16379
    volumes:
      - /usr/local/docker/redis/6379/data:/data
      - /usr/local/docker/redis/6379/redis.conf:/etc/redis/redis.conf
    command:
      redis-server /etc/redis/redis.conf

  node2:
    image: redis:6.2.6
    container_name: redis-node2
    restart: always
    ports:
      - 6380:6380
      - 16380:16380
    volumes:
      - /usr/local/docker/redis/6380/data:/data
      - /usr/local/docker/redis/6380/redis.conf:/etc/redis/redis.conf
    command:
      redis-server /etc/redis/redis.conf


  node3:
    image: redis:6.2.6
    container_name: redis-node3
    restart: always
    ports:
      - 6381:6381
      - 16381:16381
    volumes:
      - /usr/local/docker/redis/6381/data:/data
      - /usr/local/docker/redis/6381/redis.conf:/etc/redis/redis.conf
    command:
      redis-server /etc/redis/redis.conf

  node4:
    image: redis:6.2.6
    container_name: redis-node4
    restart: always
    ports:
      - 6382:6382
      - 16382:16382
    volumes:
      - /usr/local/docker/redis/6382/data:/data
      - /usr/local/docker/redis/6382/redis.conf:/etc/redis/redis.conf
    command:
      redis-server /etc/redis/redis.conf

  node5:
    image: redis:6.2.6
    container_name: redis-node5
    restart: always
    ports:
      - 6383:6383
      - 16383:16383
    volumes:
      - /usr/local/docker/redis/6383/data:/data
      - /usr/local/docker/redis/6383/redis.conf:/etc/redis/redis.conf
    command:
      redis-server /etc/redis/redis.conf

  node6:
    image: redis:6.2.6
    container_name: redis-node6
    restart: always
    ports:
      - 6384:6384
      - 16384:16384
    volumes:
      - /usr/local/docker/redis/6384/data:/data
      - /usr/local/docker/redis/6384/redis.conf:/etc/redis/redis.conf
    command:
      redis-server /etc/redis/redis.conf

执行docker-compose

docker-compose up -d

集群启动 

进入任意节点 docker exec -it redis-node1 /bin/bash

redis-cli --cluster create 39.106.53.30:6379 39.106.53.30:6380 39.106.53.30:6381 39.106.53.30:6382 39.106.53.30:6383 39.106.53.30:6384 --cluster-replicas 1

--cluster-replicas 或者 --replicas 1 表示集群中每个master的副本数为1,此时 节点总数/(replicas+1)得到的就是master的数量,因此节点中前n个是master节点 

查看集群信息 

连接集群

以cluster方式连接集群,并set test test 值 ,在其他节点中有相同的值

spring boot 整合分片集群

更改配置

server:
  port: 9000
# 哨兵集群
#spring:
#  redis:
#    sentinel:
#      master: mymaster
#      nodes:
#        - 39.106.53.30:26379
#        - 39.106.53.30:26380
#        - 39.106.53.30:26381
# 分片集群
spring:
  redis:
    cluster:
      nodes:
        - 39.106.53.30:6379
        - 39.106.53.30:6380
        - 39.106.53.30:6381
        - 39.106.53.30:6382
        - 39.106.53.30:6383
        - 39.106.53.30:6384

 测试controller

package com.test.cluster.rediscluster.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author sl
 */
@RestController
public class TestRedisClusterController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/get/{key}")
    public String getKey(@PathVariable("key") String key){
        String s = redisTemplate.opsForValue().get(key);
        if(s!= null){
            return "获取"+  s  + "成功";
        }
        return "获取"+  key  + "失败";
    }

    @RequestMapping("set/{key}/{value}")
    public String setValue(@PathVariable("key")String key,@PathVariable("value") String value){
        redisTemplate.opsForValue().set(key,value);
        return "set" +  key  + "success";
    }


}

测试集群

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

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

相关文章

mysql5.8 免安装版(压缩包)win10 安装

目录 1、下载MySQL5.82、如何安装、配置my.ini配置注意 3初始化mysql3.1. 初始化mysql3.2. 安装mysql服务3.3. 启动mysql3.4. 登录mysql3.5. 修改root密码3.6. 配置远程连接 Mysql5.8安装踩坑记录&#xff0c;推荐使用Docker安装&#xff0c;我是电脑虚拟化可能会蓝屏没用这个功…

vue3+ts+uniapp小程序封装获取授权hook函数

vue3tsuniapp小程序封装获取授权hook函数 小程序授权的时候&#xff0c;如果点击拒绝授权&#xff0c;然后就再也不会出现授权了&#xff0c;除非用户手动去右上角…设置打开 通过uni官方api自己封装一个全局的提示: uni.getSetting :http://uniapp.dcloud.io/api/other/settin…

【Mysql系列】mysql中删除数据的几种方法

写在前面 在MySQL数据库中&#xff0c;删除数据是一个常见的操作&#xff0c;它允许从表中移除不再需要的数据。在执行删除操作时&#xff0c;需要谨慎&#xff0c;以免误删重要数据。 方法介绍 以下是MySQL中删除数据的几种方法&#xff1a; DELETE语句DROP TABLE语句TRUNCAT…

【紫光同创国产FPGA教程】——【PGL22G第八章】HDMI输出彩条实验例程

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处 适用于板卡型号&#xff1a; 紫光同创PGL22G开发平台&#xff08;盘古22K&#xff09; 一&#xff1a;盘古22K开发板&#xff08;紫光同创PGL22G开…

数据结构与算法基础-学习-34-基数排序(桶排序)

目录 一、基本思想 二、算法思路 1、个位排序 &#xff08;1&#xff09;分配 &#xff08;2&#xff09;收集 2、十分位排序 &#xff08;1&#xff09;分配 &#xff08;2&#xff09;收集 三、源码分享 1、InitMyBucket 2、DestroyMyBucket 3、ClearMyBucket 4、…

Linux内核分析与应用6-系统调用

本系列是对 陈莉君 老师 Linux 内核分析与应用[1] 的学习与记录。讲的非常之好&#xff0c;推荐观看 留此记录&#xff0c;蜻蜓点水,可作抛砖引玉 6.1 Linux中的各种API LSB (Linux Standards Base) POSIX: 可移植操作系统接口(Portable Operating System Interface of UNIX) L…

如何用手机号注册亚马逊买家账号

注册亚马逊买家号可以用手机号&#xff0c;也可以用邮箱进行注册。想要用手机号注册买家号&#xff0c;那么打开相应的官网后填写手机号、设置密码、接收短信验证即可。 而如果想要批量注册亚马逊买家号&#xff0c;可以使用亚马逊鲲鹏系统进行操作&#xff0c;亚马逊鲲鹏系统也…

playwright自动化上传附件

需求 自动设置上传头像 过程 1. 首先保存本地一个文件&#xff0c;例如 aaa.php file_path files/aaa.png 2. 获取输入类型为 "file" 的按钮 file_input_element page.locator(input[typefile]) 3. 将本地保存的图片路径赋值 file_input_element.set_input_…

算法训练营day49|动态规划 part10:(LeetCode 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II)

121. 买卖股票的最佳时机 题目链接&#x1f525; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大…

堆排序与TopK问题

一、堆排序 堆排序(升序)&#xff1a;堆排序的思想就是先用数组模拟建大堆&#xff0c;然后把根结点与最后一个结点值交换&#xff0c;最后一个结点的值就是最大值&#xff0c;然后再把前(n-1)个元素重新建大堆&#xff0c;然后根结点与最后一个结点值交换&#xff0c;就找出了…

javac不是内部或外部命令也不是可运行的程序如何解决?

小伙伴们你们有没有遇到过javac不是内部或外部命令,也不是可运行的程序这样的问题呢&#xff1f;大家遇到这样的问题不要慌&#xff0c;只要学会以下的操作你就可以轻松的解决了&#xff0c;具体的步骤操作就在下方&#xff0c;小伙伴们可以认真的看一看吧&#xff01; 1.首先…

cad文件如何转换成pdf?=

cad文件如何转换成pdf&#xff1f;在现代机械制造和建筑装饰领域中&#xff0c;CAD&#xff08;计算机辅助设计&#xff09;软件的应用非常普遍。然而&#xff0c;在与他人共享设计文件时&#xff0c;会发现cad文件的使用并不方便&#xff0c;首先它需要专用的软件才能将其打开…

webpack实战:某网站RSA登录加密逆向分析

文章目录 1. 写在前面2. 抓包分析3. 定位分析4. 构建webpack 1. 写在前面 回过头看&#xff0c;已慢慢将JS爬虫逆向类型的文章从0建设到了1&#xff0c;文章所有案例真实且内容有效&#xff0c;加密类型丰富。收获了很多粉丝的关注与支持&#xff0c;非常感谢大家&#xff01; …

奥康的高尔夫鞋,圈不住投资者的心

文 | 螳螂观察 作者 | 青月 鞋服行业终于熬过了“寒冬”&#xff0c;2023年行业景气度开始逐步回暖。 东方财富Choice数据显示&#xff0c;截至8月17日&#xff0c;已有28家鞋帽服装类上市公司发布了2023年中期业绩预告或快报&#xff0c;其中&#xff0c;9家预增&#xff0…

TCP的滑动窗口与拥塞控制

客户端每发送的一个包&#xff0c;服务器端都应该有个回复&#xff0c;如果服务器端超过一定的时间没有回复&#xff0c;客户端就会重新发送这个包&#xff0c;直到有回复。 为了保证顺序性&#xff0c;每一个包都有一个 ID。在建立连接的时候&#xff0c;会商定起始的 ID 是什…

Python 数据库——链表

基本概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。链表在逻辑上是连续的&#xff0c;但是在物理空间上可能是不连续的&#xff0c;因为链表的内存都是临时申请的&#xff0c;不一定会申请到连续的…

作物模型与遥感反演值同化建模的程序化实现

目录 专题一 遥感基础理论知识 专题二 作物长势监测与产量估算国内外研究进展 专题三 Fortran编程语言 专题四 作物参数遥感反演基本原理 专题五 PROSAIL模型 专题六 参数敏感性分析 专题七 遥感反演过程中的代价函数求解问题 专题八 基于查找表方法PROSAIL模型的作物参…

antd react 文件上传只允许上传一个文件且上传后隐藏上传按钮

antd react 文件上传只允许上传一个文件且上传后隐藏上传按钮 效果图代码解析 效果图 代码解析 import { Form, Upload, message } from antd; import { PlusOutlined } from ant-design/icons; import { useState, useEffect } from react; import { BASE_URL } from /utils/…

IOMesh 为 KubeVirt 提供高效稳定的持久化存储支持(附用户实践)

7 月 11 日&#xff0c;KubeVirt 社区正式宣布发布 Kubernetes 原生虚拟机管理插件 KubeVirt v1.0。这一版本发布不仅标志着 KubeVirt 已进化为生产就绪的虚拟机管理解决方案&#xff0c;也为正在使用虚拟化环境的用户提供了更多元的云化转型路线&#xff1a;搭配 Kubernetes 持…

vue3的params传参失效的解决方案state

vue3使用vue-router4.0&#xff0c;但是使用router.push的params传参&#xff0c;一直拿不到参数 查阅资料如下&#xff1a; —————————————————————————————————————————— state方案如下&#xff1a; 要传参的组件 import { u…