Redis讲解

一、redis使用

1.1 开启reids服务器端

在这里插入图片描述

1.2 开启redis客户端

在这里插入图片描述
基本使用(修改密码):
方法一:直接在客户端进行修改

查看当前的密码  config get requirepass  
设置新的密码    config set requirepass 123456

再次查询密码时,出现:(error) NOAUTH Authentication required. 
此时报错了!现在只需要密码认证就可以了: auth 123456

再次查询密码 127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "123456"  
密码已经得到修改。

方法二:修改配置文件。(修改完了要重启redis才生效)

二、redis为什么有16个db

Redis是一个字典结构的存储服务器,一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与在一个关系数据库实例中可以创建多个数据库类似(如下图所示),所以可以将其中的每个字典都理解成一个独立的数据库。
在这里插入图片描述
reids Desktop Manager连接本机redis后
在这里插入图片描述
客户端与Redis建立连接后会默认选择0号数据库,不过可以随时使用SELECT命令更换数据库。

2.1 切库命令

# 切库
redis> SELECT 1 # 默认0号db,切换为1号db
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get w2
"w2val111111"
127.0.0.1:6379[1]> select 6
OK
127.0.0.1:6379[6]> get w6
"w6val"

idea整合redis配置:

#redis相关配置
# Redis数据库索引(默认为0)!!!!!!!这里选择库
spring.redis.database=15
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=7019
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
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
# redis的key过期时间(单位分钟)
spring.cache.redis.time-to-live=1440

2.2 正确理解Redis的“数据库”概念

由于Redis不支持自定义数据库的名字,所以每个数据库都以编号命名。开发者则需要自己记录存储的数据与数据库的对应关系。另外Redis也不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部数据库,要么全部数据库都没有权限访问

# 清空一个Redis实例中所有数据库中的数据
redis 127.0.0.1:6379> FLUSHALL

清空结果如下图所示
在这里插入图片描述
该命令可以清空实例下的所有数据库数据,这与我们所熟知的关系型数据库所不同。关系型数据库多个库常用于存储不同应用程序的数据 ,且没有方式可以同时清空实例下的所有库数据。所以对于Redis来说这些db更像是一种命名空间,且不适宜存储不同应用程序的数据。比如可以使用0号数据库存储某个应用生产环境中的数据,使用1号数据库存储测试环境中的数据,但不适宜使用0号数据库存储A应用的数据而使用1号数据库B应用的数据,不同的应用应该使用不同的Redis实例存储数据。Redis非常轻量级,一个空Redis实例占用的内在只有1M左右,所以不用担心多个Redis实例会额外占用很多内存。

2.3 集群在的redis数据库

以上所说的都是基于单体Redis的情况。而在集群的情况下不支持使用select命令来切换db,因为Redis集群模式下只有一个db0。

Redis实例默认建立了16个db,由于不支持自主进行数据库命名所以以dbX的方式命名。默认数据库数量可以修改配置文件的database值来设定。对于db正确的理解应为“命名空间”,多个应用程序不应使用同一个Redis不同库,而应一个应用程序对应一个Redis实例,不同的数据库可用于存储不同环境的数据。最后要注意,Redis集群下只有db0,不支持多db。

三、redis常见基础面试T

3.1 什么是redis

Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)
高性能非关系型(NoSQL)键值对数据库。

Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。

与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。

3.2 关系型数据库 vs 非关系型数据库

关系型数据库:指采用了关系模型来组织数据的数据库。
非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。

非关系型数据库结构

关系型数据库非关系型数据库
含义采用了关系模型来组织数据的数据库。指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。

非关系型数据库以键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销
优点容易理解、易于维护简单易部署,
查询速度快基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
缺点高并发读写需求(遵守ACID)
海量数据的高效率读写
只适合存储一些较为简单的数据,对于需要进行较复杂查询的数据,关系型数据库显的更为合适。不适合持久存储海量数据

