Remote Dictionary Server

assets/Redis入门/image-20231017214847414.png

Redis 十大数据类型

Key

命令不区分大小写 Key 区分大小写

  • 查看所有 key keys *

  • exists key

  • type key

  • del key

  • unlink key 非阻塞删除,仅仅将 keys 从 keyspace 元数据中删除,真正的删除会在后续异步中操作。 del key 是原子的删除,只有删除成功了才会返回删除结果,如果是删除大 key 用 del 会将后面的操作都阻塞,而 unlink key 不会阻塞,它会在后台异步删除数据

  • ttl key查看还有多少秒过期,-1表示永不过期,-2表示已过期

  • expire key 为给定的key设置过期时间

  • move key dbindex[0-15] 将当前数据库的key移动到给定的数据库DB当中

  • select dbindex 切换数据库【0-15】,默认为0

  • dbsize

  • flushdb [ASYNC/SYNC]

  • flushall

  • help @类型 , help @hash

keys pattern keys * keys set* exists key type key del key ../../../实战项目/assets/苍穹外卖/image-20231105225952599.png

字符串 String

string 是 redis 最基本的类型,一个 key 对应 一个 value

string 类型是 二进制安全 的,意思是 redis 的 string 可以包含任何数据,比如 jpg 图片或者序列化的对象。

string 类型是 Redis 最基本的数据类型,一个 redis 中字符串 value 最多可以是 512M

  • SET key value
  • Get key
  • SETEX key seconds value
  • SETNX key value Set if not exists ../../../实战项目/assets/苍穹外卖/image-20231105202010994.png

列表 (list)

../../../实战项目/assets/苍穹外卖/image-20231105205301485.png assets/Redis入门/image-20231121205027427.png

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

它的底层实际是个双端链表,最多可以包含 2^32-1 个元素 (4294967295,每个列表超过 40 亿个元素)

简单的字符串列表,按照插入顺序排序 assets/Redis入门/image-20231121205430305.png

  • lpush key value1 value2 value3
  • lrange key start stop 0 代表头部,-1 代表尾部
  • rpop key
  • llen key
  • lindex key index
  • llen key
  • lrem key number value number=0 代表全部
  • ltrim key index1 index2 删除从索引 index1 到索引 index2 的值
  • rpoplpush key1 key2 将 key1 最后一个数据弹到 key2 assets/Redis入门/image-20231121210221569.png
  • lset key index value 替换
  • linsert before value1 value2/aftervalue1 value2 before 在 value 1 前插入 value 2 assets/Redis入门/image-20231121210705633.png

assets/Redis入门/image-20231121205648659.png assets/Redis入门/image-20231121205704258.png

../../../实战项目/assets/苍穹外卖/image-20231105205257829.png

../../../../实战项目/assets/苍穹外卖/image-20231105204947520.png ../../../实战项目/assets/苍穹外卖/image-20231105205019432.png 最后插入的在第一位

哈希 (hash)

../../../实战项目/assets/苍穹外卖/image-20231105205328325.png

一个 String 类型的 field 和 value 的映射表,hash 特别适合存储 对象

Redis hash 是一个 string 类型 field (字段)和 value (值)的映射表, hash 特别适合用于存储对象。
Redis 中每个 hash 可以存储 2^32-1 键值对 (40 多亿) assets/Redis入门/image-20231121214424602.png

  • HSET key field value
  • HGET key field
  • HDEL key field
  • HKEYS key
  • HVALS key
  • hlen key
  • hexists key
  • hkeys/hvals
  • hincrby/hincrbyfloat
  • hsetnx

../../../../实战项目/assets/苍穹外卖/image-20231105205322936.png

assets/Redis入门/image-20231121215510513.png

集合 (set)

单值多 value, 无重复,无序无重复, list 是有序有重复

../../../实战项目/assets/苍穹外卖/image-20231105210036482.png assets/Redis入门/image-20231121215858544.png

String 类型的无序集合,集合成员是唯一的,集合中 不能重复 的数据

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,集合对象的编码可以是 intset 或者 hashtable Redis 中 Set 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1) 集合中最大的成员数为 2^32-1 (4294967295,每个集合可存储 40 多亿个成员)

assets/Redis入门/image-20231121200638105.png assets/Redis入门/image-20231121200839424.png

  • kepptll 默认改后的 ttl 会变成-1, 需要指定不变

mset/mget 批量 getrange/setrange assets/Redis入门/image-20231121201854839.png assets/Redis入门/image-20231121201952299.png

INCR INCRBY DECR DECRBY

