redis缓存数据库详解(六):高可用方案

Redis-缓存穿透、缓存雪崩、缓存击穿详解 redis有关缓存穿透、缓存雪崩、缓存击穿的详解 阅读详情

作为一个稀有的Java妹子,所写的所有博客都只是当作自己的笔记,留下证据自己之前是有用心学习的~哈哈哈哈(如果有不对的地方,也请大家指出,不要悄悄咪咪的不告诉我)

概述

redis在实际应用中安装部署的方式有所不同,如果对数据没有持久化的要求,只是为了提高读取数据效率,可能会采用单机模式;但是生产环境中基本上都会要求持久化数据,备份数据,节点失效转移等,那么这时候单节点部署就不能满足了,下面就介绍一下redis的高可用方案。

redis的高可用方案主要有两种:
1.主从复制(Replication-Sentinel模式)
2.集群(Redis-Cluster模式)

主从复制(Replication-Sentinel模式)

Redis Sentinel 是 Redis 高可用 的实现方案。Sentinel 是一个管理多个 Redis 实例的工具,它可以实现对 Redis 的 监控、通知、自动故障转移。下面先对 Redis Sentinel 的 基本概念 进行简单的介绍。

基本名词逻辑结构物理结构
Redis数据节点主节点和从节点主节点和从节点的进程
主节点(master)Redis主数据库一个独立的Redis进程
从节点(slave)Redis从数据库一个独立的Redis进程
Sentinel节点监控Redis数据节点一个独立的Sentinel进程
Sentinel节点集合若干Sentinel节点的抽象组合若干Sentinel节点进程
Redis SentinelRedis高可用实现方案Sentinel节点集合和Redis数据节点进程

1.Redis Sentinel的主要功能

1.从节点分担主节点的读压力
2.Sentinel监控主节点和从节点服务器的状态
3.当被监控的某个 Redis 服务器出现问题,Sentinel 通过 API 脚本 向 管理员 或者其他的 应用程序 发送通知。
4.当 主节点 不能正常工作时,Sentinel 会开始一次 自动的故障转移操作,它会将与 失效主节点 是 主从关系 的其中一个 从节点 升级为新的 主节点,并且将其他的 从节点 指向 新的主节点,然后还会修改配置文件。
5.在 Redis Sentinel 模式下,客户端应用 在初始化时连接的是 Sentinel 节点集合,从中获取 主节点 的信息,因为如果直接连接主节点信息,主节点挂掉后还要修改配置。

2.主观下线和客观下线

默认情况下,每个 Sentinel 节点会以 每秒一次 的频率对 Redis 节点和 其它 的 Sentinel 节点发送 PING 命令,并通过节点的 回复 来判断节点是否在线。

主观下线
主观下线 适用于所有 主节点 和 从节点。如果在 down-after-milliseconds 毫秒内,Sentinel 没有收到 目标节点 的有效回复,则会判定 该节点 为 主观下线。

客观下线
客观下线 只适用于 主节点。如果 主节点 出现故障,Sentinel 节点会通过 sentinel is-master-down-by-addr 命令,向其它 Sentinel 节点询问对该节点的 状态判断。如果超过 个数的节点判定 主节点 不可达,则该 Sentinel 节点会判断 主节点 为 客观下线。

主观下线只是其中一个哨兵节点探测到主节点不可达了,客观下线指当主节点主观下线后,超过指定个数额哨兵也去探测到主节点宕机了。主节点客观下线后就开始了故障转移,从新选举主节点的操作。

3.Redis Sentinel搭建

1.一个稳健的 Redis Sentinel 集群,应该使用至少 三个 Sentinel 实例,并且保证讲这些实例放到 不同的机器 上,甚至不同的 物理区域。
2.Sentinel 无法保证 强一致性。
3.常见的 客户端应用库 都支持 Sentinel。
4.Sentinel 需要通过不断的 测试 和 观察,才能保证高可用。

Redis Sentinel的配置文件

# 哨兵sentinel实例运行的端口,默认26379  
port 26379
# 哨兵sentinel的工作目录
dir ./
 
# 哨兵sentinel监控的redis主节点的 
## ip:主机ip地址
## port:哨兵端口号
## master-name:可以自己命名的主节点名字(只能由字母A-z、数字0-9 、这三个字符".-_"组成。)
## quorum:当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了  
# sentinel monitor <master-name> <ip> <redis-port> <quorum>  
sentinel monitor mymaster 127.0.0.1 6379 2
 
