本文已参与「新人创作礼」活动,一起开启掘金创作之路
1、Redis是什么?
Redis(
Remote Dictionary Server
)是一个使用 C 语言编写的,高性能非关系型的键值对数据库。与传统数据库不同的是,Redis 的数据是存在内存中的,所以读写速度非常快,被广泛应用于缓存方向。Redis可以将数据写入磁盘中,保证了数据的安全不丢失,而且Redis的操作是原子性的。
2、Redis优缺点?
优点:
①基于内存操作,内存读写速度快。
②支持多种数据类型,包括String、Hash、List、Set、ZSet等。
③支持持久化。Redis支持RDB和AOF两种持久化机制,持久化功能可以有效地避免数据丢失问题。
④支持事务。Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
⑤支持主从复制。主节点会自动将数据同步到从节点,可以进行读写分离。
⑥Redis命令的处理是单线程的。Redis6.0引入了多线程,需要注意的是,多线程用于处理网络数据的读写和协议解析,Redis命令执行还是单线程的。
缺点:
①对结构化查询的支持比较差。
②数据库容量受到物理内存的限制,不适合用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的操作。
③Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。
3、Redis为什么这么快?
①基于内存:Redis是使用内存存储,没有磁盘IO上的开销。数据存在内存中,读写速度快。
②IO多路复用模型:Redis 采用 IO 多路复用技术。Redis 使用单线程来轮询描述符,将数据库的操作都转换成了事件,不在网络I/O上浪费过多的时间。
③高效的数据结构:Redis 每种数据类型底层都做了优化,目的就是为了追求更快的速度。
4、讲讲Redis的线程模型?
Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。
①文件事件处理器使用I/O多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
②当被监听的套接字准备好执行连接accept、read、write、close等操作时, 与操作相对应的文件事件就会产生, 这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
虽然文件事件处理器以单线程方式运行, 但通过使用 I/O 多路复用程序来监听多个套接字, 文件事件处理器既实现了高性能的网络通信模型, 又可以很好地与 redis 服务器中其他同样以单线程方式运行的模块进行对接, 这保持了 Redis 内部单线程设计的简单性。
5、Redis应用场景有哪些?
①缓存热点数据,缓解数据库的压力。
②利用 Redis 原子性的自增操作,可以实现计数器的功能,比如统计用户点赞数、用户访问数等。
③简单的消息队列,可以使用Redis自身的发布/订阅模式或者List来实现简单的消息队列,实现异步操作。
④限速器,可用于限制某个用户访问某个接口的频率,比如秒杀场景用于防止用户快速点击带来不必要的压力。
⑤好友关系,利用集合的一些命令,比如交集、并集、差集等,实现共同好友、共同爱好之类的功能。
⑥排行榜,利用Zset的一些命令实现统计排行
6、Memcached和Redis的区别?
①MemCached 数据结构单一,仅用来缓存数据,而 Redis 支持多种数据类型。
②MemCached 不支持数据持久化,重启后数据会消失。Redis 支持数据持久化。
③Redis 提供主从同步机制和 cluster 集群部署能力,能够提供高可用服务。Memcached 没有提供原生的集群模式,需要依靠客户端实现往集群中分片写入数据。
④Redis 的速度比 Memcached 快很多。
⑤Redis 使用单线程的多路 IO 复用模型,Memcached使用多线程的非阻塞 IO 模型。(Redis6.0引入了多线程用来处理网络数据的读写和协议解析,但是命令的执行仍然是单线程)
⑥value 值大小不同:Redis 最大可以达到 512M;memcache 只有 1mb。
7、为什么要用 Redis 而不用 map/guava 做缓存?
使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 jvm 的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。
使用 redis 或 memcached 之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。
8、Redis 数据类型有哪些?
基本数据类型:
①String:最常用的一种数据类型,String类型的值可以是字符串、数字或者二进制,但值最大不能超过512MB。
②Hash:Hash 是一个键值对集合。
③Set:无序去重的集合。Set 提供了交集、并集等方法,对于实现共同好友、共同关注等功能特别方便。
④List:有序可重复的集合,底层是依赖双向链表实现的。
⑤SortedSet:有序Set。内部维护了一个score
的参数来实现。适用于排行榜和带权重的消息队列等场景。
特殊的数据类型:
①Bitmap:位图,可以认为是一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在 Bitmap 中叫做偏移量。Bitmap的长度与集合中元素个数无关,而是与基数的上限有关。
②Hyperloglog。HyperLogLog 是用来做基数统计的算法,其优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。典型的使用场景是统计独立访客。
③Geospatial :主要用于存储地理位置信息,并对存储的信息进行操作,适用场景如定位、附近的人等。
9、SortedSet和List异同点?
相同点:
①都是有序的;
②都可以获得某个范围内的元素。
不同点:
①列表基于链表实现,获取两端元素速度快,访问中间元素速度慢;
②有序集合基于散列表和跳跃表实现,访问中间元素时间复杂度是OlogN;
③列表不能简单的调整某个元素的位置,有序列表可以(更改元素的分数);
④有序集合更耗内存。
10、Redis的内存用完了会怎样?
如果达到设置的上限,Redis的写命令会返回错误信息(但是读命令还可以正常返回)。 也可以配置内存淘汰机制,当Redis达到内存上限时会冲刷掉旧的内容。