redis03---一主二从、主从切换、哨兵模式。springboot整合redis。雪崩、穿透、击穿。集群,三主三从。springboor整合redis连接集群

目录

一、主从复制

一主二从

主从切换(反客为主)

哨兵模式

哨兵

哨兵工作机制

二、springboot整合redis

1、添加依赖

2、添加配置

3、使用模版工具类完成redis的增删改查

4、测试

5、redis 序列化及常用方法

6、springboot+mysql+redis 业务整合

三、雪崩、穿透、击穿

1. redis缓存使用流程

2. 缓存穿透

2.1. 概念

2.2. 解决方案

3. 缓存雪崩

3.1. 概念

3.2. 解决方案

4. 缓存击穿

4.1. 概念

4.2. 解决方案

四、集群 三主六从---配置

五、springboot整合redis连接集群

作业

1、掌握redis的高可用实现方式

2、springboot整合redis(普通+集群版)的过程及常用方法


一、主从复制

一主二从

主机:master 读写

从机:slave 只读

redis.conf配置文件
requirepass 123456
masterauth 123456

docker run -id -p 6379:6379 --name redis7.2 -v  /opt/redis/redis.conf:/usr/local/bin/redis.conf -v  /usr/local/docker/data:/data  redis:7.0.2  redis-server /usr/local/bin/redis.conf

docker run -id -p 6380:6379 --name redis7.22 -v  /opt/redis/redis2.conf:/usr/local/bin/redis.conf -v  /usr/local/docker/data2:/data  redis:7.0.2  redis-server /usr/local/bin/redis.conf

docker run -id -p 6381:6379 --name redis7.23 -v  /opt/redis/redis3.conf:/usr/local/bin/redis.conf -v  /usr/local/docker/data3:/data  redis:7.0.2  redis-server /usr/local/bin/redis.conf

默认情况下,直接启动,三台服务,三台服务都是master主机。

实现主从复制、读写分离

选6379为master,

在6380 和 6381上,分别执行slaveof ip 6379 ,让当前主机为slave从机,让6379为master主机。

测试:

1、防火墙开放端口

firewall-cmd --zone=public --add-port=6379-6381/tcp --permanent

2、云服务器网络安全组放行(腾讯防火墙放行)

6379 6380 5381

3、重启docker容器

systemctl restart docker

4、依次启动三个容器,在从机上守护主机

docker start redis7.2

docker start redis7.22

docker start redis7.23

客户端连接:

redis-cli -h ip -p 6380 -a 123456
slaveof ip 6379
info replication

 

主从切换(反客为主)

主机故障,从机变主机的过程。

手动切换

在从机上执行

redis-cli -h ip -p 6380 -a 123456
slaveof  no  one
info replication

哨兵模式

哨兵

哨兵的作用是监控 redis系统的运行状况,他的功能如下:

监控主从数据库是否正常运行

master出现故障时,自动将slave转化为master

多哨兵配置的时候,哨兵之间也会自动监控

多个哨兵可以监控同一个redis

哨兵工作机制

./redis-sentinel sentinel.conf

哨兵进程启动时会读取配置文件的内容,通过sentinel monitor master-name ip port quorum查找到master的ip端口。一个哨兵可以监控多个master数据库,只需要提供多个该配置项即可。

配置文件还定义了与监控相关的参数,比如master多长时间无响应即即判定位为下线。

哨兵启动后,会与要监控的master建立俩条连接:

一条连接用来订阅master的sentinel:hello频道与获取其他监控该master的哨兵节点信息

另一条连接定期向master发送INFO等命令获取master本身的信息

与master建立连接后,哨兵会执行三个操作,这三个操作的发送频率都可以在配置文件中配置:

定期向master和slave发送INFO命令

定期向master和slave的sentinel:hello频道发送自己的信息

定期向master、slave和其他哨兵发送PING命令

这三个操作的意义非常重大,发送INFO命令可以获取当前数据库的相关信息从而实现新节点的自动发现。所以说哨兵只需要配置master数据库信息就可以自动发现其slave信息。获取到slave信息后,哨兵也会与slave建立俩条连接执行监控。通过INFO命令,哨兵可以获取主从数据库的最新信息,并进行相应的操作,比如角色变更等。

接下来哨兵向主从数据库的sentinel:hello频道发送信息与同样监控这些数据库的哨兵共享自己的信息,发送内容为哨兵的ip端口、运行id、配置版本、master名字、master的ip端口还有master的配置版本。这些信息有以下用处:

其他哨兵可以通过该信息判断发送者是否是新发现的哨兵,如果是的话会创建一个到该哨兵的连接用于发送PING命令。