# 当在Redis实例中开启了requirepass <foobared>,所有连接Redis实例的客户端都要提供密码。
# sentinel auth-pass <master-name> <password>  
sentinel auth-pass mymaster 123456  
 
# 指定主节点应答哨兵sentinel的最大时间间隔,超过这个时间,哨兵主观上认为主节点下线,默认30秒  
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000  
 
# 指定了在发生failover主备切换时,最多可以有多少个slave同时对新的master进行同步。这个数字越小,完成failover所需的时间就越长;反之,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为1,来保证每次只有一个slave,处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1  
 
# 故障转移的超时时间failover-timeout,默认三分钟,可以用在以下这些方面:
## 1. 同一个sentinel对同一个master两次failover之间的间隔时间。  
## 2. 当一个slave从一个错误的master那里同步数据时开始,直到slave被纠正为从正确的master那里同步数据时结束。  
## 3. 当想要取消一个正在进行的failover时所需要的时间。
## 4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来同步数据了
# sentinel failover-timeout <master-name> <milliseconds>  
sentinel failover-timeout mymaster 180000
 
# 当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本。一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
# 对于脚本的运行结果有以下规则:  
## 1. 若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10。
## 2. 若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。  
## 3. 如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
# sentinel notification-script <master-name> <script-path>  
sentinel notification-script mymaster /var/redis/notify.sh
 
# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
3.1 Redis Sentinel的节点规划

这里是模拟,所以是在一台物理机上部署的,生产环境上应该在不同的服务器上部署。特别是哨兵节点和redis节点不同部署在同一物理机上,不然redis挂了,哨兵节点也挂了,就检测不到redis的状态了。

角色IP地址端口号
Redis Master127.0.0116379
Redis Slave1127.0.0126379
Redis Slave2127.0.0136379
Redis Sentinel1127.0.0116380
Redis Sentinel2127.0.0126380
Redis Sentinel3127.0.0136380
3.2 Redis-Server的配置管理

1.分别拷贝三份 redis.conf 文件到 /usr/local/redis-sentinel 目录下面。三个配置文件分别对应 master、slave1 和 slave2 三个 Redis 节点的 启动配置。

cp /usr/local/redis-5.0.7/redis.conf /usr/local/redis-sentinel/redis-16379
cp /usr/local/redis-5.0.7/redis.conf /usr/local/redis-sentinel/redis-26379
cp /usr/local/redis-5.0.7/redis.conf /usr/local/redis-sentinel/redis-36379

2.分别修改三份配置文件如下:
主节点:redis-16379.conf

daemonize yes
pidfile /var/run/redis-16379.pid
logfile /var/log/redis/redis-16379.log
port 16379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-16379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456

从节点1:redis-26379.conf

daemonize yes
pidfile /var/run/redis-26379.pid
logfile /var/log/redis/redis-26379.log
port 26379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-26379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
replicaof 127.0.0.1 16379

从节点2:redis-36379.conf

daemonize yes
pidfile /var/run/redis-36379.pid
logfile /var/log/redis/redis-36379.log
port 36379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-36379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
replicaof 127.0.0.1 16379
	如果要做 自动故障转移,建议所有的 redis.conf 都设置 masterauth。
	因为自动故障只会重写 主从关系,即 slaveof,不会自动写入 
	masterauth。如果 Redis 原本没有设置密码,则可以忽略

3.按顺序分别启动 16379,26379 和 36379 三个 Redis 节点,启动命令和启动日志如下:

redis-server /usr/local/redis-sentinel/redis-16379.conf
redis-server /usr/local/redis-sentinel/redis-26379.conf
redis-server /usr/local/redis-sentinel/redis-36379.conf

主节点的启动日志如下:
在这里插入图片描述
6282:M 06 Mar 2020 14:19:05.966 * Replica 127.0.0.1:26379 asks for synchronization
6282:M 06 Mar 2020 14:19:08.738 * Replica 127.0.0.1:36379 asks for synchronization
这两行表明从节点从主节点同步信息