3.3 Redis的数据类型

  1. string:最基本的数据类型,二进制安全的字符串,最大512M。
  2. list:按照添加顺序保持顺序的字符串列表。
  3. set:无序的字符串集合,不存在重复的元素。
  4. zset:已排序的字符串集合
  5. hash:key-value对的一种集合。

3.3.1 String字符串

格式: set key value

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

string类型是Redis最基本的数据类型,一个键最大能存储512MB。String适合做简单的键值对缓存

3.3.2 Hash(哈希)

格式: hmset name key1 value1 key2 value2

Redis hash 是一个键值(key=>value)对集合。

Redis hash是一个string类型的field和value的映射表,hash适合用于存储对象

3.3.3 List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
list适合于存储列表型数据结构,如文章的用户评论

格式: lpush name value

在 key 对应 list 的头部添加字符串元素

格式: rpush name value

在 key 对应 list 的尾部添加字符串元素

格式: lrem name index

key 对应 list 中删除 count 个和 value 相同的元素

格式: llen name

返回 key 对应 list 的长度

3.3.4 Set(集合)

格式: sadd name value

Set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

3.3.5 zset(sorted set:有序集合)

格式: zadd name score value

zset 和 set 一样也是string类型元素的集合,且不允许重复的成员,但分数(score)却可以重复。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

Sorted set是set的升级,它在set的基础上增加了一个顺序属性,这一属性值在添加元素的时候指定,每次指定后Zset会自动重新按照新值调整顺序。

在这里插入图片描述

3.4 Redis持久化

持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。

Redis 提供了两种持久化方式:RDB(默认) 和AOF

3.4.1 RDB

RDB是Redis默认的持久化方式。按照一定的时间将内存的所有数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

在这里插入图片描述

Redis会单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。

优点

  1. 只有一个文件 dump.rdb,方便持久化。
  2. 容灾性好,一个文件可以保存到安全的磁盘。
  3. 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
  4. 相对于数据集大时,比 AOF 的启动效率更高

缺点

  1. 数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候) 。 需要注意的是,每次快照持久化都会将主进程的数据库数据复制一遍,导致内存开销加倍,若此时内存不足,则会阻塞服务器运行,直到复制结束释放内存;都会将内存数据完整写入磁盘一次,所以如果数据量大的话,而且写操作频繁,必然会引起大量的磁盘I/O操作,严重影响性能,并且最后一次持久化后的数据可能会丢失。

3.4.2 AOF

AOF是将Redis执行的每一个写命令都会记录在AOF文件,当重启Redis会重新将持久化的日志中文件恢复数据。可以看做是命令日志文件。
主要有两种方式触发:有写操作就写每秒定时写(也会丢数据)

在这里插入图片描述

优点

  1. 数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。
  2. 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
  3. AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))

缺点

  1. AOF 文件比 RDB 文件大,且恢复速度慢。
  2. 数据集大的时候,比 rdb 启动效率低。

3.4.3 使用对比

在这里插入图片描述

  1. 如果两个都配了优先加载AOF
  2. AOF文件比RDB更新频率高,优先使用AOF还原数据。
  3. AOF比RDB更安全也更大
  4. RDB性能比AOF好

当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。一般情况下,只要使用默认开启的RDB即可,因为相对于AOF,RDB便于进行数据库备份,并且恢复数据集的速度也要快很多。

开启持久化缓存机制,对性能会有一定的影响,特别是当设置的内存满了的时候,更是下降到几百reqs/s。
所以如果只是用来做缓存的话,可以关掉持久化。

3.5 Redis 有哪些架构模式?讲讲各自的特点

3.5.1 单机版

在这里插入图片描述

特点:简单
缺点:1、内存容量有限 2、处理能力有限 3、无法高可用。

3.5.2 主从复制

在这里插入图片描述

Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,可以搭建主从集群,实现读写分离。一般都是一主多从,主节点负责写数据,从节点负责读数据,主节点写入数据之后,需要把数据同步到从节点中。

