1。Redis支持哪些数据类型?字符串(string)格式:设置键值字符串类型是二进制安全的。这意味着redis的字符串可以包含任何数据。比如jpg图片或者序列化的对象。字符串类型是Redis最基本的数据类型,一个key最多可以存储512MB。哈希格式:hmsetnamekey1value1key2value2Redis哈希是一组键值对(key=>value)。Redishash是string类型字段和值的映射表,hash特别适合存储对象。List(列表)Redis列表是简单的字符串列表,按插入顺序排序。可以在列表的头部(左)或尾部(右)添加一个元素格式:lpushnamevalue在key对应的列表头部添加一个字符串元素格式:rpushnamevalue在尾部添加一个字符串元素key对应的list的of格式:lremnameindexkey对应删除list中与value相同的count个元素格式:llenname返回key,对应list的长度Set(集合)格式:saddnamevalueRedisSet是字符串类型的无序集合。集合是通过哈希表实现的,所以增删改查的复杂度都是O(1)。zset(sortedset:有序集合)格式:zaddnamescorevalueRediszset也是和set一样的字符串类型元素的集合,不允许有重复的成员。不同之处在于每个元素都将与一个双精度类型的分数相关联。Redis使用分数将集合的成员从小到大排序。zset的成员是唯一的,但是分数(score)可以重复。2、什么是Redis持久化?Redis有哪几种持久化方式?优缺点都有什么?持久化就是将内存中的数据写入磁盘,防止服务宕机时内存数据丢失。Redis提供了两种持久化方式:RDB(默认)和AOFRDB:rdb是RedisDataBase函数的缩写核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数AOF:Aof是Append-onlyfile的缩写每当执行服务器(定时)任务或函数时,都会调用flushAppendOnlyFile函数。该函数执行以下两个任务:WRITE:根据条件将aof_buf中的缓冲区写入AOF文件SAVE:根据条件调用fsync或fdatasync函数将AOF文件保存到磁盘。存储结构:内容为redis通信协议(RESP)格式的命令文本存储。比较:aof文件比rdb文件更新更频繁,首选aof恢复数据。Aof比rdb更安全,也更大。rdb比aof有更好的性能。如果两者都配置了优先加载AOF,你刚刚在上面提到了redis通信协议(RESP)。你能解释一下RESP是什么吗?有什么特点?(可以看到很多面试其实都是连环炮,面试官其实就是在等你回答这一点,如果你回答了对你的评价,还会加一分。)RESP是redis客户端和服务端之前的一次通信协议;RESP特点:实现简单,分析速度快,可读性好ForSimpleStrings回复首字节为“+”ReplyForErrors回复首字节为“-”ErrorForIntegers回复首字节为“:”IntegerForBulkStrings回复首字节为“$”StringForArrays回复首字节为“*”Arraypersistence面试中经常被问到,重点学习,篇幅有限,具体点击以下文章:10分钟吃透Redis的持久化机制:RDB、AOF3、Redis的架构模式有哪些?说说各自的特点单机版特点:简单的问题:内存容量有限,处理能力有限,不能高可用。主从复制Redis的复制功能允许用户基于一台Redis服务器创建任意数量的服务器副本。被复制的服务器是主服务器(master),复制创建的服务器副本是从服务器(slave)。只要主从服务器之间的网络连接正常,主从服务器就会有相同的数据,主服务器会一直把自己发生的数据更新同步到从服务器,从而保证数据的一致性主从服务器的配置是一样的。特点:master/slave角色master/slave数据相同,减少master从库中读取压力问题:不能保证高可用,不能解决master写压力SentinelRedissentinel是一个分布式系统,监控redismaster-从服务器和主服务器离线时自动故障转移。其中三个特点:监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否正常工作。通知:当被监控的Redis服务器出现问题时,Sentinel可以通过API向管理员或其他应用发送通知。自动故障转移(Automaticfailover):当一个主服务器无法正常工作时,Sentinel会启动自动故障转移操作。特点:保证高可用,监控各节点自动故障转移缺点:主从模式,切换需要时间数据丢失不能解决master写入压力Cluster(proxy类型)Twemproxy是一个开源的redis和memcache快速/轻量级代理服务器;Twemproxy是一个快速的单线程代理程序,支持MemcachedASCII协议和redis协议。特点:多种哈希算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins支持故障节点自动删除后端分片分片逻辑对业务透明,业务端读写方式一致与单个Redis一起运行缺点:新增proxy需要保持高可用。故障转移逻辑需要自己实现,不支持故障自动转移。扩展性差,扩缩容需要集群人工干预(直连型):redis-cluster集群从redis3.0以后的版本开始支持,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都连接到所有其他节点。特点:去中心化架构(不存在影响性能瓶颈的节点),缺少代理层。数据按照槽位存储分布在多个节点之间,节点间数据共享可以动态调整数据分布。可扩展性,线性扩展到1000个节点,可以动态添加或删除节点。高可用,当部分节点不可用时,集群仍然可用。通过添加Slave作为备份数据副本——实现故障时的自动故障转移,节点之间通过gossip协议交换状态信息,使用投票机制完成从Slave到Master的角色提升。缺点:资源隔离性差,容易相互影响。数据是异步复制的,不保证数据的强一致性。高可用Redis架构分析与搭建,可以参考:高可用Redis服务架构分析与搭建4、你用过Redis分布式锁吗?它是如何实施的?先用setnx去竞争锁,然后用expire给锁加一个过期时间,防止锁忘记释放。如果在setnx之后执行expire之前进程意外崩溃或者需要重启维护怎么办?set命令的参数非常复杂,所以应该可以把setnx和expire同时合并成一个命令!5、你用过Redis作为异步队列吗?你是怎么用的?缺点是什么?一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,需要sleep一会再试。缺点:当消费者下线时,生产的消息会丢失,必须使用rabbitmq等专业的消息队列。能否一次生产多次消费?使用pub/sub主题订阅者模式,可以实现1:N的消息队列。6、什么是缓存穿透?如何避免?什么是缓存雪崩?如何避免?缓存穿透一般缓存系统根据key进行缓存和查询。如果没有对应的值,就去后台系统(比如DB)去查找。一些恶意请求会故意查询不存在的key,大量的请求会给后端系统带来很大的压力。这称为缓存穿透。如何避免?查询结果为空时也会缓存查询结果,缓存时间设置的短些,或者插入key对应的数据后清空缓存。不能存在的过滤键。可以把所有可能的key放到一个大的Bitmap中,查询的时候通过bitmap进行过滤。缓存雪崩当缓存服务器重启或一定时间内大量缓存失效时,这会在失效时给后端系统带来很大的压力。导致系统崩溃。如何避免?缓存过期后,通过加锁或队列来控制读数据库和写缓存的线程数。例如,只允许一个线程查询某个key的数据和写cache,其他线程等待。做一个二级缓存,A1为原始缓存,A2为副本缓存,当A1失效时,可以访问A2,A1缓存过期时间设置为短期,A2设置为长期不同的key,设置不同的过期时间时间,让缓存失效时间点尽可能均匀。这个比较常见,具体可以参考下面,一定要熟悉:Redis缓存雪崩、缓存击穿、缓存穿透以及几种常见的缓存模式7、Redis常用命令管理命令#dbsize返回key的个数当前数据库。#info返回当前的redis服务器状态和一些统计信息。#monitor实时监控并返回redis服务器收到的所有请求信息。#shutdown将数据同步存盘,关闭redis服务。#configgetparameter获取一个redis配置参数信息。(个别参数可能不可用)#configsetparametervalue设置一个redis配置参数信息。(个别参数可能不可用)#configresetstat重置info命令的统计信息。(重置包括:键空间命中、#keyspace错误、处理命令、接收连接、过期键)#debugobjectkey获取某个键的调试信息。#debugsegfault导致服务器崩溃。#flushdb删除当前数据库中的所有key,这个方法不会失败。注意使用#flushall删除所有数据库中的所有键,此方法不会失败。工具命令慎用#redis-server:Redis服务器的守护启动程序#redis-cli:Redis命令行操作工具。当然你也可以使用telnet按照它的明文协议进行操作#redis-benchmark:Redis性能测试工具,测试Redis在你的系统和你的配置下的读写性能$redis-benchmark-n100000–c50#模拟同时50个客户端发送100000个SET/GET查询#redis-check-aof:更新日志检查#redis-check-dump:本地数据库检查8.Redis单例、主从模式、哨兵和集群配置及优化劣势对比Redis单例、主从模式、sentinel和集群配置方式及优缺点对比9、Redis单线程为什么可以支持高并发?为什么Redis单线程可以支持高并发?10.Redis常见性能问题及解决方法:1).master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作。当快照比较大时,对性能的影响非常大,服务会断断续续的挂掉。所以Master最好不要写内存快照。2).MasterAOF持久化,如果不重写AOF文件,这种持久化方式对性能影响最小,但是AOF文件会不断增长,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,尤其不要开启内存快照进行持久化。如果数据很关键,Slave应该开启AOF备份数据,策略是每秒同步一次。3).Master调用BGREWRITEAOF重写AOF文件。AOF在改写时会占用大量的CPU和内存资源,导致服务负载高,服务短时间停顿。4).Redis主从复制的性能问题。为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。Redis性能分析相关问题。限于篇幅,给出文章链接:Redis性能问题分析(好文推荐)11、如何解决Redis的并发竞争问题?Redis是单进程单线程模式,使用队列模式将并发访问变为串行访问。Redis本身没有锁的概念。Redis不存在多个客户端连接的竞争,但是当Jedis客户端并发访问Redis时,会出现连接超时、数据转换错误、阻塞、客户端关闭连接等问题。这些问题都是由于客户端连接混乱造成的。对此有两种解决方案:从客户端的角度,为了保证每个客户端正常有序的与Redis通信,对连接进行池化,对客户端的读写Redis操作同步内部锁.从服务器的角度,使用setnx来实现锁。注意:对于第一种,应用需要自己处理资源的同步。可以使用的方法比较流行,可以使用synchronized或者lock;第二种需要使用Redis的setnx命令,但是需要注意一些问题。12、说说Redis的内存淘汰策略。直接点这里:Redis的内存淘汰策略13.Redis最适合的场景Redis最适合所有数据入内存的场景。Redis虽然也提供了持久化功能,但其实更多的是磁盘备份的功能,与传统的持久化有很大区别,所以大家可能会有疑问。看起来Redis更像是Memcached的增强版,那么什么时候用Memcached,什么时候用Redis呢?如果单纯比较Redis和Memcached的区别,大部分人会得到以下几点:Redis不仅支持简单的k/v类型数据,还提供了list、set、zset、hash等数据结构的存储。Redis支持数据备份,即主从模式的数据备份。Redis支持数据持久化,可以将内存中的数据保存在磁盘上,重启时可以再次加载使用。使用Redis最常用的场景之一是会话缓存。使用Redis缓存会话相对于其他存储(例如Memcached)的优势在于Redis提供了持久性。当维护一个不严格一致的缓存时,如果用户的所有购物车信息都丢失了,大多数人都会不高兴。现在,他们会吗?幸运的是,随着Redis多年来的改进,很容易找到有关如何正确使用Redis进行会话缓存的文档。甚至著名的商业平台Magento也为Redis提供了一个插件。FullPageCache(FPC)除了基本的会话令牌,Redis还提供了一个非常简单的FPC平台。回到一致性问题,即使Redis实例重启,用户也不会因为磁盘持久化而看到页面加载速度下降。这是一个很大的改进,类似于PHP的本地FPC。再次以Magento为例,Magento提供了一个插件来使用Redis作为全页缓存后端。另外,对于WordPress用户,Pantheon有一个非常不错的插件wp-redis,可以帮助你以最快的速度加载你访问过的页面。队列Reids在内存存储引擎领域的优势之一是它提供了列表和集合操作,这使得Redis成为一个很好用的消息队列平台。Redis作为队列的操作类似于本地编程语言(如Python)对列表的push/pop操作。如果您在Google上快速搜索“Redis队列”,您会立即找到大量旨在使用Redis创建非常好的后端工具以满足各种队列需求的开源项目。比如Celery有后台使用Redis作为broker,可以从这里查看。排行榜/计数器Redis在内存中递增和递减数字方面做得很好。Sets和SortedSets也让我们执行这些操作变得非常简单。Redis只是提供了这两种数据结构。所以,我们想从排序集中获得前10位用户——我们称之为“user_scores”。当然,这假设您是根据用户的分数递增排序的。如果你想返回用户和用户的分数,你需要这样执行:ZRANGEuser_scores010WHITSCORESAAgoraGames是一个很好的例子,用Ruby实现,它的排行榜使用Redis存储数据,你可以在这里看到.发布/订阅最后(但并非最不重要)是Redis的发布/订阅功能。发布/订阅确实有很多用例。我见过人们在社交网络连接中使用它,作为基于发布/订阅的脚本的触发器,甚至使用Redis的发布/订阅功能来构建聊天系统!
