一、初见面

安装

https://github.com/microsoftarchive/redis/releases

windows报错

window下安装redis或启动报错:
creating server tcp listening socket 127.0.0.1:6379: bind No error

的解决方案如下按顺序输入如下命令就可以连接成功

  1. redis-cli.exe
  2. shutdown
  3. exit
  4. redis-server.exe redis.windows.conf

linux

解压 tar -zxvf,存放在opt目录

基本环境安装

yum install gcc-c++

gcc -v

make

make install

默认路径

/usr/local/bin

UTOOLS1589000015651.png

conf修改为

daemonize yes 后台启动

redis-server myConfig/redis.conf 使用该配置文件启动

redis-cli -p 6379 启动

ps -ef | grep redis是否启动

shutdown关闭

使用

redis-cli.exe -h 127.0.0.1 -p 6379

启动:
redis-server.exe redis.windows.conf
设置环境变量后启动:
redis-server.exe
本地启动:
redis-cli
使远程用:
redis-cli.exe -h 127.0.0.1 -p 6379 -a mima

使用

java

连接


import redis.clients.jedis.Jedis;

public class RedisJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
        //查看服务是否运行
        System.out.println("服务正在运行: "+jedis.ping());
    }
}

String

import redis.clients.jedis.Jedis;

public class RedisStringJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
        //设置 redis 字符串数据
        jedis.set("runoobkey", "www.runoob.com");
        // 获取存储的数据并输出
        System.out.println("redis 存储的字符串为: "+ jedis.get("runoobkey"));
    }

list


import java.util.List;
import redis.clients.jedis.Jedis;

public class RedisListJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
        //存储数据到列表中
        jedis.lpush("site-list", "Runoob");
        jedis.lpush("site-list", "Google");
        jedis.lpush("site-list", "Taobao");
        // 获取存储的数据并输出
        List<String> list = jedis.lrange("site-list", 0 ,2);
        for(int i=0; i<list.size(); i++) {
            System.out.println("列表项为: "+list.get(i));
        }
    }
}

set


import java.util.Iterator;
import java.util.Set;
import redis.clients.jedis.Jedis;

public class RedisKeyJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");

        // 获取数据并输出
        Set<String> keys = jedis.keys("*"); 
        Iterator<String> it=keys.iterator() ;   
        while(it.hasNext()){   
            String key = it.next();   
            System.out.println(key);   
        }
    }
}

测试性能

redis-benchmark

序号 选项 描述 默认值
1 -h 指定服务器主机名 127.0.0.1
2 -p 指定服务器端口 6379
3 -s 指定服务器 socket
4 -c 指定并发连接数 50
5 -n 指定请求数 10000
6 -d 以字节的形式指定 SET/GET 值的数据大小 2
7 -k 1=keep alive 0=reconnect 1
8 -r SET/GET/INCR 使用随机 key, SADD 使用随机值
9 -P 通过管道传输 请求 1
10 -q 强制退出 redis。仅显示 query/sec 值
11 –csv 以 CSV 格式输出
12 -l 生成循环,永久执行测试
13 -t 仅运行以逗号分隔的测试命令列表。
14 -I Idle 模式。仅打开 N 个 idle 连接并等待。

redis-benchmark -h localhost -p 6379 -c 100 -n 100000

UTOOLS1589001505299.png

简介

redis是单线程的

基于内存操作,瓶颈是机器的内存和网络带宽

c语言编写,100000+QPS,不比memecache

为何那么快?

  1. 误区:高性能服务器就是高线程的
  2. 误区:多线程一定比单线程效率高

核心:

redis将所有数据都放在内存中,单线程不需要上下文切换,

php扩展

https://blog.csdn.net/qq_32142513/article/details/82804193

yum -y install gcc gcc-c++ libxml2 libxml2-devel bzip2 bzip2-devel libmcrypt libmcrypt-devel openssl openssl-devel libcurl-devel libjpeg-devel libpng-devel freetype-devel readline readline-devel libxslt-devel perl perl-devel psmisc.x86_64 recode recode-devel libtidy libtidy-devel  epel-release libmcrypt-devel