其他哨兵通过该信息可以判断master的版本,如果该版本高于直接记录的版本,将会更新

当实现了自动发现slave和其他哨兵节点后,哨兵就可以通过定期发送PING命令定时监控这些数据库和节点有没有停止服务。发送频率可以配置,但是最长间隔时间为1s,可以通过sentinel down-after-milliseconds mymaster 600设置。

如果被ping的数据库或者节点超时未回复,哨兵认为其主观下线。如果下线的是master,哨兵会向其他哨兵点发送命令询问他们是否也认为该master主观下线,如果达到一定数目(即配置文件中的quorum)投票,哨兵会认为该master已经客观下线,并选举领头的哨兵节点对主从系统发起故障恢复。

如上文所说,哨兵认为master客观下线后,故障恢复的操作需要由选举的领头哨兵执行,选举采用Raft算法:

发现master下线的哨兵节点(我们称他为A)向每个哨兵发送命令,要求对方选自己为领头哨兵

如果目标哨兵节点没有选过其他人,则会同意选举A为领头哨兵

如果有超过一半的哨兵同意选举A为领头,则A当选

如果有多个哨兵节点同时参选领头,此时有可能存在一轮投票无竞选者胜出,此时每个参选的节点等待一个随机时间后再次发起参选请求,进行下一轮投票精选,直至选举出领头哨兵

选出领头哨兵后,领头者开始对进行故障恢复,从出现故障的master的从数据库中挑选一个来当选新的master,选择规则如下:

所有在线的slave中选择优先级最高的,优先级可以通过slave-priority配置

如果有多个最高优先级的slave,则选取复制偏移量最大(即复制越完整)的当选

如果以上条件都一样,选取id最小的slave

挑选出需要继任的slave后,领头哨兵向该数据库发送命令使其升格为master,然后再向其他slave发送命令接受新的master,最后更新数据。将已经停止的旧的master更新为新的master的从数据库,使其恢复服务后以slave的身份继续运行。

二、springboot整合redis

1、添加依赖

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

2、添加配置

spring:
  redis:
    host: 1.94.230.82
    port: 6381
    password: 123456
    database: 0

3、使用模版工具类完成redis的增删改查

package com.hl.mybatis03.web;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
​
@RestController
@RequestMapping("/redis")
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
​
    @RequestMapping("/test1")
    public Object test1(){
        //新增
        redisTemplate.opsForValue().set("name", "zhangsan");
        //查询
        return redisTemplate.opsForValue().get("name");
    }
​
}

4、测试

5、redis 序列化及常用方法

@SpringBootApplication
public class Mybatis03Application {
​
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 必须为 String 序列化
        return template;
    }
package com.hl.mybatis03.web;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
​
import java.util.ArrayList;
import java.util.List;
​
@RestController
@RequestMapping("/redis")
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
​
    @RequestMapping("/test1")
    public Object test1(){
        //新增 修改
        redisTemplate.opsForValue().set("name", "zhangsan");
        redisTemplate.opsForValue().set("age",20);
        List list = new ArrayList();
        list.add("beijing");
        list.add("nanjing");
        list.add("bianjing");
        redisTemplate.opsForValue().set("list",list);
​
        redisTemplate.opsForValue().increment("age");//自增加1
        redisTemplate.opsForValue().increment("age",10); //自增长度  自定义
​
        redisTemplate.opsForValue().append("name"," hello! "); //追加内容
​
        String name = (String)redisTemplate.opsForValue().get("name");
        System.out.println(name.length());
​
        redisTemplate.opsForValue().getAndDelete("list");
​
​
        return null;
    }
​
}

6、springboot+mysql+redis 业务整合

@Service
public class QueenServiceImpl implements QueenService{
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private QueenMapper queenMapper;
    @Override
    public List<Queen> getQueens() {
        Object obj = redisTemplate.opsForValue().get("queen");
        List<Queen> list = null;
        if(obj !=null ){
            list = (List<Queen>)obj;
        }else{
            list = queenMapper.getQueens();
            redisTemplate.opsForValue().set("queen",list);
        }
​
        return list;
    }
}

三、雪崩、穿透、击穿

1. redis缓存使用流程

使用Redis缓存数据的流程是:

  1. 数据查询首先进行缓存查询。

  2. 如果数据存在则直接返回缓存数据。

  3. 如果数据不存在,就对数据库进行查询,并把查询到的数据放进缓存。

  4. 如果数据库查询数据为空,则不放进缓存。

2. 缓存穿透

2.1. 概念

缓存穿透是指查询缓存和数据库中都不存在的数据。比如id为-1的数据。

