一、初见面
安装
https://github.com/microsoftarchive/redis/releases
windows报错
window下安装redis或启动报错:
creating server tcp listening socket 127.0.0.1:6379: bind No error
的解决方案如下按顺序输入如下命令就可以连接成功
- redis-cli.exe
- shutdown
- exit
- redis-server.exe redis.windows.conf
linux
解压 tar -zxvf
,存放在opt目录
基本环境安装
yum install gcc-c++
gcc -v
make
make install
默认路径
/usr/local/bin
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
简介
redis是单线程的
基于内存操作,瓶颈是机器的内存和网络带宽
c语言编写,100000+QPS,不比memecache
为何那么快?
- 误区:高性能服务器就是高线程的
- 误区:多线程一定比单线程效率高
核心:
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
导入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
配置文件单位对大小写不敏感
包含.conf
网络
bind 127.0.0.1
绑定ip- protected-mode yes 保护模式
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 #内存到达上限之后的处理策略
aof配置
appenonly no #默认不开启,默认使用rdp方式持久化,rdb够用了
appendfilename "appendonly.aof" #持久化文件的名字
八、redis持久化
RDB
rdb 保存的文件是dump.rdb
触发机制
- save规则满足的情况下,触发rdb规则
- flushall命令,会产生rdb文件
- 退出redis也会产生rdb文件
备份恢复
rdb文件放到redis启动目录,启动即可
config get dir
获取启动目录
默认的配置够用
优点:
适合大规模的数据恢复!dump.db
- 对数据完整性不高
缺点:
- 需要一定时间间隔,意外宕机,最后一次修改的数据没有了
- fork进程时,会占用一定的内存空间
AOF
append only file
将所有命令记录下来
开启AOF appendonly yes
shutdown
redis-check-aof --fix appendonly.aof
修复aof文件
优点
- 每次修改都同步,文件完整性好
- 每秒同步一次,可能丢失一秒的数据
- 从不同步,效率最高
缺点:
- aof远远大于rdb,修复速度慢
- 运行效率慢
九、发布订阅
- 实时信息订阅
- 实时聊天
- 订阅、关注
- 复杂就用消息中间件MQ
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
命令 | 描述 |
---|---|
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" #发布
十、主从复制
将一台redis服务器的数据复制到其他的redis服务器,前者为主节点(master/leader),后者为从节点,数据复制是单向的,只能又主节点到从节点,master以写为主,slave以读为主。
主从复制,读写分离,百分之八十都是读操作!减轻服务器压力,架构中经常使用,一组二从
默认情况下每一台redis都是主节点
主从复制的作用:
- 数据冗余:实现了数据的热备份,是持久化外的一种数据冗余方式
- 故障恢复:当主节点出现问题时,可由节点提供服务,实现快速的故障恢复,实际上是一种服务的冗余
- 负载均衡:在主从复制的基础上,配合读写分离,可由主节点提供服务,由节点提供读服务(写redis数据连接自主节点,读连接从节点),分担服务器负载;尤其在写少读多的场景下,通过多个从节点分担负载,可以大大提高redis服务器的并发量
- 高可用(集群)基石):主从复制还是哨兵和集群能够实施的基础,因此说主从复制的redis高可用的基础
运用于redis运用于工程项目,只用一台不够(宕机)
- 结构上:单个redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力大
- 容量上:单个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
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
启动哨兵
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
优点
- 基于主从配置,自动配置
- 主从可以切换,故障可以转移,可用性好
缺点
- 不方便在线扩容
- 哨兵模式的配置很麻烦
十一、缓存穿透和雪崩
缓存击穿:缓存过期
雪崩:集体过期
缓存穿透:查询null,一直访问数据库
布隆过滤器,用来判断某个元素(key)是否在某个集合中,没有就真的没有