LOADING

加载过慢请开启缓存 浏览器默认开启

Redis笔记

Redis笔记

https://redis.io/docs/data-types/

https://redis.io/commands/

http://www.redis.cn/commands.html

1. Redis10大数据类型

注意:这次的数据类型指的是value的类型,因为key的类型一般是字符串

  1. 字符串String
  2. 列表List
  3. 哈希表Hash
  4. 集合Set
  5. 有序集合Zset
  6. 地理空间GEO
  7. 基数统计HyperLogLog
  8. 位图bitmap
  9. 位域bitfield
  10. 流Stream

help @类型 帮助命令

### 1.1 字符串String

概念

string类型是二进制安全的

意思是redis的string支持序列化,string可以包含任何数据,比如图片或者序列化的对象

一个redis中字符串value最多可以是512M

单值单value

常用命令

下面的keepttl,用于保持一个kv的过期时间,因为直接set会导致前面设置的过期时间失效

下面的unix时间戳,可以参照System.currentTimeMillis(),返回的就是毫秒值

image-20230514173229448

mset,mget,msetnx就是批量的操作(mset 是 Multi-Set的缩写)

对于msetnx,它的操作是作为一个整体,批量中只要有一个已存在,就不执行

getrange/setrange

​ 比如getrange k1 0 -1

0 -1表示获取全部

​ 如果把0和-1改成你想要的索引,就能获取到指定的部分字符串两个位置都是闭区间

​ set key 起始位置(包括这位开始替换) 你的字符串

incr/incrby/decr/decrby:

value必须是数字

​ incr key

​ incrby key 增加的大小

setnx,setex:已经过期,可以通过set的参数来实现

image-20230514171915731

image-20230514171949226

1.2 列表List

概念

底层实际是一个双端链表

可添加到头部或者尾部

最多可以包含232-1个元素(4294967295,超过40亿个元素)

如果值全部移除,对应的键也就消失了

一个key多个value

应用于:比如微信公众号订阅的消息

常用命令

只有lrange,lindex,没有rrange,rindex命令

可以通过-1,-5这样从右边开始访问

lrange指的是从左边开始遍历

lpush从左边插入

rpush从右边插入

lrem key N v1 删除N个值位v1的元素

rpoplpush(已经弃用),改为lmove 源list 目的list left|right left|right

image-20230514185611676

image-20230514185639392

1.3 哈希表Hash

概念:

string类型的filed字段和value

适合用于存储对象

每个hash可以储存232-1个键值对(40多亿)

k v键值对中的 value 是一个哈希表 hash

常用命令

hmset被弃用,用hset就能实现

hgetall,会显示键1,值1,键2,值2......

hdel删除一个字段,del删除整个hash

image-20230514204202941

image-20230514204220306

1.4 集合Set

概念:

String类型无序集合,集合成员唯一

集合对象的编码可以是intset或者hashtable

Redis中的Set底层通过哈希表实现,所以添加,删除,查找的复杂度都是O(1)

集合最大成员同样40多亿

应用场景:

抽奖,查看点赞朋友,可能认识的人,共同关注

常用命令

sintercard交集的个数,redis7新增

image-20230514205651334

image-20230514205701682

1.5 有序集合Zset(Sorted set)

概念:

Redis的zsetset一样是string类型元素的集合,不允许重复

不同之处是:zset的每个元素都会关联一个double类型的分数分数可以重复,redis通过分数来进行从小到大排序

也是通过哈希表实现,添加,删除,查找的复杂度为O(1),集合的最大成员数为40多亿

应用

商品排序

常用命令

按score从小到大排序

1.下面命令的左括号表示不包含,默认包含,只有左括号的表达方式,limit 0 2表示从0开始取2条数据