2.2. 解决方案
  • 缓存空值:当第一次请求时,数据不存在 Redis 也不存在数据库的时候,设置一个缺省值(比如:None)。当后续再次进行查询则直接返回空值或者缺省值。

//伪代码
public object GetProductListNew(String key) {
    //首先查询redis数据
    String value = redis.get(key);
    //如果redis中没有数据
    if(value == null){
          //查询数据库中的数据
          String dbValue = db.get();
          //如果数据库中的数据为null,则设置默认值
          if (dbValue == null) {
                dbValue = "none";
          }
          //将数据存储到redis
          redis.set(key,dbValue,50000);
          //返回
          return dbvalue;
        }
    }else{
        //第二次查询数据时,redis有数据,就直接返回
        return value;
    }
}
  • 布隆过滤器:在数据写入数据库的同时将这个 ID 同步到到布隆过滤器中,当请求的 id 不存在布隆过滤器中则说明该请求查询的数据一定没有在数据库中保存,就不要去数据库查询了。

<dependencies>  
     <dependency>  
         <groupId>com.google.guava</groupId>  
         <artifactId>guava</artifactId>  
         <version>23.0</version>  
     </dependency>  
</dependencies> 
//伪代码
public class BloomFilterTest {
 
    private static final int capacity = 1000000;
    private static final int key = 999998;
 
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), capacity);
 
    static {
        for (int i = 0; i < capacity; i++) {
            bloomFilter.put(i);
        }
    }
 
    public static void main(String[] args) {
        /*返回计算机最精确的时间,单位微妙*/
        long start = System.nanoTime();
 
        if (bloomFilter.mightContain(key)) {
            System.out.println("成功过滤到" + key);
        }
        long end = System.nanoTime();
        System.out.println("布隆过滤器消耗时间:" + (end - start));
        int sum = 0;
        for (int i = capacity + 20000; i < capacity + 30000; i++) {
            if (bloomFilter.mightContain(i)) {
                sum = sum + 1;
            }
        }
        System.out.println("错判率为:" + sum);
    }
}

3. 缓存雪崩

3.1. 概念

是指在某一个时间段,redis服务器故障或者redis缓存的数据集中全部过期失效或者大量key过期失效,在缓存集中失效的这个时间段对数据的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力。

3.2. 解决方案

事前:

redis服务器设置高可用(一主二从或者集群3主3从)

  • 随机设置key失效时间,避免大量key集体失效。

  • 不设置过期时间(不推荐)。

  • 用加锁或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写。

  • 跑定时任务,在缓存失效前刷进新的缓存。

    事中:

    可以考略多种缓存机制,比如redis缓存+其他缓存机制 spring cache +mysql

    事后:

    redis崩溃、mysql崩溃,系统崩溃

    解决方案:快速恢复系统(重启mysql、重启redis服务 快速恢复数据到内存中 rdb aof机制 、重启java服务)

4. 缓存击穿

4.1. 概念

指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。

4.2. 解决方案
  • 预先把热门数据提前存入 Redis 中,并设热门数据的过期时间超大值。

  • 使用分布式锁,当发现缓存失效的时候,不是立即从数据库加载数据。而是先获取分布式锁,获取锁成功才执行数据库查询和写数据到缓存的操作,获取锁失败,则说明当前有线程在执行数据库查询操作,当前线程睡眠一段时间在重试。这样只让一个请求去数据库读取数据。

//伪代码
public String get(key) {
      String value = redis.get(key);
      if (value == null) { //代表缓存值过期
          //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
          if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表设置成功
               value = db.get(key);
               redis.set(key, value, expire_secs);
               redis.del(key_mutex);
          } else {  //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
               sleep(50);
               get(key);  //重试
          }
      } else {
         return value;      
      }
 }

四、集群 三主六从---配置

3主6从

创建redis目录和配置文件 由于这里需要配置6个redis实例的配置文件,所以在这里,可以先创建一个模板配置文件,之后使用代码批量替换的方式来创建每个redis的配置文件。

创建模板文件

创建目录

 mkdir -p /data/docker_redis/

vi redis_cluster.conf.template

port ${PORT}
requirepass 123456
masterauth 123456
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 82.157.170.39
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}

在这里需要讲解2个参数 cluster-announce-port:此端口为redis提供服务端口,用于应用客户端连接 cluster-announce-bus-port:此端口用于redis集群进行故障检测、配置更新、故障转移授权和内部通讯使用,不用于应用客户端连接使用。

创建6个redis实例的数据目录,配置文件目录和配置文件

