Redis 属于单线程还是多线程?
Redis 是单线程的,主要是指 Redis 的网络 I/O 线程,以及键值的 SET 和 GET 等读写操作都是由一个线程来完成的
但 Redis 的持久化、集群同步等操作,则是由另外的线程来执行的。
-
Redis 采用单线程为什么还这么快?
Redis 的大部分操作都在内存中完成,并且采用了高效的数据结构,比如哈希表和跳表。
单线程模型避免了多线程之间的竞争,省去了多线程切换带来的时间和性能上的开销,而且也不会导致死锁问题。
Redis 采用了 I/O 多路复用机制,处理大量的客户端 Socket 请求,这让 Redis 可以高效地进行网络通信,因为基于非阻塞的 I/O 模型,就意味着 I/O 的读写流程不再阻塞。
Redis 4.0 版本之后,Redis 添加了多线程的支持,但这时的多线程主要体现在大数据的异步删除功能上
Redis 6.0 版本之后,为了更好地提高 Redis 的性能,新增了多线程 I/O 的读写并发能力
Redis 如何实现数据不丢失?
缓存数据库的读写都是在内存中,所以它的性能才会高,但在内存中的数据会随着服务器的重启而丢失,为了保证数据不丢失,要把内存中的数据存储到磁盘,以便缓存服务器重启之后,还能够从磁盘中恢复原有的数据,这个过程就是 Redis 的数据持久化。
-
AOF 日志(Append Only File,文件追加方式):记录所有的操作命令,并以文本的形式追加到文件中。
-
RDB 快照(Redis DataBase):将某一个时刻的内存数据,以二进制的方式写入磁盘。
-
混合持久化方式:Redis 4.0 新增了混合持久化的方式,集成了 RDB 和 AOF 的优点。
关系型数据库(如 MySQL)的日志都是“写前日志”(Write Ahead Log, WAL)
Redis 的 AOF 日志的记录顺序与传统关系型数据库正好相反,它是写后日志
Reids 为什么先执行命令,在把数据写入日志呢?
-
因为 ,Redis 在写入日志之前,不对命令进行语法检查;
-
所以,只记录执行成功的命令,避免了出现记录错误命令的情况;
-
并且,在命令执行完之后再记录,不会阻塞当前的写操作。
数据可能会丢失
可能阻塞其他操作
RDB 快照是如何实现的呢?
AOF 方法做故障恢复时,需要全量把日志都执行一遍,一旦日志非常多,势必会造成 Redis 的恢复操作缓慢。
为了解决这个问题,Redis 增加了 RDB 内存快照(所谓内存快照,就是将内存中的某一时刻状态以数据的形式记录在磁盘中)的操作,它即可以保证可靠性,又能在宕机时实现快速恢复。
-
RDB 做快照时会阻塞线程吗?
Redis 提供了两个命令来生成 RDB 快照文件,分别是 save 和 bgsave。save 命令在主线程中执行,会导致阻塞。而 bgsave 命令则会创建一个子进程,用于写入 RDB 文件的操作,避免了对主线程的阻塞
-
RDB 做快照的时候数据能修改吗?
如果主线程执行读操作,则主线程和 bgsave 子进程互相不影响;
-
如果主线程执行写操作,则被修改的数据会复制一份副本,然后 bgsave 子进程会把该副本数据写入 RDB 文件,在这个过程中,主线程仍然可以直接修改原来的数据。
Redis 对 RDB 的执行频率非常重要,因为这会影响快照数据的完整性以及 Redis 的稳定性,所以在 Redis 4.0 后,增加了 AOF 和 RDB 混合的数据持久化机制: 把数据以 RDB 的方式写入文件,再将后续的操作命令以 AOF 的格式存入文件,既保证了 Redis 重启速度,又降低数据丢失风险。
Redis 如何实现服务高可用?
解决数据高可用的手段是什么?是副本。那么要想设计一个高可用的 Redis 服务,一定要从 Redis 的多服务节点来考虑,比如 Redis 的主从复制、哨兵模式,以及 Redis 集群
-
主从同步 (主从复制)
-
Redis Sentinel(哨兵模式)
-
Redis Cluster(集群)Redis Cluster 方案采用哈希槽(Hash Slot),来处理数据和实例之间的映射关系。在 Redis Cluster 方案中,一个切片集群共有 16384 个哈希槽,这些哈希槽类似于数据分区