assets/Redis入门/image-20231121202052446.png STRLEN k1 xxx (String Length) APPEND key value assets/Redis入门/image-20231121202136946.png

  • sadd key nember1 number2 number3 添加的有重复时会自动去重

  • smembers key 遍历

  • scard key 个数

  • srem key member1 member2 member3 删除

  • srandmember key [数字] 从 key 中随机展示[数字]个的元素,元素不删除

  • spop key[数字] 从集合中随机弹出一个元素,弹一个删除一个

  • smove key1 key2 value 将 key1 中的 value 迁移给 key2 assets/Redis入门/image-20231121220621472.png

  • sdiff key1 key2 : key 1-key 2的结果

  • sinter key1 key2 key3 交集

  • sintercard numkeys key [key...] [LIMIT limit] 也是交集,返回个数 assets/Redis入门/image-20231121220933551.png

  • sunion key1 key2 key3 并集

../../../../实战项目/assets/苍穹外卖/image-20231105210029219.png

assets/Redis入门/image-20231121201629268.png 全部成功才有效

有序集合 (ZSET)

../../../../实战项目/assets/苍穹外卖/image-20231105210503319.png

String 类型元素的集合,且不允许有重复成员,每个元素都会关联一个 double 类型的分数,通过分数进行排序

  • zadd key 分1 名1 分2 名2 分3 名3
  • zscore key member 获取元素分数
  • zCARD key 获取集合中元素的数量
  • zrangen key start stop [withscores]
  • zincrby key increment member
  • zrem key member [memeber ...] 删除
  • zmpop number key min count 1
  • zrank key values/zrevrank key values 获取下标值/逆序或者下标值

../../../Project/assets/苍穹外卖/image-20231105210408970.png

assets/Redis入门/image-20231122192919337.png

地理空间 (GEO)

乱码 : 使用中文连接 reids 时候要加 --raw

Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作 (经度,维度)

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

assets/Redis入门/image-20231122204143924.png

  • geoadd key 经度 维度 name GEOADD city 116.403963 39.915119 "天安门" 116.403414 39.924091 "故宫" 116.024067 40.362639 "长城"

  • geopos 返回经纬度 assets/Redis入门/image-20240228120420573.png

  • geohash 返回坐标的 geohash 表示 生成 base32 的编码值,代表了坐标 assets/Redis入门/image-20240228120448132.png

  • geodist key name1 name2 [m|km|ft|mi] 自动计算两个地方相距 assets/Redis入门/image-20231122210330694.png

  • georadius 以给定的经纬度为中心,返回键包含的位置元素中,与中心的距离不超过给定最大距离的所有位置元素 assets/Redis入门/image-20231122210524494.png

  • georadiusbymember assets/Redis入门/image-20231122205359002.png

redis 基数统计(HyperLogLog)

储存数据个数,不存储实际内容

HyperLogLog 是用来做 基数统计 的算法,具有 去重复统计 功能,是 String 类型

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

HyperLogLog是一种概率算法,储存的是数据的个数

在Redis里面,每个HyperLogLog键只需要花费12KB内存,就可以计算接近2^64个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

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

统计大致多少人访问过一个页面,IP 同一个只代表一个,去重复统计独立访客

assets/Redis入门/image-20231122202717716.png assets/Redis入门/image-20231122202857682.png

  • pfadd key value1 value2 value3
  • pfcount key
  • pfmerge key key1 key2 合并 key1 ,key 2 ,并不会存储具体的值,只会告诉你数量

一句话:去重脱水后的真实数据 assets/Redis入门/image-20240227201541008.png

assets/Redis入门/image-20231122203556920.png

redis 位图(bitmap)

由 0 和 1 状态表现的二进制位的 bit 数组,相当于 string 的子类,类型还是string

assets/Redis入门/image-20231121190255065.png 是否登陆过,是否点过,打卡上下班,签到统计 使用 mysql 的数据量过大

  • setbit key 位置 值 值只能 0 或 1
  • getbit key 位置
  • strlen 统计字节占用多少, 8 位一个 bitmap setbit k1 1 1 setbit k1 7 1 占用一个字节 setbit k1 1 1 setbit k1 8 1 占用两个字节
  • bitcount key 统计

assets/Redis入门/image-20231122200304768.png

assets/Redis入门/image-20231122200255908.png

assets/Redis入门/image-20231122200827153.png

redis 流(Stream)

Redis Stream 是 Redis5.0版本新增加的数据结构。

Redis Stream主要用于消息队列(MQ,Message Queue),Redis本身就是一个Redis发布订阅(pub/sub)来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis宕机等,消息就会被丢弃。

简单来说发布订阅(pub/sub)可以分发消息,但无法记录历史消息。

而Redis Stream提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。

5.0 之前 assets/Redis入门/image-20231123092240065.png assets/Redis入门/image-20231123092226220.png assets/Redis入门/image-20231123092353082.png

assets/Redis入门/image-20231123092836878.png assets/Redis入门/image-20231123093213705.png

队列相关指令

队列: 即产生的一列 IDx

队列相关指令

  • xadd 队列名 * key1 value1 key2 value2 消息 id 必须比上一个大, * 用于让系统自动生成 id, 会生成消息 ID assets/Redis入门/image-20231123100537117.png