从节点启动日志:
在这里插入图片描述
在这里插入图片描述
6285:S 06 Mar 2020 14:19:05.964 * Connecting to MASTER 127.0.0.1:16379
从节点的这句话表明已经连接到主节点上

3.3 Sentinel的配置管理

1.分别拷贝三份 redis-sentinel.conf 文件到 /usr/local/redis-sentinel 目录下面。三个配置文件分别对应 master、slave1 和 slave2 三个 Redis 节点的 哨兵配置。

cp /usr/local/redis-5.0.7/sentinel /usr/local/redis-sentinel/sentinel-16380.conf
cp /usr/local/redis-5.0.7/sentinel /usr/local/redis-sentinel/sentinel-26380.conf
cp /usr/local/redis-5.0.7/sentinel /usr/local/redis-sentinel/sentinel-36380.conf

三个节点的配置信息如下

protected-mode no
bind 0.0.0.0
port 16380
daemonize yes
sentinel monitor mymaster 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /var/log/redis/sentinel-16380.log
protected-mode no
bind 0.0.0.0
port 26380
daemonize yes
sentinel monitor mymaster 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /var/log/redis/sentinel-26380.log
protected-mode no
bind 0.0.0.0
port 36380
daemonize yes
sentinel monitor mymaster 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /var/log/redis/sentinel-26380.log

2.按顺序分别启动 16380,26380 和 36380 三个 Sentinel 节点,启动命令和启动日志如下:

MacBook-Pro:redis-5.0.7 root# tail -200f sentinel-16380.log
8684:X 06 Mar 2020 16:02:11.450 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8684:X 06 Mar 2020 16:02:11.451 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=8684, just started
8684:X 06 Mar 2020 16:02:11.451 # Configuration loaded
8685:X 06 Mar 2020 16:02:11.453 * Increased maximum number of open files to 10032 (it was originally set to 4864).
8685:X 06 Mar 2020 16:02:11.454 * Running mode=sentinel, port=16380.
8685:X 06 Mar 2020 16:02:11.455 # Sentinel ID is 1188a54e05eed0df0e230bfa1c9cec01929252a2
//这里显示监控的主节点信息
8685:X 06 Mar 2020 16:02:11.455 # +monitor master mymaster 127.0.0.1 16379 quorum 2
//监控的从节点的信息
8685:X 06 Mar 2020 16:02:11.458 * +slave slave 127.0.0.1:26379 127.0.0.1 26379 @ mymaster 127.0.0.1 16379
8685:X 06 Mar 2020 16:02:11.459 * +slave slave 127.0.0.1:36379 127.0.0.1 36379 @ mymaster 127.0.0.1 16379
//当另外两个哨兵节点启动后,也会加入到该哨兵节点的配置中去
8685:X 06 Mar 2020 16:02:17.138 * +sentinel sentinel 9fd6cb78ef74b46530f9ce74c7d7abf53a606c12 127.0.0.1 26380 @ mymaster 127.0.0.1 16379
8685:X 06 Mar 2020 16:02:19.946 * +sentinel sentinel 1a47466bf6142d00039cf6983ba1e860db4cfe00 127.0.0.1 36380 @ mymaster 127.0.0.1 16379
MacBook-Pro:redis-5.0.7 root# tail -200f sentinel-26380.log
8686:X 06 Mar 2020 16:02:15.086 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8686:X 06 Mar 2020 16:02:15.086 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=8686, just started
8686:X 06 Mar 2020 16:02:15.086 # Configuration loaded
8687:X 06 Mar 2020 16:02:15.089 * Increased maximum number of open files to 10032 (it was originally set to 4864).
8687:X 06 Mar 2020 16:02:15.091 * Running mode=sentinel, port=26380.
8687:X 06 Mar 2020 16:02:15.092 # Sentinel ID is 9fd6cb78ef74b46530f9ce74c7d7abf53a606c12
8687:X 06 Mar 2020 16:02:15.092 # +monitor master mymaster 127.0.0.1 16379 quorum 2
8687:X 06 Mar 2020 16:02:15.094 * +slave slave 127.0.0.1:26379 127.0.0.1 26379 @ mymaster 127.0.0.1 16379
8687:X 06 Mar 2020 16:02:15.095 * +slave slave 127.0.0.1:36379 127.0.0.1 36379 @ mymaster 127.0.0.1 16379
8687:X 06 Mar 2020 16:02:15.503 * +sentinel sentinel 1188a54e05eed0df0e230bfa1c9cec01929252a2 127.0.0.1 16380 @ mymaster 127.0.0.1 16379
8687:X 06 Mar 2020 16:02:19.946 * +sentinel sentinel 1a47466bf6142d00039cf6983ba1e860db4cfe00 127.0.0.1 36380 @ mymaster 127.0.0.1 16379
MacBook-Pro:redis-5.0.7 root# tail -200f sentinel-36380.log
8688:X 06 Mar 2020 16:02:17.917 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8688:X 06 Mar 2020 16:02:17.917 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=8688, just started
8688:X 06 Mar 2020 16:02:17.917 # Configuration loaded
8689:X 06 Mar 2020 16:02:17.920 * Increased maximum number of open files to 10032 (it was originally set to 4864).
8689:X 06 Mar 2020 16:02:17.921 * Running mode=sentinel, port=36380.
8689:X 06 Mar 2020 16:02:17.922 # Sentinel ID is 1a47466bf6142d00039cf6983ba1e860db4cfe00
8689:X 06 Mar 2020 16:02:17.922 # +monitor master mymaster 127.0.0.1 16379 quorum 2
8689:X 06 Mar 2020 16:02:17.923 * +slave slave 127.0.0.1:26379 127.0.0.1 26379 @ mymaster 127.0.0.1 16379
8689:X 06 Mar 2020 16:02:17.924 * +slave slave 127.0.0.1:36379 127.0.0.1 36379 @ mymaster 127.0.0.1 16379
8689:X 06 Mar 2020 16:02:19.151 * +sentinel sentinel 9fd6cb78ef74b46530f9ce74c7d7abf53a606c12 127.0.0.1 26380 @ mymaster 127.0.0.1 16379
8689:X 06 Mar 2020 16:02:19.554 * +sentinel sentinel 1188a54e05eed0df0e230bfa1c9cec01929252a2 127.0.0.1 16380 @ mymaster 127.0.0.1 16379

