179.redis 是什么?都有哪些使用场景?

  1. Redis是一个key-value存储系统。
  2.  
  3. 缓存,消息队列,排行榜/计数器,分布式架构,做session共享

180.redis 有哪些功能?

181.redis 和 memecache 有什么区别?

  1. 1 Redis不仅仅支持简单的k/v类型的数据,同时还提供listsetzsethash等数据结构的存储。memcache支持简单的数据类型,String
  2.  
  3. 2 Redis支持数据的备份,即master-slave模式的数据备份。
  4.  
  5. 3 Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中
  6.  
  7. 4 redis的速度比memcached快很多
  8.  
  9. 5Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的IO复用模型。

182.redis 为什么是单线程的?

  1. 数据都存在内存里,单线程避免多线程多上下文的切换浪费时间

183.什么是缓存穿透?怎么解决?

  1. 缓存穿透,是指查询一个数据库一定不存在的数据。
  2. 解决:会采用缓存空值的方式,如果从数据库查询的对象为空,也放入缓存,只是设定的缓存过期时间较短,比如设置为60秒。
  3.  
  4. 缓存雪崩,是指在某一个时间段,缓存集中过期失效。
  5. 解决:过期时间加上一个随机因子
  6.  
  7. 缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

184.redis 支持的数据类型有哪些?

  1. string:最基本的数据类型,二进制安全的字符串,最大512M
  2. list:按照添加顺序保持顺序的字符串列表。
  3. set:无序的字符串集合,不存在重复的元素。
  4. sorted set:已排序的字符串集合。
  5. hashkey-value对的一种集合。
  6. bitmap:更细化的一种操作,以bit为单位。
  7. hyperloglog:基于概率的数据结构。

185.redis 支持的 java 客户端都有哪些?

  Redis的Java客户端很多,官方推荐的有三种:Jedis、Redisson和lettuce。

186.jedis 和 redisson 有哪些区别?

  1. Jedis
  2.  
  3. 轻量,简洁,便于集成和改造
  4. 支持连接池
  5. 支持pipelining、事务、LUA ScriptingRedis SentinelRedis Cluster
  6. 不支持读写分离,需要自己实现
  7. 文档差(真的很差,几乎没有……)
  8. Redisson
  9.  
  10. 基于Netty实现,采用非阻塞IO,性能高
  11. 支持异步请求
  12. 支持连接池
  13. 支持pipeliningLUA ScriptingRedis SentinelRedis Cluster
  14. 不支持事务,官方建议以LUA Scripting代替事务
  15. 支持在Redis Cluster架构下使用pipelining
  16. 支持读写分离,支持读负载均衡,在主从复制和Redis Cluster架构下都可以使用
  17. 内建Tomcat Session Manager,为Tomcat 6/7/8提供了会话共享功能
  18. 可以与Spring Session集成,实现基于Redis的会话共享
  19. 文档较丰富,有中文文档
  20. 对于JedisRedisson的选择,同样应遵循前述的原理,尽管Jedis比起Redisson有各种各样的不足,但也应该在需要使用Redisson的高级特性时再选用Redisson,避免造成不必要的程序复杂度提升。