主从同步数据的流程
主从同步分为了两个阶段,一个是全量同步,一个是增量同步

全量同步是指从节点第一次与主节点建立连接的时候使用全量同步,具体流程见下:

  • 第一:从节点请求主节点同步数据,其中从节点会携带自己的replication id和offset偏移量。
  • 第二:主节点判断是否是第一次请求,主要判断的依据就是,主节点与从节点是否是同一个。replicationid,如果不是,就说明是第一次同步,那主节点就会把自己的replication
    id和offset发送给从节点,让从节点与主节点的信息保持一致。
  • 第三:在同时主节点会执行bgsave,生成rdb文件后,发送给从节点去执行,从节点先把自己的数据清空,然后执行主节点发送过来的rdb文件,这样就保持了一致。
  • 当然,如果在rdb生成执行期间,依然有请求到了主节点,而主节点会以命令的方式记录到缓冲区,缓冲区是一个日志文件,最后把这个日志文件发送给从节点,这样就能保证主节点与从节点完全一致了,后期再同步数据的时候,都是依赖于这个日志文件,这个就是全量同步。

增量同步指的是,当从节点服务重启之后,数据就不一致了,所以这个时候,从节点会请求主节点同步数据,主节点还是判断不是第一次请求,不是第一次就获取从节点的offset值,然后主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步。
————————————————

特点

1、master/slave 角色

2、master/slave 数据相同

3、降低 master 读压力在转交从库

问题

1、无法保证高可用

2、没有解决 master 写的压力

3.5.3 哨兵

在这里插入图片描述

1、哨兵特性

Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。其中四个特性:

  • 监控:哨兵会不断地检查主节点和从节点是否运作正常。
  • 自动故障恢复:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
  • 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

2、服务状态监控
Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令

主观下线: 如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线。
客观下线: 若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

3、哨兵选主规则

  • 首先判断主与从节点断开时间长短如超过指定值就排该从节点。因为断开时间越长,丢失的数据越多,所以选择断开时间短的,丢失数据少的节点为主节点。
  • 然后判断从节点的slave-priority值,越小优先级越高。
  • 如果slave-prority一样,则判断slave节点的offset值,越大优先级越高。因为offset的值越大,说明该从节点与主节点的数据差越少,所以选offset大的为主节点。
  • 最后是判断slave节点的运行id大小,越小优先级越高。

4、脑裂
https://blog.csdn.net/weixin_55127182/article/details/130328362

解决方法:设置redis中的两个配置参数

  1. min-replicas-to-write 1 表示最少的salve节点为1个。必须每个主节点至少有一个从节点,才可以接受客户端的请求,否则失败。
  2. min-replicas-max-lag 5表示数据复制和同步的延迟不能超过5秒

5、哨兵优缺点

特点

1、保证高可用

2、监控各个节点

3、自动故障迁移

缺点
1、主从模式,切换需要时间丢数据

2、没有解决 master 写的压力

3.5.4 集群(proxy 型)

在这里插入图片描述

Twemproxy 是一个 Twitter 开源的一个 redis 和 memcache 快速/轻量级代理服务器; Twemproxy 是一个快速的单线程代理程序,支持 Memcached ASCII 协议和 redis 协议。

特点
1、多种 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins

2、支持失败节点自动删除

3、后端 Sharding 分片逻辑对业务透明,业务方的读写方式和操作单个 Redis 一致

缺点:增加了新的 proxy,需要维护其高可用。

3.5.5 集群(直连型)

在这里插入图片描述

从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

特点:

1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。

2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。

3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本

5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。

缺点:

1、资源隔离性较差,容易出现相互影响的情况。

2、数据通过异步复制,不保证数据的强一致性

3.6 缓存处理流程及异常

缓存处理流程:前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

在这里插入图片描述

3.6.1 缓存穿透

描述
缓存穿透是指缓存和数据库中都没有的数据,而用户发起大量请求。如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

  1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