4.springboot整合Redis Sentinel

1.配置文件

java.redis.pool.max-total=10
java.redis.pool.max-idle=5
java.redis.pool.min-idle=5
# 多个用逗号隔开,host:port,host2:port2
java.redis.sentinel.nodes=127.0.0.1:16380,127.0.0.1:26380,127.0.0.1:36380
java.redis.sentinel.password=123456
java.redis.sentinel.master-name=mymaster
java.redis.sentinel.pool.max-total=10
java.redis.sentinel.pool.max-idle=5
java.redis.sentinel.pool.min-idle=5

2.配置类

@Slf4j
@Component
public class RedisNodeConfig implements InitializingBean {
    @Value("${java.redis.pool.max-total:10}")
    private Integer redisMaxTotal;
    @Value("${java.redis.pool.min-idle}")
    private Integer redisMaxIdle;
    @Value("${java.redis.pool.min-idle}")
    private Integer redisMinIdle;
    @Value("${java.redis.sentinel.nodes}")
    private String redisSentinelNodes;
    @Value("${java.redis.sentinel.password}")
    private String redisSentinelPassword;
    @Value("${java.redis.sentinel.master-name}")
    private String redisSentinelMasterName;
    @Value("${java.redis.sentinel.pool.max-total}")
    private Integer redisSentinelMaxTotal;
    @Value("${java.redis.sentinel.pool.max-idle}")
    private Integer redisSentinelMaxIdle;
    @Value("${java.redis.sentinel.pool.min-idle}")
    private Integer redisSentinelMinIdle;


    private JedisSentinelPool jedisPool;

