一零七零、Redis基础稳固篇

Redis是什么,优缺点?
Redis本质是一个K-V类型的内存数据库
纯内存操作,每秒可处理超过10w的读写操作
优点:
读写性能极高
非阻塞IO
单线程
支持持久化
支持事务
数据结构丰富


缺点:
容易受到物理内存的限制
主机宕机可能会造成数据的丢失


Redis为什么这么快?
基于内存存储
单线程实现
非阻塞IO,IO多路复用

Redis与Memcached有哪些优势?
支持的数据类型更丰富,String,Hash,list,set,zset等,memcached只支持K-V类型
Redis有持久化机制,Memcached没有
Redis 原生支持集群模式,Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;
Redis 支持发布订阅模型、Lua 脚本、事务等功能,而 Memcached 不支持;


为什么用Redis做缓存?
1、高并发
2、高性能


Redis的常用场景有哪些?

  • 缓存
  • 排行榜
  • 计数器
  • 分布式会话
  • 社交网络
  • 消息系统

Redis如何实现持久化?
1、AOF:日志追加的方式,将Redis的写操作记录下来,根据日志进行恢复追加
2、RDB:快照形式,在指定的时间间隔内将快照内的数据写入磁盘,恢复时将快照文件读入内存

 

Redis持久化数据和缓存怎么做扩容?
如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。
如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。
否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。


Redis过期键的删除策略?
Redis的过期删除策略就是:惰性删除和定期删除两种策略配合使用。
惰性删除:惰性删除不会去主动删除数据,而是在访问数据的时候,再检查当前键值是否过期,如果过期则执行删除并返回null给客户端,如果没有过期则返回正常信息给客户端。它的优点是简单,不需要对过期的数据做额外的处理,只有在每次访问的时候才会检查键值是否过期,缺点是删除过期键不及时,造成了一定的空间浪费。
定期删除:Redis会周期性的随机测试一批设置了过期时间的key并进行处理。测试到的已过期的key将被删除。

定时删除:
在设置某个key 的过期时间同时,我们创建一个定时器,让定时器在该过期时间到来时,立即执行对其进行删除的操作。
优点:定时删除对内存是最友好的,能够保存内存的key一旦过期就能立即从内存中删除。
缺点:对CPU最不友好,在过期键比较多的时候,删除过期键会占用一部分CPU时间,对服务器的响应时间和吞吐量造成影响。

Redis key的过期时间和永久有效分别怎么设置?
通过expire或pexpire命令,客户端可以以秒或毫秒的精度为数据库中的某个键设置生存时间,让某个键在某个时间点过期。


Redis内存淘汰策略?
当Redis内存不足的时候会进行淘汰,删除不常用的数据。
Redis4.0之前:
volatile-lru:利用LRU算法移除设置过过期时间的key (LRU:最近使用Least Recently Used )
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-random:从数据集( server.db[i].dict)中任意选择数据淘汰
no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!
Redis4.0后:
volatile-lfu:从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰(LFU(Least Frequently Used)算法,也就是最频繁被访问的数据将来最有可能被访问到)
allkeys-lfu:当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的key。

如何保证缓存与数据库双写时的数据一致性?
1、先删除缓存,后更新数据库
2、先更新数据库,后删除缓存


redis的集群模式有哪些?
主从复制,优点是读写分离,可以分担服务器压力,提高读写效率。缺点是当主宕机时可能会造成主从数据不—致。
哨兵模式,主从的基础上增加了哨兵机制。当主挂了时,从节点会选票投出新主节点。优点就是提高了redis的可用性,心跳机制监测主节点的健康情况。缺点是配置麻烦,在选举过程中,无法工作。多主多从。

 

什么是热Key问题?如何解决?
大量请求一个key,导致这个key 的并发访问量很大,产生缓存击穿问题。集群部署,分摊请求压力。

 

什么是缓存击穿、缓存穿透、缓存雪崩?以及对应的解决方案?
缓存击穿:某个热点Key失效,造成缓存读取不到,大量请求落在数据库上
通过互斥锁来控制读写的线程数,其他线程等待
不设置热点key的过期时间
缓存穿透:请求的key在缓存中找不到,在数据库中也找不到,找不到后就去数据库找一遍导致数据库压力剧增
布隆过滤器:在缓存之前设置过滤器,将key存储在布隆过滤器上,不存在直接进行返回,减少对数据库的压力
缓存雪崩:某一时间大量热点Key失效,大量请求落在数据库上,很可能直接打崩数据库
设置不同的过期时间,让缓存失效的时间尽量均匀
保证Redis缓存的高可用,防止Redis宕机导致缓存雪崩的问题。可以使用主从+哨兵,Redis集群来避免 Redis全盘崩溃的情况。

 

Redis高可用方案如何实施?
使用官方推荐的哨兵(sentinel)机制就能实现,当主节点出现故障时,由Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。
它有四个主要功能:
集群监控,负责监控Redis master和slave进程是否正常工作。
消息通知,如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
故障转移,如果master node挂掉了,会自动转移到slave node上。
配置中心,如果故障转移发生了,通知client客户端新的master地址。


什么是分布式锁?为什么用分布式锁?
锁在程序中的作用就是同步工具,保证共享资源在同一时刻只能被一个线程访问,Java中的锁我们都很熟悉了,像synchronized 、Lock都是我们经常使用的,但是Java的锁只能保证单机的时候有效,分布式集群环境就无能为力了,这个时候我们就需要用到分布式锁。
分布式锁,顾名思义,就是分布式项目开发中用到的锁,可以用来控制分布式系统之间同步访问共享资源。
思路是:在整个系统提供一个全局、唯一的获取锁的"东西",然后每个系统在需要加锁时,都去问这个"东西"拿到一把锁,这样不同的系统拿到的就可以认为是同一把锁。至于这个"东西",可以是Redis、Zookeeper,也可以是数据库。
一般来说,分布式锁需要满足的特性有这么几点:
1、互斥性:在任何时刻,对于同一条数据,只有一台应用可以获取到分布式锁;
2、高可用性:在分布式场景下,一小部分服务器宕机不影响正常使用,这种情况就需要将提供分布式锁的服务以集群的方式部署;
3、防止锁超时:如果客户端没有主动释放锁,服务器会在一段时间之后自动释放锁,防止客户端宕机或者网络不可达时产生死锁;
4、独占性:加锁解锁必须由同一台服务器进行,也就是锁的持有者才可以释放锁,不能出现你加的锁,别人给你解锁了。
 

你可能感兴趣的:(#,Redis,redis,数据库,缓存)