一、什么是Redis
Redis是一个开源的,使用C语言编写、支持网络调用、基于内存亦可持久化的Key-Value数据库,并提供多种语言的API。
二、Redis的特性(好处)
1.它是内存数据库,速度很快,因为内存的读取速度是磁盘的读取速度的大概几十倍
2.它的工作线程(worker线程)是单线程的,能有效避免数据读取时发生的错乱,但是它的IO线程是多线程的,能够避免上下文切换
3.它是IO(inpoll模型)模型的,天生支持高并发
4.具有kv模型,v具有多种类型结构,string,hash,set
5.将数据以二进制形式存储,能够保证数据安全,并且最大value值为512M
6.具有本地方法(交集并集差集),数据库可以计算,计算向数据移动。(a,b) => 交集
三、Redis是单线程还是多线程的?
Redis6.0之前 IO 线程和 工作线程woker 是同一个线程 -》 单线程
Redis6.0之后 IO线程是多线程的,工作线程是单线程
四、docker安装redis
docker run -d -p 6379:6379 --name redis01 redis:7.2.4
我们需要挂载数据文件,在宿主机上面,这样就可以持久化数据.
docker run -p 6379:6379 -d --name redis01 --restart=always
-v /opt/redis/redis.conf:/etc/redis.conf
-v /opt/redis/data:/data
redis:7.4.0 redis-server /etc/redis.conf
//如果拉不下来请使用m.daocloud.io/docker.io/redis:7.4.0
注意不同版本的redisconf文件存储的位置不同,需要去官网找到对应的版本作为参考。
上边命令每次启动新的容器数据会丢失,因为启动的新容器不是本来的那个容器,里面没有原来的数据,所以会丢失数据。
五、Redis持久化存储
主要有两个持久化机制
1.RDB:是一种快照式的持久化方法,Redis 可以在某个时间点创建内存中的数据集的快照,并将这个快照保存到硬盘上。当 Redis 重启时,它可以加载最新的 RDB 文件到内存中,从而恢复到之前的状态。
Redis会通过fork函数创建一个子进程来进行持久化存储,先把数据写入到一个临时文件(dump.rdb)中,持久化结束后,会用这个临时文件替换上次的文件,fork函数的作用是复制一个与当前线程一模一样的进程,然后作为当前线程的子进程,子进程是一个新进程
优点:
数据恢复速度快:由于 RDB 文件是数据集在某一个时间点的快照,所以在 Redis 重启时加载 RDB 文件的速度非常快。
占用较少磁盘空间:RDB 文件通常比 AOF 文件占用的空间少。
缺点:
数据可能丢失:由于 RDB 文件是在某个时间点创建的,快照之间有时间间隔,不能实时备份数据,所以在创建 RDB 文件之后到 Redis 下一次创建 RDB 文件之前的数据可能会丢失。
创建 RDB 文件的过程可能会阻塞主进程一段时间:特别是在数据集非常大的情况下,创建 RDB 文件的过程可能会阻塞主线程。
2.AOF:是一种日志式的持久化方法,每当有写命令执行时,Redis 就会将这些写命令追加到 AOF 文件的末尾。将操作同步到磁盘的AOF文件中,当AOF文件大小超过重写策略或手动重写时,会对AOF文件进行重写来压缩AOF文件容量,当 Redis 重启时,可以通过重新执行 AOF 文件中的所有写命令来恢复数据。开启的时候手动开启。
压缩就是如果对同一个key执行操作的时候,只会保留最后一个命令
优点:
安全性高,数据丢失的可能性低:通过调整同步频率,可以减少数据丢失的风险。例如,设置为每秒同步一次可以保证最多只丢失一秒的数据。
可维护性较好:AOF 文件是一个简单的文本文件,可以通过文本编辑器查看其内容,也可以通过 Redis 提供的工具来修复损坏的 AOF 文件。
缺点:
占用较多磁盘空间:随着时间推移,AOF 文件可能会变得非常大。
数据恢复速度较慢:相对于 RDB 文件,AOF 文件的恢复速度会慢一些,因为它需要重新执行所有的写命令。
六、Redis常用命令
String:
DECRBY:递减操作,可以指定递减值
GET:根据key获取value值
INCRBY:递增操作,可以指定增加值
MGET:可以一次获取一个或多个值
MSET:可以一次设置一个或多个键值
SET:设置键的值
SETEX:在设置键的值并且设置过期时间,单位是秒
SETNX:这个命令用于设置键值对,但只有在键不存在时才会设置成功。如果键已经存在,则 SETNX
命令不会做任何操作并且返回 0
;如果键不存在,则设置键值对并返回 1
Key:
DEL:删除键值
EXISTS:检查key是否存在,存在返回1,不存在返回0
EXPIRE:设置键过期时间,单位为秒
KEYS:查找匹配的值,用于查找与给定模式匹配的所有键
KEYS pattern
pattern:模糊字符
*所有字符
?一个字符
[ab]查询包含a或b任意一个字符
SCAN:查找匹配的值,用于安全地迭代数据库中的键。它不会像 KEYS
命令那样一次性返回所有匹配的键,而是通过多次请求逐步返回键,避免了对服务器性能的影响
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
cursor:迭代游标,开始为0
pattern:模糊字符
count:可选参数,每次迭代返回的大致参数,只起参考作用
type:查询类型
PERSIST:删除键的存活时间,让他变成永久的
TTL:以秒为单位,返回key的存活时间,如果存在就返回存活时间,如果没有设置存活时间,返回-1,如果键不存在返回-2.
Hash(哈希表):
HDEL:删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。返回值是被成功移除的域的数量,不包括被忽略的域。
HDEL key field [field ...]
key
: 存储哈希表的键。(key是大key)field
: 要删除的一个或多个字段名。(field是小key)
HEXISTS:用于检查哈希表中的指定字段是否存在,如果字段存在返回1,不存在返回0
HGET:返回哈希表 key 中给定域 field 的值。当给定域不存在或是给定 key 不存在时,返回 null
HMGET:返回哈希表 key 中,一个或多个给定域的值。
HSET:将哈希表 key 中的域 field 的值设为 value 。如果field已经存在于表中,旧值会被覆盖,如果key不存在,一个新的表会被创建并赋值
HMSET:用于在一个哈希(Hash)类型的数据结构中设置一个或多个字段及其对应的值
HGETALL:用于获取哈希(Hash)类型中所有字段及其对应的值
HINCRBY:用于在哈希(Hash)类型的字段中递增整数值。该命令允许你增加或减少哈希中特定字段的整数值
HINCRBY key field increment
increment:要增加的数值。可以是正数也可以是负数,如果是负数则为减法操作。
HKEYS:获取哈希(Hash)类型中所有的字段名称。
HVALS:获取哈希(Hash)类型中所有的字段的值
List(列表):
BLPOP:用于从一个或多个列表中弹出(移除并返回)一个元素。如果列表为空,BLPOP
将阻塞等待直到列表中有新的元素可用。这是一个非常有用的命令,常用于实现队列和消息传递系统
BRPOP:用于从一个或多个列表的尾部弹出(移除并返回)一个元素。如果列表为空,BRPOP
将阻塞等待直到列表中有新的元素可用
LINDEX:,用于获取列表中指定索引位置的元素,索引是从0开始的,如果索引给负数,是从尾部开始查找元素。列表在 Redis 中是一种有序的数据结构,可以用来存储一系列的字符串元素
LPOP:用于从列表的头部(左端)弹出(移除并返回)一个元素。如果列表为空,LPOP
将立即返回 null
而不会阻塞
RPOP:用于从列表的尾部(右端)弹出(移除并返回)一个元素。如果列表为空,LPOP
将立即返回 null
而不会阻塞
LPUSH:用于将一个或多个值插入到列表的头部(左端)。如果列表不存在,LPUSH
将创建一个新的列表
RPUSH:用于将一个或多个值插入到列表的尾部(右端)。如果列表不存在,LPUSH
将创建一个新的列表
LSET:用于设置列表中指定索引位置的元素值。这允许你修改列表中已存在的元素
Set(集合)
SADD:用于向集合(Set)类型的数据结构中添加一个或多个成员。集合是一种不允许重复成员的无序数据结构
SCARD:用于获取集合(Set)类型数据结构中的成员数量
SDIFF:用于计算两个或多个集合之间的差集。差集是指第一个集合中存在但不在其他指定集合中的成员。
SINTER:用于计算两个或多个集合之间的交集。交集是指所有集合中共有的成员
SUNION:用于计算两个或多个集合之间的并集。并集是指所有集合中所有成员的组合
SISMEMBER:用于检查一个给定的成员是否属于一个集合(Set)类型的数据结构,存在返回1,不存在返回0
SMEMBERS:用于获取集合(Set)类型数据结构中的所有成员
SPOP:用于从集合(Set)类型的数据结构中随机弹出(移除并返回)一个成员,若集合为空或者不存在,返回null
SRANDMEMBER:用于从集合(Set)类型的数据结构中随机返回一个或多个成员,不会移除成员
SortedSet(有序集合):
ZADD:用于向有序集合(Sorted Set)类型的数据结构中添加一个或多个成员及其分数
ZADD key score member [score member ...] [NX|XX|CH|INCR]
key
:有序集合的键名。score
:成员的分数。member
:要添加到有序集合中的成员。NX
:仅当成员不存在时才添加。XX
:仅当成员已存在时才更新分数。CH
:返回被修改的元素数量。INCR
:对已经存在的成员的分数进行增量更新。
ZCARD:用于获取有序集合(Sorted Set)类型数据结构中的成员数量。有序集合是一种特殊的数据结构,其中的每个成员都有一个关联的分数,并且可以根据分数对成员进行排序。
ZCARD key
ZCOUNT:用于计算有序集合(Sorted Set)类型数据结构中分数在指定范围内(包括边界值)的成员数量。
ZCOUNT key min max
min
:最小分数(包含)。max
:最大分数(包含)。
ZINCRBY:用于在有序集合(Sorted Set)类型的数据结构中递增成员的分数,可以加负数变成递减
ZRANK:用于获取有序集合(Sorted Set)类型数据结构中指定成员的排名。排名是基于成员的分数进行排序的,从低到高排列,从 0 开始计数。
ZSCORE:用于获取有序集合(Sorted Set)类型数据结构中指定成员的分数。
七、BitMap
Redis中的BitMap是一种数据结构,利用Redis的string类型实现。BitMap 本质上是一个非常大的数组,其中的每个元素都是一个 bit(比特),只能存储 0 或 1。由于每个 bit 只占用很小的空间(通常是 1/8 字节),因此 BitMap 非常适合用于处理大量稀疏的二进制数据。
Redis BitMap 的基本操作命令
-
SETBIT: 设置或清除字符串值中指定偏移量上的位(bit)。
SETBIT key offset value
其中 key
是 BitMap 存储的键名,offset
表示位的位置,value
是要设置的值(0 或 1)。
-
GETBIT: 获取字符串值中指定偏移量上的位(bit)。
GETBIT key offset
key
是 BitMap 存储的键名,offset
表示位的位置。
-
BITCOUNT: 计算存储在 key 中的所有位中值为 1 的位的数量。
BITCOUNT key [start end]
如果没有提供 start
和 end
,则计算整个 BitMap 中值为 1 的位的数量;如果提供 了 start
和 end
,则只计算指定范围内的位。
-
BITPOS: 返回值为 1 或 0 的第一个位的位置。
BITPOS key value [start] [end]: value
指定查找的位值,
start
和end
用于指定查找的范围。
BitMap常常用在用户签到或者统计活跃人数上边,例如车展上统计三天内的参展人数
bitop
bitop用到的运算
and(与):全1出1,有一个0就出0
or (或):全0出0,有一个1就出1
not(非) :有1出0;有0出1。(全0出1)
xor(异或) :相同得0;相异得1
八、EVAL
EVAL
是 Redis 中的一个命令,用于执行一个给定的 Lua 脚本。Lua 脚本可以直接在 Redis 服务器上运行,而不需要客户端进行任何解释或编译,这使得脚本执行既快速又安全
基本语法;
EVAL script numkeys key [key ...] arg [arg ...]
script
: 是一个 Lua 脚本字符串。numkeys
: 是脚本中将要访问的键的数量。key [key ...]
: 是脚本将要访问的键。arg [arg ...]
: 是传递给脚本的参数。
例子:
eval "return redis.call('mset',KEYS[1],ARGV[1],KEYS[2],ARGV[2],KEYS[3],ARGV[3])" 3 name age score 李四 18 90
设置多个key的值以及对应的value,注意访问键的数量一定要写,因为如果我们后期Redis集成的时候可以避免不兼容
九、Spring操作Redis
Lettuce是什么
Lettuce 是一个现代的、反应式的、线程安全的 Redis 客户端库,主要用于 Java 应用程序。它支持 Redis 的所有功能,并且提供了非阻塞的 API,允许开发者构建高性能和可伸缩的应用程序。Lettuce 是 Spring Data Redis 的默认客户端,并且在 Spring Boot 2.x 版本之后成为了默认的 Redis 客户端。
十、redis慢日志
客户端从发送命令到获取返回结果经过了以下几个步骤:
慢查询日志两个配置项:
slowlog-log-slower-than
-
Redis 慢查询日志的时间阈值,单位微妙。
-
1) 值为正数,执行时间大于该值设置的微秒时才记录到慢日志中。默认 10000 微秒(0.01 秒)。
-
2) 值为负数,禁用慢查询日志。
-
3) 值为 0,所有命令都记录到慢日志中
slowlog-max-len
-
慢查询日志长度,最小值为零。默认 128
-
当记录新命令并且当前慢日志已达到最大长度时,最旧的一条记录将被删除。
十一、Redis过期删除策略
1、惰性删除:放任键不管,每次获取键的时候先检查键是否过期,如果过期了就删除这个键,如果没有过期就返回这个键。
2、定期删除:每隔一段时间对数据库进行一次检查,删除里面过期的键,每次删除或者检查多少键由内置的算法决定
十二、内存淘汰策略
Redis提供8种数据淘汰策略
LRU(Least recently used):删除最近最少使用,有时间概念
LFU(Least-frequently used):删除一直以来最少使用,无时间概念,从Redis服务器启动开始以来
1.noeviction(不驱逐):不删除数据,写不进去就报错
2.volatile-lru:删除带有过期时间的最近最少使用的key
3.volatile-lfu:删除带有过期时间的一直以来最少使用的key
4.volatile-random:从带有过期时间的key中随机删除一个
5.volatile-ttl:删除带有过期时间的即将过期的key
6.allkeys-lru:对于所有keys,删除最近最少使用
7.allkeys-random:从所有key中随机删除一个
8.allkeys-lfu:从所有key中删除一直以来最少使用的
十三、redis主从同步机制
步骤:
1、从服务器向主服务器发送同步命令sync
2、主服务器收到同步请求以后会执行bgsave命令生成一个rdb文件,并使用一个临时缓冲区记录从现在开始的所有写命令,主服务器会把生成的rdb文件发送给从服务器
3、从服务器收到这个rdb文件以后会加载这个rdb文件到内存,主服务器会把缓存区里的写命令发送给从服务器去执行,这样两边就一致了(前三步是全量同步)
4、接下来主服务器每次有写命令就会发送给从服务器去执行(增量同步)
十四、Redis和MySQL如何保证数据一致性
1、延迟双删策略
2、使用阿里开源的cannl监听数据库,如果对数据库的字段进行了增删改操作,就直接去Redis中删除对应的键,这样每次我们访问Redis都会是最新的数据
十五、Redis集群模式
1、主从模式:
主节点负责写入数据,而从节点负责读取数据;从节点会复制主节点的数据
优点:实现简单,能够读写分离
缺点:没有分片,如果主节点死了从节点也就不能用了,不能水平扩展
2、哨兵模式:
监控主节点状态,当主节点挂了的时候会从从节点里选出一个充当主节点
优点:提供了自动化监控和故障恢复机制
缺点:不支持分片
3、Redis Cluster模式:
Redis Cluster是官方正式支持的分布式解决方案,它采用了数据分片(sharding)技术,将数据分散在多个节点上。
优点:实现了分布式存储,每个节点都可以读写数据,可以水平扩展
缺点:搭建较为复杂,耗费网络资源