for port in `seq 8001 8006`; do \
  mkdir -p /data/redis_data/${port}/conf \
  && PORT=${port} envsubst < /data/docker_redis/redis_cluster.conf.template > /data/redis_data/${port}/conf/redis.conf \
  && mkdir -p /data/redis_data/${port}/data;\
done
 

批量创建容器 在这里使用for循环批量创建redis容器,代码如下所示

 #防火墙开放端口
sudo firewall-cmd --permanent --add-port=8001-8006/tcp
sudo firewall-cmd --permanent --add-port=18001-18006/tcp

#重新加载防火墙使得开放端口生效
sudo firewall-cmd --reload

#查看是否开放成功
sudo firewall-cmd --list-ports

#在服务器上开放相应端口

for port in $(seq 8001 8006); do \
  docker run -id -p ${port}:${port} -p 1${port}:1${port} --restart always --name redis-${port} \
  -v /data/redis_data/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  -v /data/redis_data/${port}/data:/data \
  redis:7.0.2 redis-server /usr/local/etc/redis/redis.conf; \
done

#纯启动几个容器
for port in $(seq 8001 8006); do \
  docker start redis-${port} ;\
done

在这里使用-v参数,让容器的redis配置参数和数据全部使用宿主机的文件目录。这样做的好处是,保证redis的数据不丢失。

查看刚刚创建的redis容器

[root@mysql data]# docker ps CONTAINER ID       IMAGE               COMMAND                 CREATED             STATUS             PORTS                                                       NAMES f4c971ce2d84       redis:7.0.2-buster   "docker-entrypoint.s鈥 6 seconds ago       Up 5 seconds       0.0.0.0:8006->8006/tcp, 6379/tcp, 0.0.0.0:18006->18006/tcp   redis-8006 1b5a8b0a1c93       redis:7.0.2-buster   "docker-entrypoint.s鈥 7 seconds ago       Up 6 seconds       0.0.0.0:8005->8005/tcp, 6379/tcp, 0.0.0.0:18005->18005/tcp   redis-8005 35d8fe01fc71       redis:7.0.2-buster   "docker-entrypoint.s鈥 7 seconds ago       Up 6 seconds       0.0.0.0:8004->8004/tcp, 6379/tcp, 0.0.0.0:18004->18004/tcp   redis-8004 408e5302378a       redis:7.0.2-buster   "docker-entrypoint.s鈥 8 seconds ago       Up 7 seconds       0.0.0.0:8003->8003/tcp, 6379/tcp, 0.0.0.0:18003->18003/tcp   redis-8003 c1c23c543233       redis:7.0.2-buster   "docker-entrypoint.s鈥 8 seconds ago       Up 7 seconds       0.0.0.0:8002->8002/tcp, 6379/tcp, 0.0.0.0:18002->18002/tcp   redis-8002 c752fab6c6b8       redis:7.0.2-buster   "docker-entrypoint.s鈥 9 seconds ago       Up 8 seconds       0.0.0.0:8001->8001/tcp, 6379/tcp, 0.0.0.0:18001->18001/tcp   redis-8001

创建redis-cluster集群 6个redis容器创建好之后,选择其中的一个容器进入,进行redis-cluster集群创建

[root@mysql bin]# docker exec -it redis-8001 /bin/bash
root@f4c971ce2d84:~# redis-cli -a 123456 --cluster create 82.157.170.39:8001 82.157.170.39:8002 82.157.170.39:8003 82.157.170.39:8004 82.157.170.39:8005 82.157.170.39:8006 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 1.94.230.82:8005 to 1.94.230.82:8001
Adding replica 1.94.230.82:8006 to 1.94.230.82:8002
Adding replica 1.94.230.82:8004 to 1.94.230.82:8003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: c9e549f4d04d4466d2550d1e027412304099b1f2 1.94.230.82:8001
   slots:[0-5460] (5461 slots) master
M: 0956927ee74737d5ff91a1885e77f94d531dab76 1.94.230.82:8002
   slots:[5461-10922] (5462 slots) master
M: d6321788b2717b4142390c158ba70ca758f70964 1.94.230.82:8003
   slots:[10923-16383] (5461 slots) master
S: 96d2cb55f163ecc13a714ba01d90348c1c3ad02f 1.94.230.82:8004
   replicates c9e549f4d04d4466d2550d1e027412304099b1f2
S: 8a771c26a95e82d9a6818e372d7c0226937670ac 1.94.230.82:8005
   replicates 0956927ee74737d5ff91a1885e77f94d531dab76
S: aa7c2f6173904973f041b35efc5200359188eb0f 1.94.230.82:8006
   replicates d6321788b2717b4142390c158ba70ca758f70964
