Redis


Redis

NoSql概述

为什么要用NoSql

单机MySQL的年代

一个基本的网站访问量一般不会太大,单个数据库完全足够

更多的使用静态网页,服务器没有太大的压力

整个网站的瓶颈:

  1. 数据量如果太大,一个机器放不下了
  2. 数据的索引,一个机器内存放不下
  3. 访问量(读写混合),一个服务器承受不了

只要开始出现以上三个情况之一,那必须晋级

Memcached(缓存)+MySQL+垂直拆分

网站80%的情况都是在读,每次都要去查数据库就十分麻烦,所以我们希望减轻数据库的压力,可以用缓存来保证效率

发展过程:优化数据结构和索引-》文件缓存-》Memcached

分库分表+水平拆分+MySQL集群

本质:数据库读写

早些年MyISAM:表锁,十分影响效率,高并发会出现严重的锁问题

InnoDB:行锁

慢慢地就开始分库分表来解决写的压力

最近的年代

MySQL关系型数据库不够用。数据量很多,变化快

MySQL使用一些较大的文件。数据库表很大,效率降低。如果有一种数据库来专门处理这种数据,MySQL压力就会变小

大数据的压力下,表几乎无法更改

目前一个基本的互联网项目

为什么要用NoSQL

用户的个人信息,社交网络,地理位置,用户自己产生的数据,用户的日志等等爆发式增长

这时我们需要使用NoSQL数据库,可以很好地处理以上情况

什么是NoSQL

Not Only SQL

泛指非关系型数据库

随着web2.0的互联网诞生,传统的关系型数据库很难对付,尤其是超大规模的高并发的社区。暴露出来很多难以克服的问题

关系型数据库:表格、行、列(POI)

很多数据类型的存储不需要一个固定的格式,不需要多余的操作就可以横向扩展

NoSQL特点

  1. 方便扩展(数据之间无关系)

  2. 大数据量高性能(是一种细粒度的缓存)

  3. 数据类型多样(不需要事先设计数据库,随取随用)

  4. 传统RDBMS和NoSQL

    1
    2
    3
    4
    5
    6
    7
    传统RDBMS
    - 结构化组织
    - SQL
    - 数据和关系都在单独的表中
    - 数据定义语言
    - 严格的一致性
    - 基础的事务
    1
    2
    3
    4
    5
    6
    7
    NoSQL
    - 不仅仅是数据
    - 没有固定的查询语言
    - 键值对存储,列存储,文档存储,图形数据库
    - 最终一致性
    - CAP定理和BASE(异地多活)
    - 高性能,高可用,高可扩展性

    了解:3V+3高

    3V:海量,多样,实时

    3高:高并发,高可拓,高性能

    真正在公司中的时间:NoSQL+RDBMS一起使用才是最强的

阿里巴巴演进分析

思考问题:这么多东西难道在一个数据库中吗?

任何一家互联网公司,都不可能只是简简单单让用户能用就好了

没有什么是加一层解决不了的

1
2
3
4
5
6
7
8
9
10
11
12
13
#商品的基本信息
名称、价格、商家信息
关系型数据库就解决了
#商品的描述、评论(文字比较多)
文档型数据库中,MongoDB
#图片
分布式文件系统,FastDFS
#商品关键字(搜索)
搜索引擎
#商品热门波段信息
内存数据库,Redis
#商品的交易,外部的支付接口
三方应用

要知道,一个简单地网页背后的技术一定不是想象的那么简单

大型互联网应用问题:

  • 数据类型太多
  • 数据源繁多。经常重构
  • 数据要改造,需要大面积改造

解决问题:UDSL(统一数据服务平台)

以上都是NoSQL入门概述,不仅能提高知识,还能帮助了解大厂工作内容

NoSQL的四大分类

KV键值对:

  • 新浪:Redis
  • 美团:Redis+Tair
  • 阿里、百度:Redis+Memcached

文档型数据库:

  • MongoDB
    • 是一个基于分布式文件存储的数据库,C++编写,主要用来处理大量的文档
    • 是一个介于关系型数据库和非关系型数据库的产品。MongoDB是非关系型数据库中功能最丰富,最像关系型数据库的。
  • ConthDB

列存储数据库:

  • HBase
  • 分布式文件系统

图形关系数据库:

  • 不是存图形,放的是关系,比如:朋友圈社交网络,广告推荐
  • Neo4j