assets/Redis入门/image-20231123094601208.png assets/Redis入门/image-20231123094610916.png

  • xrange mstream - +

assets/Redis入门/image-20231123100544429.png assets/Redis入门/image-20231123100556622.png

  • xdel key ID

  • xlen key - +

  • xtrim key maxlen number 最大的数量,前面的会被截掉 assets/Redis入门/image-20231123100609675.png

  • xread mstream - +

assets/Redis入门/image-20231123100707593.png assets/Redis入门/image-20231123100818606.png assets/Redis入门/image-20231123101137027.png assets/Redis入门/image-20231123101244474.png 阻塞有最大的而才会返回,会告诉你等了多久

消费相关指令

assets/Redis入门/image-20231123112957755.png

  • xgroup 队列名 组名 assets/Redis入门/image-20231123113100326.png assets/Redis入门/image-20231123113033042.png

  • XREADGROUP GROUP 组名 消费名 STREAMS 队列名 assets/Redis入门/image-20231123113313298.png 因为游标已经从头走到尾了,即使同组也不能读 但是不同组可以读 assets/Redis入门/image-20231123113542833.png

assets/Redis入门/image-20231123114041008.png

  • xpending 队列名 组名 查询每个消费组内所有消费者

assets/Redis入门/image-20231123114405793.png

  • xpending 队列名 组名 - + count 消费者 查看某个消费者读取了哪些数据 assets/Redis入门/image-20231123114926474.png 签收后再查读取过的数据会只剩没有签收的

xinfo stream 队列名 assets/Redis入门/image-20231123115317186.png

redis 位域(bitfield)(了解)

将 redis 字符串看作一个由二进制组成的数组,并能对变长位宽和任意没有字节对其的指定整形位域进行寻址和修改

通过 bitfield 命令可以一次性操作多个比特位域(指的是连续的多个比特位),它会执行一系列操作并返回一个响应数组,这个数组中的元素对应参数列表中的相应的执行结果。

说白了就是通过 bitfield 命令我们可以一次性对多个比特位域进行操作。

assets/Redis入门/image-20231123115707795.png assets/Redis入门/image-20231123115754768.png assets/Redis入门/image-20231123115826030.png ascii码 | ascii码对照表

位域修改 ,溢出控制

assets/Redis入门/image-20231123120056197.png

相当于可以改字节码

assets/Redis入门/image-20231123120325015.png assets/Redis入门/image-20231123121343466.png

assets/Redis入门/image-20231123120639247.png

assets/Redis入门/image-20231123120652968.png -128-127 超过则溢出

assets/Redis入门/image-20231123121237132.png

../../../../实战项目/assets/苍穹外卖/image-20231115200200782.png ../../../实战项目/assets/苍穹外卖/image-20231115200205004.png 两个:: 就会有 empty ../../../Project/assets/苍穹外卖/image-20231115200324146.png ../../../Project/assets/苍穹外卖/image-20231115200336930.png

redis 持久化

Redis persistence | Redis

Persistence refers to the writing of data to durable storage

  1. 通过 RDB 快照文件 (dump.rab) 恢复,将磁盘的快照恢复到内存
  2. 通过 AOF 记录的命令进行恢复

RDB

启用: save time num time 内触发 num 次就生效 禁用 : save "" 或 redis-cli config set save ""(非永久性) 依旧可以手动 save/bgsave 生成 RDB

  • 路径修改

  • 文件名修改: 配置文件搜 dump.

  • 配置文件搜索 config get dir 获取目录

  • 遇到的问题: 需要 dumpfiles 文件夹权限更改

SAVE 阻塞,其他命令都会不能处理,线上禁止使用 BGSAVE: fork 一个子进行进行复制持久化,主进行可以同时修改数据

assets/Redis入门/image-20231126151848905.png

fork()

fork() 函数会创建一个完全和父进程相同的子进程,包括代码、数据和打开的文件描述符等。 assets/Redis入门/image-20231126151647572.png assets/Redis入门/image-20240411183509864.png

lastsave date -d

lastsave于获取最近一次成功执行持久化操作(快照或AOF)的时间戳。它可以告诉你上次完成持久化的时间,对于监控和管理 Redis 实例非常有用 assets/Redis入门/image-20240411183910192.png assets/Redis入门/image-20231126152035426.png date -d @16695455399 assets/Redis入门/image-20231126152053891.png

RDB 优缺点
  1. 适合大规模数据恢复
  2. 比AOF快
  3. 定时备份

assets/Redis入门/image-20231126153008277.png assets/Redis入门/image-20231126153045751.png

  • RDB 缺点
  1. 在没有触发达到保存条件时发生意外的数据会丢失
  2. fork()可能消耗性能大 assets/Redis入门/image-20231126153320689.png assets/Redis入门/image-20231126153352477.png assets/Redis入门/image-20231126162523850.png
修复

check -rdb /myredis/dumpfiles/dump6379.rdb

assets/Redis入门/image-20231126160209266.png 写到一半断电导致破损了 assets/Redis入门/image-20231126160331485.png

