redis常见9大面试题
Redis是一个非关系数据库,我们项目中主要用它来存储热点数据的,减轻数据库的压力,单线程纯内存操作mysql持久化,采用了非阻塞IO多路复用机制,就是单线程监听,我们项
1、介绍一下redis Redis是一个非关系数据库,我们项目中主要用它来存储热点数据的,减轻数据库的压力,单线程纯内存操作mysql持久化,采用了非阻塞IO多路复用机制,就是单线程监听,我们项目中使用springdata-redis来操作redis 我们项目中使用redis的地方很多,比方说首页的热点数据,数据字典里的数据等都用热地说存储来提高访问速度 redis呢有5种数据类型,string、list、hash、set、zset,我们常用的有string、list和hash,一些简单的key-value类型的都存储在string类型中,比如一些系统开关之类的,是否开放注册等,还有一些存储在hash中,比如我们的首页的推荐数据和热门数据,都是用hash来存储的,一个固定的字符串作为key,每条数据的id作为field,对应的数据作为value存储 2、redis的持久化 redis有两种持久化方式,一个是RDB,这也是redis默认的持久化方式,这种方式是以快照的方式存储数据,在固定的时间段内如果有多少变化,那么就会生成快照存储到磁盘上,redis 在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。对于 RDB 方式,redis 会单独创建一个子进程来进行持久化,而主进程是不会进行任何 IO 操作的,这样就确保了 redis 极高的性能。 这种方式的优点呢就是快,但是如果没等到持久化开始redis宕机了,那么就会造成数据丢失 还有一种是AOF,是即时性的持久化方式,是将 redis 执行过的所有写指令记录下来,在下次 redis 重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。AOF的方式会导致性能下降 两种方式可以同时开启,当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。 我们项目中使用的持久化方式就是默认的RDB,因为我们存储的数据首先来说不是很重要的数据,如果丢失了,还可以从数据库加载到,主要用的就是性能这块 vv 我们可以简单的理解为:由于原有缓存失效,新缓存还没有存入到redis的期间 比方说:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期,所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。 解决办法: 加最多的解决方案就是锁,或者队列的方式来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。还有一个简单方案就是缓存失效时间分散开,不设置固定的实效时间,采用随机失效的策略来解决 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空,这就相当于进行了两次无用的查询。像这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题 解决办法 最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法,如果一个查询返回的数据为空,不管是数据不存在,还是系统故障,我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。 缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据! 操作方式: 1、直接写个缓存刷新页面,上线时手工操作下; 2、数据量不大,可以在项目启动的时候自动进行加载; 然后就是缓存更新: 1、定时去清理过期的缓存; 2.、当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存 当访问量剧增、服务出现问题,比如响应时间慢或不响应,或者非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有问题的服务。redis可以帮助系统实现数据降级载体,系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。 3、redis分布式锁 这个分布式锁这里,我们原来传统的项目都在单台服务器上部署用java里的锁synchronized这个同步锁就行,但是他这个是针对对象的锁,但是我们分布式的项目需要把项目部署到多台服务器上,每台服务器的对象都不同,所以就得考虑用分布式锁,这块实现起来也比较简单,其实这个锁就是redis中的一个key-value的一对值,在使用的时候吧,首先使用setnx方法进行尝试加锁,并可以设置过期时间,如果返回1则代表加锁成功,然后立即对这个锁设置一个实效时间,防止服务宕机,锁一致存在,在处理完业务逻辑之后,删除锁就行了,其他线程就可以获取锁进行业务了 4、redis主从复制 通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失)数据,因为持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据。但是由于数据是存储在一台服务器上的,如果这台服务器出现硬盘故障等问题,也会导致数据丢失。为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。为此, Redis 提供了复制功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步到其他数据库上。 Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步,配置非常简单,只需要在从节点配置slave of主节点的ip即可,如果有密码,还需要配置上密码,从节点只能读数据,不能写数据 全量同步主要发生在初次同步的时候,大概的步骤是 还有就是增量同步,主要发生在redis的工作过程中,Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。 5、redis集群 Redis本身就支持集群操作redis_cluster,集群至少需要3主3从,且每个实例使用不同的配置文件,主从不用配置,集群会自己选举主数据库和从数据库,为了保证选举过程最后能选出leader,就一定不能出现两台机器得票相同的僵局,所以一般的,要求集群的server数量一定要是奇数,也就是2n+1台,并且,如果集群出现问题,其中存活的机器必须大于n+1台,否则leader无法获得多数server的支持,系统就自动挂掉。所以一般是3个或者3个以上的奇数节点。 Redis 2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。哨兵的作用就是监控redis主、从数据库是否正常运行,主数据库出现故障自动将从数据库转换为主数据库 我们公司搭建的redis集群是用的ruby脚本配合搭建的,我们一共搭建了6台服务器,3主3备,他们之间通信的原理是有一个乒乓协议进行通信的,我再给你说下一他们往里存储数据的机制吧,其实这个redis搭建好集群以后每个节点都存放着一个hash槽,每次往里存储数据的时候,redis都会根据存储进来的key值算出一个hash值,通过这个hash值可以判断到底应该存储到哪一个哈希槽中,取的时候也是这么取的,这就是我了解的redis集群 6、除了redis,还了解哪些别的非关系型数据库 有memacache,MongoDB这些,以及redis这几个都是非关系型数据库 memacache是纯内存型的,只支持简单的字符串数据,并且value值最大只能是1MB,而且所有的数据都只能存储在内存中,如果服务宕机或者关机重启,数据就会丢失,没有持久化功能 MongoDB的话是存储的数据都在磁盘上,功能比较多,不过性能没有其他两种好 而redis呢,支持的数据类型比较多,而且速度也非常快,value最大可以支持到512MB,而且既可以把数据存储在内存里,也可以持久化到磁盘上,重启之后还可以把磁盘中的数据重新加载到内存里,从性能以及数据安全上来说,都比memacache和MongoDB好一些 7、redis数据同步 这一块主要是跟mysql数据同步吧,mysql数据可能会发生变动,那么redis就要跟数据库的数据保持一致我们实际去使用的时候,是在数据发生变动的地方,比如增删改的时候,新奇一个线程,然后将变动的数据更新到redis中,根据不同的场景需求,也可以在数据变动时,把redis里的数据删掉,下一次用户查询的时候,发现redis中没有数据,就会重新去数据库加载一遍,这样也可以实现同步的效果 8、介绍一下redis的pipeline pipeline的话,就是可以批量执行请求的命令 我们都知道redis是单线程的,在执行命令的时候,其他客户端是阻塞状态的,如果在高并发的时候,其实是会影响一定效率的,所以redis提供了pipeline,可以让我们批量执行命令,大大的减少了IO阻塞以及访问效率 因为pipeline是批量执行命令,我们一般会结合redis的事物去使用,它也符合事务的ACID特性,MULTI开启事物,EXEC执行,DISCARD清除事物状态,回到非事物状态,在使用前,还可以结合WATCH监控来使用,如果我们在执行一组命令的过程中,不想让其中的某个值被其他客户端改动,就可以使用WATCH,使用了之后,如果被改动,事务会自动回滚,可以很好的保证我们批量执行命令的时候,数据的准确性,在使用完成之后,可以使用UNWATCH解除监控。 9、介绍下redis中key的过期策略 定时删除:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除 惰性删除:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null 定期删除:每隔一段时间执行一次删除过期key操作 redis 过期策略是:定期删除+惰性删除。 所谓定期删除,指的是 redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除。 (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |