目前最全的Redis知识点及面试题汇总

Redis(全称为REmoteDIctionaryServer)是一个由SalvatoreSanfilippo写的key-value存储系统。Redis是一个开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是字符串(String),哈希(Map),列表(list),集合(sets)和有序集合(sortedsets)等类型。

Redis最大的特点有2个,一个是采用IO端口多路复用模型,极大的提升了处理IO的能力;另外一个是可以支持上述所说多种类型。Redis的整体架构如图1所示,它可以监听多个句柄的事件,并在有事件的时候分发到具体的业务单元进行处理。

Redis已经是最火的KV数据库了,在各个领域应用广泛。为了方便大家学习,本号整理了Redis的一些知识点和线上问题,希望对大家的日常开发、运维或者跳槽有所帮助。

1什么是Redis?

Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作,是已知性能最快的Key-ValueDB。

Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是MB,不像memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能。

2Redis的主要特性

速度快

Redis使用标准C编写实现,而且将所有数据加载到内存中,所以速度非常快。官方提供的数据表明,在一个普通的Linux机器上,Redis读写速度分别达到/s和/s。

2)数据结构

可以将Redis看做“数据结构服务器”。目前,Redis支持5种数据结构。

3)持久化

由于所有数据保持在内存中,所以对数据的更新将异步地保存到磁盘上,Redis提供了一些策略来保存数据,比如根据时间或更新次数。数据超过内存,使用swap,保证数据;

memcacache不能持久化,mongo是部分在内存;

4)自动操作

Redis对不同数据类型的操作是自动的,因此设置或增加key值,从一个集合中增加或删除一个元素都能安全的操作。

5)支持多种语言

Redis支持多种语言,诸如Ruby,Python,TwistedPython,PHP,Erlang,Tcl,Perl,Lua,Java,Scala,Clojure等。

6)主-从复制

Redis支持简单而快速的主-从复制。

官方提供了一个数据,Slave在21秒即完成了对Amazon网站10Gkeyset的复制。

7)Sharding

很容易将数据分布到多个Redis实例中,但这主要看该语言是否支持。目前支持Sharding功能的语言只有PHP、Ruby和Scala。

3Redis支持哪几种数据类型?

1)String(字符串)

string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。string类型是二进制安全的,也就是说redis的string可以包含任何数据。比如jpg图片或者序列化的对象。string类型的值最大能存储MB。

2)Hash(哈希)

Redishash是一个键值(key=value)对集合。Redishash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

3)List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

4)Set(集合)

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

5)zset(sortedset:有序集合)

Rediszset和set一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

4Redis相比memcached有哪些优势?

1)memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

2)redis的速度比memcached快很多

3)redis可以持久化其数据

5Redis有哪些适合的场景?

1)会话缓存(SessionCache)

最常用的一种使用Redis的情景是会话缓存(sessioncache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

幸运的是,随着Redis这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

2)全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。

此外,对WordPress的用户来说,Pantheon有一个非常好的插件wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

3)队列

Reids在内存存储引擎领域的一大优点是提供list和set操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对list的push/pop操作。

如果你快速的在Google中搜索“Redisqueues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

4)排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(SortedSet)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:

ZRANGEuser_scoresWITHSCORES

AgoraGames就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。

5)发布/订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。

6Redis有哪几种数据淘汰策略?

noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)

allkeys-lru:尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。

volatile-lru:尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。

allkeys-random:回收随机的键使得新添加的数据有空间存放。

volatile-random:回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。

volatile-ttl:回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

7Redis官方为什么不提供Windows版本?

目前数据中心服务端的软件大都是运行在Linux操作系统上的,Windows应用场景不多;另外Linux版本已经相当稳定,windows环境用户量小,开发的必要性不大,反而会带来兼容性等问题。

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

最大支持值的大小是M,另外键(Key)的最大长度也是MB。

9为什么Redis需要把所有数据放到内存中?

根据性能金字塔我们知道内存的性能是机械磁盘的百万倍,如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。

如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。

10Redis集群方案应该怎么做?都有哪些方案?

1.twemproxy,大概概念是,它类似于一个代理方式,使用方法和普通redis无任何区别,设置好它下属的多个redis实例后,使用时在本需要连接redis的地方改为连接twemproxy,它会以一个代理的身份接收请求并使用一致性hash算法,将请求转接到具体redis,将结果再返回twemproxy。使用方式简便(相对redis只需修改连接端口),对旧项目扩展的首选。问题:twemproxy自身单端口实例的压力,使用一致性hash后,对redis节点数量改变时候的计算值的改变,数据无法自动移动到新的节点。

2.codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数量改变情况下,旧节点数据可恢复到新hash节点。

3.rediscluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。具体看官方文档介绍。

4.在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key进行hash计算,然后去对应的redis实例操作数据。这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的替代算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。

11Redis集群方案什么情况下会导致整个集群不可用?

有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少-这个范围的槽而不可用。

12MySQL里有w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?

redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。

13Redis支持的Java客户端都有哪些?官方推荐用哪个?

Redisson、Jedis、lettuce等等,官方推荐使用Redisson。

14Redis和Redisson有什么关系?

Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-MemoryDataGrid)。充分的利用了Redis键值数据库提供的一系列优势,基于Java实用工具包中常用接口,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。

15Jedis与Redisson对比有什么优缺点?

Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的


转载请注明:http://www.aierlanlan.com/cyrz/4974.html