assets/Redis入门/image-20231126160712998.png

优化配置

assets/Redis入门/image-20231126161731124.png

  • stop-writes-on-bgsave-error assets/Redis入门/image-20231126161858568.png

  • yes: 如果在 bgsave 过程中, 发生写入错误, Redis 将停止接收任何请求, 直到 bgsave 完成为止

  • no:即使在bgsave过程中,发生写入错误,Redis也会继续接收请求并尝试写入

assets/Redis入门/image-20231126162149866.png

  • rdbcopression 压缩变小,消耗一点 cpu assets/Redis入门/image-20231126162225061.png

rdbchecksum 安全/一致性 建议 yes assets/Redis入门/image-20231126162254828.png

rdb-del-sync-files 不用管

assets/Redis入门/image-20231126162436632.png

AOF

appendonly yes assets/Redis入门/image-20231126193414852.png

三种写回策略

appendsync everysec

assets/Redis入门/image-20231126193529835.png 一般选 everysec, always 会导致 IO 太多,性能下降

assets/Redis入门/image-20231126193756484.png no 则取决与 linux 内核刷新数据的配置,通常 30 秒

保存规则

assets/Redis入门/image-20231126195937792.png

incr 文件内容 assets/Redis入门/image-20231126210856856.png

修复redis-check-aof --fix 文件名

如果只是数据被截断 redis 不会被影响,redis 会自动抛弃错误的数据,当如果错误的数据发生在文件中,后面的数据也会被抛弃,可能造成数据丢失

人为破坏 incr 文件会连接不上 redis assets/Redis入门/image-20231129221629181.png

AOF 重写机制

appendfsync every/always/no auto- aof- rewrite- percentage 100设置为100表示只要当前 AOF 文件的大小是上一次 AOF 文件大小的两倍或更多 auto- aof- rewrite- min- size 1k incr 文件达到 1k的两倍就会重写

assets/Redis入门/image-20231127115732684.png assets/Redis入门/image-20231127115842764.png

redis 事物

Transactions

事物的要求 : 希望一个命令/多条命令能够合到一起成为一个不可分割,具备原子性,不被干扰打断,统一执行的批处理命令

assets/Redis入门/image-20231127155613382.png assets/Redis入门/image-20231127155650633.png

assets/Redis入门/image-20231127155803172.png assets/Redis入门/image-20231127155755041.png

正常执行

multi exec

放弃事物

multi discard

全体连坐

输入过程中检查出错误,redis 会直接返回错误,任何命令都不会执行

assets/Redis入门/image-20231127161053009.png

冤头债主

前期检查不出的错误,运行时才知道,只有出错的才不会执行 assets/Redis入门/image-20231127161546569.png assets/Redis入门/image-20231127161532114.png

watch 监控

无加塞情况 assets/Redis入门/image-20231127162554965.png

有加塞情况 assets/Redis入门/image-20231127162726154.png assets/Redis入门/image-20231127163027159.png

Redis 管道

Redis pipelining | Redis 如何优化频繁命令往返造成的性能瓶颈

assets/Redis入门/image-20231127190117404.png assets/Redis入门/image-20231127190122911.png assets/Redis入门/image-20231127190249430.png 降低 RTT(Round Trip Time) 对性能的影响

assets/Redis入门/image-20231127190300529.png

assets/Redis入门/image-20231127190801826.png

assets/Redis入门/image-20231127191453890.png 需要 linux 客户端和 服务端共同完成 assets/Redis入门/image-20231127191824419.png

assets/Redis入门/image-20231127191846890.png

Redis 发布订阅 (了解)

assets/Redis入门/image-20231127192118410.png assets/Redis入门/image-20231127192133520.png

assets/Redis入门/image-20231127192035674.png 就是 redis 消息队列的前身雏形 assets/Redis入门/image-20231127192244259.png assets/Redis入门/image-20231127192255279.png assets/Redis入门/image-20231127192312758.png

assets/Redis入门/image-20231127192329346.png

  • subscribe channel [channel ...]

assets/Redis入门/image-20231127192355858.png

  • publish channel message assets/Redis入门/image-20231127192454696.png

  • publish pattern [pattern ...] assets/Redis入门/image-20231127192503194.png

  • pubsub subcommand [argument [argument ...]] assets/Redis入门/image-20231127192606406.png

  • unsubscribe [channel [channel ...]] assets/Redis入门/image-20231127192722621.png

  • Punsubscribe [pattern [pattern ...]]

assets/Redis入门/image-20231127192732320.png

redis 复制(replica)

Redis replication | Redis

主从复制 : master 以写为主,slave 以读为主 当 master 数据变化时,自动将新的数据异步同步到其他 slave 数据库

assets/Redis入门/image-20231127194141359.png 配从库不配主库

配置


