Redis进阶(集群,雪崩,击穿,穿透.......)

news2024/11/27 17:40:13

Redis进阶

Redis事务_事务的概念与ACID特性

Redis的事物不保证原子性

数据库层面事务

在数据库层面,事务是指一组操作,这些操作要么全都被成功执行,要么全都不执行。

数据库事务的四大特性

A:Atomic,原子性,将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行;

C:Consistent,一致性,事务完成后,所有数据的状态都是一致的,即A账户只要减去了100,B账户则必定加上了100;

I:Isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离;

D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。

Redis事务

Redis事务是一组命令的集合,一个事务中的所有命令都将被序列化,按照一次性、顺序性、排他性的执行一系列的命令。

Redis事务三大特性

1. 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断;

2. 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”。

3. 不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

Redis事务执行的三个阶段:

 开启:以 MULTI 开始一个事务;

入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面;

执行:由 EXEC 命令触发事务;

Redis事务基本操作:

 Multi、Exec、discard 事务从输入Multi命令开始,输入的命令都会依次压入命令缓冲队列中,并不会执行,直到输入Exec后, Redis会将之前的命令缓冲队列中的命令依次执行。组队过程中,可以通过discard来放弃组队。

下面进行命令的执行操作

正常的事物的操作

 不正常的操作:取消事物操作(discard

 还有一种情况如果我们操作语法不当,会造成事物中的所有操作都失败:

 还有一种情况是在整个事物中哪一个命令出错哪个命令不能执行成功

注意:运行时错误,即非语法错误,正确命令都会执行,错误命令返回错误

 Redis集群_Cluster模式概述:

Redis有三种集群模式

主从模式

Sentinel模式

Cluster模式

哨兵模式的缺点:

缺点:

当master挂掉的时候,sentinel 会选举出来一个 master,选举的时候是没有办法去访问Redis的,会存在访问瞬断的情况;

哨兵模式,对外只有master节点可以写,slave节点只能用于读。尽管Redis单节点最多支持10W的QPS,但是在电商大促的时候,写数据的压力全部在master上;

Redis的单节点内存不能设置过大,若数据过大在主从同步将会很慢;在节点启动的时候,时间特别长;

Cluster模式概述:

Redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性

Redis集群的优点

Redis集群有多个master,可以减小访问瞬断问题的影响

Redis集群有多个master,可以提供更高的并发量 

Redis集群可以分片存储,这样就可以存储更多的数据

Redis集群_Cluster模式搭建

 Redis的集群搭建最少需要3个master节点,我们这里搭建3个master,每个下面挂一个slave节点,总 共6个Redis节点;

环境准备:

第1台机器:192.168.205.130 8001端口 8002端口

第2台机器:192.168.205.129 8001端口 8002端口

第3台机器:192.168.205.131 8001端口 8002端口

我们先在第1台机器上进行操作即可,然后我们克隆服务器过去就可以了

在目录/usr/local下上传我们redis文件redis-6.2.6.tar.gz

通过rz命令上传

然后我们通过 tar –zxvf redis-6.2.6.tar.gz 对redis文件进行解压缩

如果没有安装gcc先安装yum install gcc

进入到redis的目录cd redis-6.2.6/

使用make命令进行安装

安装完成抽使用mv命令进行移动:

mv redis-6.2.6 redis  把文件移动到redis中

然后创建文件夹:

mkdir -p /usr/local/redis/redis-cluster/8001 /usr/local/redis/redis-cluster/8002

拷贝配置文件

将redis安装目录下的 redis.conf 文件分别拷贝到8001目录下

cp /usr/local/redis/redis.conf /usr/local/redis/redis-cluster/8001

修改redis.conf文件以下内容

port 8001

daemonize yes

pidfile "/var/run/redis_8001.pid"

#指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据

dir /usr/local/redis/redis-cluster/8001/

#启动集群模式

cluster-enabled yes

#集群节点信息文件,这里800x最好和port对应上

cluster-config-file nodes-8001.conf

# 节点离线的超时时间

cluster-node-timeout 5000

#去掉bind绑定访问ip信息

#bind 127.0.0.1

#关闭保护模式

protected-mode no

#启动AOF文件

appendonly yes

#如果要设置密码需要增加如下配置:

#设置redis访问密码

#requirepass 123

#设置集群节点间访问密码,跟上面一致

#masterauth 123

对上面内容挨个搜索进行修改,修改完成后保存并退出即可

文件拷贝到8002文件夹

cp /usr/local/redis/redis-cluster/8001/redis.conf  /usr/local/redis/redis-cluster/800

进入到8002目录修改redis.conf

我在配置文件中进行全局修改即可

在编辑模式下输入:%s/8001/8002/g

然后保存并退出即可

然后我们把防火墙全部关闭掉即可:

systemctl stop firewalld.service

systemctl disable firewalld.service

操作完成后我们先把第1台服务器关机进行克隆操作,然后我们同时启动就可以了

我们进入到redis目录的src目录进行启动

在xshell中的左下角有个全部回话同时发布命令操作3台服务器启动redis即可

操作:

cd  etc 

vim   hostname   //修改名

下面所有命令都要进行全部会话操作

首先进入到src目录,然后输入下面的命令

 输入命令:

启动8001

./redis-server ../redis-cluster/8001/redis.conf

启动8002

./redis-server ../redis-cluster/8002/redis.conf

查看3台服务器的redis是否运行:

  至此我们的环境基本准备完成

当然我们在准备环境的时候也可以进行把文件拷贝的操作第1台服务的redis拷贝到第2台和第3台服务

# 第二台机器

scp /usr1/redis/redis-cluster/8001/redis.conf

root@192.168.205.129:/usr1/redis/redis-cluster/8001/

scp /usr1/redis/redis-cluster/8002/redis.conf

root@192.168.205.129:/usr1/redis/redis-cluster/8002/

# 第三台机器

scp /usr1/redis/redis-cluster/8001/redis.conf

root@192.168.205.131:/usr1/redis/redis-cluster/8001/

scp /usr1/redis/redis-cluster/8002/redis.conf

root@192.168.205.131:/usr1/redis/redis-cluster/8002/

换上自己的ip

然后通过命令构建集群

注意:这里一定要把 hostname下的主机名称改掉否则不能构建集群

在第一台服务器上进行操作:

在src目录下完成

完整写法

./redis-cli -a 123 --cluster create --cluster-replicas 1 192.168.205.130:8001 192.168.205.130:8002 192.168.205.129:8001 192.168.205.129:8002 192.168.205.131:8001 192.168.205.131:8002

不需要密码写法

./redis-cli --cluster create --cluster-replicas 1 192.168.205.130:8001 192.168.205.130:8002 192.168.205.129:8001 192.168.205.129:8002 192.168.205.131:8001 192.168.205.131:8002

回车即可:

 输入yes即可

 说明集群创建成功

下面我们进入客户端,输入命令:

./redis-cli -c -h 192.168.205.130 -p 8001

 查看集群状态:cluster info命令、

 Redis集群_Cluster模式原理分析:

Redis Cluster将所有数据划分为16384个slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储 于每个节点中。只有master节点会被分配槽位,slave节点不会分配槽位。

PS:

槽位定位算法: k1 = 127001

 Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。

HASH_SLOT = CRC16(key) % 16384

槽位主要是负责把数据保存到哪里服务集群中,或者提取数据时去哪个槽位中去获取数据从而分摊了服务器器的压力

在我们插入数据的时候就会返回我们插入数据所对应的槽位数据

如添加数据 set k1 v1

根据k1计算出的槽值进行切换节点,并存入数据。不在一个slot下的键值,是不能使用mget、 mset等多建操作。

我们可以通过{}来定义组的概念,从而是key中{}内相同内容的键值对放到同一个slot中。

mset k1{test} v1 k2{test} v2 k3{test} v3

故障恢复

查看节点:

192.168.205.131:8001> cluster nodes

 我们看到上面的节点中有3台master和3台slave节点

比如我们现在想要一个干掉一个主节点,看看他是否给我们在找一个主节点:

Ctrl + c 退出客户端

输入命令lsof -i:8001

 输入命令:kill -9 17696

然后切换到第2台服务器输入命令再次进入客户端: ./redis-cli -c -h 192.168.205.129 -p 8001

输入命令:cluster info

 输入命令:cluster nodes

 Redis集群_Java操作Redis集群

 创建项目:

 Jedis整合Redis

引入jedis的maven坐标:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.vv.demo</groupId>
    <artifactId>springredistest</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>
</project>

代码进行测试:

package com.vv.demo;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class springredistest {
    public static void main(String[] args) throws IOException {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(10);
        config.setMinIdle(5);
        Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
        jedisClusterNode.add(new HostAndPort("192.168.205.131", 8001));
        jedisClusterNode.add(new HostAndPort("192.168.205.129", 8002));
        jedisClusterNode.add(new HostAndPort("192.168.205.130", 8001));
        JedisCluster jedisCluster = null;
        try {
            //connectionTimeout:指的是连接一个url的连接等待时间
            //soTimeout:指的是连接上一个url,获取response的返回等待时间
            //SpringBoot 整合 Redis 引入maven坐标
            //配置文件 java代码
            jedisCluster = new JedisCluster(jedisClusterNode, 6000, 5000, 10, config);
            System.out.println(jedisCluster.set("name", "admin"));
            System.out.println(jedisCluster.get("name"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedisCluster != null) {
                jedisCluster.close();
            }
        }
    }
}

 SpringBoot 整合 Redis

 引入坐标:

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

application.properties:

##单服务器
spring.redis.cluster.nodes=192.168.205.129:8001,192.168.205.129:8002,192.168.205.132:8001,192.168.205.132:8002,

192.168.205.133:8001,192.168.205.133:8002
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=300
## Redis数据库索引(默认为0)
spring.redis.database=0
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
## 连接池中的最大空闲连接
spring.redis.pool.max-idle=100
## 连接池中的最小空闲连接
spring.redis.pool.min-idle=20
## 连接超时时间(毫秒)
spring.redis.timeout=60000

创建controller进行测试即可:

package com.vv.demo.controller;

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;

@RestController
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @RequestMapping("/test_cluster")
    public void testCluster() throws InterruptedException {
        redisTemplate.opsForValue().set("user:name", "admin");
        System.out.println(redisTemplate.opsForValue().get("user:name"));
    }
}

 

Redis企业级解决方案_Redis脑裂:

什么是Redis的集群脑裂

Redis的集群脑裂是指因为网络问题,导致Redis Master节点跟Redis slave节点和Sentinel集群处于不同

的网络分区,此时因为sentinel集群无法感知到master的存在,所以将slave节点提升为master节点。

 注意:

此时存在两个不同的master节点,就像一个大脑分裂成了两个。集群脑裂问题中,如果客户端还在基于原来的master节点继续写入数据,那么新的Master节点将无法同步这些数据,当网络问题解决之后,sentinel集群将原先的Master节点降为slave节点,此时再从新的master中同步数据,将会造成大量的数据丢失。

解决方案 redis.conf配置参数:

min-replicas-to-write 1

min-replicas-max-lag 5

参数:

第一个参数表示最少的slave节点为1个

第二个参数表示数据复制和同步的延迟不能超过5秒

配置了这两个参数:如果发生脑裂原Master会在客户端写入操作的时候拒绝请求。这样可以避免大量数据丢失。

Redis企业级解决方案_缓存预热

缓存冷启动:

缓存中没有数据,由于缓存冷启动一点数据都没有,如果直接就对外提供服务了,那么并发量上来 Mysql就裸奔挂掉了。

 

缓存冷启动场景:

新启动的系统没有任何缓存数据,在缓存重建数据的过程中,系统性能和数据库负载都不太好,所以最 好是在系统上线之前就把要缓存的热点数据加载到缓存中,这种缓存预加载手段就是缓存预热。

 解决思路:

提前给redis中灌入部分数据,再提供服务如果数据量非常大,就不可能将所有数据都写入redis,因为数据量太大了,第一是因为耗费的时间太长了,第二根本redis容纳不下所有的数据需要根据当天的具体访问情况,实时统计出访问频率较高的热数据然后将访问频率较高的热数据写入redis中,肯定是热数据也比较多,我们也得多个服务并行数据去写,并行的分布式的缓存预热

Redis企业级解决方案_缓存穿透: 

 概念

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

 

解释:

缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时 候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查 询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。

解决方案

1. 对空值缓存:如果一个查询返回的数据为空(不管数据是否存在),我们仍然把这个空结果缓存,设置空结果的过期时间会很短,最长不超过5分钟。

2. 布隆过滤器:如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定。

布隆过滤器

什么是布隆过滤器

布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效 地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。【可以处理上亿甚至几十亿的数据】

 

注意:

布隆说不存在一定不存在,布隆说存在你要小心了,它有可能不存在

代码实现:

引入hutool包:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.17</version>
</dependency>

测试:

package com.vv.demo;
import cn.hutool.bloomfilter.BitMapBloomFilter;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootredistestApplicationTests {
    @Test
    void contextLoads() {
        // 初始化 注意 构造方法的参数大小10 决定了布隆过滤器BitMap的大小
        BitMapBloomFilter filter = new BitMapBloomFilter(10);
        filter.add("123");
        filter.add("abc");
        filter.add("ddd");
        boolean abc = filter.contains("abc123");
        System.out.println(abc);
    }
}

Redis企业级解决方案_缓存击穿

 概念

某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最 终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。

 解决方案

1. 互斥锁:在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,其他线程直接查询缓存。

 2. 热点数据不过期:直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存

 代码实现:

private Jedis jedis;

/**
 * 初始化jedis实列
 */
@Before
public void init() {
    // 创建redis连接实列
    jedis = new Jedis("192.168.205.130", 6379);
}


@Test
public String lock(String key) throws InterruptedException {
    //首先获取数据
    String value = jedis.get(key);
    // 缓存过期
    if (value == null){

        //setnx命令只有key不存在的时候我们才去创建这个key
        Long setnx = jedis.setnx(key + "mutex", "1");
        // 设置3分钟超时,防止删除操作失败的时候 下一次缓存不能load db
        jedis.pexpire(key + "mutex", 3 * 60);
        // 代表设置成功,我们才准许它对数据库进行操作
        if (setnx == 1){
            // 数据库查询
            //value = db.get(key);
            //这里模拟个假的数据
            value= "aaaaaaa";
            //保存缓存
            jedis.setex(key,3*60,value);

            //为了让其他线程不阻塞我们要把key干掉
            jedis.del(key + "mutex");
            return value;
        }else {
            // 这个时候代表同时操作的其他线程已经load db并设置缓存了。 需要重新重新获取
            Thread.sleep(50);
           // 重试进行递归调用操作
            return lock(key);
        }
    }else {
        return value;
    }
}

Redis企业级解决方案_缓存雪崩

概念

缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。

缓存正常从Redis中获取,示意图如下:

 缓存失效瞬间示意图如下:

 

解决方案

过期时间打散:既然是大量缓存集中失效,那最容易想到就是让他们不集中失效。可以给缓存的过期时间时加上一个随机值时间,使得每个 key 的过期时间分布开来,不会集中在同一时刻失效。

热点数据不过期:该方式和缓存击穿一样,也是要着重考虑刷新的时间间隔和数据异常如何处理的情况。

加互斥锁: 该方式和缓存击穿一样,按 key 维度加锁,对于同一个 key,只允许一个线程去计算, 其他线程原地阻塞等待第一个线程的计算结果,然后直接走缓存即可。

加锁排队代码如下:

public Object GetProductListNew(String cacheKey) {
    int cacheTime = 30;
    String lockKey = cacheKey;
    // 获取key的缓存
    String cacheValue = jedis.get(cacheKey);
    // 缓存未失效返回缓存
    if (cacheValue != null) {
        return cacheValue;
    } else {
        // 枷锁
        synchronized(lockKey) {
            // 获取key的value值
            cacheValue = jedis.get(cacheKey);
            if (cacheValue != null) {
                return cacheValue;
            } else {
                //这里一般是sql查询数据
                // db.set(key)
                // 添加缓存
                jedis.set(cacheKey,"");
            }
        }
        return cacheValue;
    }
}

 

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

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

相关文章

Docker笔记5 | 容器的基本操作

5 | 容器的基本操作 1 启动容器1.1 启动方式1.2 新建容器并启动1.3 docker run时的运行过程1.4 启动已终止容器1.5 后台运行1.6 查看容器信息 2 终止容器3 进入容器3.1 docker attach3.2 docker exec 4 导入导出容器4.1 导出容器4.2 导入容器 5 删除容器 1 启动容器 1.1 启动方…

Linux内核主要组成部分有哪些?

Linux 内核由几大子系统构成&#xff0c;分别为进程调度、进程间通信&#xff08;IPC&#xff09; 、内存管理、虚拟 文件系统和网络接口。这几大子系统既相互独立又有非常紧密的关联。图 3-5 展示了内核的 几大子系统之间以及这些子系统和计算机系统的其他模块之间的关系。 接…

ADS-B教学实验方案

ADS-B教学系统是为了让学生学习ADS-B原理、ADS-B系统组成、ADS-B信号处理技术。可以通过ADS-B教学系统进一步研究分析ADS-B位置的精度、准确性、稳定性、实时性&#xff0c;设计基于ADS-B的空中碰撞告警系统&#xff0c;混合空域的空中交通管理系统(UTM)设计。也可以研究ADS-B报…

《花雕学AI》你不知道的AI 机器人:29个让你大开眼界的事实

AI 机器人是人工智能技术的最具代表性的应用之一&#xff0c;它们可以模仿人类的行为和思维&#xff0c;完成各种复杂的任务&#xff0c;如识别图像、语音和文字&#xff0c;进行对话、翻译和推理&#xff0c;控制机械臂、汽车和飞机等。AI 机器人的发展速度令人惊叹&#xff0…

Windows命令提示行使用指南二(批处理)

命令提示行使用指南 前言四、批处理简介五、如何编写批处理1、Hello world2、做加法3、查找文件&#xff0c;并输出到文本。4、批量重命名5、自动记录开机时间 前言 cmd 是 Windows 操作系统中的命令行界面&#xff08;CLI&#xff09;&#xff0c;也称为命令提示符&#xff0…

Linux shell编程 数组排序算法

冒泡排序 循环对比相邻的元素&#xff0c;交换较大元素到后面的位置 大循环根据列表中存在的元素数量循环n-1次&#xff0c;保证所有元素都能被排序完成 小循环从前向后遍历&#xff0c;循环一次循环范围减少一位&#xff08;由于后面的已经排列完成无需再比较&#xff09;小循…

【halcon知识】应用仿射变换

一、说明 无论什么样的变换&#xff0c;都离不开齐次变换矩阵。一般地&#xff0c;先准备一个空的齐次变换矩阵&#xff0c;这个矩阵随便填写&#xff1a;1&#xff09;填入旋转类参数就是旋转矩阵&#xff0c;2——填入仿射参数就可进行仿射变换&#xff0c;3&#xff09;填入…

Kali-linux攻击WordPress和其他应用程序

今天越来越多的企业利用SAAS&#xff08;Software as a Service&#xff09;工具应用在他们的业务中。例如&#xff0c;他们经常使用WordPress作为他们网站的内容管理系统&#xff0c;或者在局域网中使用Drupal框架。从这些应用程序中找到漏洞&#xff0c;是非常有价值的。 为…

[JAVA数据结构]堆

目录 1.堆的概念 2.堆的创建 3.堆的插入与删除 3.1堆的插入 3.2堆的删除 1.堆的概念 如果有一个关键码的集合K {k0&#xff0c;k1&#xff0c; k2&#xff0c;…&#xff0c;kn-1}&#xff0c;把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中&#xff0c;…

【Linux】远程桌面连接服务器报错:未启用对服务器的远程访问......

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 文章目录 前述操作环境说明&#xff1a;远程报…

<数据结构>NO4.带头双向循环链表

文章目录 前言1. 头文件2. 函数实现1&#xff09;创建哨兵位节点2&#xff09;新增一个节点3&#xff09;打印链表4&#xff09;头插5&#xff09;尾插6&#xff09;头删7&#xff09;尾删8&#xff09;查找9&#xff09;pos前插入10&#xff09;删除pos处节点11&#xff09;销…

Redis 缓存穿透、缓存击穿与缓存雪崩

文章目录 1. 缓存穿透解决方法 2. 缓存击穿解决方法 3. 缓存雪崩解决方法 在 redis 的应用场景中&#xff0c;需要考虑缓存在某些场景下可能出现的问题&#xff1a; 缓存穿透 缓存击穿 缓存雪崩 以下缓存问题的讨论都是基于以下应用架构讨论的&#xff1a; 1. 缓存穿透 对应…

数据备份系列:Rsync 备份实战记录(二)

一、Rsync Cron 场景使用 在对数据备份要求实时性不高的情况下&#xff0c;可优先考虑该场景&#xff0c;选择一个合适的时间&#xff0c;对数据进行定时远程增量同步。 在《数据备份系列&#xff1a;Rsync 备份详解&#xff08;一&#xff09;》中我们已经对服务搭建以及远程…

DAD-DAS模型

DAD-DAS模型 文章目录 DAD-DAS模型[toc]1 产品服务:需求方程2 实际利率:费雪方程3 通货膨胀:菲利普斯方程4 预期通货膨胀&#xff1a;适应性预期5 货币政策规则&#xff1a;泰勒方程6 动态总供给-总需求方程&#xff08;DAS-DAD&#xff09;7 总供给冲击模拟 1 产品服务:需求方…

【JavaEE初阶】文件操作——IO

摄影分享~ 文章目录 文件文件路径&#xff08;Path&#xff09; 文件的类型Java中操作文件File概述 文件内容的读写——数据流字节流InputStream概述OutputStream 概述字符流FileInputStream 概述利用 Scanner 进行字符读取 实例练习 文件 文件&#xff1a;File这个概念&…

PostSQL内存管理之内存上下文

瀚高数据库 目录 环境 文档用途 详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;14 文档用途 了解pg内存分配 详细信息 1.MemoryContex机制 内存上下文是pg相关的内存控制结构&#xff0c;树形结构组织下的内存上下文能在频繁的…

SNMPc软件的下载和安装教程,计算机网络管理,网络工程师

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;(*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &am…

vue 改变数据后,数据变化页面不刷新

文章目录 导文文章重点方法一&#xff1a;使用this.$forceUpdate()强制刷新方法二&#xff1a;Vue.set(object, key, value)方法三&#xff1a;this.$nextTick方法四&#xff1a;$set方法 导文 在vue项目中&#xff0c;会遇到修改完数据&#xff0c;但是视图却没有更新的情况 v…

让开发者成为创新主体 | 阿里云云原生4月动态

作者&#xff1a;云原生内容小组 云原生月度动态 ✦ 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》&#xff0c;从趋势热点、产品新功能、服务客户、开源与开发者动态等方面&#xff0c;为企业提供数字化的路径与指南。 本栏目每月更新。 01 趋势热点 &…

vue - 实现登录后用户无操作后自动退出登录功能,当用户鼠标不动、键盘不动、无窗口滚动时自动清除登录状态(可自定义删减条件,详细示例源码一键复制开箱即用)

需求 很多教程都是无效而且有bug。。很难用索性自己搞了最健壮的解决方案。 在vue项目中,实现自动检测用户没有【移动鼠标】【操作键盘】【窗口滚动】时,自动清除登录信息强制退出登录下线,支持自定义触发时间(比如无操作10分钟就执行),自定义条件(比如只监听用户鼠标是…