加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

spymemcached源码中Reactor模式分析

发布时间:2020-12-15 04:57:14 所属栏目:百科 来源:网络整理
导读:简介 spymemcached 是一个 memcached 的客户端, 使用 NIO 实现。采用Reactor模式实现,单线程,高性能Memcached客户端。 spymemcached源码分析:http://my.oschina.net/astute/blog/93492 Reactor模式介绍 所谓reactor模式,其实是event-driven pattern在网

简介

spymemcached 是一个 memcached 的客户端, 使用 NIO 实现。采用Reactor模式实现,单线程,高性能Memcached客户端。

spymemcached源码分析:http://my.oschina.net/astute/blog/93492

Reactor模式介绍

所谓reactor模式,其实是event-driven pattern在网络服务设计中的应用,以平衡CPU与IO速率,最大化CPU资源与IO资源的利用率;

先来看看经典的服务器设计:

经典网络服务接受客户端请求,响应请求过程可以抽象为以下步骤:

  1. 读取请求数据 : read
  2. 解码数据: decode
  3. 计算:compute
  4. 编码数据:encode
  5. 发送数据:send

网络服务所有动作被抽象为这个五个步骤的handler;可能每个handler有单独线程执行,或者由一个线程顺序执行;

这种经典设计中存在以下问题:

  1. 每个连接分配一个线程,而每个连接发送请求数据较少,导致大量空闲线程;
  2. 大量线程上下文切换和锁竞争

为了解决上述问题,采用两个方法实现:


  1. 采用分治的思想,将连接划分为更小粒度的非阻塞任务:将用户连接划分为 多个用户请求,每个请求一个线程处理;减少 请求间空闲时间占用线程
  2. 采用事件处理模式,分派可执行任务;通过IO 事件触发 handler 处理


采用事件处理模式的单线程Reactor模式:

单线程Reactor 处理 连接请求,所有用户请求都在同一个线程中;通过IO事件触发相应的操作;IO事件触发机制可参考java nio机制;

单线程版本的Reactor模式,还有以下问题:

  1. 触发事件处理 与 处理事件 在同一个线程中;减缓了Reactor的事件触发及时性
  2. 所有请求必须等待之前请求中IO操作之外的处理过程
  3. 无法解决CPU与IO速率不一致问题
  4. 不能有效利用多核优势

为解决上述问题,采用多线程设计方案的Reactor模式:

多线程版本的Reactor模式,有以下优势:

  1. Reactor可以快速触发handler执行
  2. IO操作以外操作由线程池中线程独立处理
  3. Reactor 线程满负荷 IO操作
  4. 平衡CPU 与 IO 速率

reactor模式就介绍到此,具体看下spymemcached中reactor模式的应用吧

spymemcached中Reactor模式实现

spymemcached中reactor模式设计到以下概念:

  1. IO线程:MemcachedConnection 负责处理
  2. 工作线程:调用spymemcached操作的线程;通常是应用线程,例如tomcat线程等等;

工作线程职责:

  1. 通过MemcachedClient提交操作请求给MemcachedConnection
  2. MemachedClient提交操作过程:实例化异步操作回执OperationFuture(该回执都会实例化一个CountDownLatch(1));通过OperationFactory 生成定制Callback操作的Operation对象;将Operation操作加入对应ShardedNode 的inputQ;返回异步结果回执OperationFuture对象
  3. 调用OperationFuture对象的get操作阻塞在CountDownLatch,等待后台IO线程,调用countDown;

IO线程职责:

  1. 由MemcachedClient初始化启动后台MemcachedConnection线程,接受工作线程提交操作:从inputQ拷贝到writableQ;发送操作请求到Memcached服务器;添加操作到readQ,并把操作从writableQ删除;修改监听IO事件
  2. 执行select操作,获取感兴趣IO事件
  3. 执行handleIO处理:根据SelectKey发生事件类型:执行读取操作 or 写入操作;
  4. 当IO操作完成后,调用Operation Callback对象的receivedStatus设置回执结果;调用countDown释放阻塞的工作线程;

由此可见,spymemcached Reactor模式实现中,工作线程相当于客户端请求; IO线程相当于单线程Reactor设计中的Reactor负责接收请求,处理请求;spymemcached对数据解码部分可以扩展实现线程池方式提供解码计算,无需占用Reactor线程资源,使得Reactor线程满负荷IO操作和事件触发;


在spymemcached的Reactor设计中:

MemcachedClient负责接收请求

MemcachedConnection负责处理IO请求

同时还可以扩展支持线程池TranscodeService对解码计算提供异步线程支持; 这也是OperationFuture.get()返回值仍未一个Futrue,内部再次调用future.get返回最终数据的原因。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读