---通用部分---
bind 0.0.0.0 # 允许地址
protected-mode: yes #防止Redis实例在未进行任何安全配置(如requirepass/bind)的情况下被外界访问。
daemonize yes               # 允许后台启动
logfile "/usr/local/redis/redis.log"                # 日志路径
dir /opt/software/redis-7.0.3/data                 # RDB文件存放目录
appenddirname "appendonlydir"  # AOF文件会在dir的位置上的appenddirname文件夹保存
appendfilename "appendonly.aof" # AOF文件名
appendonly yes                  # AOF 开启

`redis` 主从: 读写分离,容灾恢复,数据备份,水平扩容支撑高并发

主从:slave依旧可以作为其他slave的master(减少master的压力)
只有最顶层master可以执行命令,slave会复制之前的也可以复制 
主机挂了从机会等待主机上线
中途变更:从机可以随时修改主机,修改后会自动清楚之间的数据,拷贝新master的

缺点: 
	挂了需要人工干预
	系统繁忙时,slave导致延迟高
	
--- Master.conf-----
requirepass xxx #master设置

--- 主从Slave.conf(只需要改从库配置,无需更改主库配置)------
# 指定主节点的 IP 和端口(推荐)
replicaof 主库IP 主库端口
# 或者使用旧的方式
slaveof 主库IP 主库端口
slaveof no one #停止当前数据库和其他数据库的同步

masterauth xxx #slave设置

---- 命令行 ----

info replication #查看信息
slaveof 主库IP 主库端口  # 手动执行,当前会话有效

复制原理和工作流程

assets/Redis入门/image-20231128082838348.png

redis 哨兵sentinel

assets/Redis入门/image-20231128083837925.png 无人值守运维 : 将 slave 通过某种机制进行选取,进行主从替换

作用 主从监控: 监控主从 redis 运行 消息通知: 故障转移结果发送客户端 故障转移: 自动主从切换 配置中心: 通过连接哨兵来获得当前 Redis 服务器主节点地址

sentinel.conf 配置文件

在上一章复制配置好的情况下进行配置

sentinel.conf(配置好一个后直接拷贝改动)


配置文件

assets/Redis入门/image-20231202212105408.png assets/Redis入门/image-20231128162041506.png assets/Redis入门/image-20231128162104861.png assets/Redis入门/image-20231128162109484.png assets/Redis入门/image-20231128162114947.png assets/Redis入门/image-20231128162136182.png assets/Redis入门/image-20231128162129561.png

解释

assets/Redis入门/image-20231128162400248.png assets/Redis入门/image-20231128161705724.png sentinel monitor <master-name> <ip> <redis-port> <quorum> assets/Redis入门/image-20231128162455437.png quorum : 2 即 2 个哨兵同意就行 assets/Redis入门/image-20231128161803719.png assets/Redis入门/image-20231128161809890.png 网络拥堵,黑客攻击,网络波动等等,哨兵之前互相沟通,来判断是否真的故障了,有时只是某个哨兵自身问题 sentinel auth-pass <master-name> <password> assets/Redis入门/image-20231128162738844.png

启动集群

assets/Redis入门/image-20231128163233329.png assets/Redis入门/image-20231128163700822.png

sentinel log

assets/Redis入门/image-20231128164037050.png assets/Redis入门/image-20231128164208041.png

conf 文件被自动修改

assets/Redis入门/image-20231128164435226.png

关闭 master 接近 1s ,后台进行了选举,同时 slave. conf 的文件也会被修改

被选为主机的 conf 文件内容被自动删除

assets/Redis入门/image-20231128185117573.png

被选为 slave 的自动被修改 assets/Redis入门/image-20231128184954431.png

assets/Redis入门/image-20231128185229310.png

assets/Redis入门/image-20231128164551422.png assets/Redis入门/image-20231128164737006.png

第一次失败是因为需要进行网络的重新读取和规划,告诉你原有的连接被断开了,可能需要重发一次心跳包,重新续接上去

剩下的两台slave其中一台会被选为master

assets/Redis入门/image-20231128165424672.png

即使之前的 master 回来,也不会成为现在的 master 了

assets/Redis入门/image-20231128174912268.png

小问题

assets/Redis入门/image-20231128174728658.png

assets/Redis入门/image-20231128174756181.png

assets/Redis入门/image-20231128174813772.png

哨兵的运行流程和选举原理

assets/Redis入门/image-20231128190252964.png

  1. SDown 主观下线 (Subjectively Down)

