RDB和AOF机制
首先,我们必须清楚的一点,Redis是内存数据库,如果不进行持久化,服务器在宕机或退出的时候,数据就会丢失,所以需要实现持久化。
- RDB的实现是先fork出一个子进程,在指定的时间间隔内将内存中的数据集快照写入临时文件中,写入成功后,覆盖最终的RDB文件,用二进制压缩存储。RDB也是Redis默认的持久化机制。
- AOF持久化的实现,是将所有的写命令都记录下来,以aof文件的形式进行记录(在aof文件中,我们可以看到具体的命令),在redis启动之后,会读取该文件,重新构建出内存中的数据,默认情况下AOF机制是关闭的,需要使用的时候需要进行配置。
Redis的过期键的删除策略?
对于过期键一般有三种删除策略
- 定时删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作;
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,那就返回该键;
- 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于删除多少过期键,以及要检查多少个数据库,则由算法决定。
三种策略的优缺比较:
- 定时删除策略对内存是最友好的:通过使用定时器,定时删除策略可以保证过期键会尽可能快地被删除,并释放过期键所占用的内存;但另一方面,定时删除策略的缺点是,他对CPU是最不友好的:在过期键比较多的情况下,删除过期键这一行为可能会占用相当一部分CPU时间,在内存不紧张但是CPU时间非常紧张的情况下,将CPU时间用在删除和当前任务无关的过期键上,无疑会对服务器的响应时间和吞吐量造成影响;
- 惰性删除策略对CPU时间来说是最友好的:程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行;惰性删除策略的缺点是,它对内存是最不友好的:如果一个键已经过期,而这个键又仍然保留在数据库中,那么只要这个过期键不被删除,它所占用的内存就不会释放;
- 定时删除占用太多CPU时间,影响服务器的响应时间和吞吐量;惰性删除浪费太多内存,有内存泄漏的危险。定期删除策略是前两种策略的一种整合和折中:
1.定期删除策略每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响;
2.通过定期删除过期键,定期删除策略有效地减少了因为过期键而带来的内存浪费;
3.定期删除策略的难点是确定删除操作执行的时长和频率。
Redis线程模型,单线程为什么快?
1.Redis线程模型?
多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。
2.Redis为什么这么快
- 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
- 数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;
- 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
- 使用多路I/O复用模型,非阻塞IO;
- 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
3.为什么Redis是单线程的?
官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。
参考为什么说Redis是单线程的以及Redis为什么这么快!
缓存穿透 缓存击穿 缓存雪崩
- 缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
- 缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
- 缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
简述redis事物实现?
Redis事务的实现原理
Redis通过MULTI、EXEC、WATCH、DISCARD等命令来实现事务功能。主要有以下三个阶段:
- 事务开始:MULTI命令的执行,标识着一个事务的开始。MULTI命令会将客户端状态的flags属性中打开REDIS_MULTI标识来完成的。
- 命令入队:当一个客户端切换到事务状态之后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客户端发送的命令为MULTI、EXEC、WATCH、DISCARD中的一个,立即执行这个命令,否则将命令放入一个事务队列里面,然后向客户端返回QUEUED回复
- 事务执行:当一个处于事务状态的客户端向服务器发送EXEC命令时,服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将执行完的结果全部返回给客户端(每个命令对应一个返回)
- WATCH命令的实现:WATCH命令是一个乐观锁,它可以在EXEC命令执行之前,监视任意数量的数据库键,并在执行EXEC命令时,检查被监视的键是否至少有一个已经被修改,如果有,服务器拒绝执行事务,向客户端返回代表事务执行失败的空回复
Redis事务的ACID性质
- 原子性:对于Redis的事务功能来说,事务队列中的命令要么就全部执行,要么就一个都不执行,但是Redis的事务是不支持回滚操作的;
-
一致性:Redis通过谨慎的错误检测和简单的设计保证事务的一致性。Redis事务可能出错的地方以及解决方案:
1.入队错误:如果一个事务在入队命令的过程中发现命令不存在或者命令格式不正确,Redis将拒绝执行这个事务;
2.执行错误:事务在执行的过程中发生错误的命令会被服务器识别出来,并进行相应的错误处理,所以这些出错的命令不会对数据库做任何修改,也不会对事务的一致性产生任何影响;
3.服务器停机:如果Redis服务器在执行事务的过程中停机,且服务器运行在任意模式下(无持久化的内存模式、RDB模式或者AOF模式),事务执行中途发生的停机都不会影响数据库的一致性; -
隔离性:Redis使用单线程的方式执行事务,并且服务器保证在执行事务期间不会对事务进行中断,因此,Redis的事务总是串行的方式运行,并且事务总是具有隔离性的;
4.耐久性:当服务器运行在AOF持久化模式下,并且appendfsync选项的值是always时,事务是具有耐久性的,其他情况不具有耐久性;
Redis集群方案?
Redis主从复制的核心原理?
1.什么是主从复制?
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);
2.为什么要主从复制?
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
3.主从复制可能会造成的问题?
4.主从复制的核心原理?
CAP理论 BASE理论
负载均衡算法、类型?
负载均衡(Load balancing)是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。 使用带有负载均衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载均衡服务通常是由专用软件和硬件来完成。 主要作用是将大量作业合理地分摊到多个操作单元上进行执行,用于解决互联网架构中的高并发和高可用的问题。
类型
- 轮询法:每个请求按时间顺序逐一分配到不同的后端服务器,如果服务器down掉,能自动剔除。
- weight(权重):指定轮询几率,weight和访问比率成正比,用于服务器性能不均的情况。
- ip_hash:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个服务器,可以解决session的问题。
- fair(第三方):按服务器的响应时间来分配请求,响应时间短的优先分配。
- url_hash(第三方):按访问url的hash结果来分配请求,使每个url定向到同一个服务器,服务器为缓存时比较有效。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method使用的是hash算法。
分布式架构下,session共享有什么方案?
简述你对RPC、RMI的理解?
分布式id的生成方案?
- 数据库自增长序列或字段
- UUID
- UUID的变种:为了解决UUID不可读,可以使用UUID to Int64的方法。
- Redis生成ID
- Twitter的snowflake算法
- 利用zookeeper生成唯一ID
- MongoDB的ObjectId
- TiDB的主键
分布式锁解决方案?
- 数据库
- redis
- zookeeper
分布式事务解决方案?
如何实现接口幂等性?
幂等性说的是:如何防止接口的重复无效请求。
对于一个接口而言,无论调用了多少次,最终得到的结果都是一样的。
四种解决方法:
前端拦截。不安全,可能被专业人士修改,跳过该过程。
使用数据库实现幂等性
使用 JVM 锁实现幂等性。缺点:只能引用于单机环境
使用分布式锁实现幂等性。通常使用redis或者zookeeper实现分布式锁。保证分布式锁的key是业务id的唯一标识。
网友评论