zrangebysocre zset (60 (90 withscores limit 0 2

2.下面是redis7的新增命令

ZMPOP numkeys key [key ...] <MIN | MAX> [COUNT count]

从键名列表中的第一个非空排序集中弹出一个或多个元素,它们是成员分数对。当使用MIN修饰符时,弹出的元素是第一个非空排序集中得分最低的元素。MAX修改器会弹出得分最高的元素,numkeys表示key的数量

可选的COUNT可用于指定要弹出的元素数量,默认情况下设置为1,弹出元素的数量是排序集的基数和COUNT值中的最小值

image-20230514213558371

image-20230514211604228

image-20230514211630415

1.6 地理空间GEO

概念:

经纬度,存储地理位置信息

并且可以进行操作:

  1. 添加地理位置的坐标
  2. 获取地理位置的坐标
  3. 计算两个位置之间的距离
  4. 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合

类型zset

中文乱码问题:

进入redis客户端时加入参数raw

redis-cli -a 123456 --raw

常用命令

image-20230514223709505

georadiusbymember与georadius相比不写经纬度,而是名称

image-20230514223224395

1.7 基数统计HyperLogLog

概念:

用来做基数统计的算法

类型属于string

:HyperLogLog以完美的准确性换取有效的空间利用

​ Redis HyperLogLog实现最多使用12 KB标准误差为0.81%

基数:一种数据集,去重后的真实个数

优点:输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定且是很小的

在Redis里,每个HyperLogLog键只需要花费12KB,就可以计算接近264个不同元素的基数

这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比

但是,因为HyperLogLog只会根据输入元素来计算基数,而不会存储输入元素本身,所以HyperLogLog不能像集合那样,返回输入的各个元素

常用命令

image-20230514221408395

1.8 位图bitmap

概念:

0和1状态表现的二进制位的bit数组

偏移量从0开始

只能是0和1

type bitmap ----> string

应用

打卡签到记录

常用命令

setbit的返回值,不代表成功,而是set之前的值

get bitmap 返回的是对应的字符串(一个字节占8位,所以8个一组,超过8位自动扩容,8位,8位扩容)

bitcount返回的是1的数量

默认情况下,bitcount按byte,如果start end 要按bit算,要写明bit

BITCOUNT key [start end [BYTE | BIT]]

image-20230514214836224

1.9 位域bitfield(使用少,了解)

概念:

通过bitfield命令可以一次性操作多个比特位域(连续多个比特位),执行一系列操作并返回一个响应数组

这个数组中的元素对应参数列表中的相应操作的执行结果

作用

    1. 位域修改,直接修改对应的bit位
    1. 溢出控制

命令

image-20230516174420691

image-20230516174457403

image-20230516174522180

image-20230516174554000

image-20230516174740599

image-20230516174703834

image-20230516174817066

image-20230516174633083

1.10 流Stream

概念:

用于消息队列MQ,

Redis原本有发布订阅(pub/sub)来实现消息队列,但缺点是消息无法持久化

如果网络断开,Redis宕机等,消息就会被丢弃,无法记录历史消息

而Redis Stream提供了消息的持久化和主备复制功能,

可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失

类型:

​ type mystream --> stream

历程

​ 1. 简单的用list,lpush,rpop能实现(只能点对点,不能一对多),无法实现发布订阅

​ 因此引入了发布订阅**,能一对多了

​ 2. 但是无法实现消息的持久化,如果出现网络断开,Redis宕机等,消息就会被丢弃

​ 而且没有Ack机制来保证数据的可靠性,如果一个消费者都没有,消息就丢弃了

​ 因此又引入了Stream的数据结构 (since Redis 5.0

作用:

image-20230515172345283

底层结构:

image-20230515173212744

总结Stream就是Redis版的MQ消息中间件+阻塞队列

常用命令

xrange:

’-‘表示最小值,‘+’表示最大值,这个值和stream里面的id无关,相当于正无穷和负无穷

​ 所以对于xrange,从小到大顺序, + -就返回空

​ 和之前一样,默认前后都是闭区间,要想去掉边界就加上左括号正负无穷不能加左括号

​ count表示最多获取多少个值,如果要限制获取个数,那么count单词必须写

xtrim:

minid: 允许的最小id,比它小的会抛弃

maxlen 允许的最大长度,会抛弃时间戳小的,也即保留最近时间的

这两个都要带上单词本身

xadd:

​ NOMKSTREAM表示不创建stream,只添加kv键值对

XADD key [NOMKSTREAM] [<MAXLEN | MINID> [= | ~] threshold
  [LIMIT count]] <* | id> field value [field value ...]

image-20230515181959689

xread:

streams必须写

count(如果要写明条数,就要写count)

id表示从哪里开始,不包括该id,开区间

$是一个特殊ID,它比当前存储的最大ID还大,因此用于下一条消息(阻塞时接收消息)

​ id可以是0或者00或者000等,0等价于0-0(这个是redis编号id,毫秒-次序)

几个key就要写几个ID

xread不会影响stream,只是读取出来

image-20230515194452832

image-20230515195428571

image-20230515202045323

下面这里同一个消费组,一个消息只能读取一次,哪怕还是同一个消费者读取,也为nil

但是不同组可以消费同一个消息

这个均衡就相当于MQ中的轮询

image-20230515204141320

image-20230515203345706

xpending

​ 额外参数:

​ 传递一个id范围(与XRANGE类似)和一个非可选的count参数

​ 以限制每次调用返回的消息数量,返回详细信息

​ 如下图:

​ 1.消息ID

​ 2.消费但没确认的消费者名称

​ 3.自上次将此消息传递给此消费者以来,到此刻所经过的毫秒数

​ 4.此消息被传递的次数

​ 当访问消费者组中的消费者历史记录时,则增加

​ 这里的次数指的是传递给(消费者)自己的次数与其他消费组的人无关

xclaim:

image-20230516091041552

image-20230516091425686

当其他消费者(或者当前消费过的消费者)使用XCLAIM声明消息时,都会+1

xclaim的retrycount可以直接指定count计数器的值

​ ?或者当消息再次通过XREADGROUP传递时(一个消费组不是只能消费该消息一次吗)

image-20230515205542997

image-20230515204457107

image-20230515173359221

image-20230515173426778

image-20230515173445970

image-20230515173559164

2. Redis 常用key操作命令

命令不区分大小写,但是key区分!!!

image-20230514170254016

image-20230514170311746

image-20230514171040578

image-20230514171144344

3. Redis持久化

3.1 RDB(redis database)

3.1.1 定义

​ 在指定的时间间隔,把某一时刻数据和状态文件的形式写到磁盘上,也就是快照Snapshot,

​ 这样即使宕机,快照文件也不会丢失,保证了数据的可靠性

​ 保存备份执行的是全量快照,记录内存的所有数据

​ 这个快照文件称为RDB文件(dump.rdb)

​ 恢复时,将快照文件直接读回到内存

3.1.2 配置

Redis6:

image-20230516185958337

Redis7:

image-20230516192251930

15min --> 1h 1

5min 10-->100

1min 10000

配置说明

https://www.bilibili.com/video/BV13R4y1v7sP?p=30&vd_source=7e34085a459b4e9ffab42ccd04776d69

image-20230516194349738

修改save

image-20230516194442353

修改dump文件保存路径(文件夹要存在)

image-20230516194552378

修改dump文件名称(加上端口号,方便区分不同的机器实例)

image-20230516194657755

3.1.3 RDB自动触发

设置为5秒2次的结果:

image-20230516195224697

这里为什么超过了5秒,却更新了

​ 是因为5秒指的是检查,而更新的次数是累积的,第二个5秒检查到的是从上次save以来累积的次数,

​ 达到了2次,所以文件变化

image-20230516220946824

flushdb/flushall会产生一个dump.rdb文件,里面是空的,无意义

shutdown这种宕机操作,会自动保存当前快照(但是kill进程这种不会保存

下图的备注指的是:dump.rdb和redis服务器要放在不同的机器上

image-20230516222006232

image-20230516215718179

3.1.4 RDB手动触发

  1. save
  2. bgsave(一般用这个)

save:

​ 会阻塞当前redis服务器,直到持久化完成,持久化时Redis不能处理其他命令,线上禁止使用

bgsave:

​ 在后台进行异步的快照操作,不会阻塞,持久化的同时,redis可以响应客户端请求,该触发方式

​ 会fork一个子进程,由子进程进行持久化过程

image-20230517113039646

image-20230517113055952

lastsave查看上一次保存时间(linux下可通过date -d转成日期时间)

image-20230517113226868

3.1.5 RDB优点

image-20230517113530808

image-20230517113713873

3.1.6 RDB缺点

意外down掉(比如kill -9)快照之间的数据会丢失

image-20230517114127198

image-20230517114315483

image-20230517115154534

3.1.7 RDB修复

保存的时候,突然断电宕机,可能写入不完整,文件破损

因为这一条,可能导致整个文件无法使用,此时就需要修复

image-20230517115456957

image-20230517115521930

image-20230517115434743

3.1.8 RDB小结

image-20230517120130610

image-20230517120233842

image-20230517120310975

image-20230517121300884

3.1.9 RDB优化参数

image-20230517121320478

image-20230517121339733

image-20230517121407994

image-20230517121422852

image-20230517121444023

主从复制时,是否删除用于同步的从机上的 RDB 文件。默认是 no,不删除。

不过需要注意,只有当从机的RDB 和 AOF持久化功能都未开启时才生效。

3.2 AOF(Append Only File)

3.2.1 使用原因

​ 因为前面RDB的缺点,可能存在最新数据的丢失,所以引入了aof

3.2.2 基本

记录写操作,保存的是appendonly.aof,

​ 重启的时候,就会把aof文件加载回redis,也即再次执行里面所有的写操作

image-20230517163615999

3.2.3 工作流程

image-20230517164346421

3.2.4 三种写回策略

  1. Always同步回写,每个写命令执行完后立刻同步地将日志写回磁盘,但是导致频繁地I/O操作

  2. everysec(默认)每秒写回,每个写命令执行完后,先写到aof文件的内存缓冲区

    每隔1秒缓冲区的内容写入磁盘

  3. no,由操作系统控制,每个写命令执行完后,只是先把日志写到AOF文件的内存缓冲区

    由操作系统决定何时将缓存区的内容写回磁盘

image-20230517171442239

3.2.5 AOF功能配置

image-20230517173653562

开启AOF

image-20230517173627536

aof保存路径

image-20230517174004034

image-20230517173802482

image-20230517173854818

aof保存名称

image-20230517174352877

image-20230517174318060

image-20230517174439918

3.2.6 AOF恢复

模拟正常恢复:写入 --> 保存后复制文件备份成bak --> shutdown

​ -->删除rdb和appendonlydir文件 --> 从bak复制appendonlydir --> 重启

异常恢复:下图的这个来修复incr文件

执行redis-check-aof --fix,必须加上--fix

​ 修复后,会清空掉不符合语法规则的部分

image-20230517185724297

3.2.7 AOF优缺点

使用everysec时,最多丢失一秒的数据

image-20230517215841348

image-20230517214941934

image-20230517215907511

image-20230517215150192

#### 3.2.8 AOF重写

aof文件会不断增大,恢复的时候也越来越慢,为了减少其大小,为其瘦身,使用aof重写

image-20230517221204656

image-20230517221305037

image-20230517221335801

aof重写举例

image-20230517221526346

配置

image-20230517221724662

重写案例

image-20230517222543505

image-20230517222628634

重写总结

image-20230517222738616

重写原理

Redis >= 7.0

  • Redis forks,所以现在我们有一个子进程和一个父进程。
  • 子进程开始在临时文件中写入新的基本AOF(new base)。
  • 父进程打开一个新的增量AOF文件(new incr)以继续写入更新。如果重写失败,旧的基文件(old base)和增量文件(old incr)(如果有的话)加上这个新打开的增量文件(new incr)代表完整的更新数据集,所以我们是安全的。
  • 当子进程重写完基本文件后,父进程获得一个信号,并使用新打开的增量文件(new incr)和子进程生成的基本文件(new base)构建一个临时清单,并将其持久化。
  • 现在,Redis对清单文件进行原子交换,以便AOF重写的结果生效。Redis还会清理旧的基本文件和任何未使用的增量文件。

Redis < 7.0

  • Redis forks,所以现在我们有一个子进程和一个父进程。
  • 子进程开始在临时文件中写入新的AOF(重写)。
  • 父进程在内存缓冲区中累积所有新更改(但同时它将新更改写入旧的AOF文件,因此如果重写失败,我们是安全的)。
  • 当子进程重写完文件后,父进程获得一个信号,并将内存缓冲区(新的更改)附加到子进程生成的文件(重写后的AOF)的末尾
  • 现在Redis自动将新文件重命名为旧文件,并开始将新数据附加到新文件中。

3.2.9 AOF小结

image-20230518105520209

image-20230518105538156

image-20230518105857990

3.3 RDB + AOF混合持久化

3.3.1 AOF优先

同时生效时,AOF优先

image-20230518115919714

image-20230518115745198

RDB:隔一段时间存储快照

AOF:记录写入操作

3.3.2 为什么AOF优先

因为:通常情况下,AOF保存的文件更加完整,最多丢失一秒的数据(everysec)

​ 而RDB可能缺少更多的数据

3.3.3 为什么不只使用AOF

因为:RDB更适合于备份数据库,而AOF在不断变化不好备份,大数据量时RDB能更快加载

3.3.4 混合使用

image-20230518121617115

image-20230518121544327

image-20230518121758378

3.4 纯缓存模式(关闭持久化)

为了专注于高性能的缓存服务,高速缓存

关闭持久化,即同时关闭RDB和AOF

这个禁用只是禁用了自动触发

image-20230518122029793

image-20230517120233842

image-20230517120310975

4. Redis事务

4.1 是什么

回顾——数据库事务一次在跟数据库的连接会话当中,所有执行的sql,要么一起成功,要么一起失败

Redis事务:

总的来说:就是一串操作命令队列,一次性执行

image-20230524164746886

image-20230524165317888

4.2 使用

注意事项

  • watch监控只在下一次事务有效,当discard或者exec之后,watch失效

  • watch监控是乐观锁,watch监控后,会记录当前值,exec的时候,在执行操作队列(Redis事务)之前,会先进行判断watch的值是否被修改,被修改则整个操作队列都不执行

  • Redis事务,会检查语法,一旦语法编译不通过,整个队列的命令都不执行

  • Redis事务,如果语法正确,但执行时发现命令有错误,只有错的命令不执行,不会停下后面的只要是正确的,都要执行

    image-20230524173452598

    image-20230524173057292

image-20230524165552750

image-20230524170542597

image-20230524172951823

image-20230524173018391

image-20230524173534429

image-20230524173557400

image-20230524173621964

image-20230524173654049

5. Redis管道

5.1引出

image-20230526102946700

image-20230526103301237

image-20230526103328889

因此我们需要批处理这样的操作,类似于mset这样的操作,所以使用了管道的概念

image-20230526103512130

5.2 是什么

image-20230526103640940

image-20230526103711223

5.3 使用

image-20230526104151570

5.4 总结

Pipeline VS 原生批量命令:

image-20230526104904254

Pipeline VS Redis事务:

Redis是不保证原子性(比如编译正确,但执行错误的时候)

image-20230526110350630

Pipeline 注意事项:

image-20230526111634795

6. Redis发布订阅(了解)

6.1 定义

image-20230526111900927

image-20230526113355690

image-20230526113422146

image-20230526113518491

image-20230526113549311

6.2 命令

image-20230527163239002

image-20230527165124893

image-20230527165145025

image-20230527165330301

image-20230527165346784

image-20230527165424126

6.3 缺点

image-20230527165641768

image-20230527165618256

7. Redis复制

7.1 是什么

image-20230527170021654

7.2 功能

读写分离:写找主机,读找从机

image-20230527170238575

7.3 使用理论

image-20230527171131609

image-20230527171144005

image-20230527171355140

image-20230527171414856

7.4 使用

image-20230527171825703

image-20230527172121342

image-20230701165808973

7.5 主从复制

7.5.1 一主二从

image-20230701172627011

image-20230701173224914

读写分离,从机不允许写入

在主机写入,从机读取

主机写入的,从机都会复制到,也就是主从的数据一样

流程

从机在启动后,会一次性写入主机的数据(覆盖原有数据,完全复制主机数据

主机收到同步命令后,会在后台保存快照(RDB持久化),并缓存收集到的修改数据集的命令,RDB持久化完成后,master将rdb快照文件和所有缓存的命令发送到所有slave,完成完全同步,slave收到后加载到内存

然后每10秒(默认)保持通信,完成增量复制(批次)

从机如果关机了,在开机的时候会一次性写入主机之前新写入的数据(根据backlog的offset来确定,只会复制其后的数据,类似断点续传),然后继续跟随复制

主机挂掉,从机原地等待,从机数据可以正常使用

前面是采用配置文件来声明为从机

如果采用命令方式来声明为从机(slaveof),只是临时有效,shutdown之后恢复为master

image-20230701171727452

7.5.2 薪火相传

image-20230701172650093

image-20230701172126659

一条链中间的slave仍然是从机,不能写入

7.5.3 反客为主

image-20230701172858578

image-20230701172947394

7.5.4 缺点

同步有一定延迟,当系统繁忙时或机器数量多的时候更加严重

主机挂了,从机会等待(导致不能写入,只能读取),只能手动重启

8. Redis哨兵

8.1 理论

监控master主机是否故障,如果故障,按投票数自动将某个从机转为新主机

image-20230702154644903

8.2 实操

image-20230702155701829

sentinel26379.conf文件:

可以同时监控多个master

image-20230702155343398

image-20230702160239677

image-20230702160354116

image-20230702160604626

image-20230702174733445

image-20230702175143744

再连一次即可

由于主机挂了,会变成从机,所以也要填写masterauth,但是为什么不用填写replicaof,因为后面会自动rewrite,而密码她不知道,所以我们要自己填写(masterauth)

image-20230702175414054

image-20230702175739890

8.3 主观下线(SDown)

即单个哨兵认为,主机挂了

image-20230702190622828

8.4 客观下线(ODown)

image-20230702190808041

image-20230702190824779

当判断为客观下线后,选出一个哨兵作为leader(由Raft算法完成),由它一个人来完成故障迁移(failover)image-20230702191030317

8.5 新master的选法

规则:

1. 设置的优先级 最高
1. 复制的offset 最大
1. RUN ID 最小

image-20230702193452992

image-20230702193610361

image-20230702193628828

8.6 更换主从关系

image-20230702193806569

对于老的master:

image-20230702193922634

8.7 过程总结

image-20230702194046490

image-20230702194020052

8.8 使用建议

image-20230702194145868

由于更换主从需要时间,这段时间可能导致数据丢失,故引出后面的集群

9. Redis集群

9.1 是什么

原来只有一台master提供写操作,写操作的压力大,现在集群是多个master,数据共享,各自记录分别的数据(通过slot计算),一个挂了,他的从机自动上位变成master

image-20230703164058667

image-20230703164417411

image-20230703164432113

9.2 能干吗

image-20230703165313807

9.3 槽位slot

最多16384个,建议小于1000

多个master会一起分配这16384个slot(分片),每个master都有一定范围的slot

这样,可以通过计算来判断写入操作寻找哪个master

image-20230703170057810

9.4 分片

image-20230703170237741

image-20230703170817325

9.5 槽位和分片的优势

image-20230703171456382

加一台,只需要前面几台匀一些给它,方便扩容,并且重分配时不会停止服务

9.6 slot槽位映射的3种解决方案

9.6.1 哈希区域分区

直接对N取余,分配到0,1,2...N-1台机器

缺点:

1. 不好扩容,N变化,需要修改映射关系
1. 某个或某些机器故障,导致N不确定,不可控 ![image-20230703172352867](/typora-user-images/image-20230703172352867.png)

9.6.2 一致性哈希算法分区

步骤:

image-20230703172745214

image-20230703173052759

image-20230703173440730

image-20230703173346242

优点:

容错性、扩展性

image-20230703173844800

image-20230703173917037

image-20230703173940174

image-20230703174021560

缺点:

数据倾斜

image-20230703174229330

总结:

image-20230703174416554

9.6.3 哈希槽计算

是什么:

​ 实质是一个数组:image-20230703174838552 214 = 16384

image-20230703174724756

能干什么:

image-20230703174948881

image-20230703175108797

为什么采用16384而不是216

image-20230703180851057

image-20230703180914979

image-20230703181151244

image-20230703180404201

image-20230703180701749

9.7 Redis集群不保证强一致性

image-20230703182111088

image-20230703182229666

9.8 集群搭建

image-20230703183215202

image-20230703183155279

image-20230703183840189

image-20230703183912717

image-20230703183938257

image-20230703184328914

image-20230703184441905

9.9 读写数据

普通的登录,写入可能出错:

image-20230703185400159

image-20230703185344279

解决方法(-c):

image-20230703185526766

image-20230703185608669

image-20230703185752939

输出槽位号(cluster keyslot)

image-20230703185821040

9.10 容错切换

一台master宕机,其从机上位,旧master归来后变成从机

如果想要保持原来的关系,使用cluster failover命令(节点从属调整)

image-20230703192915729

image-20230703193122985

9.11 扩容

image-20230703201616376

image-20230703201708794

image-20230703201839723

image-20230703201915949

image-20230703202011563

直接选部分,用来分配,而不是全部重新分配(即不是平均一人一段),现在新加的,由三段构成

image-20230703202421950

image-20230703202454189

9.12 缩容

image-20230703202629131

image-20230703202647612

image-20230703202736835

image-20230703202819827

image-20230703203107239

image-20230703203434552

image-20230703203543429

image-20230703203615772

9.13 总结

image-20230703203806476

image-20230703203826213

image-20230703204122407

image-20230703204319115

可以是x,也可以是任意的

image-20230703205357485

image-20230703205251468

10. Springboot整合Redis

Jedis -> lettuce -> RedisTemplate

Jedis是最早的,lettuce是第二代,现在主要用springboot整合的RedisTemplate

10.1 连接Redis问题

image-20230704155022413

10.2 Jedis

image-20230704160702865

10.3 Lettuce

解决Jedis的线程不安全问题

image-20230704160710001

image-20230704165831372

10.4 RedisTemplate

10.4.1 单机

image-20230704173730481

image-20230704173819635

image-20230704173911805

image-20230704174032187

image-20230704175451752

存在序列化问题(因此需要Redis配置类或者StringRedisTemplate)

image-20230704183043918

对于Key乱码

  1. 使用StringRedisTemplate能够解决key的乱码问题,但是局限于String
  2. 最好使用Redis配置类,就能继续使用RedisTemplate,如下,下面springboot高版本报错,但是不影响使用
package com.xxx.studyredistemplate.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    /**
     * redis序列化的工具配置类,下面这个请一定开启配置
     * 127.0.0.1:6379> keys *
     * 1) "ord:102"  序列化过
     * 2) "\xac\xed\x00\x05t\x00\aord:102"   野生,没有序列化过
     * this.redisTemplate.opsForValue(); //提供了操作string类型的所有方法
     * this.redisTemplate.opsForList(); // 提供了操作list类型的所有方法
     * this.redisTemplate.opsForSet(); //提供了操作set的所有方法
     * this.redisTemplate.opsForHash(); //提供了操作hash表的所有方法
     * this.redisTemplate.opsForZSet(); //提供了操作zset的所有方法
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory )
    {
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();

        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        //设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

}

对于Value乱码的解决:

使用--raw启动客户端

image-20230704182721318

10.4.2 集群

image-20230704183357009

问题

当一个master挂掉,从机上位,springboot客户端没有动态感知到架构变化

image-20230704184743501

image-20230704184817931

image-20230704184900567

image-20230704184927423

image-20230704185026760