当前位置: 首页 > 科技观察

Redis陷阱完整一览,是否跳过这些陷阱

时间:2023-03-11 20:25:04 科技观察

Redis在互联网技术存储中应用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理上给小伙伴们各种刁难.作为一名在互联网科技行业打过几十万[请允许我夸大]的资深技术面试官,看到无数孤独的身影失望离去,心里有些愧疚,所以献上这篇文章,希望各位读者在未来,面试将铺天盖地,永不失败!Redis有哪些数据结构?StringString、字典Hash、列表List、集合Set、有序集合SortedSet。如果你是Redis的高级用户,还需要添加以下数据结构HyperLogLog、Geo、Pub/Sub。如果你说你玩过RedisModule,比如BloomFilter、RedisSearch、Redis-ML,面试官的眼睛会开始放光。你用过Redis分布式锁吗,是什么情况?先用setnx去竞争锁,然后用expire给锁加一个过期时间,防止锁忘记释放。这时候对方会告诉你,你的回答很好,然后问如果在expire之前执行了setnx之后进程意外崩溃或者需要重启维护怎么办?这时候,你要给出惊人的反馈:哦,是的,这个锁永远不会被释放。然后你需要挠头,假装想一会,好像接下来的结果就是你自己的主动思考,然后回答:我记得set命令的参数很复杂,这个应该可以setnx和expireat同时合成一个命令使用!对方这时候才会露出笑容,开始在心里默念道:“坚持住,这小子不坏。”假设Redis中有1亿个键,其中10w个键以固定的已知前缀开头,如何将它们全部找到?使用keys命令扫描出指定模式的按键列表。对方接着问:如果这个redis是为在线业务提供服务,使用keys命令会有什么问题?这时候你就不得不回答redis的一个关键特性:单线程redis。keys指令会导致线程阻塞一段时间,在线服务会暂停,直到该指令执行完毕才能恢复服务。这时候可以使用扫描命令。scan命令可以无阻塞地提取指定模式的key列表,但是会有一定的重复概率。在客户端做一个去重就可以了,但是整体花费的时间会比直接使用要长一些。keys命令很长。你用过Redis作为异步队列吗?你是怎么用的?一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,需要sleep一会再试。如果对方问你能不能用sleep?该列表还有一个名为blpop的指令。当没有消息时,它会阻塞,直到消息到达。如果对方问是否可以一次生产多次消费?使用pub/sub主题订阅者模式,可以实现1:N的消息队列。如果对方问pub/sub有什么缺点?当消费者下线时,生产的消息会丢失,必须使用rabbitmq等专业的消息队列。如果对方问redis是如何实现延迟队列的?我猜你现在真的很想把面试官打死。如果你手里拿着棒球棒,你怎么会问这么详细的问题。但是你很克制,然后淡定的回答:使用sortedset,使用timestamp作为score,以消息内容为key调用zadd生成消息,consumer使用zrangebyscore命令获取之前轮询的数据N秒处理。至此,面试官已经偷偷给你竖起了大拇指。可他不知道的是,此刻你竖起中指,在椅子后面。如果有大量的key需要同时设置过期,需要注意什么?如果大量key的过期时间设置的过于密集,redis在过期时可能会出现短暂的卡顿。一般需要在时间上加上一个随机值,使过期时间更加分散。Redis是如何做持久化的?bgsave用于全图持久化,aof用于增量持久化。因为bgsave耗时较长,不够实时,关机时会造成大量数据丢失,所以需要aof配合。当redis实例重启时,会通过bgsave持久化文件重建内存,然后通过aof重放最近的操作指令,实现完全恢复到重启前的状态。对方问机器突然没电了怎么办?根据aof日志的sync属性的配置,如果对性能要求不高,每次写命令都会同步磁盘,不会丢失数据。但是在高性能要求下每次都同步是不现实的。一般采用定时同步,比如1s1次。这时候最多会丢失1s的数据。对方问bgsave的原理是什么?你随便给两个字,fork和cow。fork表示redis通过创建子进程进行bgsave操作,cow表示copyonwrite。子进程创建后,父子进程共享数据段,父进程继续提供读写服务。脏页数据会逐渐从子进程中分离出来。打开。Pipeline有什么好处,为什么要用pipeline?多次IO往返的时间可以减少到一次,前提是流水线执行的指令之间没有因果关系。在使用redis-benchmark进行压测的时候,可以发现影响redisQPS峰值的一个重要因素是pipelinebatchinstructions的数量。你了解Redis的同步机制吗?Redis可以使用主从同步和从从同步。第一次同步时,master节点做一次bgsave,同时将后续的修改操作记录到内存缓冲区中。完成后将rdb文件完全同步到复制节点,复制节点接受后将rdb镜像加载到内存中。加载完成后,通知主节点将修改后的操作记录同步到复制节点进行重放,完成同步过程。你用过Redis集群吗?集群的原理是什么?RedisSentinal专注于高可用性。当master宕机时,会自动将slave提升为master,继续提供服务。RedisCluster注重扩展性,当单个redis内存不足时使用Cluster进行分片存储。