redis

[root@localhost php]# cd /root/software/
[root@localhost software]# wget http://pecl.php.net/get/redis-3.1.3.tgz
[root@localhost software]# tar zxvf redis-3.1.3.tgz
[root@localhost software]# cd redis-3.1.3

生成configure php安装目录下的phpize文件

/usr/bin/phpize

执行configure,使用php-config

./configure --with-php-config=/usr/bin/php-config

编译安装

make
make install

查看

php -m | grep redis

添加扩展

vim /etc/php.ini

extension=redis.so

重启php-fpm

# ps aux | grep php-fpm | grep master | grep -v grep
root     13225  0.0  0.0 204820  7508 ?        Ss   09:37   0:01 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
kill -USR2 13225  

二、语法

命令

连接

redis-cli 连接本地

ping 检测是否启动

redis-cli -h host -p port -a password 连接远程

dbsize查看db大小

select n 切换数据库

keys * 查看所有的key

flushdb 清空当前数据库

flushall 清空所有数据库

键redis-key

格式 command key_name

设置 set name ming

删除 del name

命令 描述
del key 删除 key
dump key 序列化给定 key ,并返回被序列化的值
exists key 检查给定 key 是否存在
expire key seconds 为给定 key 设置过期时间,以秒计
expireat key timestamp 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计
keys pattern 查找所有符合给定模式( pattern)的 key
move key db 将当前数据库的 key 移动到给定的数据库 db 当中。
persist key 移除key的过期时间,key永久保持
pttl key 以毫秒为单位返回 key 的剩余的过期时间
ttl key 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)
randomkey 从当前数据库中随机返回一个 key
rename key newkey 修改 key 的名称
type key 返回 key 所储存的值的类型

字符串String

除了字符串,还能是数字

  • 计数器

  • 阅读量

    粉丝数

  • 对象缓存存储

set name ming

get name

命令 描述
set key value 设置指定 key 的值
get key 获取指定 key 的值。
getrange key start end 返回 key 中字符串值的子字符
getset key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
getbit key offset 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
mget key1 [key2…] 获取所有(一个或多个)给定 key 的值。
setbit key offset value 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
setex key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
setnx key value 只有在 key 不存在时设置 key 的值。set lock 1 EX 300 NX,设置锁和过期时间
setrange key offset value 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。
strlen key 返回 key 所储存的字符串值的长度。
mset key value [key value] 同时设置一个或多个 key-value 对。
msetnx key value [key value] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在,同时
psetex key millseconds value 以毫秒为单位设置 key 的生存时间
incr key 将 key 中储存的数字值增一。
incrby key increment 将 key 所储存的值加上给定的增量值(increment) 。
incrbyfloat key increment 将 key 所储存的值加上给定的浮点增量值(increment) 。
decr key 将 key 中储存的数字值减一。
decrby key decrement key 所储存的值减去给定的减量值(decrement) 。
append key value 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。
mset user:1:name mingyue user:1:age 20
#对象
set user:1 {name:ming,age:3}

列表List

栈、队列、阻塞队列

list命令l开头

Redis 列表命令

下表列出了列表相关的基本命令:

命令 解释
lpush key value 插入列表头部(左)
rpush key value 插入尾部(右)
lrange key begin end lrange key 0 -1
lpop 返回并移除左边第一个
rpop
lindex key offset 获取key中n的值
llen key 获取长度
lrem key number value 删除number个 key中的value
ltrim begin end 通过下标截取指定位置的list,会修改
rpoplpush key newkey 移除列表中最后一个元素移动到新list
lset key index value 在index设置为value,不存在列表就报错
linsert key after|before value [value]

集合set

无序、不能重复

命令 解释
sadd key value
smemebers key 获取集合元素
sismember key value 返回1,0
scard key 获取set集合中元素个数
srem key value 移除value
srandmember key 随机获取一个
spop key 随机移除并返回一个
smove key newkey value
sdiff key1 key2 a、b差集
sinter key1 key2 a、b交集 (共同好友)
sunion key1 key2 a、b并集

哈希hash

和string没有很大区别,map集合

适合对象(用户信息)存储