    @Override
    public void afterPropertiesSet() throws Exception {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(redisMaxTotal);
        jedisPoolConfig.setMaxIdle(redisMaxIdle);
        jedisPoolConfig.setMinIdle(redisMinIdle);
        String[] hosts = redisSentinelNodes.split(",");
        Set<String> sentinels = new HashSet<>(Arrays.asList(hosts));
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(redisSentinelMaxTotal);
        poolConfig.setMaxIdle(redisSentinelMaxIdle);
        poolConfig.setMinIdle(redisSentinelMinIdle);
        jedisPool = new JedisSentinelPool(redisSentinelMasterName, sentinels, jedisPoolConfig);
        if (isConnectSuccess()) {
            // 初始化成功
            log.info("++++++ Init Redis Sentinel Pool SUCCESS! ++++++");
        } else {
            // 初始化失败
            log.info("++++++ Init Redis Sentinel Pool FAILURE! ++++++");
        }
    }
    public boolean isConnectSuccess() {
        Jedis jedis = getRedis();
        String ping = jedis.ping();
        recycleRedis(jedis);
        return ping.equals("PONG");
    }
    /**
     * @return 连接池中的Jedis实例
     */
    public Jedis getRedis() {
        return jedisPool.getResource();
    }
    /**
     * 资源回收
     *
     * @param jedis jedis实例
     */
    public void recycleRedis(Jedis jedis) {
        jedis.close();
    }
    
    /**
     * 销毁Redis连接池
     */
    public void close() {
        if (null != jedisPool) {
            jedisPool.close();
        }
    }
}

3.服务类

@Component
public class RedisNodeService implements InitializingBean {
    @Autowired
    private RedisNodeConfig redisNodeConfig;

    private Jedis jedis;

    @Override
    public void afterPropertiesSet() throws Exception {
        jedis = redisNodeConfig.getRedis();
    }

    public void set(String key,String value){
        jedis.set(key,value);
    }
}

4.测试

@Service
@Slf4j
public class TestService{
    @Autowired
    private RedisNodeService redisNodeService;

    public void testRedisService() {
        redisNodeService.set("testnode","testnode");
    }
}

连接redis的主节点:

127.0.0.1:16379> get testnode
"testnode"

5.模拟主节点失效

1.将主节点进程手动杀掉

MacBook-Pro:redis-5.0.7 root# ps -ef|grep 16379
    0  8208     1   0  3:38下午 ??         0:15.52 redis-server 0.0.0.0:16379
    0  9683  6027   0  4:54下午 ttys000    0:00.01 grep 16379
MacBook-Pro:redis-5.0.7 root# kill -9 8208

2.查看sentinel日志

//判断主节点主观下线
8685:X 06 Mar 2020 16:54:16.817 # +sdown master mymaster 127.0.0.1 16379
8685:X 06 Mar 2020 16:54:16.916 # +new-epoch 1
8685:X 06 Mar 2020 16:54:16.917 # +vote-for-leader 9fd6cb78ef74b46530f9ce74c7d7abf53a606c12 1
//超过2个哨兵节点认同主节点失效,主节点变为客观下线
8685:X 06 Mar 2020 16:54:17.887 # +odown master mymaster 127.0.0.1 16379 #quorum 3/2
8685:X 06 Mar 2020 16:54:17.887 # Next failover delay: I will not start a failover before Fri Mar  6 17:00:17 2020
8685:X 06 Mar 2020 16:54:18.045 # +config-update-from sentinel 9fd6cb78ef74b46530f9ce74c7d7abf53a606c12 127.0.0.1 26380 @ mymaster 127.0.0.1 16379
//开始更换主节点为36379
8685:X 06 Mar 2020 16:54:18.045 # +switch-master mymaster 127.0.0.1 16379 127.0.0.1 36379
//然后把原来的从节点26379和原来的主节点16379都变为36379的从节点
8685:X 06 Mar 2020 16:54:18.046 * +slave slave 127.0.0.1:26379 127.0.0.1 26379 @ mymaster 127.0.0.1 36379
8685:X 06 Mar 2020 16:54:18.046 * +slave slave 127.0.0.1:16379 127.0.0.1 16379 @ mymaster 127.0.0.1 36379
8685:X 06 Mar 2020 16:54:23.092 # +sdown slave 127.0.0.1:16379 127.0.0.1 16379 @ mymaster 127.0.0.1 36379

这时候去看redis的配置文件会发现replicaof 127.0.0.1 16379这一行变为了replicaof 127.0.0.1 36379,sentinel的配置文件中的sentinel monitor mymaster 127.0.0.1 16379 2也变为了sentinel monitor mymaster 127.0.0.1 36379 2

3.因为哨兵模式的节点故障转移,现在主节点已经变为了端口号为36379的服务了,再测试下springboot项目是否能正常连接redis,所有的配置项都没有动,

@Service
@Slf4j
public class TestService{
    @Autowired
    private RedisNodeService redisNodeService;

