Redis面经1

1.Redis 为何这么快

优点:

  1. 读写性能优异,Redis能读的速度是110000次/s,写的速度是81000次/s;

  2. 支持数据持久化,支持AOF和RDB两种持久化方式;

  3. 支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性操作;

  4. 数据结构丰富,除了支持String类型的value外还支持hash,set,zset,list等数据结构;

  5. 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点:

  1. 数据库容量收到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上;

  2. Redis不具备自动容错和恢复功能,主机从机宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复;

  3. 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性;

  4. Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

2.为什么要用Redis/为什么要用缓存

  • 高性能:

假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变之后,同步改变缓存中响应的数据即可!

  • 高并发:

直接操作缓存能够承受的请求是远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

3.redis是单线程的,为什么还能这么快?

redis 单线程指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块仍用了多个线程。

因此Redis完全基于内存操作,CPU不是redis的瓶颈,redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会称为瓶颈,那么就顺理成章地使用单线程地方案了:

  1. Redis完全基于内存,绝大部分请求是纯粹的内存操作,非常迅速,数据存在内存中,类似于HashMap, HashMap的优势就是查找和操作的时间复杂度是O(1);

  2. 数据结构简单,对数据的操作也简单;

  3. 采用单线程,避免了不必要的上下文切换和竞争条件,不存在多线程导致的CPU切换,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗;

  4. 使用多路复用IO模型,非阻塞IO;

  5. 使用的底层模型不同,它们之间底层实现方法以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM机制,因为一般的系统调用系统函数的时候,会浪费一定的事件去移动和请求。

4.缓存和数据库一致性问题

分布式环境下非常容易出现缓存和数据库间数据一致性问题,如果项目对缓存的要求是强一致性的,那么就不要用缓存。我们只能采用适当的策略来降低缓存和数据库间数据不一致的概率,而无法保证两者间的强一致性。合适的策略包括合适的缓存更新策略,更新数据库后及时更新缓存、缓存失败时增加重试机制。

5.Redis雪崩

举个例子: 如果所有key的失效时间都是12小时,中午12点刷新的,零点有一个大促活动大量用户涌入,假设每秒6000个请求,本来缓存可以抗住每秒5000个请求,但是缓存中所有Key都失效了。此时6000个/秒的请求全部落在了数据库上,数据库必然扛不住,真实情况可能DBA都没反应过来就直接挂了,此时,如果没有什么特别的方案来处理,DBA很着急,重启数据库,但是数据库立马又被新流量给打死了。这就是缓存雪崩。

处理方法:在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效。 如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效。或者设置热点数据永不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那就刷新缓存就好了,不用设置过期时间),电商首页的数据也可以用这个操作。

猜你喜欢

转载自blog.csdn.net/slave_of_life/article/details/130662177