key field value

命令 解释
hset key field value 添加
hget key field 获取
hmset key field value [field value]
hmget key field [field]
hgetall key 获取所有
hdel key field 删除
hlen 长度
hexists key field 判断
hkeys/hvalues key 获取键值
hincr key field
hincrby key field n
hsetnx key field value 不存在则添加

有序集合zset

在set上添加排序,排行榜

命令 解释
zadd key score value [score value]
zrange key begin end 获取所有
zrangebyscore key min max 【withscores】 排序 -inf无穷小
zrerangebyscore key
zrem key value 删除
zcard keys 获取个数
zrerange key 0 -1 从大到小排序
zcount key min max 获取指定区间的数量

三、特殊的数据类型

geospatical地理位置

朋友定位,附近的人,打车

zset,zrange key 0 -1

zrem,zrem key value

命令 解释
geoadd key value(经度、纬度、名称)
geopos key value [value]
geodist key value1 value2 单位(km/m/mi/ft) 两地距离
georadius key 经 纬 dist 单位 withdist[with coord] [count n] 点的半径范围内的
georadiusbymember key value dist 单位(km/m/mi/ft) 城市半径范围内的
geohash key value[value] 将经纬度转换为字符串

hyperloglog

目的,计数,0.81%的错误率,12kb

命令 解释
pfadd key value [value]
pfcount key
pfmerge newkey key1 key2 合并不同的

bitmaps

位存储

打卡

命令 解释
setbit key offset value
getbit key offset
bitcount key [start end]

四、事务

ACID:原子性,一致性,隔离性,持久性

redis单条命令原子,事务不保证原子,redis事务没有隔离级别的概念

事务:一组命令的集合,一个事务的命令都会被序列化,在执行过程中,会顺序执行

redis事务

  • 开启事务(multi)

  • 命令入队()

  • 执行事务(exec)

  • 放弃事务(discard)

编译错误,全部不执行,部分错误,接着执行

五、锁

悲观锁

全部加锁

乐观锁

  • 不上锁,更新数据时判断是否有人修改过该数据

  • 获取version

  • 更新时比较version

监视

watch key 使用watch当做乐观锁操作,运行完之前,key的值被修改了就会失败

multi

exec

unwatch

事务运行失败后先unwatch重新运行

六、jedis

官方推荐java操作redis

空项目–》meaven

修改3个java版本8

UTOOLS1589020739879.png

UTOOLS1589020765443.png

UTOOLS1589020792513.png

导入jedis包

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.2.0</version>
</dependency>
<!--json-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

步骤

//1. new jedis对象
Jedis jedis = new Jedis("127.0.0.1", 6379);
//方法基本一致
System.out.println(jedis.ping());
jedis.close();

常用API

String/List/Set/Hash/Zset

package com.ming;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class TestPing {
    public static void main(String[] args) {
        //1. new jedis对象
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.flushDB();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("hello", "world");
        jsonObject.put("name", "mingming");
        Transaction multi = jedis.multi();
        String result = jsonObject.toJSONString();
        jedis.watch(result);
        try{
            multi.set("user1", result);
            multi.set("user2", result);
            multi.exec();
        }catch(Exception e){
            multi.discard();
            e.printStackTrace();
        }finally{
            System.out.println(jedis.get("user1"));
            System.out.println(jedis.get("user2"));
            System.out.println(jedis.ping());
            jedis.close();
        }

    }
}

七、Redis.conf

  1. 配置文件单位对大小写不敏感

  2. 包含.conf

  3. 网络

    1. bind 127.0.0.1 绑定ip
    2. protected-mode yes 保护模式
    3. port 6379 端口

通用

daemonize yes #以守护进程方式运行,默认为no

pidfile /var/run/redis_6379.pid #以后台方式运行,需要指定pid文件

#日志
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
logfile "" #日志文件位置名
databases 16
always-show-logo yes

快照

持久化,在规定时间内自行了多少次操作则会持久化到文件 .rdb rdf

redis是内存数据库,如果没有数据库,断电即失

save 900 1  # 900s内,有一个key进行了修改,则进行持久化
save 300 10
save 60 10000

