java面试---Redis

  1. redis 是什么?都有哪些使用场景?
    Redis是一个开源的 key—value型 单线程非关系型数据库,支持string、list、set、zset和hash类型数据。
    默认端口:6379
    默认数据库数量:16
    适用场景:
    1.数据高并发的读写
    2.海量数据的读写
    3.对扩展性要求高的数据

  2. redis 有哪些功能?
    1)、会话缓存(Session Cache)
    2)、全页缓存(FPC)
    3)、队列
    4)、排行榜/计数器
    5)、发布/订阅

  3. redis 和 memecache 有什么区别?
    1、存储方式:
    memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小
    redis有部份存在硬盘上,这样能保证数据的持久性。
    2、数据支持类型:
    redis在数据支持上要比memecache多的多。
    3、使用底层模型不同:
    新版本的redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
    4、运行环境不同:
    redis目前官方只支持LINUX 上去行,从而省去了对于其它系统的支持,这样的话可以更好的把精力用于本系统 环境上的优化,虽然后来微软有一个小组为其写了补丁。但是没有放到主干上

  4. redis 为什么是单线程的?
    因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

  5. 什么是缓存穿透?怎么解决?
    缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。
    解决:
    1、在某些特定场景下(登录),进行验证码,这种方法并不是很安全,因为目前图像识别技术在很大程度上能够解决验证码的问题,所以仅供简单使用。
    2、布隆过滤器

  6. redis 支持的数据类型有哪些?
    1、string(字符串)
    2、hash(哈希)
      Redis hash 是一个键值(key=>value)对集合。
      Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
    3、list(列表)
      Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
    4、set(集合)
      Redis的Set是string类型的无序集合。
    5、zset(sorted set:有序集合)Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

  7. redis 支持的 java 客户端都有哪些?
    Redisson,Jedis,lettuce等等,官方推荐使用Redisson。

  8. jedis 和 redisson 有哪些区别?
    1.概况对比
    Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。
    2.编程模型
    Jedis中的方法调用是比较底层的暴露的Redis的API,也即Jedis中的Java方法基本和Redis的API保持着一致,了解Redis的API,也就能熟练的使用Jedis。而Redisson中的方法则是进行比较高的抽象,每个方法调用可能进行了一个或多个Redis方法调用。3. 可伸缩性
    Jedis使用阻塞的I/O,且其方法调用都是同步的,程序流需要等到sockets处理完I/O才能执行,不支持异步。Jedis客户端实例不是线程安全的,所以需要通过连接池来使用Jedis。Redisson使用非阻塞的I/O和基于Netty框架的事件驱动的通信层,其方法调用是异步的。Redisson的API是线程安全的,所以可以操作单个Redisson连接来完成各种操作。
    4 . 数据结构
    Jedis仅支持基本的数据类型如:String、Hash、List、Set、Sorted Set。Redisson不仅提供了一系列的分布式Java常用对象,基本可以与Java的基本数据结构通用,还提供了许多分布式服务,其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service)。在分布式开发中,Redisson可提供更便捷的方法。
    5 . 第三方框架整合
    1)Redisson提供了和Spring框架的各项特性类似的,以Spring XML的命名空间的方式配置RedissonClient实例和它所支持的所有对象和服务;
    2)Redisson完整的实现了Spring框架里的缓存机制;
    3 )Redisson在Redis的基础上实现了Java缓存标准规范;
    4) Redisson为Apache Tomcat集群提供了基于Redis的非黏性会话管理功能。该功能支持Apache Tomcat的6、7和8版。
    5)Redisson还提供了Spring Session会话管理器的实现。

  9. 怎么保证缓存和数据库数据的一致性?
    采用延时双删策略、异步更新缓存(基于订阅binlog的同步机制)

  10. redis 持久化有几种方式?
    一种RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)

  11. redis 怎么实现分布式锁?
    获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
    获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
    释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。

  12. redis 分布式锁有什么缺陷?
    (一)缓存和数据库双写一致性问题
    (二)缓存雪崩问题
    (三)缓存击穿问题
    (四)缓存的并发竞争问题

  13. redis 如何做内存优化?
    一. redisObject对象
    二. 缩减键值对象
    三. 共享对象池
    四. 字符串优化
    五. 编码优化
    六. 控制key的数量

  14. redis 淘汰策略有哪些?
    1)voltile-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(驱逐):禁止驱逐数据

  15. redis 常见的性能问题有哪些?该如何解决?
    1.Master写内存快照
    save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
    2.Master AOF持久化
    如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。
    3.Master调用BGREWRITEAOF
    Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
    4.Redis主从复制的性能问题
    第一次Slave向Master同步的实现是:Slave向Master发出同步请求,Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的命令转发给Slave,初次同步完成。第二次以及以后的同步实现是:Master将变量的快照直接实时依次发送给各个Slave。不管什么原因导致Slave和Master断开重连都会重复以上过程。Redis的主从复制是建立在内存快照的持久化基础上,只要有Slave就一定会有内存快照发生。虽然Redis宣称主从复制无阻塞,但由于Redis使用单线程服务,如果Master快照文件比较大,那么第一次全量传输会耗费比较长时间,且文件传输过程中Master可能无法提供服务,也就是说服务会中断,对于关键服务,这个后果也是很可怕的。
    5.单点故障问题
    由于目前Redis的主从复制还不够成熟,所以存在明显的单点故障问题,这个目前只能自己做方案解决,如:主动复制,Proxy实现Slave对Master的替换等

    解决:
    1.Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。
    2.如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
    3.为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。
    4.尽量避免在压力较大的主库上增加从库
    5.为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变。

你可能感兴趣的:(java,redis)