Redis(面试篇)

目录

什么是Redis?

Redis有哪些优缺点

Redis为什么这么快

Redis有哪些数据类型

Redis的应用场景

持久化

什么是事务?

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

Redis有哪些功能

什么是缓存穿透?这么解决?

Redis支持的数据类型有哪些?

Redis支持的Java客户端有哪些?

怎么保存缓存和数据库的一致性?

Redis持久化有几种方式?

RDB

AOF

Reids怎么实现分布式锁

一个字符串类型的值能存储最大容量时多少?

Redis主要消耗什么物理资源?


一起努力,加油,!!!

什么是Redis?

Redis是一个使用C语言写成的,开源的高新能key-value非关系缓存数据库。它支持存储的value类型相对跟多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。Redis的数据都基于缓存的,所以很快,每秒可以处理超过10万次读写操作,已知性能最快的key-valueDB。Redis也可以实现数据写入磁盘中,保证数据的安全不丢失,而且Redis的操作是原子性的。

Redis有哪些优缺点

优点

  • 读写性能优异,Redis能读的速读是110000次/s,写的速度是81000次/s
  • 支持数据持久化,支持AOF和RDB两种持久化方式。
  • 支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
  • 数据结构丰富,除了支持string类型的hash,set,zset,list等数据结构。
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点

  • 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高新能操作和运算上。
  • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的ip才能恢复。
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了胸痛的可能性
  • Redis较难支持在线扩容,在集群容量达到上线时在线扩容会变很复杂。为避免这一问题,运维人员在系统上线时必须确保足够的空间,这对资源照成很大的浪费。

Redis为什么这么快

  1. 完全基于内存,绝大部分请求时存储的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
  2. 数据结构简单,对数据操作也简单,Redis中数据结构是专门进行设计的;
  3. 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多线程或者多进程的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。
  4. 使用多路I/O复用模型,非阻塞IO;
  5. 使用底层模型不同,他们之间底层实现方法以及与客户端之间通信的应用协议不一样,Redis直接自己构建VM机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

Redis有哪些数据类型

Redis主要有5种数据类型,包括String,List,Set,Zset,Hash,满足大部分的使用要求

|--------|-------------|----------------------------------------------------|-------------------------------------|
| 数据类型 | 可以存储的值 | 操作 | 应用场景 |
| String | 字符串,整数或者浮点数 | 对整个字符串或者字符串的其中一部分执行操作 对整数和浮点数执行自增或则自减操作 | 做简单的键值对缓存 |
| List | 列表 | 从两端压入或则弹出元素 对单个或者多个元素进行修剪,保留一个范围内的元素 | 存储一些列表型的数据结构,类似粉丝列表,文章的评论列表之类的数据 |
| Set | 无序集合 | 添加,获取,移除单个元素 检查一个元素是否存在于集合中 计算交集,并集,差集 从集合里面随机获取元素 | 交集,并集,差集的操作,比如交集,可以把来共呢个人的分时列表整一个交集 |
| Hash | 包含键值对的无序散列表 | 添加、获取、移除单个键值对 获取所有键值对检查某个键是否存在 | 结构化的数据,比如一个对象 |
| ZSet | 有序集合 | 添加、获取、删除元素 根据分值范围或者成员来获取元素计算一个键的排名 | 去重但可以排序,如获取排名前几名的用户 |

Redis的应用场景

计数器:

可以对String进行自增自减运算,从而实现计数器功能。Redis这种内存数据的读写性能非常高,很适合存储频繁读写的计数量。

缓存:

将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。

会话缓存:

可以使用Redis来统一存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用、高可性以及可伸缩性。

全页缓存(FPC)

除基本的会话token之外,Redis还提供很简单的FPC平台。以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。此外,对WordPress的用户来说,Pantheon有一个非常好用的插件wp-redis,这个插件能帮助你以最快的速读加载你曾浏览过的页面。

查找表

例如DNS记录就很适合使用Redis进行存储。查找表和缓存类似,也是利用Redis快速查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因此缓存不作为可靠的数据来源。

消息队列(发布/订阅功能)

List是一个双向链表,可以通过plush和rpop写入和读取消息。不过最好使用kafka、RabbitMQ等消息中间件。

分布式锁

在分布式场景下,无法使用单机环境下的锁来对多个结点上的进程进行同步。可以使用Redis自带的SETNX命令实现分布式锁,除此之外,还可以使用官方提供的RedLock分布式锁实现。

其他

Set可以实现交集、并集等操作,从而实现共同好友等功能。ZSet可以实现有序性操作,从而实现排行榜等功能。

持久化

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

