【问题标题】:Maximizing concurrency in externally IO bound applications (JVM)最大化外部 IO 绑定应用程序 (JVM) 中的并发性
【发布时间】:2019-09-09 01:32:03
【问题描述】:

我有一类问题可以表述如下:

想象一个完全水平可扩展的服务,称为 Service A,即从消费者的角度来看,服务 A 可以处理无限数量的并发请求而不会发生故障转移(通过非常好的自动扩展策略,没有单数据层争用或极其容忍的请求队列)

CLI 程序(CLI) 必须遍历相对较大的文件(例如 10GB),文件中的每一行都包含对服务 A 的请求。 CLI 程序在遍历文件时构造这些请求,并将请求转发给服务 A。对于每个请求,当服务 A 响应时,CLI 会以短期方法解析响应

虽然服务 A 非常擅长处理并发,但每个请求都是同步的,可能需要任意长的时间。

直接的想法是:我们可以使用 ThreadPool,但每个工作线程都会受到 IO 限制 - 在 CLI 上不会看到太多的堆/CPU 利用率,但 CLI 仍然会显得很慢

处理此类问题以最大化并发性的首选非阻塞架构是什么?

【问题讨论】:

  • 我会查看nio 包,例如使用AsynchronousSocketChannel。老实说,我没有仔细阅读,但乍一看似乎是正确的道路。
  • 这是基于 HTTP 的服务吗?每个请求花费的平均时间是多少?这是什么数据?是json吗?它是压缩二进制吗?它是一种运行数小时的批处理作业吗?完成的总体 SLA 是多少,现在花费的总时间是多少?
  • 是的,我猜这个想法是基于 HTTP 的(尽管我会抽象出它并说某种“TCP 套接字连接”,不一定是超文本或绑定到任何第 7 层协议一个用例可能是处理时间 = 10 - 50 秒,但无限并行 我认为 java.nio.* 包是一个好的开始,一个管理多个通道的单线程将是一个很好的开始 我发现 HTTP Apache Http Async 非常漂亮有用

标签: java concurrency architecture nonblocking


【解决方案1】:

我会重新评估您的要求。看起来您需要处理一个大文件并对其执行批处理操作,而每条记录可能需要很长时间来处理。恕我直言,为此使用 CLI 并不理想,因为:

  • 并行度受单个 CLI 客户端进程的限制
  • CLI 进程失败将丢失所有进度
  • 您提到每个请求都是同步的,但可能会花费不可预测的时间。您如何设置此类请求的超时时间?标准解决方案是使用请求实现处理程序的心跳来快速了解故障。
  • 虽然您声明下游服务在现实生活中具有无限的吞吐量,但您希望能够独立于同时处理多少个文件来控制对其的调用速率。

我建议使用像Cadence Workflow 这样的编排系统以容错和可扩展的方式实现您的业务逻辑。例如,它将允许从多个工作进程并行处理文件,并轻松处理重试和长时间运行的操作。它已经在 Uber 内部用于与您类似的多种场景。

【讨论】:

    猜你喜欢
    • 2011-03-24
    • 1970-01-01
    • 2010-09-13
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多