Redis入门

概述

Redis是什么

Redis,即远程字典服务

是当下最热门的NoSQL技术之一,也被人们称之为结构化数据库

Redis能做什么

  1. 内存存储,持久化。内存是断电即失,所以说持久化很重要(RDB、AOF)
  2. 效率高,可以用于高速缓存
  3. 发布订阅系统
  4. 地图信息分析
  5. 计时器、计数器(浏览量)

特性

  1. 多样的数据类型
  2. 持久化
  3. 集群
  4. 事务

学习中要用到的东西

  1. 官网
  2. Redis中文网

Redis推荐在Linux服务器上搭建,基于Linux学习

Windows安装

默认端口号:6379

Windows下使用确实简单,但是Redis推荐我们使用Linux开发

Linux安装

  1. 下载安装包redis-6.2.5.tar.gz

  2. 解压Redis的安装包 程序在opt下

  3. 进入解压后的文件,可以看到Redis的配置文件

  4. 基本的环境安装

    1
    2
    3
    yum install gcc-c++
    make
    make install
  5. Redis的默认安装路径:usr/local/bin

  6. 将Redis配置文件复制到当前目录下

  7. Redis默认不是后台启动的,修改配置文件

  8. 启动Redis服务

  9. 使用Redis客户端进行连接

  10. 查看Redis的进程是否开启

  11. 如何关闭Redis服务?(shutdown)

  12. 再次查看进程是否存在

  13. 后面会使用单机多Redis集群

测试性能

redis-benchmark是一个压力测试工具

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

基础知识

Redis默认有16个数据库,默认使用的是第0个数据库

1
2
3
4
select n//切换数据库
keys *//查看数据库所有的key
flushdb//清空当前数据库
flushall//清空全部数据库

为什么Redis是6379?(了解一下即可)

Redis是单线程的!

Redis是很快的。官方表示,Redis基于内存操作,CPU不是Redis的性能瓶颈,Redis的瓶颈是根据机器的内存和网络的带宽。既然能用单线程实现,那就用单线程。

Redis是C语言写的。官方数据为100000+的QPS,这个不必Memcached差

Redis为什么单线程还这么快?

  1. 误区1:高性能的服务器一定是多线程的?
  2. 误区2:多线程(CPU上下文会切换)一定比单线程效率高?

核心:Redis将所有数据放在内存中,所以说使用单线程操作效率最高。对于内存来说,如果没有上下文切换效率就是最高的。多次读写都在一个CPU上。

五大数据类型

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库缓存消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

Redis-Key

1
2
3
4
5
6
7
keys *//查看所有key
set xxx xxx//set key
EXISTS xxx//判断当前key是否存在
move xxx 1//移除当前的key
EXPIRE xxx t//设置当前key的过期时间
ttl xxx//查看当前key的剩余时间
type xxx//查看当前key的数据类型

String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
set key1 v1
get key1
keys *
EXISTS key1
APPEND key1 v2//追加字符串,如果key不存在,就新建
STRLEN key1//获取字符串长度

incr key2
decr key2
INCRBY key2 step(步长)
DECRBY key2 step

GETRANGE key1 start end
GETRANGE key1 0 -1//获取全部字符串
SETRANGE key2 1 xx//替换字符串

setex mykey value//如果mykey不存在,创建
setnx mykey value//如果mykey存在,创建失败

mset k1 v1 k2 v2 k3 v3//批量创建
mget k1 k2 k3
msetnx k1 v1 k3 v4//setnx是一个原子性的操作,要么一起成功,要么一起失败

set user:1 {name:dogegg,age:3}#设置对象

getset#先get再set
getset db value#如果不存在值,返回nil,如果存在值,获取原来的值并设置新值

String类型应用场景:

  • 字符串
  • 计数器
  • 统计多单位的数量
  • 对象缓存存储

List

在Redis中,能把list用成栈、队列、阻塞队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
LPUSH list one#将值插到列表头部
LRANGE list 0 -1#获取list中的值
RPUSH list two#将值插到列表尾部

LPOP#移除
RPOP

Lindex list 1#通过下标获取值

Llen list#获取长度

Lrem list 2 three#移除某个具体元素

ltrim list 1 2#截取部分

rpoplpush mylist myanotherlist#移除某个元素,将它添加到另一个list