stop-writes-on-bgsave-error yes #持久化如果出错,是否继续工作

rdbcompression yes #是否压缩rdb文件,消耗CPU资源

rdbchecksum yes #保存rdb文件时,进行错误检查

dir  ./ #rdb 文件保存的目录

REPLICATION复制

主从复制

sercurity

config get requirepass

配置文件 requirepass 123456

config set requirepass "123456" 修改密码

auth 123456 密码登录

clients客户端

maxclients 10000 #设置最大连接客户端数量

maxmemory <bytes> #redis配置的最大内存

maxmemory-policy noeviction #内存到达上限之后的处理策略

UTOOLS1589025706947.png

aof配置

appenonly no #默认不开启,默认使用rdp方式持久化,rdb够用了
appendfilename "appendonly.aof" #持久化文件的名字

image-20200509200554745.png

八、redis持久化

UTOOLS1589027964664.png

RDB

rdb 保存的文件是dump.rdb

触发机制

  1. save规则满足的情况下,触发rdb规则
  2. flushall命令,会产生rdb文件
  3. 退出redis也会产生rdb文件

备份恢复

rdb文件放到redis启动目录,启动即可

config get dir 获取启动目录

默认的配置够用

优点

  1. 适合大规模的数据恢复!dump.db

    1. 对数据完整性不高

缺点

  1. 需要一定时间间隔,意外宕机,最后一次修改的数据没有了
  2. fork进程时,会占用一定的内存空间

AOF

append only file

将所有命令记录下来

UTOOLS1589028219014.png

开启AOF appendonly yes

shutdown

redis-check-aof --fix appendonly.aof 修复aof文件

优点

  1. 每次修改都同步,文件完整性好
  2. 每秒同步一次,可能丢失一秒的数据
  3. 从不同步,效率最高

缺点:

  1. aof远远大于rdb,修复速度慢
  2. 运行效率慢

九、发布订阅

  1. 实时信息订阅
  2. 实时聊天
  3. 订阅、关注
  4. 复杂就用消息中间件MQ

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

img

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

img

命令 描述
subscribe channel [channel] 订阅给定的一个或多个频道的信息
publish channel message 将信息发送到指定的频道
psubscribe pattern [pattern] 订阅一个或多个给定模式的频道
pubsub subcommand [argument [argument …]] 查看订阅与发布系统状态
unsubscribe [channel] [channel] 退订给定的频道
punsubscribe [pattern [pattern …]] 退订为定模式的频道

例子

subscribe mingyue   #订阅

publish mingyue "i love you"  #发布

UTOOLS1589034850649.png

十、主从复制

将一台redis服务器的数据复制到其他的redis服务器,前者为主节点(master/leader),后者为从节点,数据复制是单向的,只能又主节点到从节点,master以写为主,slave以读为主。

主从复制,读写分离,百分之八十都是读操作!减轻服务器压力,架构中经常使用,一组二从

默认情况下每一台redis都是主节点

主从复制的作用:

  1. 数据冗余:实现了数据的热备份,是持久化外的一种数据冗余方式
  2. 故障恢复:当主节点出现问题时,可由节点提供服务,实现快速的故障恢复,实际上是一种服务的冗余
  3. 负载均衡:在主从复制的基础上,配合读写分离,可由主节点提供服务,由节点提供读服务(写redis数据连接自主节点,读连接从节点),分担服务器负载;尤其在写少读多的场景下,通过多个从节点分担负载,可以大大提高redis服务器的并发量
  4. 高可用(集群)基石):主从复制还是哨兵和集群能够实施的基础,因此说主从复制的redis高可用的基础

运用于redis运用于工程项目,只用一台不够(宕机)

  1. 结构上:单个redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力大
  2. 容量上:单个redis服务器内存容量有限,就算一台redis服务器内存容量为256G,也不能将所有内存用作redis存储内存,单台redis最大内存不应该超过20G

电商:一次上传,无数次浏览,多读少写

info replication 查看当前库的信息

# Replication
role:master
connected_slaves:0
master_replid:3232a49ef723168b5f6a5dd04a51734e4edc9719
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:

