Redis

配置:

两种持久化机制:

RDB

RDB (Redis Database)

# save 秒  写请求
save 900 1 #当有一条 Keys 数据被改变时,900 秒刷新到 Disk 一次
save 300 10 #当有 10 条 Keys 数据被改变时,300 秒刷新到 Disk 一次
save 60 10000 #当有 10000 条 Keys 数据被改变时,60 秒刷新到 Disk 一次

AOF

AOF (Append Only File)

#启用 AOF 持久化方式
appendonly yes
#AOF 文件的名称,默认为 appendonly.aof
appendfilename appendonly.aof 
#每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。
# appendfsync always 
#每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。
appendfsync everysec 
#完全依赖 OS 的写入,一般为 30 秒左右一次,性能最好但是持久化最没有保证,不被推荐。
# appendfsync no

常见问题:

redis 链接不上的一个原因:

使用缺省的链接库lettuce会有链接不上的情况,出现这种情况时可以改用jedis库,如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

穿透

定义

被访问的数据不存在,导致每次请求得数据都不能在缓存中找到,导致请求都要到数据库里。 最终导致数据库压力过大。

解决方案

每次从数据库中读不到的数据,都在缓存里存放一个空对象。一般要设置一个过期时间, 以防止以后某个时间对应的数据又有了。

击穿

定义

某个非常热点的数据在key失效的瞬间,导致大量的请求直接到了数据库。

解决方案

  • 基于redis或zookeeper实现互斥锁
  • 将热点数据设置为永不过期
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;      
    }
}

雪崩

定义

雪崩在不同的语境里有不同的内涵,在redis这里的雪崩就是大量热点数据过期,导致大部分缓存数据 在redis层失效,请求直接到数据库层,进而导致数据库压力堵塞甚至宕机。

解决方案

  • 缓存过期时间分散化
  • 热点数据均匀分布到不同的redis和数据库 (业务不一定允许)
  • 多级缓存 ehcache + redis

redis 和 mysql 保持一致

延时双删
后删除,失败再由MQ的重试机制重复删除。
canal 读取binlog再同步到redis。

修改密码

    # 如果是docker,则需要进入docker内部
    docker exec -it myredis redis-cli;
    # 查询当前密码
    config get requirepass
    # 设置密码 your_password 替换成你自己的密码
    config set requirepass your_password

参考:

[canal:]( https://zhuanlan.zhihu.com/p/177001630)