Can I set the above configuration? (type 'yes' to accept): 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 1.94.230.82:8001)
M: c9e549f4d04d4466d2550d1e027412304099b1f2 1.94.230.82:8001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 0956927ee74737d5ff91a1885e77f94d531dab76 1.94.230.82:8002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 96d2cb55f163ecc13a714ba01d90348c1c3ad02f 1.94.230.82:8004
   slots: (0 slots) slave
   replicates c9e549f4d04d4466d2550d1e027412304099b1f2
S: aa7c2f6173904973f041b35efc5200359188eb0f 1.94.230.82:8006
   slots: (0 slots) slave
   replicates d6321788b2717b4142390c158ba70ca758f70964
S: 8a771c26a95e82d9a6818e372d7c0226937670ac 1.94.230.82:8005
   slots: (0 slots) slave
   replicates 0956927ee74737d5ff91a1885e77f94d531dab76
M: d6321788b2717b4142390c158ba70ca758f70964 1.94.230.82:8003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

上述命令执行之后,redis-cluster集群就搭建好了,下面是整个redis-cluster集群的架构图

测试

D:\programmeSoft\redis>redis-cli -h 82.157.170.39 -p 8001 -a 123456 -c
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
82.157.170.39:8001> set s1 v1
-> Redirected to slot [15224] located at 82.157.170.39:8003
OK
82.157.170.39:8003> set s2 v2
-> Redirected to slot [2843] located at 82.157.170.39:8001
OK
82.157.170.39:8001> set s3 v3
-> Redirected to slot [6970] located at 82.157.170.39:8002
OK
82.157.170.39:8002> get s3
"v3"
82.157.170.39:8002> get s1
-> Redirected to slot [15224] located at 82.157.170.39:8003
"v1"
82.157.170.39:8003> get s2
(error) CLUSTERDOWN The cluster is down
82.157.170.39:8003> get s2
-> Redirected to slot [2843] located at 82.157.170.39:8005
"v2"
82.157.170.39:8005> info repliation
82.157.170.39:8005> get s3
-> Redirected to slot [6970] located at 82.157.170.39:8002
"v3"
82.157.170.39:8002> info repliation
82.157.170.39:8002> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=82.157.170.39,port=8006,state=online,offset=346,lag=0
master_failover_state:no-failover
master_replid:71429ed7b1b2d6e86ea87bad2f22887427d2ed8a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:346
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:346
82.157.170.39:8002> get s2
-> Redirected to slot [2843] located at 82.157.170.39:8005
"v2"
82.157.170.39:8005> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:a1dcdef78f7736baa9b72c95158920d482ecce6a
master_replid2:5171ae1660acd424fbad40555badf369f8ccc5ff
master_repl_offset:234
second_repl_offset:235
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:234
82.157.170.39:8005> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=82.157.170.39,port=8001,state=online,offset=248,lag=0
master_failover_state:no-failover
master_replid:a1dcdef78f7736baa9b72c95158920d482ecce6a
master_replid2:5171ae1660acd424fbad40555badf369f8ccc5ff
master_repl_offset:248
second_repl_offset:235
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:248
82.157.170.39:8005> get s2
"v2"

五、springboot整合redis连接集群

作业

1、掌握redis的高可用实现方式

  1. 主从复制:一主多从,数据异步复制,实现读写分离和备份,但主节点故障需手动切换。

    #查看主从关系
    info replication
       role:slave
       master_host:<ip>
       master_port:<port>
    
    #接触从节点身份
    slaveof no one
    
    #将其他节点指向新主节点
    slaveof <new_master_ip> <new_master_port>
  2. 哨兵模式(Sentinel):通过哨兵集群监控主节点,自动选举新主节点,解决主从切换问题,适合中小规模场景。

  3. Redis Cluster:数据分片存储,支持多主多从,自动故障转移和水平扩展,适合大规模高并发场景。

2、springboot整合redis(普通+集群版)的过程及常用方法

  1. 添加依赖spring-boot-starter-data-redis

  2. 配置连接:在 application.yml 中设置主机、端口、密码等。

  3. 使用 RedisTemplate

    • opsForValue():操作 String 类型。

      // 带过期时间
      redisTemplate.opsForValue().set("key", "value", 10, TimeUnit.SECONDS); 
      String value = (String) redisTemplate.opsForValue().get("key");
    • opsForHash():操作 Hash 类型。

      redisTemplate.opsForHash().put("user", "name", "Alice");
      Map<Object, Object> user = redisTemplate.opsForHash().entries("user");
    • expire():设置过期时间。

    • execute():支持事务和 Lua 脚本。

  4. 自定义序列化(解决JDK序列化乱码)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值