    public void testRedisService() {
        redisNodeService.set("redis-sentinel","redis-sentinel");
    }
}
127.0.0.1:36379> get redis-sentinel
"redis-sentinel"

集群(Redis-Cluster模式)

主从模式下从节点只能分担读压力,不能分担写压力,而且主节点的写能力和存储能力受单机的限制。集群模式可以做到从节点分担写压力,可以扩充主节点的写能力和存储能力。

具体如何实现还未研究

【从零开始学习SLAM】官方tf教程小海龟跟随程序 ros tf 进行坐标系之间转换的运算和发布 阅读详情

相关推荐

旅行青蛙破解汉化教程——蹭个热度

汉化破解版资源(无尽三叶草与点券): https://github.com/wisdombyzf/lxqw/blob/master/lxqw_zf.apk 截图: 破解方法: 工具: 1,APKIDE https://www.pd521.com/thread-818-1-2.html 2,dnspy https://down.52pojie.

github_38838414的博客 3783

redis高可用几种方案

redis高可用方案 主从 哨兵 集群

ganyouxian_java的博客 7752

SAP移动类型

SAP移动类型移动类型定义 移动类型定义

qq_20593197的博客 6201

Redis的几种高可用方案部署

主从切换技术的操作是:当主机宕机后,需要手动把一台从机切换为主机。这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。Redis 从2.8开始正式提供了Sentinel(哨兵)架构来解决这个问题。它是“谋朝篡位”的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从机转换为主机。哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,它会独立运行。

WU18948905539的博客 2049

基于FPGA的心电信号实时处理与智能诊断系统实现【附源码解析】

本文详细介绍了基于FPGA的心电信号实时处理与智能诊断系统的设计与实现。系统通过高精度采集电路和FPGA数字滤波技术处理微弱心电信号,采用自适应算法准确检测QRS波群,实现心率计算和心律异常诊断。附源码解析展示了FIR滤波器、中值滤波器和诊断逻辑的Verilog实现,为心电监护系统开发提供实用参考。

g8f9d0s1a2的博客 769

【读论文】AI陪伴场景长期记忆(用户画像)解决方案

在长程人机交互中,如何让 AI 记住用户,不再是简单的“检索增强(RAG)”就能解决的问题。传统的向量数据库面临“信息信噪比低”、“人格不一致”以及“随着对话无限增长而崩塌”的困境。MemTensor 团队联合人大提出的Inside Out框架,从认知心理学汲取灵感,提出了一种基于PersonaTree(人格树)的显式记忆进化机制。该方案通过训练一个轻量级的(使用 DeepSeek-R1 蒸馏数据 + GRPO 强化学习),实现了将非结构化对话流实时压缩为结构化树操作(新增|更新|删除)。

kakaZhui的博客 816

Redis 高可用方案

SDOWN(主观下线):这是 Sentinel 单个实例对 Redis 节点的主观判断。即某个 Sentinel 认为该 Redis 节点不可用,但这种判断仅仅是该 Sentinel 的“个人观点”。ODOWN(客观下线):这是 Sentinel 集群的共同判断。即多个 Sentinel 一致认为该 Redis 节点不可用,这时该节点被标记为客观下线,触发故障转移机制。

ArchManual 分布式技术架构手册 2606

Winform美化框架AntdUI中Table的使用方法

使用核心注意点: 数据模型中属性名需要完全与new Column里的列名一致否则添加数据源则无法读取到详细内容。

wevix的博客 3676

Redis高可用的三种实现方式

Redis主从模式,哨兵模式,集群模式,高可用

weixin_44183721的博客 1万+

Windows Server远程桌面断开后,PyWinAuto/按键精灵脚本失效?试试这个‘会话保持’的终极配置

本文深入解析Windows Server远程桌面断开后导致PyWinAuto/按键精灵脚本失效的问题,提供会话保持的终极配置方案。通过转换到控制台会话(console模式)和调整组策略,确保自动化程序在断开连接后持续稳定运行,适用于Windows Server各版本。

weixin_28738165的博客 227

黑猫带你学eMMC协议第26篇:eMMC的硬件复位操作(H/W reset)

