杂谈

一点随笔,胡扯,有很多自己还没学习验证的地方。

redis与netty的reactor模式的体现?

  • redis采用reactor机制,netty也用了reactor机制。
  • Redis没有使用第三方的libevent等网络库,而是自己开发了一个单线程的Reactor模型的事件处理模型。而Memcached内部使用的libevent库,多线程模型。

  • netty工作机制如下:netty工作模型。
    netty中,有bossGroup和workerGroup。

    1. bossGroup中,每个线程维护一个包装的ServerSocket,监听一个端口。ServerSocket监听到新连接后,得到Socket并包装,并注册到workerGroup其中一个EventLoop所维护的selector上。每个workerGroup有多个EventLoop,每个EventLoop维护着一个Selector实例,类似单线程Reactor模式地工作着(参考)
    2. workerGroup有多个线程通过多路复用监听读写事件。每个EventLoop都是一个单线程Reactor模型,不断循环 监听事件的发生->取出激活的socket->依次处理事件->监听事件的发生。
  • redis中,由多路复用监听连接、读写事件,触发事件的socket被放置到队列中。文件事件分派器从队列中一个一个取出触发了事件的socket。再转交给对应的事件处理器处理事件。因为由单线程一个一个处理事件,所以redis是单线程的。

    杂谈_第1张图片

epoll实现、事件处理、编程方式、LT ET

LT/ET
Level Triggered (LT) 水平触发

  • socket接收缓冲区不为空 有数据可读 读事件一直触发
  • socket发送缓冲区不满 可以继续写入数据 写事件一直触发

事件的触发是以缓冲区的空/满状态决定的,只要状态满足,就会触发。

java nio

既然如此,java的nio是水平触发吗?
我写了此文进行探究

  • Linux epoll的水平触发是以缓冲区空满状态来判断的。
  • 所以我觉得,验证java nio水平触发的办法是客户端写多个字节(比如1000个),服务端每次只读一两个字节,缓冲区一直没读完,处于非空状态。由于水平触发,读事件应当会触发多次,也就可以分多次读完消息了。
    如果能多次触发读事件,就应当是水平触发

redis源码查看

ae.c/aeProcessEvents(其中包含文件事件分派器)为主的源码让我受益匪浅。该函数作用是完成事件处理的一次循环
ae_epoll.c/aeApiPoll函数讲述了redis如何用epoll实现事件监听

内存一致性

如何保证线程在切换到另一个CPU上运行之前,cache里的变量已经被写回内存?因为如果没写回内存,其它CPU的cache就会读到错误的数据。
答:内存一致性协议

你可能感兴趣的:(杂谈)