目录
为啥redis是单线程模型,效率还高(相比于关系型数据库mysql)?
引言
Redis是一个单线程的内存数据库,这意味着它在任何给定时间只能处理一个请求。这与传统的多线程数据库不同,后者可以同时处理多个请求。
Redis之所以采用单线程模型,是因为它使用了非阻塞I/O和多路复用技术来实现高效的吞吐量。Redis使用事件驱动机制,将所有的客户端操作都转换成事件,然后通过事件分派器来处理这些事件,从而实现了高效地处理请求。
在Redis中,所有的命令都是原子操作,即使是复杂的命令也是如此。这使得Redis的性能非常出色。虽然Redis是单线程的,但它可以处理大量的请求,并支持每秒数百万级别的操作。
需要注意的是,虽然Redis是单线程的,但它允许在不同的进程或服务器上运行多个实例,以提高可扩展性和性能。此外,Redis还支持例如发布/订阅、事务和Lua脚本,使其成为一种非常强大和灵活的数据库。
单线程模型是啥意思
redis的单线程模型指的是只使用一个线程去处理所有命令请求,并不是说redis进程服务器只有一个线程, 也有多个线程,多个线程用于处理网络IO。
当多个请求同时到达redis服务器,redis的单线程模型就保证了当前收到的请求指令是串行执行的,
例如,在学校,下课,大家都跑去饭堂, 都去排米饭,此时还是要在窗口处排队的
为啥redis可以使用单线程模型(同下)
redis的核心逻辑业务短平快,不太消耗cpu资源,不太吃多核,redis可以使用单线程模型很好的工作。
需要注意:redis要避免一个线程占用太长时间,否则会阻塞其他线程。
网络IO密集型:Redis主要是一个内存数据库,读写操作都发生在内存中,非常快速。而网络IO是Redis的瓶颈之一,因为网络通信需要等待较长时间的响应,会占用大量CPU时间。使用单线程模型可以避免多线程之间的上下文切换,减少了线程切换的开销,提高了效率。
单线程模型减小开销:由于Redis采用单线程模型,因此代码量相对较小,易于管理和维护,减少了开发和维护成本。
- 非抢占式多任务处理:Redis是基于事件驱动的非阻塞IO模型,它采用了一种非抢占式的多任务处理方式。这意味着,在任何时候,Redis都只会处理一个客户端请求,而不会被其他请求所打断。这样可以避免线程之间的竞争和同步问题,简化了程序设计。
IO多路复用机制:Redis使用了多路复用机制,一个线程中同时处理多个客户端的请求。
Redis采用单线程模型,是为了避免多线程之间的上下文切换和同步问题,提高程序的效率和可靠性。
为啥redis是单线程模型,效率还高(相比于关系型数据库mysql)?
- 1. redis访问内存,mysql访问硬盘。
- 2. redis的核心业务比数据库简单。
- 3.redis的单线程模型避免了不必要的线程开销。
- 4.处理网络IO时,采用了epoll的IO多路复用机制。——一个线程管理多个socket
针对TCP来说,服务器每次服务一个客户端,都需要给这个客户端安排一个socket(
Socket是一种计算机网络通信的编程接口(API),它提供了一套用于网络通信的函数和数据结构。通过Socket,程序可以创建网络连接、发送和接收数据,实现不同计算机之间的通信。
Socket通常用于在客户端和服务器之间建立网络连接,并进行双向的数据传输。它是一种抽象的概念,对于不同的网络协议(如TCP、UDP等),会有相应的Socket实现。
);
一个服务器服务多个客户端,此时就有多个socket,但是socket并不是一直在传输数据,也只有少数线程活跃。
在传统的阻塞IO模型中,每个网络连接都需要一个线程或进程来处理,当并发连接数量增加时,线程或进程的创建和销毁开销较大,而且线程切换也会带来一定的开销。
而采用epoll的IO多路复用机制可以有效地减少线程或进程的数量,提高系统的并发处理能力。Linux上提供的IO多路复用也主要是,select,poll,epoll,java可以使用NIO,底层封装了epoll。
epoll使用了事件驱动的方式,通过一个专门的系统调用
epoll_wait
来等待多个IO事件的发生,并将就绪的文件描述符返回给应用程序。应用程序可以通过设置非阻塞IO和注册感兴趣的事件来使用epoll。epoll的IO多路复用机制在高并发网络编程中被广泛使用,可以提高系统的并发处理能力和IO性能。IO多路复用:
场景:我想买奶茶,A朋友想吃鸡腿,B朋友想吃包子。
效率最低的方式:我一个买完等它做好去买另一个;效率嘎嘎低
"传统方式":三个人一起去。效率提升但是开销大
IO多路复用:我先去奶茶,等的过程中去买鸡腿,买鸡腿的过程中买包子,哪个老板做好喊我。(在这里 “谁好了喊我” 就是epoll的回调机制/事件通知)
此时我这一个线程通知执行完成了三件事情,前提是:三件事的交互不频繁,大部分时间在等待。如果交互频繁那还是得多搞几个线程。