本文依据eMMC JEDEC5.1及个人工作经验整理而成,如有错误请留言。 文章为个人辛苦整理,付费内容,禁止私自转载。 文章所在专栏:《黑猫带你学:eMMC协议详解》 1 概述 什么是硬件复位? 硬件复位就是使用一个特殊硬件信号(这个信号在RST_n这根实实在在的物理线路上传输)将emmc复位到pre-idle state,而不需要使用cmd0或者power cycle讲emmc复位到pre-idle state。 如何进行硬件复位? 1、设置RST_n_FUNCTION [162]为1,使emm.

黑猫奥利奥的博客 6316

Redis保证高可用的三种方式

Redis保证高可用主要有三种方式:主从、哨兵、集群。

qq_39940634的博客 2587

数据集FFHQ和LSUN介绍【包含FFHQ1024,515,256,128分辨率图像获取方法】

FFHQ全称Flickr-Faces-High-Quality(Flickr-Faces-HQ),最初是作为生成式对抗网络(GAN)的基准创建的,也用于StyleGAN的训练数据集中,并由英伟达于2019年开源。CVPR_2019Flickr-Faces-HQ (FFHQ)其由 70,000 张分辨率为 1024×1024 的高质量 PNG 图像组成,在年龄、种族和图像背景方面包含相当大的差异。它对眼镜、太阳镜、帽子等配饰也有很好的覆盖。

zik的博客 3976

Redis缓存高可用实战:三种高可用方案详解

Redis缓存高可用方案解析 本文探讨了Redis高可用的三种主流实现方案。首先分析了缓存高可用的必要性,指出单点故障会导致数据库压力剧增和系统崩溃风险。随后详细介绍了三种解决方案: 主从复制方案:通过"一主多从"架构实现数据备份和读写分离,但需要手动故障转移 Sentinel方案:官方推荐的自动故障转移方案,具备监控、通知和自动主从切换能力 集群方案:通过数据分片实现水平扩展,同时支持自动故障转移 文章重点阐述了主从复制的实现原理、配置步骤和Java读写分离实现代码,并比较了各方案的适

小工匠 1467

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Redis | Redis缓存穿透、缓存击穿、缓存雪崩问题及解决方案

目录 缓存问题 1. 缓存穿透---查不到 解决方案 2. 缓存击穿---量太大,缓存过期 解决方案 3. 缓存雪崩 解决方案 缓存问题 1. 缓存穿透---查不到 缓存穿透是指用户想查询一个数据,发现Redis中没有,也就是缓存没有命中,就向持久性数据库发起查询,发现数据库也没有这个数据,于是查询失败了。当用户请求很多的情况下,缓存没有命中,数据库也没有数据,会给数据库造成很大的压力,这就是缓存穿透。 解决方案 第一种解决方案:使用布隆过滤器 使用布隆过滤器之后,将存储

quwenjing_blog 6319

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

redis设置database 不生效剖析

redis 设置database 不生效原因剖析

爱媳妇儿爱编程 6567

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Redis缓存三大坑:缓存击穿、缓存穿透和缓存雪崩——问题定位与解决方案全解析

在高并发缓存系统中,缓存击穿、缓存穿透和缓存雪崩是三个最常见的性能杀手。它们会导致大量请求直接打到数据库,造成数据库压力骤增甚至崩溃。本文将深入剖析这三种问题的成因、区别以及各自的解决方案,帮助你在实际项目中构建高可用的缓存架构。fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;否无数据用户请求缓存中有数据?查询数据库返回空恶意攻击。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 1878

Redis 缓存穿透、击穿、雪崩现象及解决方案

前言 如何有效的理解并且区分 Reids 穿透、击穿和雪崩 缓存穿透 关键词:穿过 Redis 和数据库 当 Redis 和数据库中都没有我们想要的数据时,就需要考虑缓存穿透的问题了。下面这段逻辑大家用的会比较多:先去 Redis 中查找某资源,Redis 中查不到就去 DB 中查,DB 中查到后回写一份数据到 Redis 中。 这段逻辑正常情况下问题并不大,但是如果用户恶意重复请求资源 X,该资源在 Redis 和 DB 中都不存在。那么每次请求都会直接打到 DB 上,甚至导致物理 DB 宕机。 解决方

Java流浪记 1万+

Redis更新缓存的正确姿势(先更新DB,再删除缓存)

