前言这里整理了一些关于Redis中常见的面试题,希望可以帮到还在求职路上的你们。1. 什么是Redis?Redis 是一个基于内存的高性能key-value数据库,由C语言编写。引申问题常见nosql数据库分类及区别2. Redis的特...
前言
这里整理了一些关于Redis中常见的面试题,希望可以帮到还在求职路上的你们。
1. 什么是Redis?
Redis 是一个基于内存的高性能key-value数据库,由C语言编写。
引申问题
常见nosql数据库分类及区别
2. Redis的特点
Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性能消息队列服务,用他的Set可以做高性能的Tag系统等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一个功能加强版的memcached来用。
Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
3. Redis持久化的几种方式
快照(snapshots)
缺省情况情况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb。你可以配置Redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘;或者你可以手工调用命令SAVE或BGSAVE。
工作原理
(1) Redis forks.
(2)子进程开始将数据写到临时RDB文件中。
(3)当子进程完成写RDB文件,用新文件替换老文件。
(4)这种方式可以使Redis使用copy-on-write技术。
AOF
快照模式并不十分健壮,当系统停止,或者无意中Redis被kill掉,最后写入Redis的数据就会丢失。这对某些应用也许不是大问题,但对于要求高可靠性的应用来说,Redis就不是一个合适的选择,Append-only文件模式是另一种选择,你可以在配置文件中打开AOF模式。
虚拟内存方式
当你的key较小而value很大时,使用VM的效果会比较好,因为这样节约的内存比较大。
当你的key较大时,可以考虑使用一些非常方法将很大的key变成很大的value,比如你可以考虑将key,value组合成一个新的value。
vm-max-threads这个参数,可以设置访问swap文件的线程数,设置最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的.可能会造成比较长时间的延迟,但是对数据完整性有很好的保证。
如果数据量很大,可以考虑分布式或者其他数据库。
4. 使用Redis的优势
(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) 。
(2) 支持丰富数据类型,支持String,List,Set,Sorted Set,Hash 。
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行 。
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除。
5. Redis各数据类型底层实现
String
字符串对象的编码可以是int、raw或者embstr。
(1) int 编码:保存的是可以用 long 类型表示的整数值。
(2) raw 编码:保存长度大于44字节的字符串(redis3.2版本之前是39字节,之后是44字节)。
(3) embstr 编码:保存长度小于44字节的字符串(redis3.2版本之前是39字节,之后是44字节)。
int 编码是用来保存整数值,raw编码是用来保存长字符串,而embstr是用来保存短字符串。
普通的字符串有两种,embstr和raw。embstr是Redis 3.0新增的数据结构,在2.8中是没有的。如果字符串对象的长度小于39字节,就用embstr对象。否则用传统的raw对象。
embstr和raw使用的存储结构如图:
embstr的好处有如下几点:
embstr的创建只需分配一次内存,而raw为两次(一次为sds分配对象,另一次为objet分配对象,embstr省去了第一次)。
相对地,释放内存的次数也由两次变为一次。
embstr的objet和sds放在一起,更好地利用缓存带来的优势。
embstr的坏处也很明显,如果字符串的长度增加需要重新分配内存时,整个redisObject和sds都需要重新分配空间,因此redis中的embstr实现为只读。
List
列表对象的编码可以是ziplist(压缩链表) 和 linkedlist(双端链表)。
ziplist是一种压缩链表,它的好处是更能节省内存空间,因为它所存储的内容都是在连续的内存区域当中的。当列表对象元素不大,每个元素也不大的时候,就采用ziplist存储。但当数据量过大时就ziplist就不是那么好用了。因为为了保证他存储内容在内存中的连续性,插入的复杂度是O(N),即每次插入都会重新进行realloc。如下图所示,对象结构中ptr所指向的就是一个ziplist。整个ziplist只需要malloc一次,它们在内存中是一块连续的区域。
linkedlist是一种双向链表。它的结构比较简单,节点中存放pre和next两个指针,还有节点相关的信息。当每增加一个node的时候,就需要重新malloc一块内存。
Hash
哈希对象的编码可以是 ziplist 或者 hashtable。
hashtable 编码的哈希表对象底层使用字典数据结构,哈希对象中的每个键值对都使用一个字典键值对。
Set
集合对象的编码可以是 intset 或者 hashtable。
intset 编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合中。
SortedSet
有序集合的编码可以是 ziplist 或者 skiplist。
skiplist 编码的有序集合对象使用 zet 结构作为底层实现,一个 zset 结构同时包含一个字典和一个跳跃表:
7. 如何保证Redis中的数据都是热点数据
Redis 内存数据集大小上升到一定大小的时候,就会执行数据淘汰策略(回收策略)。Redis 提供 6种数据淘汰策略:
(1)volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。
(2)volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。
(3)volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
(4)allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰。
(5)allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。
(6)no-enviction(驱逐):禁止驱逐数据。
8. Redis常见性能问题和解决方案
Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。
9. 一个字符串类型的值能存储最大容量是多少?
512M
10. Redis集群方案应该怎么做?都有哪些方案?
(1)Codis目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数量改变情况下,旧节点数据可恢复到新hash节点。
(2)Redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。
(3)在业务代码层实现,启动几个毫无关联的redis实例,在代码层,对key 进行hash计算,然后去对应的Redis实例操作数据。
本文标题为:Redis中一些常见的面试题
基础教程推荐
- Mysql查询所有表和字段信息的方法 2023-07-26
- python中pandas库的iloc函数用法解析 2023-07-28
- 【Redis】数据持久化 2023-09-12
- 关于MySQL中explain工具的使用 2023-07-27
- 如何将excel表格数据导入postgresql数据库 2023-07-20
- Python常见库matplotlib学习笔记之多个子图绘图 2023-07-27
- Sql Server Management Studio连接Mysql的实现步骤 2023-07-29
- Redis如何实现延迟队列 2023-07-13
- Mysql主从三种复制模式(异步复制,半同步复制,组复 2022-09-01
- SQLServer 清理日志的实现 2023-07-29