187.怎么保证缓存和数据库数据的一致性?

  1. 缓存和数据库数据不一样的原因:
  2. 在分布式环境下,数据的读写都是并发的,对同一个数据进行读写,在数据库层面并发的读写并不能保证完成顺序,也就是说后发出的读请求很可能先完成(读出脏数据):
  3. a)发生了写请求AA的第一步淘汰了cache(如上图中的1
  4.  
  5. bA的第二步写数据库,发出修改请求(如上图中的2
  6.  
  7. c)发生了读请求BB的第一步读取cache,发现cache中是空的(如上图中的步骤3
  8.  
  9. dB的第二步读取数据库,发出读取请求,此时A的第二步写数据还没完成,读出了一个脏数据放入cache(如上图中的步骤4
  10.  
  11. 即在数据库层面,后发出的请求4比先发出的请求2先完成了,读出了脏数据,脏数据又入了缓存,缓存与数据库中的数据不一致出现了
  12.  
  13. 思路:
  14. 解决这个问题的关键是如何保证多个线程更新有序性,化并行为串行是解决这个问题的基本思路。
  15.  
  16. 解决方法:
  17. 由于数据库层面的读写并发,引发的数据库与缓存数据不一致的问题(本质是后发生的读请求先返回了),可能通过两个小的改动解决:
  18.  
  19. 1)修改服务Service连接池,id取模选取服务连接,能够保证同一个数据的读写都落在同一个后端服务上
  20.  
  21. 2)修改数据库DB连接池,id取模选取DB连接,能够保证同一个数据的读写在数据库层面是串行的

188.redis 持久化有几种方式?

  1. 1.RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。
  2. 优势:
  3. 整个Redis数据库将只包含一个文件,这样非常方便进行备份;
  4. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
  5. RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
  6. 劣势:
  7. 一旦发生故障停机, 你就可能会丢失好几分钟的数据;
  8. 每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时
  9.  
  10. 2.AOF持久化是将每一个收到的写命令都通过write函数追加到文件中。
  11. 优势:
  12. 使用 AOF 持久化会让 Redis 变得非常耐久;
  13. AOF 文件有序地保存了对数据库执行的所有写入操作;
  14. 劣势:
  15. AOF 文件的体积通常要大于 RDB 文件的体积;
  16. 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB

189.redis 怎么实现分布式锁?

  1. 先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。
  2. 如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?set指令有非常复杂的参数,这个应该是可以同时把setnxexpire合成一条指令来用的!
  3. 总的来说,执行上面的set()方法就只会导致两种结果:1. 当前没有锁(key不存在),那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。2. 已有锁存在,不做任何操作。

190.redis 分布式锁有什么缺陷?

  1. 1.单点问题
  2. 一般都使用集群
  3. 2.锁过期后业务没有处理完成,有并发问题
  4. 在时间上加一个随机值,使得过期时间分散一些。设置短的过期时间,启用一个线程更新过期时间,完成后停止线程。

191.redis 如何做内存优化?

  1. 1.降低Redis内存使用最直接的方式就是缩减键(key)和值(value)的长度。
  2. key长度:如在设计键时,在完整描述业务情况下,键值越短越好。
  3. value长度:值对象缩减比较复杂,常见需求是把业务对象序列化成二进制数组放入Redis
  4. 注:高并发写入场景中,在条件允许的情况下建议字符串长度控制在39字节以内,减少创建redisObject内存分配次数从而提高性能。
  5. 2.共享对象池
  6. 对象共享池指Redis内部维护[0-9999]的整数对象池。创建大量的整数类型redisObject存在内存开销,每个redisObject内部结构至少占16字节,甚至超过了整数自身空间消耗。所以Redis内存维护一个[0-9999]的整数对象池,用于节约内存。 除了整数值对象,其他类型如list,hash,set,zset内部元素也可以使用整数对象池。因此开发中在满足需求的前提下,尽量使用整数对象以节省内存。
  7. 3.字符串优化
  8. 字符串对象是Redis内部最常用的数据类型。所有的键都是字符串类型, 值对象数据除了整数之外都使用字符串存储。
  9. 4.控制key的数量
  10. 当使用Redis存储大量数据时,通常会存在大量键,过多的键同样会消耗大量内存。

192.redis 淘汰策略有哪些?

  1. 1noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。
  2.  
  3. 2allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种。
  4.  
  5. 3allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。
  6.  
  7. 4volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐
  8.  
  9. 5volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐
  10.  
  11. 6volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐

193.什么是分布式锁?有哪些分布式锁?

  1. 要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁、进程锁。
  2. 线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段。线程锁只在同一JVM中有效果,因为线程锁的实现在根本上是依靠线程之间共享内存实现的,比如synchronized是共享对象头,显示锁Lock是共享某个变量(state)。
  3. 进程锁:为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程的资源,因此无法通过synchronized等线程锁实现进程锁。
  4. 分布式锁:当多个进程不在同一个系统中,用分布式锁控制多个进程对资源的访问。

194.分布式锁的实现有哪几种?

  1. 1.基于数据库实现的分布式锁
  2. 当我们想要锁住某个方法时,执行以下SQL
  3. insert into methodLock(method_name,desc) values (‘method_name’,‘desc’)
  4. 因为我们对method_name做了唯一性约束,这里如果有多个请求同时提交到数据库的话,数据库会保证只有一个操作可以成功,那么我们就可以认为操作成功的那个线程获得了该方法的锁,可以执行方法体内容。
  5. 当方法执行完毕之后,想要释放锁的话,需要执行以下Sql:
  6. delete from methodLock where method_name ='method_name'
  7.  
  8. 优点:直接借助数据库,容易理解。
  9. 缺点:会有各种各样的问题,在解决问题的过程中会使整个方案变得越来越复杂。操作数据库需要一定的开销,性能问题需要考虑
  10.  
  11. 2.基于缓存实现的分布式锁 redis
  12. 通过setnx()获取锁,并设置释放锁的过期时间。
  13. 优点:性能好。
  14. 缺点:过期时间设置多久合适(过短时间不够处理业务,过长等待时间就长)?因为业务处理时间过长或者full gc 的原因导致锁过期,其他线程获取锁有并发问题。单点问题。
  15. 方案:每获得一个锁时,只设置一个很短的超时时间,同时起一个线程在每次快要到超时时间时去刷新锁的超时时间。在释放锁的同时结束这个线程。如redis官方的分布式锁组件redisson,就是用的这种方案。 使用集群处理
  16.  
  17. 3.基于Zookeeper实现的分布式锁
  18.  
  19. 基于zookeeper临时有序节点可以实现的分布式锁。每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。 判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。 当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。
  20. 优点:有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题。实现起来较为简单。
  21. 缺点:性能上不如使用缓存实现分布式锁。 需要对ZK的原理有所了解。
  22.  
  23. 原文:https://blog.csdn.net/u010963948/article/details/79006572
  24. 版权声明:本文为博主原创文章,转载请附上博文链接!

193.redis 常见的性能问题有哪些?该如何解决?

  1. 1.Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。   2.如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。   3.为了主从复制的速度和连接的稳定性,SlaveMaster最好在同一个局域网内。

194.redisobject对象

  1. Redis存储的所有值对象在内部定义为redisObject结构体,内部结构如下图所示。
  2.  
  3. Redis存储的数据都使用redisObject来封装,包括string,hash,list,set,zset在内的所有数据类型。理解redisObject对内存优化非常有帮助,下面针对每个字段做详细说明:
  4.  
  5. 1.type字段:
  6. 表示当前对象使用的数据类型,Redis主要支持5种数据类型:string,hash,list,set,zset。可以使用type {key}命令查看对象所属类型,type命令返回的是值对象类型,键都是string类型。
  7.  
  8. 2.encoding字段:
  9. 表示Redis内部编码类型,encodingRedis内部使用,代表当前对象内部采用哪种数据结构实现。理解Redis内部编码方式对于优化内存非常重要 ,同一个对象采用不同的编码实现内存占用存在明显差异,具体细节见之后编码优化部分。
  10.  
  11. 3.lru字段:
  12. 记录对象最后一次被访问的时间,当配置了 maxmemorymaxmemory-policy=volatile-lru | allkeys-lru 时, 用于辅助LRU算法删除键数据。可以使用object idletime {key}命令在不更新lru字段情况下查看当前键的空闲时间。
  13.  
  14. 开发提示:可以使用scan + object idletime 命令批量查询哪些键长时间未被访问,找出长时间不访问的键进行清理降低内存占用。
  15. 4.refcount字段:
  16. 记录当前对象被引用的次数,用于通过引用次数回收内存,当refcount=0时,可以安全回收当前对象空间。使用object refcount {key}获取当前对象引用。当对象为整数且范围在[0-9999]时,Redis可以使用共享对象的方式来节省内存。具体细节见之后共享对象池部分。
  17.  
  18. 5. *ptr字段:
  19. 与对象的数据内容相关,如果是整数直接存储数据,否则表示指向数据的指针。Redis3.0之后对值对象是字符串且长度<=39字节的数据,内部编码为embstr类型,字符串sdsredisObject一起分配,从而只要一次内存操作。
  20.  
  21. 开发提示:高并发写入场景中,在条件允许的情况下建议字符串长度控制在39字节以内,减少创建redisObject内存分配次数从而提高性能。

面试简单整理之Redis的更多相关文章

  1. 面试简单整理之JVM

    194.说一下 jvm 的主要组成部分?及其作用? JVM内存分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据. 堆内存用于存储使用new关键字所创建的对象: 栈内存用于存储程序运行时在 ...

  2. 面试简单整理之zookeeper

    157.zookeeper 是什么? ZooKeeper 是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现. 分布式应用程序可以基于 ZooKeeper 实现诸如数据 ...

  3. 面试简单整理之rabbitmq

    135.rabbitmq 的使用场景有哪些? 单反单收,单发多收,发布订阅,按路由发送,按主题发送 136.rabbitmq 有哪些重要的角色? Server,Consumer,Producer 13 ...

  4. 面试简单整理之mybatis

    125.mybatis 中 #{}和 ${}的区别是什么? 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解 ...

  5. 面试简单整理之spring、spring mvc

    90.为什么要使用 spring? 解决企业应用开发的复杂性,IOC.aop 91.解释一下什么是 aop? 面向切面编程.... 92.解释一下什么是 ioc? 控制反转.. 93.spring 有 ...

  6. 面试简单整理之IO

    1.字节流,字符流 整个Java IO体系都是基于字节流(InputStream/OutputStream) 和 字符流(Reader/Writer)作为基类,根据不同的数据载体或功能派生出来的. 2 ...

  7. 面试简单整理之web

    63.servlet是什么?运行过程? Servlet是一门用于开发动态web资源的技术. 运行过程: Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后: ①W ...

  8. 阿里面试这样问:redis 为什么把简单的字符串设计成 SDS?

    2021开工第一天,就有小伙伴私信我,还给我分享了一道他面阿里的redis题(这家伙绝比已经拿到年终奖了),我看了以后觉得挺有意思,题目很简单,是那种典型的似懂非懂,常常容易被大家忽略的问题.这里整理 ...

  9. springboot整合redis(简单整理)

    Redis安装与开启 我这里是在windows上练习,所以这里的安装是指在windows上的安装,操作非常简单,点击https://github.com/MicrosoftArchive/redis/ ...

随机推荐

  1. nginx跨域配置(windos走过的坑)

    nginx下载地址: http://nginx.org/en/download.html 红圈区域是稳定版 解压之后放在文件夹就可以了. 解压后: 注意:这里面有个nginx.exe文件,一般情况下双 ...

  2. Springboot+ mybatis+ mysql配置@Slf4j

    spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver # 驱动 name: testDB # 配置名,可以随便写 userna ...

  3. 解决jQuery和其他库冲突

    <script> console.log($); // //jquery在其他库之前导入,直接使用jQuery()或 // var $replace = jQuery.noConflict ...

  4. 李清华201772020113《面向对象程序设计(java)》第十三周学习总结

    1.实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: (2) 掌握AWT事件模型的工作机制: (3) 掌握事件处理的基本编程模型: (4) 了解GUI界面组件观感设置方法: (5) 掌握W ...

  5. sqlserver2008R2 全日志恢复 实例操作

    --创建数据库create database test;--将数据库日志备份模式设置为全日志ALTER DATABASE test SET RECOVERY FULL ; --查询.确认数据库日志备份 ...

  6. win10关不了机解决办法以及win10怎么禁止开机启动项

    1.win10关不了机解决办法:https://zhidao.baidu.com/question/693962749213927924.html 2.win10怎么禁止开机启动项:https://j ...

  7. xml模块学习

    import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() pr ...

  8. python module -- sys

    sys模块主要是用于提供对python解释器相关的操作 http://www.cnblogs.com/pycode/p/sysos.html http://blog.csdn.net/pipisorr ...

  9. ---- 关于Android蓝牙搜索到设备的图标显示和设备过滤

    根据: https://www.douban.com/note/637446089/http://bbs.16rd.com/blog-23795-3446.html 以下摘自原文: (Android主 ...

  10. JS里的<!-- //--> 注释有什么作用

    早期浏览器有很多种(目前很少了),对HTML的解释也不同.有种纯文本浏览器,只“翻译”文本内容,并只支持少量HTML标签.对交互式的代码视同纯文本.因此,我们称其为不支持javascript的浏览器( ...