Linsert

小结

  • 实际上是一个链表,left、right都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有值,空链表,也代表不存在
  • 在两边插入或者改动值,效率最高。中间元素相对来说效率会低一点

Set

Set中的值是不能重复的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Sadd myset "hello"
Smembers myset#所有元素
Sismember myset xxx#元素是否存在
scard myset#获取set集合中的内容元素个数
srem myset "hello"

set是无需不重复集合
SRANDMEMBER myset#随机获取一个元素

spop myset#随机移除元素

将一个指定的值移动到指定的集合中
smove myset myset2 "kuangshen"

- 差集
- 交集
- 并集
SDIFF key1 key2#差集
SINTER key1 key2#交集
SUNION key1 key2#并集

共同关注,共同爱好

Hash

Map集合,key-Map集合

1
2
3
4
5
6
7
8
9
10
11
12
13
Hset myhash field1 aaa
Hget myhash field1
Hmset myhash field1 hello field2 wild
Hmget myhash field1 field2
Hgetall myhash
Hdel myhash field2

Hlen myhash
Hexists myhash field1#判断是否存在
Hkeys myhash
hvals myhash

Hincrby

Hash存储变更的数据,尤其是用户信息之类的,经常变动的信息。Hash更适合于对象的存储,String更加适合字符串存储

Zset(有序集合)

在Set的基础上,增加了一个值

1
2
3
4
5
6
7
8
9
Zadd myset 1 one
Zadd myset 2 two 3 three
ZRANGE myset 0 -1

ZRANGEBYSCORE salary -inf +inf

Zrem salary xiaohong
zcard salary#查看多少元素
Zcount

其余的一些API,通过我们的学习,剩下的如果工作中有需要,这个时候可以去看看官网

三种特殊数据类型

Geospatial地理位置

只有六个命令

GEOADD

添加地理位置

规则:两极无法直接添加,我们一般会下载城市数据,通过java程序一次性导入

参数:纬度、经度、名称

GEOPOS

获取指定的经度和纬度:一定是一个坐标值

GEODIST

两人之间的距离

GEORADIUS

查看方圆半径内的地址

获得指定数量的人

GEORADIUSMEMBER

找出位于指定范围内的元素,中心点是由给定的位置元素决定

GEOHASH

返回一个或多个位置元素

GEO底层原理其实就是Zset。我们可以使用Zset来操作GEO

Hyperloglog

基数

Redis2.8.9版本就更新了Hyperloglog数据结构

是用来做基数统计的算法

网页的UV(一个人访问一个网站多次,但还是算作一个人)

传统的方式:Set保存用户的id,然后就可以统计Set中的元素数量作为标准判断。这个方式如果保存大量的id,就会比较麻烦。我们的目的是计数,而不是保存id

Hyperloglog:占用的内存是固定的,2^64不同元素的计数,只需要12KB的内存。如果从内存角度来比较,Hyperloglog首选

1
2
3
4
PFadd mykey a b c d e f g h i j
PFCOUNT mykey
PFadd mykey2 a j h i j k o
PFMERGE mykey3 mykey mykey2

如果允许容错,就可以使用Hyperloglog,否则使用Set或其它

Bitmap

位存储

两个状态的,都可以使用Bitmap

都是操作二进制位来进行记录,只有0和1两个状态

1
2
3
4
5
6
7
8
9
10
11
12
#使用Bitmap记录周一到周日的打卡
setbit sign 0 1
setbit sign 1 0
setbit sign 2 1
setbit sign 3 0
setbit sign 4 1
setbit sign 5 1
setbit sign 6 0
#查看某一天是否打卡
getbit sign 6
#统计打卡天数
bitcount sign

事务

Redis事务本质:一组命令的集合。一个事务中的所有命令都会被序列化。在事务执行的过程中,会按照顺序执行。

一次性、顺序性、排他性。执行一系列的命令

Redis事务没有隔离级别的概念

所有的命令在事务中并没有直接被执行,只有发起执行命令时才会被执行

Redis单条命令保证原子性,但是事务不保证原子性

Redis事务:

  • 开启事务(Multi)
  • 命令入队
  • 执行事务(Exec)

正常执行事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) OK
3) "v2"
4) OK

放弃事务

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> DISCARD#取消事务
OK
127.0.0.1:6379> get k4#事务队列中的命令都不会被执行
(nil)