3.6.2 缓存击穿

描述:
缓存击穿是指缓存中没有但数据库中有的数据一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

解决方案:

  1. 设置热点数据永远不过期;
  2. 加互斥锁

3.6.3 缓存雪崩

描述
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机
和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
  3. 设置热点数据永远不过期。

以上描述参考链接在此~~~~~~~~

3.7 如何保证缓存与数据库双写时的数据一致性?

先更新db再失效缓存的策略

觉大多数高并发的情况下,对数据的实时更新要求并不是那么严谨。作为一个缓存数据,它的更新时间是17:01.001还是17:01.789,这个其实不是很重要。

缓存本质上是存储分布

要求严格高一致就没缓存啥事~~~~~~~~~~~~~~~~~

3.8 reids vs Memcached

两者都是非关系型内存键值数据库,现在公司一般都是用 Redis 来实现缓存,而且 Redis 自身也越来越强大了!Redis 与 Memcached 主要有以下不同:
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据

在这里插入图片描述

3.9 Redis主要有哪些功能?

1.哨兵(Sentinel)和复制(Replication)
Redis服务器毫无征兆的罢工是个麻烦事,如何保证备份的机器是原始服务器的完整备份呢?这时候就需要哨兵和复制。

哨兵Sentinel可以管理多个Redis服务器,它提供了监控,提醒以及自动的故障转移的功能,Replication则是负责让一个Redis服务器可以配备多个备份的服务器。

Redis也是利用这两个功能来保证Redis的高可用的。

2.事务
很多情况下我们需要一次执行不止一个命令,而且需要其同时成功或者失败。redis对事务的支持也是源自于这部分需求,即支持一次性按顺序执行多个命令的能力,并保证其原子性

3.LUA脚本
在事务的基础上,如果我们需要在服务端一次性的执行更复杂的操作(包含一些逻辑判断),则lua就可以排上用场了。

4.持久化
redis的持久化指的是redis会把内存的中的数据写入到硬盘中,在redis重新启动的时候加载这些数据,从而最大限度的降低缓存丢失带来的影响。

5.集群(Cluster)
单台服务器资源的总是有上限的,CPU资源和IO资源我们可以通过主从复制,进行读写分离,把一部分CPU和IO的压力转移到从服务器上,这也有点类似mysql数据库的主从同步。

3.10 为什么要进行两次删除缓存

为了保证缓存和数据库的一致性。因为不管是先修改数据库还是先删缓存都会导致数据库和缓存的值不同。而两次删除缓存会避免这种情况发生。

3.11 为什么要进行延迟双删

在这里插入图片描述

一般情况下数据库都是主从分离的,所以可能出现主从数据库数据不一致的情况。为了避免这种情况,就会延迟一会,等待主节点同步到从节点。所以要延时,但是这个延时时间不好控制,在这个过程中依然可能会出现脏数据。所以延时双删只是控制减少了脏数据的出现,但无法避免脏数据的出现。

延迟双删实际使用过程问题如果是写操作,我们先把缓存中的数据删除,然后更新数据库,最后再延时删除缓存中的数据,其中这个延时多久不太好确定,在延时的过程中可能会出现脏数据,并不能保证强一致性,所以没有采用它。

3.12 一致性方法!

1、强一致性

在这里插入图片描述

强一致性的,采用Redisson提供的读写锁:

  • 共享锁: 读锁readLock,加锁之后,其他线程可以共享读操作,读写互斥
  • 排他锁: 独占锁writeLock,加锁后,阻塞其他线程读写操作

读锁相关代码,注意读锁和写锁的锁名必须一致:
在这里插入图片描述
写锁相关代码:
在这里插入图片描述

2、异步通知保证数据的最终一致性

在这里插入图片描述

  • 允许延时一致的业务,采用异步通知:
    使用MQ中间中间件,更新数据之后,通知缓存删除

3.13 数据过期策略

