室友有个大佬,一说redis就问我为什么使用redis,redis单线程为什么这么快,redis…
redis的部分面试题,自己整理的,当然实际工作中使用的redis比较简单,但是了解redis部分底层还是有必要的…
什么是redis
Redis 是一个使用 C 语言写成的,开源的基于内存的,单线程的高性能key-value数据库,redis的值是可以支持多种数据结构的.
redis 的数据类型,以及每种数据类型的使用场景
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
String就是存—key-value可以是String,也可以是数字啥的
Hash就相当于hashmap,但是是key–hashmap,就是key–> key,value适合存储对象类型的.
List就相当于List key --List
Set相当于HashSet key–HashSet也是通过hash表实现的
Sorted Set有序集合,不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
为什么使用 redis
嗯,项目中使用redis主要用作缓存数据库,那为什么使用redis呢?应该从两个方面去回答:性能和并发.
性能:
对一些复杂的耗时的sql查询,如果对实时性不是很高而且仅仅只是用作展示的话,就最好将执行的结果放入缓存,这样在重复请求下就可以重缓存中去获取,能够很快响应.这样避免重复多次执行复杂耗时的sql,减少了数据库开销.
并发
如果做一个秒杀系统的话,一下子有很多请求,如果直接对数据库进行操作,数据库可能会挂,可以使用redis做一个缓冲.具体则需要根据实际场景使用…
单线程的 Redis 为什么这么快
一般面试官会先问一句,redis是单线程还是多线程的,然后又问redis单线程(多进程,因为有线程执行数据备份)为什么这么快?回答主要围绕以下三点回答:
1.存内存的,reids的所有数据都是在内存中的
2.单线程操作,避免了频繁的上下文切换
3.采用了非阻塞 I/O 多路复用机制,I/O就是指的我们网络I/O,多路指多个TCP连接(或多个Channel),复用指复用一个或少量线程。串起来理解就是很多个网络I/O复用一个或少量的线程来处理这些连接。这一块比较复杂,这里不做过多描述.可以百度一下,了解一下.
什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?
持久化就是把内存数据写到磁盘中去,防止服务宕机导致内存数据丢失。主要有两种:RDB(默认) 和AOF,4.0版本开始支持RDB和AOF混用的方式来进行持久化 。
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照
AOF持久化redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。
他们优缺点的话,就自己根据他们做的事情来说,简单的举个栗子,AOF文件是对命令进行存储,所以,AOF持久化的文件通常比较大,如果设置的是每一秒去执行一次fsync的话那AOF 的速度可能会慢于 RDB等等…
redis 有什么优缺点
有点的话就是上面讲的,丰富的类型,高效率的读写,支持持久化等等…
缺点的话,就相当于缓存的缺点:
- 缓存和数据库双写一致性问题
如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。
- 缓存雪崩问题
- 缓存击穿问题
一般公司很难碰到这个问题,我公司数据量不大也没碰到过,但是我们要了解是怎么回事,如果碰到了该怎么解决,
缓存穿透,黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而数据库连接异常。这个有几种解决方案,主要就是限流问题,可以通过计数器、漏桶和令牌桶算法。
- 缓存的并发竞争问题