大家好,我是moon。Redis作为我们最常用的内存数据库,在很多地方都能找到它的身影,比如登录信息的存储,分布式锁的使用。它经常被我们用作缓存。不过,用了这么久的reids,你明白了吗?1、什么是redis?它能做什么?redis:redis即RemoteDictionaryServer,翻译成中文可以理解为远程数据服务或远程字典服务。是一个用C语言写的key-value存储系统应用场景:缓存,数据库,消息队列,分布式锁,likelist,排行榜等。2.redis有哪八种数据类型?有哪些应用场景?Redis一共有八种数据结构,五种基本数据类型和三种特殊数据类型。五种基本数据类型:1.string:字符串类型,常用于存储计数器,粉丝等,简单的分布式锁也会用到这种类型2.hashmap:key-value形式,value是一个map3.list:基础数据类型,列表。在Redis中,列表可以用作栈、队列和阻塞队列。4.set:集合,无重复元素,可以做点赞,收藏等。5.zset:有序集合,无重复元素,有序集合中的每个元素需要指定一个分数,元素根据score按升序排序。三种特殊的数据类型可以用于排名:1.geospatial:Redis在3.2推出了Geo类型。这个函数可以计算地理位置信息和两地之间的距离。2.hyperloglog:基数:数学集合中元素的个数不能重复。该数据结构常用于统计网站的UV。3.bitmap:位图是通过最小单位位置0或1,表示一个元素对应的值或状态。一位的值要么是0,要么是1;也就是说一个bit最多可以存储2条信息。Bitmap常用来统计活跃粉丝和不活跃粉丝、登录和未登录、是否签到等用户信息。3、为什么redis这么快?根据官方数据,redis每秒可以达到近10w的并发。这种速度的原因主要归纳为:1:完全基于内存操作2:使用单线程模型处理客户端请求,避免Context切换3:IO多路复用机制4:用C语言编写,有很多优化机制,比如动态字符串sds4.听说redis6.0又用上了多线程,不会有线程安全问题了是吧?事实上,redis仍然采用单线程模型来处理客户端请求,但是采用多线程处理数据读写和协议解析,使用单线程执行命令,所以不会存在线程安全问题。之所以加入多线程,是因为redis的性能瓶颈在于网络IO而不是CPU。使用多线程可以提高IO读写的效率,从而提高redis的整体性能。5、redis的持久化机制有哪些?的优点和缺点。redis的持久化方式有两种,AOF和RDB。在文件中,然后通过fsync策略,将命令执行后的数据持久化到磁盘”(不包括读命令),AOF的优缺点AOF的“优点”:1.AOF可以”更好的保护数据不丢失”,一般AOF会每隔1秒通过后台线程执行一次fsync操作,如果redis进程挂掉,最多丢失1秒数据。2.AOF直接在命令追加文件末尾,“write性能非常高”3.AOF日志文件的命令以非常易读的方式记录,非常“适合灾难性误删的应急恢复”。如果有人不小心用flushall命令清除了所有数据,只要这个时候还没有执行rewrite,就可以删除日志文件中的flushall来恢复AOF的“缺点”:1.对于相同的数据source,AOF文件一般比RDB数据快照大2.由于.aof每一条命令都会写,所以相对于RDB来说,“需要消耗的性能更多”,当然会有aof改写为优化aof文件。3、“数据恢复比较慢”,不适合冷备份。RDB:将redis内存中某一点的数据以二进制形式存储在一个后缀为.rdb的文件中,即“定期备份redis中的全部数据”,这是redis默认的持久化方式。也就是我们所说的快照(snapshot),写的时候使用fork子进程的方式来同步。RDB的优缺点RDB的优缺点:1.它把某个时间点的所有数据都保存在redis中,所以我们在做“大数据恢复的时候,RDB的恢复速度会很快”2.由于RDB的FROK有了子进程机制,队友对客户端提供读写服务的影响会很小。RDB的缺点:比如假设我们每隔5分钟定时备份一次,redis在10:00备份数据,但是如果在10:04的时候服务挂了,那么我们就会从10开始丢失全部数据:00到10:041:“可能会出现长时间的数据丢失”2:可能会出现长时间的停顿:我们前面说过,fork子进程的进程与in的数据量有很大关系雷迪斯。如果“数据量很大,很可能会导致redis暂停几秒”。6、Redis的过期key有哪些删除策略?过期策略通常分为三种:定时过期:每个有过期时间的key都需要创建一个定时器,当达到过期时间后立即清除。该策略可以立即清除过期数据,对内存友好;但是处理过期数据会占用大量的CPU资源,从而影响缓存的响应时间和吞吐量。惰性过期:只有在访问某个key的时候,才会判断这个key是否过期,过期就清空。这种策略可以最大程度的节省CPU资源,但是对内存很不友好。在极端情况下,大量过期的key可能不会被再次访问,因此不会被清除,占用大量内存。周期性过期:每隔一段时间,会扫描一定数量数据库的expires字典中的一定数量的key,清除过期的key。该策略是前两者的折衷方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下优化平衡CPU和内存资源。7、Redis内存满了怎么办?其实Redis定义了“8种内存淘汰策略”来处理redis内存满的情况:1.noeviction:直接返回错误,不淘汰任何已有的rediskeys2.allkeys-lru:所有keys使用lru算法淘汰3.volatile-lru:使用lru算法淘汰有过期时间的4.allkeys-random:随机删除rediskey5.volatile-random:随机删除过期时间为6的rediskey.volatile-ttl:删除即将过期的rediskey7.volatile-lfu:根据lfu算法删除有过期时间的key8.allkeys-lfu:根据lfu算法删除所有key8.如何解决热点Redis的key问题?hotkey是指在某个时刻,访问某个key的请求很多,流量过大,导致redi服务器宕机。解决方案:可以将结果缓存在本地内存中,并将热键分发到不同的服务器九.什么是缓存击穿、缓存穿透和缓存雪崩?如何解决?缓存穿透:缓存穿透是指用户请求的数据在缓存中不存在,在数据库中也不存在。结果,每次用户请求数据,都得重新查询数据库,然后返回空。解决方案:布隆过滤器返回一个空对象。缓存击穿:缓存击穿是指某个key非常热,不断承载着大并发。大并发集中访问这个点。当key失效的瞬间,持续的大并发会突破缓存,直接请求数据库,就像在屏障上挖洞一样。解决方案:Mutexneverexpires缓存雪崩:缓存雪崩是指缓存中有大量不同的数据,直到过期时间,但是查询数据量巨大,请求直接落在数据库上,造成宕机。解决方案:统一过期加互斥缓存永不过期双层缓存策略十。Redis的部署方式有哪些?单机模式:这也是最基本的部署方式。读写只需要一台机器,一般只用于开发者自己测试哨兵模式:哨兵模式是一种特殊模式。首先,Redis提供了哨兵的命令。哨兵是一个独立的进程。作为一个进程,它将独立运行。原理是Sentinel通过发送命令等待Redis服务器响应来监控多个正在运行的Redis实例。具有自动故障转移、集群监控、消息通知等功能。Cluster集群方式:Redis3.0版本支持cluster集群部署方式。这种集群部署方式可以自动对数据进行切分,将一部分数据放在每个master上,并提供内置的高可用服务。即使某个master宕机了,依然可以正常提供服务。主从复制:在主从复制的集群部署模式下,我们将数据库分为两种,第一种称为主库(master),另一种称为从库(slave)。主库负责我们整个系统的读写操作,从库负责我们整个数据库的读操作。职场开发中的真实情况是,我们会让主库只负责写操作,让从库只负责读操作,以实现读写分离,减少服务器的压力。11.哨兵有哪些功能?1、监控整个主库和从库,看是否正常运行。2、当主库出现异常时,会自动将从库升级为主库,继续保证整个服务的稳定性。12.哨兵选举过程是怎样的?1、第一个发现master挂了的哨兵给每个哨兵发出命令,让对方选举自己为领头哨兵。2.如果其他哨兵还没有选出其他哨兵,则给第一个发现master挂掉的哨兵发这个哨兵投票3.如果第一个发现master挂掉的哨兵发现一半以上的哨兵为自己投票,数量超过设定的quoram参数,则该哨兵成为领头哨兵4。如果有多个哨兵同时参与本次选举,则重复该过程,直到选出领头哨兵。领头哨兵选好后,开始故障修复,选出一个从库作为新的主十三。cluster集群模式如何存储数据?一个集群集群中一共有16384个节点,集群会将这16384个节点平均分配给每个节点。当然,这里的节点指的是各个主节点,如下图所示:十四个。集群故障恢复如何工作?判断失败的逻辑其实和sentinel模式有点类似。在集群中,每个节点都会周期性的向其他节点发送ping命令。收到回复判断其他节点是否已经下线。如果长时间没有回复,发起ping命令的节点会认为目标节点疑似下线。也可以叫像哨兵一样的主观下线。当然,集群中一定有一定数量的节点认为该节点下线。下面说说具体过程:1.当节点A发现目标节点疑似下线时,会将消息传播到集群中的其他节点,其他节点向目标节点发送命令,判断目标节点是否下线nodeisoffline2.如果集群中有超过半数的节点认为目标节点下线,那么他们会将目标节点标记为下线,从而告诉其他节点在整个集群中让目标节点下线。主从同步的原理是什么?1、从库启动时,会向主库发送SYNC命令。master收到后,将快照保存在后台,也就是我们所说的RDB持久化。当然,保存快照是需要时间的,redis是单线程的,在保存快照的过程中,redis收到的命令会被缓存起来。2、快照完成后,会将缓存的命令和快照打包发送给从节点,保证主从数据库的一致性。3、收到数据库的快照和缓存命令后,会将这部分数据写入硬盘的一个临时文件中。写入完成后,将使用该文件替换RDB快照文件。当然这个操作不会被Blocked,可以继续接收命令并执行。具体原因是fork了一个子进程,子进程就是用来完成这些功能的。因为不会阻塞,所以这部分初始化完成后,当主库执行更改数据的命令时,会异步发送给从库。这就是我们所说的复制同步阶段。这个阶段会贯穿整个中从同步过程。在中,直到主从同步结束,复制同步才会终止。16、什么是无硬盘复制?刚才我们说了主从是通过RDB快照进行交互的。虽然逻辑看似简单,但还是有一些问题,但是也会有一些问题。1、当master禁用RDB快照时,会发生主从同步(复制初始化)操作,同时也会产生RDB快照。但是,如果master稍后发送重启,它将使用RDB快照来恢复数据。这个数据可能已经很久了2.在这种一主多从的结构中,master每次和slave同步数据的时候都需要做一次快照,从而在硬盘上生成一个RDB文件,这个文件会影响性能。为了解决这个问题,Redis在后续的更新中也加入了免硬盘拷贝功能,也就是直接通过网络发送给slave,避免了与硬盘的交互,但是也会消耗io
