网络IO工作模型以及在分布式中的应用

本文旨在深入探讨流式计算框架中处理异构数据源的底层技术,包括主线程与工作线程的协作、收发包机制、错误处理策略以及多线程并发模型的应用。通过简化分布式计算框架中的IO模型原则,本文详细阐述了如何在实际应用中高效地管理和处理数据流,特别关注于错误处理和多服务器请求的实现。同时,本文还针对关键的技术挑战,如内存管理、错误重试机制及并发模型的选择,提供了实用的指导和建议。
为了写【流式计算和异构数据源的整合】这篇文章,我手贱,打算先写两篇基础文章
这是个说简单不简单,说难不难的问题,简单是因为现在会的人多了,难是新手总会犯浑;只能说这是些个成熟的模型;以下是个人看法,有不对的地方请指出;

主线程收发包,这是基调(one loop)

  • 工作线程是一个线程池(multithread)

  • 工作线程需对外发包

    • 阻塞的把包发出去
      • 下游socket-buffer满了的话,要等着对端socket-buffer有空闲空间
    • 非阻塞把包发出去
      • 工作线程任务结束,发包的事情交给主线程,主线程交给系统进程(这个过程是很多初学者不好理解的地方)
  • 工作线程需对外请求结果

    • 阻塞把包发出去
      • 那就阻塞把结果包读回来吧,简单(其实不简单,还跟对端的收发包逻辑有关系)
      • 工作线程不阻塞,继续干别的,等主线程把包读回来,这又是一个有点小绕的过程,读包的是主线程,主线程把包又得交给工作线程(这个工作线程不一定是发起请求的线程),这就需要工作线程知道这个任务是处理外部请求,还是处理自己的读包请求结果,至少有一个地方需要做dispatch外部请求还是自己的请求结果;
    • 非阻塞把包发出去
      • 阻塞把包读回来,理论上是可以的,单觉得这方式有点搞笑;(可以想象如果对端的回包方式如果跟自己的收发包方式不匹配的话,可能读错包了)
      • 工作线程不阻塞,继续干别的,带来跟上面同样的问题
  • 工作线程就是主线程(one thread)

    • 工作时需要对外发包

      • 阻塞把包发出
        • 在把包发出去之前,是没法响应外部请求的,因为你用的是主线程,它被你自己卡死了(新手常犯错误的地方)
      • 非阻塞把包发出去
        • 这才对头,主线程可以干别的了
    • 需要对外请求结果

      • 阻塞把包发出去
        • 阻塞把包读回来,自己承受被卡死的后果吧
        • 非阻塞把包读回来,很自然的方式,但是在socket的管理上也是有技巧的;
      • 非阻塞把包发出去
        • 阻塞把包读回来,同上搞笑方式;
        • 非阻塞把包读回来,很自然的方式;

多线程同时收发包(multi loop,multi thread)


这方式我本人没实际做过,此前一直以为lock的代价不会比one lookup,multi thread小,后来看到有人用spin-lock来做,效果貌似不错的样子,倒是蛮有意思的;


// =======================NB的分割线====================================

// =======================NB的分割线====================================

// =======================NB的分割线====================================


分布式计算中的应用

如果觉得上面说的有点复杂,下面我来简化一下,实际在你的分布式的系统里,往往只需要某些特定的模型的组合;以下是我的分布式计算框架中的IO模型原则

  • socket

    • “accept的socket”绝对不允许和“connect的socket”同一管理(这两个是属于完全不同的东西)
    • 对所有服务,每个请求的回包,都必须从收到请求的socket返回
    • 内部服务之间,全部必须使用长连接(内存换cpu)
  • one loop,multi thread

    • 所有收发包,都必须采用非阻塞方式,但是对IO使用者提供阻塞接口;
  • one loop,one thread

    • 所有收发包,都必须采用非阻塞方式,同时做IO的模块提供简洁的非阻塞接口;
对IO的使用者来说,这东西的确简单了很多,但是这还是可能把问题推到了一个理论上最难的IO模型(可怜的网络IO码农),下面介绍应用中的问题
  • 收发包时的错误处理

    • 对任意一个ip-port的请求,都会有这几个错误发生的可能:connect失败,写包失败,读包失败,读到包了,包校验失败,更恶心的是超时,因为超时可以发生在以上任意一个时机。
  • 对某个ip-port处理失败后的重试

    • 重试原始ip-port、重试另外的ip-port
    • 在重试的过程,收发包同样会出现以上的错误,别忘了,在你决定retry的时候,和刚去retry的时候,也有可能timeout;
  • 如何实现multi-get

    • 一个请求要发往多种server,结果需要合并给用户
    • 多个请求要发往同一种server的不同节点,结果合并给用户
  • 包的内存管理

    • 常见两种core-dump情况:double-free,mem-leak,引用栈上内存(这基本是完全没理解啥叫异步);
  • 问题的解决

    • 觉得太难的话,放弃c/c++,用erlang or node.js吧;
    • 非要用c/c++?等我写完另外两篇文章,补上我认为稍好点的解决方案(其实不难,需要的是细心,为请求包,允许的发送ip-port列表,等同一session所需要的所有数据建立一个上下文,再做个class转门响应以上任意一个错误和成功的回调,同时需要考虑超时,并且维护好自己的socket)。// @@ TODO

// ====================================


饭前一口气说了一通,吃完饭,好像没啥说的了,归栈写上一篇【流式计算的总结】文章吧... ... 欢迎讨论。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值