1、假如redis的key过期之后,会立即删除吗?

Redis对数据设置数据的有效时间,数据过期以后,就需要将数据从内存中删除掉。可以按照不同的规则进行删除,这种删除规则就被称之为数据的删除策略(数据过期策略)。

2、Redis数据删除策略-惰性删除

惰性删除:设置该key过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。

  • 优点:对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查
  • 缺点:对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放

3、Redis数据删除策略-定期删除

定期删除:每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中的过期key)。
定期清理有两种模式:

  • SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf 的hz 选项来调整这个次数。
  • FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms。

优点:可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。另外定期删除,也能有效释放过期键占用的内存。
缺点: 难以确定删除操作执行的时长和频率。

4、Redis选择的策略

Redis的过期删除策略: 惰性删除 + 定期删除两种策略进行配合使用。

3.14 数据淘汰策略

数据的淘汰策略:当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。

1、Redis支持8种不同策略来选择要删除的key:

  • noeviction: 不淘汰任何key,但是内存满时不允许写入新数据,直接报错。这是redis的默认策略
  • volatile-ttl: 对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰。
  • allkeys-random:对全体key ,随机进行淘汰。
  • volatile-random:对设置了TTL的key ,随机进行淘汰。
  • allkeys-lru: 对全体key,基于LRU算法进行淘汰。
  • volatile-lru:对设置了TTL的key,基于LRU算法进行淘汰。
  • allkeys-lfu: 对全体key,基于LFU算法进行淘汰。
  • volatile-lfu: 对设置了TTL的key,基于LFU算法进行淘汰。

2、 LRU与LFU区别

LRU(Least Recently Used)最近最少使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。

  • key1是在3s之前访问的,key2是在9s之前访问的,删除的就是key2。

LFU (Least Frequently Used) 最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。

  • key1最近5s访问了4次, ey2最近5s访问了9次,删除的就是key1。

3、淘汰策略使用建议

  • 优先使用 allkeys-lru 策略。充分利用LRU 算法的优势,把最近最常访问的数据留在缓存中。如果业务有明显的冷热数据区分,建议使用。
  • 如果业务中数据访问频率差别不大,没有明显冷热数据区分,建议使用 allkeys-random,随机选择淘汰。
  • 如果业务中有置顶的需求,可以使用 volatile-lru 策略,同时置顶数据不设置过期时间,这些数据就一直不被删除会淘汰其他设置过期时间的数据。
  • 如果业务中有短时高频访问的数据,可以使用 allkeys-lfu 或 volatile-lfu 策略。

4、关于数据淘汰策略其他的面试问题

数据库有1000万数据,Redis只能缓存20w数据,如何保证Redis中的数据都是热点数据?

  • 使用allkeys-lru(挑选最近最少使用的数据淘汰)淘汰策略,留下来的都是经常访问的热点数据。

Redis的内存用完了会发生什么?

  • 主要看数据淘汰策略是什么? 如果是默认的配置 (noeviction ),会直接报错。

5、概括

数据淘汰策略

  • Redis提供了8种不同的数据淘汰策略,默认是noeviction不删除任何数据,内存不足直接报错。
  • LRU: 最少最近使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
  • LFU:最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高 。

平时开发过程中用的比较多的就是allkeys-lru (结合自己的业务场景) ,因为allkeys-lru保存下来的数据一般都是热点数据。

6、 面试官: Redis的数据淘汰策略有哪些?

  • 嗯,这个在redis中提供了很多种,默认是noeviction,不删除任何数据,内部不足直接报错。可以在redis的配置文件中进行设置的,里面有两个非常重要的概念,一个是LRU,另外一个是LFU。
  • LRU的意思就是最少最近使用,用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
  • LFU的意思是最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。
    我们在项目设置的是allkeys-lru,挑选最近最少使用的数据淘汰,把一些经常访问的key留在redis中。