编译型异常(命令有错),事务中所有的命令都不会被执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> getset k3
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> set k5 v5
QUEUED
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k2#所有命令都不会被执行
(nil)

运行时异常(例如1/0),如果事务队列中存在语法型错误,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6379> set k1 "v1"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incr k1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get k3
QUEUED
127.0.0.1:6379(TX)> exec
1) (error) ERR value is not an integer or out of range#虽然第一条命令报错,但其他依旧正常执行成功了
2) OK
3) OK
4) "v3"

监控(watch)

悲观锁:

  • 认为什么时候都会出问题,无论做什么都会加锁

乐观锁:

  • 认为什么时候都不会出现问题,所以不会上锁。更新数据时去判断一下,在此期间是否有人修改过这个数据,version
  • 获取version
  • 更新时比较version

Redis监视测试

正常执行成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money#监视money
OK
127.0.0.1:6379> multi#事务正常结束
OK
127.0.0.1:6379(TX)> decrby money 20
QUEUED
127.0.0.1:6379(TX)> incrby out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> watch money#watch可当做乐观锁操作
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> DECRBY money 10
QUEUED
127.0.0.1:6379(TX)> incrby out 10
QUEUED
127.0.0.1:6379(TX)> exec
(nil)
#########################################
127.0.0.1:6379> get money
"80"
127.0.0.1:6379> set money 1000
OK

Jedis

通过Java操作Redis

什么是Jedis?

Java操作Redis中间件

测试

  1. 导入对应的依赖
1
2
3
4
5
6
7
8
9
10
11
12
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
</dependencies>
  1. 编码测试

    • 连接数据库
    • 操作命令
    • 断开连接
    1
    2
    3
    4
    5
    6
    public class TestPing {
    public static void main(String[] args) {
    Jedis jedis = new Jedis("127.0.0.1", 6379);
    System.out.println(jedis.ping());
    }
    }

    输出:PONG

常用API

String

List

Set

Hash

Zset

事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class RedisTX {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.flushDB();
JSONObject jsonObject = new JSONObject();
jsonObject.put("hello", "world");
jsonObject.put("name", "kuang");
Transaction multi = jedis.multi();
String s = jsonObject.toJSONString();
try {
multi.set("user1", s);
multi.set("user2", s);
int i = 1/0;
multi.exec();
} catch (Exception e) {
multi.discard();
e.printStackTrace();
} finally {
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
jedis.close();
}
}
}

SpringBoot整合

说明:在SpringBoot2.x之后,原来使用的Jedis被替换成了lettuce

Jedis:直连,多个线程操作的话不安全,如果要避免,使用Jedis pool

Lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全,可以减少线程数量

Redis.conf详解

启动的时候,通过配置文件来启动

单位

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

包含

网络

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

通用General

1
2
3
4
5
6
7
8
9
10
11
12
13
14
daemonize yes#以守护进程的方式运行,默认是no,我们需要开启为yes
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 no#是否总是显示logo

快照

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

1
2
3
4
5
6
7
8
# save 3600 1      如果900s内,至少有1个key进行了修改,就持久化
# save 300 100 如果300s内,至少有100个key进行了修改,就持久化
# save 60 10000 如果60s内,至少有10000个key进行了修改,就持久化
#之后学习持久化,会自己定义这个测试
stop-writes-on-bgsave-error yes#持久化出错是否还继续工作
rdbcompression yes#是否压缩rdb文件,需要消耗一些CPU资源
rdbchecksum yes#保存rdb文件的时候,进行文件校验
dir ./#rdb文件保存的目录

REPLICATION 复制,后面主从复制再讲解

SECURITY安全

可以设置redis密码,默认是没有密码的

限制

1
2
3
4
5
6
7
8
9
maxclients 10000#设置Redis的最大客户端数量
maxmemory <bytes>#Redis配置最大的内存容量
maxmemory-policy noeviction#内存到达上限之后的处理策略
1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)
2、allkeys-lru : 删除lru算法的key
3、volatile-random:随机删除即将过期key
4、allkeys-random:随机删除
5、volatile-ttl : 删除即将过期的
6、noeviction : 永不过期,返回错误

APPEND ONLY模式 aof配置

1
2
3
4
5
6
appendonly no#默认不开启aof模式,默认rdb方式持久化。在大部分情况下,rdb够用
appendfilename "appendonly.aof"#持久化地文件名字