assets/Redis入门/image-20231128190530847.png assets/Redis入门/image-20231128191904890.png

  1. ODown 客观下线 ( Objectively Down) assets/Redis入门/image-20231128192001394.png assets/Redis入门/image-20231128192020926.png
    1. 选出哨兵

    assets/Redis入门/image-20231128192654194.png assets/Redis入门/image-20231128192617151.png assets/Redis入门/image-20231128192143544.png 三个中选出一个 leader, 这个 leader 选出 master 4. 选举日志 assets/Redis入门/image-20231128192349190.png

  • 选举 Raft 算法 assets/Redis入门/image-20231128192506406.png
    1. 由哨兵开始推动 故障切换 流程并选出一个新的 master assets/Redis入门/image-20231128193708167.png
      1. 选出新 master

      assets/Redis入门/image-20231128193445312.png assets/Redis入门/image-20231128192952244.png assets/Redis入门/image-20231128193141643.png 复制偏移量 (replication offset) : 由于网络等原因,两个 slave 不一定一样大 2. 生成 master, 别的变成 master 的 slave assets/Redis入门/image-20231128193431966.png 3. 将已下线的老的 master 设置为新选出的 master 的从节点 assets/Redis入门/image-20231128193459673.png assets/Redis入门/image-20231128193636342.png

使用建议

assets/Redis入门/image-20231128193847788.png

虽然能够无人值守的故障迁移 : 但是选举哨兵 leader 和生成新的 master,少说需要 5-10s, 这期间的数据就会丢失

-

redis 集群 (cluster)

redis-cli -a password -p 6385 -c -c 进行路由传递

assets/Redis入门/image-20231202212649536.png assets/Redis入门/image-20231202212834197.png assets/Redis入门/image-20231202213448232.png assets/Redis入门/image-20231202213554725.png 不再需要之前的哨兵

作用

assets/Redis入门/image-20231202213834193.png

集群算法-分片-槽位 slot

assets/Redis入门/image-20231203131219819.png assets/Redis入门/image-20231203131116284.png

优势 assets/Redis入门/image-20231203131040071.png

assets/Redis入门/image-20231203131230997.png 读写都是同一个槽位 assets/Redis入门/image-20231203131554439.png

键值会用 CRC16 算法进行校验和,然后对 16384 取模,得到一个槽位的编号(如 1234 号)

assets/Redis入门/image-20231203132043842.png

哈希槽位映射

哈希取余分区

assets/Redis入门/image-20231203144348748.png assets/Redis入门/image-20231203144408975.png

一致性哈希算法分区

一致性哈希算法分区 : 所有的 hash 值构成一个全量集,逻辑控制使其首尾相连形成一个闭合空间,所有哈希值都落到环上,服务器节点也根据哈希落到环上,然后值会顺时针找到最近的服务器节点进行存储

优点 : 容错性,拓展性

缺点: 服务器太少时会出现数据倾斜问题

assets/Redis入门/image-20231203235042370.png 提出一致性 Hash 解决方案,目的是当服务器个数发动变化时,尽量减少影响客户端到服务器的映射关系

算法构建一致性哈希环

assets/Redis入门/image-20231203235403225.png assets/Redis入门/image-20231203235412330.png assets/Redis入门/image-20231203235419050.png assets/Redis入门/image-20231204194821114.png

redis 服务器 IP 节点映射 assets/Redis入门/image-20231204193546139.png assets/Redis入门/image-20231204193557277.png

key 落到服务器的落键规则

assets/Redis入门/image-20231204194356866.png assets/Redis入门/image-20231204194413583.png

优点

  • 容错性 assets/Redis入门/image-20231204195936881.png assets/Redis入门/image-20231204195941607.png

  • 拓展性

assets/Redis入门/image-20231204195956302.png assets/Redis入门/image-20231204200040523.png

缺点

assets/Redis入门/image-20231204200101720.png assets/Redis入门/image-20231204200111578.png

哈希槽分区 assets/Redis入门/image-20231204200408320.png assets/Redis入门/image-20231204200413940.png

哈希槽分区

哈希槽分区 : 在 数据 和 节点 中加了一层 哈希槽 (16384),来管理 数据和节点间的关系, 槽 解决了粒度问题,哈希 解决了映射问题,

redis 会将大致相等的哈希槽分别映射到不同节点上

哈希值对 16384 取模,余数是几落到对应的槽里

assets/Redis入门/image-20231204200722768.png assets/Redis入门/image-20231204200821099.png assets/Redis入门/image-20231204200826047.png HASH_SLOT= CRC16(key) mod 16384

  • 哈希值计算 assets/Redis入门/image-20231205083811562.png assets/Redis入门/image-20231205083818441.png assets/Redis入门/image-20231205083827192.png

为何 redis 集群最大槽数是 16384 个

  1. assets/Redis入门/image-20231205084534724.png assets/Redis入门/image-20231205084554208.png assets/Redis入门/image-20231205084713411.png assets/Redis入门/image-20231205085258694.png assets/Redis入门/image-20231205085304306.png assets/Redis入门/image-20231205085318451.png

redis 集群不保证强一致性,在特定条件下,redis 集群可能会丢掉一些被被系统收到的写入请求命令 assets/Redis入门/image-20231205085505374.png

集群环境搭建步骤

三主三从 redis 集群配置

assets/Redis入门/image-20231205230852024.png

1. 新建6个配置目录 mkdis -p /myredis/cluster
2. 配置6个配置文件
3. 构建主从关系