7、面试官:数据库有1000万数据,Redis只能缓存20w数据,如何保证Redis中的数据都是热点数据?

嗯,我想一下~~可以使用 alkeys-lru(挑选最近最少使用的数据淘汰)淘汰策略,那留下来的都是经常访问的热点数据

8、面试官: Redis的内存用完了会发生什么?

会触发数据淘汰策略,默认为noeviction,不删除任何数据,内部不足直接报错。但是redis有8中淘汰策略,其中有两种主要概念就是LRU和LFU。其余的几种淘汰策略主要围绕这两种进行。

3.15 分布式

https://blog.csdn.net/weixin_55127182/article/details/130328362

3.10 RedisTemplate

RedisTemplate详解

3.xx redis常用命令

Redis常用命令?

Keys pattern

*表示区配所有

以bit开头的

查看Exists key是否存在

Set

设置 key 对应的值为 string 类型的 value。

setnx

设置 key 对应的值为 string 类型的 value。如果 key 已经存在,返回 0,nx 是 not exist 的意思。

删除某个key

第一次返回1 删除了 第二次返回0

Expire 设置过期时间(单位秒)

TTL查看剩下多少时间

返回负数则key失效,key不存在了

Setex

设置 key 对应的值为 string 类型的 value,并指定此键值对应的有效期。

Mset

一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置。

Getset

设置 key 的值,并返回 key 的旧值。

Mget

一次获取多个 key 的值,如果对应 key 不存在,则对应返回 nil。

Incr

对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误,incr 一个不存在的 key,则设置 key 为 1

incrby

同 incr 类似,加指定值 ,key 不存在时候会设置 key,并认为原来的 value 是 0

Decr

对 key 的值做的是减减操作,decr 一个不存在 key,则设置 key 为-1

Decrby

同 decr,减指定值。

Append

给指定 key 的字符串值追加 value,返回新字符串值的长度。

Strlen

取指定 key 的 value 值的长度。

persist xxx(取消过期时间)

选择数据库(0-15库)

Select 0 //选择数据库

move age 1//把age 移动到1库

Randomkey随机返回一个key

Rename重命名

Type 返回数据类型

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Python 中使用 Redis 数据库时,可以使用 `hgetall` 命令获取指定哈希表中的所有字段和值。具体讲解如下: 1. 连接 Redis 数据库 首先需要使用 Redis 的 Python 客户端连接 Redis 数据库。可以使用 `redis` 模块中的 `Redis` 类来实现: ```python import redis # 创建 Redis 客户端对象 r = redis.Redis(host='localhost', port=6379, db=0) ``` 2. 添加哈希表数据 在获取哈希表数据之前,需要先向 Redis 数据库中添加一些数据。可以使用 `hmset` 命令添加哈希表数据: ```python # 添加哈希表数据 r.hmset('myhash', {'field1': 'value1', 'field2': 'value2', 'field3': 'value3'}) ``` 上述代码中,首先指定哈希表名称为 `myhash`,然后添加了三个字段和对应的值。 3. 获取哈希表数据 使用 `hgetall` 命令可以获取指定哈希表中的所有字段和值。具体使用方法如下: ```python # 获取指定哈希表中的所有字段和值 result = r.hgetall('myhash') print(result) ``` 输出结果为: ``` {b'field1': b'value1', b'field2': b'value2', b'field3': b'value3'} ``` 上述结果中,键名和键值都以字节字符串的形式输出,需要使用 `decode()` 方法将其转换为字符串: ```python # 将字节字符串转换为字符串 result = {key.decode(): value.decode() for key, value in result.items()} print(result) ``` 输出结果为: ``` {'field1': 'value1', 'field2': 'value2', 'field3': 'value3'} ``` 上述代码中,使用字典生成式将字节字符串转换为字符串,并将其存储在 `result` 变量中。 总结: `hgetall` 命令可以获取指定哈希表中的所有字段和值,使用 Redis 的 Python 客户端可以轻松实现该功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值