什么是事务?

  • 事务时一个单独的隔离操作:事务中所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

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

  • 你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要时双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?
  • 一般来说,就是如果你的系统不是严格要求缓存+数据库必须一致性的话,缓存可以稍微的跟数据库偶尔不一致的情况,最好不要做这个方案,读请求和写请求串行化,串到一个内存队列里去,这样就可以保证一定不会出现不一致的情况
  • 串行话之后,就会导致系统的吞吐量会大幅度的降低,用比正常情况下多几倍的机器去支持线上的一个请求。
  • 还有一种方式及时可能会暂时产生不一致的情况,但是发生的几率特别小,就是先更新数据库然后再删除缓存

|-------------------------|--------------------------------------------------------|----------------------------------------------------------------|
| 问题场景 | 描述 | 解决 |
| 先写缓存,再写数据库,缓存写成功,数据库写失败 | 缓存写成功,但写数据失败或则响应延迟,则下次读取(并发度)缓存时,就出现脏读 | 这个写缓存的方式,本身就是错误的,需要改为先写数据库,把旧缓存置为失效;读取数据的时候,如果缓存不存在,则读取数据库再写缓存 |
| 先写数据库,再写缓存,数据库写成功,缓存写失败 | 写数据库成功,但写缓存失败,则下次读取(并发读)缓存时,则读不到数据 | 缓存使用时,假如读缓存失败,先读数据库,再回写缓存的方式实现 |
| 需要缓存异步刷新 | 指数据库操作和写缓存不再一个操作步骤中,不如再分布式场景下,无法做到同时写缓存或需要异步刷新(补救措施)时候 | 确定哪些数据适合此场景,根据经验值确定合理的数据不一致时间,用户数据刷新的时间间隔 |

Redis有哪些功能

  1. 数据缓存功能

  2. 分布式锁的功能

  3. 支持数据持久化

  4. 支持事务

  5. 支持消息队列

什么是缓存穿透?这么解决?

**缓存穿透:**指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

**解决方案:**最简单粗暴的方法如果一个查询返回的数据为空(不管时数据不存在,还是系统故障),我们就把这个空结果进行缓存,但它的过期时间会很短,最长不超过5分钟。

Redis支持的数据类型有哪些?

Redis 支持的数据类型:string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。

Redis支持的Java客户端有哪些?

支持的Java客户端Redisson、jedis、lettuce

怎么保存缓存和数据库的一致性?

合理设置缓存的过期时间。

新增、更改、删除数据库操作时同时更新Redis,可以使用事务机制来保证数据的一致性。

Redis持久化有几种方式?

Redis持久化有两种方式,或者说有两种策略:

RDB(Redis Database):指定的时间间隔能对你的数据进快照存储。

AOP(Append Only File):每一个收到的写命令都通过write函数追加到文件中。

RDB

  1. RDB(Redis DataBase)持久化方式:是指用数据集快照的方式半持久化模式记录redis数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,这个临时文件替换上次持久化的文件,达到数据恢复。
  2. 优点
    1. 只有一个文件dump.rdb方便持久化
    2. 容灾性好,一个文件可以保存到安全的磁盘。
    3. 新能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证redis的高性能,
    4. 相对于数据集大时,比AOF的启动效率更高
  1. 缺点
    1. 数据安全性低。RDB时间隔一段时间进行持久化,如果持久化直接按redis发生故障,会发生数据丢失,所以这种方式更适合要求不严谨的时候

AOF

  1. AOF(Append-only file) 持久化方式:是指所有命令行记录以redis命令请求协议的格式完全持久化存储,保存为aof文件。
  2. 优点
    1. 优点数据安全,aof持久化可以配置appendfsync属性,有always,每经行异常命令操作就记录到aof文件中一次。
    2. 通过append模式写文件,即使中途服务器宕机,也可通过redis-check-aof工具解决数据一致性问题。
    3. AOF机制rewrite模式。AOF文件没被rewrite之间(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)
  1. 缺点
    1. AOF文件比RDB文件大,且恢复速度慢。
    2. 数据集大的时候,比rdb启动效率低。

Reids怎么实现分布式锁

Redis分布式不能解决超时问题,分布式有一个超时时间,程序的执行如果超出锁的超出时间就会出现问题

一个字符串类型的值能存储最大容量时多少?

512M

Redis主要消耗什么物理资源?

内存

相关推荐
Ai 编码助手18 分钟前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql
陈燚_重生之又为程序员33 分钟前
基于梧桐数据库的实时数据分析解决方案
数据库·数据挖掘·数据分析
caridle35 分钟前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
白云如幻36 分钟前
MySQL排序查询
数据库·mysql
萧鼎38 分钟前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
^velpro^40 分钟前
数据库连接池的创建
java·开发语言·数据库
荒川之神1 小时前
ORACLE _11G_R2_ASM 常用命令
数据库·oracle
IT培训中心-竺老师1 小时前
Oracle 23AI创建示例库
数据库·oracle
小白学大数据1 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
time never ceases2 小时前
使用docker方式进行Oracle数据库的物理迁移(helowin/oracle_11g)
数据库·docker·oracle