1.更新缓存的三种模式 引入缓存势必会导致数据的一致性问题(因为分别存放到缓存以及DB),那么在数据更新时,缓存和DB都得更新,并且更新时序的不同会导致不同的结果。关于数据更新目前业界已经沉淀了Cache Aside Pattern,Read/Write through,Write Behind Caching等三种方式。 Cache Aside :同时更新缓存和数据库; Read/Write Through:先更新缓存,缓存负责同步更新数据库; ...

Java后端技术栈 7572

Redis缓存雪崩、缓存击穿终极解决方案:从原理到实战

缓存雪崩指在某一个时间段,大量缓存key同时过期或Redis服务宕机,导致所有请求直接打到数据库,瞬间将数据库压垮。缓存击穿指一个热点key在过期瞬间,同时有大量请求访问这个key,这些请求直接穿透缓存打到数据库。问题类型原因解决方案适用场景缓存雪崩大量key同时过期随机过期时间通用场景Redis宕机集群+本地缓存高可用要求永不过期+后台更新热点数据缓存击穿热点key过期互斥锁并发不高永不过期极高并发布隆过滤器防止穿透。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 887

Redis缓存穿透、缓存击穿、缓存雪崩详解及解决方案

1. 缓存穿透定义:请求查询不存在的数据,由于缓存未命中导致每次请求都要访问数据库,若恶意攻击或错误配置产生大量此类请求,将严重影响数据库性能。影响:增加数据库负担,降低系统整体性能,极端情况可能导致数据库崩溃。2. 缓存击穿定义:热点key在缓存过期的瞬间,同时受到大量请求,这些请求发现缓存未命中后都会转向数据库查询。影响:短时间内给数据库带来巨大压力,影响系统性能。3. 缓存雪崩定义:大量缓存同时过期,导致所有的请求都落到数据库上,数据库可能因此过载。影响。

lssffy的博客 1509

Redis100篇 - Redis面试场景题 怎么设计一个高可用的Redis缓存系统

本文摘要: Redis高可用缓存系统设计指南,从6大核心维度剖析高可用性要求,对比主从复制+哨兵、Redis Cluster、Proxy分片等4种主流架构方案。文章包含Mermaid架构图、容灾流程图,详细分析各方案优缺点及适用场景,推荐Redis Cluster作为大规模生产环境首选。提供Java代码实战示例,展示Lettuce连接Redis Cluster的配置方法,包含连接池优化、拓扑自动刷新等增强容错性的实现。最后给出8条生产验证的最佳实践,涵盖监控告警、容量规划、多级缓存等关键要素,帮助构建真正高

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

Redis缓存机制(详解)

redis是*一个运行在内存上的key-value存储系统。是NoSQL数据库之一。redis持久化的意义,在于故障恢复,数据恢复,也可以归类到高可用的一个环节里面去。线程模型,数据结构,持久化,网络模型。持久化,主从复制,哨兵机制。...

m0_71202849的博客 1万+

AI 辅助:Redis 高可用设计:缓存不是数据库的廉价替身

Redis 高可用设计要先明确数据定位。缓存可以降级和回源,关键状态则需要持久化、一致性和故障语义设计。把 Redis 当数据库替身,是很多线上事故的起点。

dicky_zhang3的博客 5898

Redis 的缓存雪崩、缓存穿透和缓存击穿详解,并提供多种解决方案

本文详细讲解了Redis在不同场景下为什么会出现缓存雪崩、缓存穿透和缓存击穿的问题,并对每一种问题做出了详细解释,给出了多种解决方案。本文用于学习记录,还存在许多不足之处,会在后续持续更新。

青灯文案的博客 1897

一文彻底搞懂Redis中缓存穿透,缓存击穿和缓存雪崩的区别以及解决方案

缓存击穿指的是数据库有数据,缓存本应该也有数据,但是缓存过期了,Redis 这层流量防护屏障被击穿了,请求直奔数据库。缓存穿透指的是数据库本就没有这个数据,请求直奔数据库,缓存系统形同虚设。缓存雪崩指的是大量的热点数据无法在 Redis 缓存中处理(大面积热点数据缓存失效、Redis 宕机),流量全部打到数据库,导致数据库极大压力。

永远在路上 2702
上一篇: redis缓存数据库详解(五):分布式锁的实现
下一篇: mysql数据库详解(一):sql语句
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值