搭建集群

配置3个配置文件

端口

port 6380

pid名字

pidfile /var/run/redis_6380.pid

log名字

logfile “6379.log”

备份名字

dbfilename dump6379.rdb

启动redis

redis-server myConfig/redis79.conf

UTOOLS1589040422883.png

redis-cli -p 6379连接

info repolication

一组二从

==默认情况下每一台redis都是主节点==,配置从机

slaveof 127.0.0.1 6379

info repolication

# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:42
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:575e2d5475971e481145a2211a7d98e52c67f4fe
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=140,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=140,lag=0
master_replid:575e2d5475971e481145a2211a7d98e52c67f4fe
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:140
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:140

应该在配置文件中配置才是永久的

conf

replication <masterip> <masterport>

masterauth <master-password>

主机才能写,从机只能读

断开连接

主机断开,从机没有写能力,恢复了才能继续

从机断开,使用的是命令配置,重启后变成了主机,主机新的信息无法更新,只要变成从机,就能恢复数据

复制原理

slave启动成功连接到master后发送一个sync同步命令

master接到命令,启动后台的存盘进程,同时收集所有接收到用于修改数据集命令,在后台进程执行完毕后,master将传送整个数据文件到slave,并完成一次完全同步

全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中

增量复制:master继续将新的所有收集到的修改命令一次传给slave,完成同步

只要重新连接master,全量复制将被执行

  • 一主二从

  • 层层链路

    • slaveof no one 主机断开连接,使自己变成主机

哨兵模式

自动选取主机,sentinel(哨兵)

原理:哨兵通过发送命令,等待redis服务器响应,从而监控运行的多个redis实例

哨兵配置

vim sentinel.conf
                #被监控的名称   host     port   投票
sentinel monitor  myredis   127.0.0.1  6379    1

全部配置

port 26379
dir /tmp
sentinel monitor mymaster 127.0.0.1 6379 2
#有密码
sentinel auth-pass mymaster MYSUPER--sercret 123passwOrd
#默认30秒改变
sentinel down-after-millisenconds mymaster 30000

UTOOLS1589080559264.png

启动哨兵

redis-sentinel myConfig/sentinel.conf

failover

主机挂了之后,哨兵

14231:X 10 May 2020 10:59:45.972 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
14231:X 10 May 2020 10:59:45.974 # Sentinel ID is 966f8534f576844c2d789f75bdadf0b87de7e1fd
14231:X 10 May 2020 10:59:45.974 # +monitor master myredis 127.0.0.1 6379 quorum 1
14231:X 10 May 2020 10:59:45.975 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 10:59:45.976 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:21.994 # +sdown master myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:21.994 # +odown master myredis 127.0.0.1 6379 #quorum 1/1
14231:X 10 May 2020 11:01:21.994 # +new-epoch 1
14231:X 10 May 2020 11:01:21.994 # +try-failover master myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:21.996 # +vote-for-leader 966f8534f576844c2d789f75bdadf0b87de7e1fd 1
14231:X 10 May 2020 11:01:21.996 # +elected-leader master myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:21.996 # +failover-state-select-slave master myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:22.086 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:22.086 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:22.158 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:23.161 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:23.161 # +failover-state-reconf-slaves master myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:23.209 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:24.201 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:24.201 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:24.283 # +failover-end master myredis 127.0.0.1 6379
14231:X 10 May 2020 11:01:24.283 # +switch-master myredis 127.0.0.1 6379 127.0.0.1 6380
14231:X 10 May 2020 11:01:24.283 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380
14231:X 10 May 2020 11:01:24.283 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6380

#复活后
14231:X 10 May 2020 11:04:32.915 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6380

优点

  1. 基于主从配置,自动配置
  2. 主从可以切换,故障可以转移,可用性好

缺点

  1. 不方便在线扩容
  2. 哨兵模式的配置很麻烦

十一、缓存穿透和雪崩

缓存击穿:缓存过期

雪崩:集体过期

缓存穿透:查询null,一直访问数据库

布隆过滤器,用来判断某个元素(key)是否在某个集合中,没有就真的没有