redis与NIO
2020-12-10 14:16:33 0 举报
redis与NIO
作者其他创作
大纲/内容
kernel
mmap可以挂载到文件,将内核缓存中的网卡数据写到文件
线程/进程
单项链表
kernel改变:解决内核与进程进程频繁的fd拷贝
client
file.txt
1、告诉内核要读取的fd并写到共享存
mmap
redis对于高并发的处理是通过内核的系统调用epoll来实现。epoll实现了同步非阻塞以及多路复用。
fd3
进程通过sendfile读取数据
redis
fd8
kernel改变:解决进程与内核间的频繁调用
fd9
1、告诉内核要读取的所有fd,select(fds)
read(fd9)
2、取到进程要读取的fd
sendfile
共享内存
write(fd4)
kafka
3、读取准备就绪的fd,read(fd)
linux
NIO时期:内核提供的socket中可以选择为非阻塞的socket,也就是说一个进程中的socket可以轮询(此时的轮询发生在用户空间)去读取内核中的数据,如果一个文件描述符中没有数据就去读取另外一个文件描述符,而不用一直等待读取一个文件描述符数据。同时,由于只有一个线程处理数据,所以避免了线程间切换而额外耗费资源。此时是同步非阻塞的。
kernel改变:解决进程阻塞问题
输入数据到内核
select
零拷贝
网卡
进程
BIO时期:不同的进程分别负责读取不同的文件描述符。当内核中没有客户端发送的数据时,相应的进程将处于阻塞状态,直到内核中相应的文件描述符有数据可读。如果此时只有一颗CPU,那么线程需要在CPU时间片范围内进行切换工作并不能同时去处理数据,造成了内核中更多数据无法处理。
系统调用sendfile实现了零拷贝
read(fd8)
NIO时期:此时的NIO是多路复用的NIO,进程指挥对已准备就绪的fd进行IO,减少了进程对内核的调用次数。此时由内核去轮询fd是否准备就绪,即轮询发生在内核中。
read(fd8)read(fd9)
epoll
read(fd3)
mmap和sendfile结合后就形成了kafka。mmap、sendfile均与与内核共享空间,同时意味着共享数据
2、告诉进程哪些客户端的fd准备就绪
4、从共享内存读取就绪的fd
基于JVM的kafka
NIO时期:此时通过共享内存解决了进程与内核间频繁的fd拷贝,进一步提高了性能。
红黑树
3、将准备就绪的fd放入共享内存
fd4
原本需要通过系统调用read读取file到进程,然后进程对文件做出改变后通过write给到内核,进一步给到网卡输出
0 条评论
回复 删除
下一页