assets/Redis入门/image-20231205153658678.png assets/Redis入门/image-20231205153741767.png assets/Redis入门/image-20231205154742443.png 不一定按照写的分配, 以实际分配为准

assets/Redis入门/image-20231205153138122.png 主,从的配置文件完全一样,如下(视频 6 台配置文件全部都是下面内容) assets/Redis入门/image-20231205152529952.png 5000ms = 5s

3.构建主从关系

不一定按照写的分配, 以实际分配为准

redis-cli -a password --cluster create --cluster-replicas x 
ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6

assets/Redis入门/image-20231205154211128.png assets/Redis入门/image-20231205154225253.png assets/Redis入门/image-20231205154317053.png assets/Redis入门/image-20231205154328501.png

以 6381 为切入点,查看并检验集群关系

info replication assets/Redis入门/image-20231205155031182.png assets/Redis入门/image-20231205155430747.png

cluster nodes

assets/Redis入门/image-20231205155115235.png assets/Redis入门/image-20231205155143405.png

三主三从 redis 集群读写

assets/Redis入门/image-20231205230916809.png assets/Redis入门/image-20231205161316784.png assets/Redis入门/image-20231205161350237.png 由于槽位的限制,不再是想怎么存就怎么存,需要路由到位 assets/Redis入门/image-20231205161521080.png assets/Redis入门/image-20231205161717414.png 内部由于有 CRC16 和重定向算法 k1 被重定向到另一个槽位

连接集群需要加 c, 这样连接的是大redis redis-cli -a password -p 6385 -c assets/Redis入门/image-20231205162004326.png

  • cluster keyslot 键

查看某个 key 的槽位值 assets/Redis入门/image-20231205162205983.png

主从容错切换迁移案例

assets/Redis入门/image-20231205230907949.png

master 挂后 slave 会自动上位,即使之前 master 重新回归,也会变成slave assets/Redis入门/image-20231205165234327.png assets/Redis入门/image-20231205170302315.png 恢复后变成slave assets/Redis入门/image-20231205170323087.png assets/Redis入门/image-20231205170339639.png

手动故障转移 or 节点从属调整

assets/Redis入门/image-20231205230829552.png

CLUSTER NODES

assets/Redis入门/image-20231205170556028.png 将之前的 master 恢复后还变成master

主从扩容案例

assets/Redis入门/image-20231205230817239.png

assets/Redis入门/image-20231205170824165.png

添加 redis-cli -a password --cluster add-node ip1:port1 ip:port ip1:port1 是新加的地址 ip:port 是已有的地址 加入后不会被分配槽号 assets/Redis入门/image-20231205173021176.png assets/Redis入门/image-20231205173035025.png assets/Redis入门/image-20231205173042672.png

检查

assets/Redis入门/image-20231205173056997.png 加入后不会被分配槽号 assets/Redis入门/image-20231205173102117.png

重新分配槽号 (reshard)

redis-cli -a psw --cluster reshard ip:port

assets/Redis入门/image-20231205174241978.png 填 16384/4=4096 assets/Redis入门/image-20231205174344627.png 填新的 assets/Redis入门/image-20231205174353465.png assets/Redis入门/image-20231205174409229.png assets/Redis入门/image-20231205174420847.png

分配好了槽位,目前还没有挂slave assets/Redis入门/image-20231205174526896.png assets/Redis入门/image-20231205175038245.png assets/Redis入门/image-20231205175226091.png

assets/Redis入门/image-20231205175404224.png assets/Redis入门/image-20231205175418201.png assets/Redis入门/image-20231205175431590.png

assets/Redis入门/image-20231205175548040.png

主从缩容案例

assets/Redis入门/image-20231205230804953.png

assets/Redis入门/image-20231205230308788.png

redis-cli -a psw --cluster del-node ip:port ID assets/Redis入门/image-20231205231045083.png assets/Redis入门/image-20231205231253566.png slave 被成功删除,接下来将 6387 的槽号清空,重新分配 (本例群不还给了 6381)

redis-cli -a psw --cluster reshard ip:6381 然后输入 4096

assets/Redis入门/image-20231205231545653.png assets/Redis入门/image-20231205231614693.png assets/Redis入门/image-20231205231816259.png 不需要两个 slave , 之后将 6387 删除

redis-cli -a psw --cluster del-node ip:port ID

assets/Redis入门/image-20231205232000366.png

集群常用操作命令和 CRC16 算法分析

assets/Redis入门/image-20231205232531447.png

assets/Redis入门/image-20231205232249543.png assets/Redis入门/image-20231205232547770.png

assets/Redis入门/image-20231205232600766.png assets/Redis入门/image-20231205232616885.png assets/Redis入门/image-20231205232645850.png cluster keyslot key cluster countkeysinslot 12707 assets/Redis入门/image-20231205233046866.png

Spring 使用 Redis

Redis 的 Java 客户端很多,常用的几种: Jedis Lettuce Spring Data Redis