# appendfsync always#每次修改都会sync,消耗性能
appendfsync everysec#每秒执行一次sync,但可能丢失这1s的数据
# appendfsync no #不执行sync,操作系统自己同步数据,速度最快

Redis持久化

RDB(Redis DataBase)

什么是RDB

在主从复制中,RDB备用

默认的是RDB,一般情况下不需要修改这个配置

缺点:最后一次持久化后的数据可能丢失

RDB保存的文件是dump.rdb都是在配置文件的快照中进行配置

触发机制

  1. save的规则满足的情况下,会自动触发RDB规则
  2. 执行flushall命令,也会触发RDB规则
  3. 退出Redis,会触发

备份就会自动生成一个dump.rdb文件

如何恢复RDB文件

  1. 只要将RDB文件放到Redis启动目录,Redis启动会检查dump.rdb,会自动恢复数据
  2. 查看需要存放的位置

基本上默认的配置就够用了

优点:

  1. 适合大规模的数据恢复
  2. 对数据的完整性要求不高

缺点:

  1. 需要一定的时间间隔进程操作。如果Redis宕机了,最后一次的数据就没了
  2. fork进程的时候,会占用一定内存

AOF(Append Only File)

将我们的所有命令都记录下来,history,回复的时候就把这个文件全部再执行一遍

是什么

以日志的形式记录每一个操作,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件

Aof保存的是appendonly.aof文件

append

默认不开启,我们需要手动进行配置

重启Redis就能生效

如果aof文件有错误,Redis是启动不起来的,我们需要修复配置文件

Redis给我们提供了一个工具redis-check-aof --fix

优点和缺点

优点:

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

缺点:

  1. 相对于数据文件来说,aof远远大于rdb,修复速度比rdb慢
  2. aof运行效率比rdb低

扩展:

Redis发布订阅

通信 队列 发送者 订阅者

订阅、发布消息图

命令

原理

使用场景:

  • 实时消息系统
  • 实时聊天(频道作为聊天室,信息回显即可)
  • 订阅、关注

稍微复杂的场景我们会使用消息中间件

Redis主从复制

概念

一主二从

环境配置

只配置从库,不配置主库

1
info replication#查看当前库的信息

一主二从

默认情况下,每台Redis服务器都是主节点

我们一般情况只用配置从机就好

1
slaveof x.x.x.x port

真是的主从配置应该在配置文件中配置,这样的话是永久的

细节

主机可以设置值,从机只能读不能写。主机中的所有信息和数据都会被从机保存

测试:主机断开连接,从机依旧连接到主机,但是没有写操作。如果主机恢复了,从机会立刻恢复连接

如果使用命令行配置来配置主从,这时候重启了,就会变为主机。只要变为从机,就会立刻从主机中获取值

复制原理

层层链路

上一个M连接下一个S这时候也可以完成我们的主从复制

如果没有老大了,能不能自己选择一个老大呢?

如果主机断开了连接,我们可以使用slaveof no one让自己变成主机,其他主机可以手动连接到这个新的主节点

如果老大修复了,只能重新配置

哨兵模式

概述

测试

  1. 配置哨兵文件sentinel.conf

    1
    sentinel monitor myredis ip port 1

    后面的数字1,代表主机挂了,slave投票看让谁接替成为主机,票数最多的就会成为主机

  2. 启动哨兵

  3. 断开主机

    如果Master节点断开了,就会从从机中选择一个服务器

如果主机此时回来了,只能归并到新的主机下,当做从机,这就是哨兵模式的规则

哨兵模式

优点:

  1. 哨兵集群基于主从复制模式,所有的主从配置有点他都有
  2. 主从可以切换,故障可以转移,系统可用性更好
  3. 哨兵模式是主从模式的升级,手动到自动,更加健壮

缺点:

  1. Redis不好在线扩容,达到上限,在线扩容十分麻烦
  2. 实现哨兵模式十分麻烦,有很多选择

Redis缓存穿透和雪崩

缓存穿透(查不到)

概念

解决方案

布隆过滤器

缓存空对象

缓存击穿(量太大,缓存过期)

概述

解决方案

缓存雪崩

概念

某个时间段,缓存集中过期失效,或者Redis宕机

解决方案


文章作者: ZDogEgg
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ZDogEgg !