Spring Data Redis 是 Spring 的一部分, 对 Redis 底层开发包进行了高度封装。 在 Spring 项目中, 可以使用 Spring Data Redis 来简化操作

RedisTemplate

连接时注意 :

auth 是客户端的后续认证命令 password 是服务器端的连接认证配置

yaml
server.port=7777

spring.application.name=redis7_study

# ========================logging=====================
logging.level.root=info
logging.level.com.atguigu.redis7=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n 

logging.file.name=D:/Users/XCJY/Desktop/qianduan
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n

# ========================swagger=====================
spring.swagger2.enabled=true
#在springboot2.6.X结合swagger2.9.X会提示documentationPluginsBootstrapper空指针异常,
#原因是在springboot2.6.X中将SpringMVC默认路径匹配策略从AntPathMatcher更改为PathPatternParser,
# 导致出错,解决办法是matching-strategy切换回之前ant_path_matcher
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

# ========================redis单机=====================
spring.redis.database=0
# 修改为自己真实IP
spring.redis.host=192.168.111.185
spring.redis.port=6379
spring.redis.auth=111111
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

lettuceConnectionFactory 适合高并发

RedisConfig

@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)  
    {  
        //开始创建redis模板对象...  
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();  
        //设置redis的连接工厂对象  
       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 的所有属性设置完成后,进行一些初始化操作
        redisTemplate.afterPropertiesSet();  
  
        return redisTemplate;  
    }  
}
SwaggerConfig
@Configuration  
@EnableSwagger2  
public class SwaggerConfig  
{  
    @Value("${spring.swagger2.enabled}")  
    private Boolean enabled;  
  
    @Bean  
    public Docket createRestApi() {  
        return new Docket(DocumentationType.SWAGGER_2)  
                .apiInfo(apiInfo())  
                .enable(enabled)  
                .select()  
                .apis(RequestHandlerSelectors.basePackage("com.atguigu.redis7")) //你自己的package  
                .paths(PathSelectors.any())  
                .build();  
    }  
    public ApiInfo apiInfo() {  
        return new ApiInfoBuilder()  
                .title("springboot利用swagger2构建api接口文档 "+"\t"+ DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()))  
                .description("springboot+redis整合,有问题给管理员阳哥邮件:zzyybs@126.com")  
                .version("1.0")  
                .termsOfServiceUrl("https://www.atguigu.com/")  
                .build();  
    }  
}

RedisTemplate 操作类

Spring 提供的 Redis 数据结构的操作类

  • ValueOperations 类,提供 Redis String API 操作
  • ListOperations 类,提供 Redis List API 操作
  • SetOperations 类,提供 Redis Set API 操作
  • ZSetOperations 类,提供 Redis ZSet(Sorted Set) API 操作
  • GeoOperations 类,提供 Redis Geo API 操作

序列化问题

assets/Redis入门/image-20231206170034684.png

//ThreadLocalRandom.current(): 获取与当前线程绑定的线程本地随机数生成器  
//.nextInt(1000): 生成一个0到999之间的随机整数  
//+1: 将生成的随机整数加1,使范围变为1到1000  
int keyId= ThreadLocalRandom.current().nextInt(1000)+1;  
String serialNO= UUID.randomUUID().toString();

将 redisTemplate 默认使用的``

想让 linux 客户端查看中文 --raw 否则是乱码 assets/Redis入门/image-20231206174534541.png assets/Redis入门/image-20231206171032961.png

原因

assets/Redis入门/image-20231206171347835.png assets/Redis入门/image-20231206171358790.png 默认的是 JDK 序列化方式,会导致乱码,通过手动指定替换掉默认的

assets/Redis入门/image-20231206171523544.png

连接集群

连接集群配置
spring.redis.password=111111
# 获取失败 最大重定向次数
spring.redis.cluster.max-redirects=3
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭,不添加master挂后spring不知道
spring.redis.lettuce.cluster.refresh.adaptive=true

#定时刷新
spring.redis.lettuce.cluster.refresh.period=2000
spring.redis.cluster.nodes=192.168.111.175:6381,192.168.111.175:6382,192.168.111.172:6383,192.168.111.172:6384,192.168.111.174:6385,192.168.111.174:6386

assets/Redis入门/image-20231207091438992.png assets/Redis入门/image-20231207091457707.png

解决方案 assets/Redis入门/image-20231207091744697.png

https://github.com/lettuce-io/lettuce-core/wiki/Redis-Cluster#user-content-refreshing-the-cluster-topology-view

assets/Redis入门/image-20231207091636337.png assets/Redis入门/image-20231207091646755.png

#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭,不添加master挂后spring不知道
spring.redis.lettuce.cluster.refresh.adaptive=true

#定时刷新
spring.redis.lettuce.cluster.refresh.period=2000

资料

  1. 起步思维: 官网
  2. 排除故障思维 : 日志

Redis脑图(基础篇+高级篇) ↗