C++ Workflow 异步调度框架 - 基本介绍篇
C++ Workflow 异步调度框架 - 基本介绍篇
最近在努力同步维护文章积累~方便后续持续更新~
原文是 2020 年 7 月底开源时 po 的,这里对近况进行了调整和补充。
希望自己和项目都可以持续进步 (๑╹ヮ╹๑)ノ 欢迎多多交流!
我们的项目 C++ Workflow 于两天前开源啦=>w<=
👉 https://github.com/sogou/workflow
目前文档、开源管理及其他方面都在摸索推进中,我也按捺不住想要以开发者之一的名义,写一系列个人博客,让大家可以从方方面面了解到 workflow 的全部信息~最官方的更新还是要以 github 为准,欢迎大家关注我们的项目,尝试使用并提出宝贵意见。
项目主页的 README 里已经有非常详细的介绍了,这里我来补充一些基本信息。本系列其他文章链接也会持续更新到这里。
一、 使用情况
Workflow 是搜狗的 C++服务器引擎,支撑搜狗和腾讯的海量线上请求,包括搜狗几乎所有后端 C++在线服务,如搜索服务,云输入法,在线广告等,每日处理超百亿请求。这是一个设计轻盈优雅的企业级程序引擎,是由首席架构师带领我们小几人的虚拟团队经历一年多打磨出来并开源的,可以满足大多数 C++后端开发需求,目前开源一年多了也在持续迭代中,开发者社区也在用心维护。
除了公司内,很多中小型公司使用,有的是用作计算 server,有的是用作异步 MySQL 客户端,更多的是更加复杂的高吞吐低延迟异步流程复杂系统,用以重构基本基本性能提升好几倍,轻松把 cpu 吃满,开源一路以来能够被认可真的是一件非常振奋人心的事情。然而开源对我们来说只是刚刚开始,这是一条充满挑战的道路。非常期待亮相于 github 的 workflow 未来可以拥有更多的可能性。
感慨完毕,说回正题~在公司内部和 github 中容易被用户接纳和使用,我认为得益于以下几个优点:
1.1 极其优异的性能
我们这里说的性能,不是单指如何跑满 cpu、如何单独地让网络请求极速响应、或者说如何异步操作文件或其他设备,而是所有这些资源都可以被其具体的调度器管理,尽可能地全部都调度起来。
由于 workflow 是个框架,除非是具体业务场景的前后对比否则很难给出 benchmark,因此性能优化因业务而已。但当作 webserver 这一场景的话,和业内比较通用的 nginx 和 brpc 在吞吐和长尾方面做了一些 benchmark,可供大家参考:workflow benchmark。
值得一提的是,workflow 用做 proxy 的时候,压测最大 QPS 是 echo server 的结果的 1/2,是 workflow 中异步调度无损耗的最好证明。
性能比 nginx 要好是很自然的,可以参考我先前的一篇用以改造异步调度 QAT 加速卡的小伙伴的测试,还没细优化,随便看看:OpenSSL异步模式与Intel QAT加速卡(四) 新一代异步调度框架workflow
我老大、也就是项目主作者的习惯是喜欢把东西做到最简洁、把性能做到最极致,因此项目对性能的每一个细节都不会马虎,本人受益匪浅。但是我们团队接触开源比较少,因此我个人非常希望能在性能优化方面学习到更多优秀的做法。
1.2 比其他 C++框架更友好的用户体验
我们给开发者用户接触到的是 task(任务)和 series(任务流):
task 由工厂创建、自行销毁;
series 可以手动从工厂创建或者自动创建,也是自行销毁。
用户再也接触不到连接池、线程池、包括想要做 aio 时的文件 fd 与各种异步通知机制。
从语言的发展来看,go 的出现与被喜爱是必然的,原因之一就是天下苦 C++久矣,而 go 的封装很高级很简约。虽然 C++后续也推出了各种新用法,但不是所有用户都会升到更高的标准,目前 workflow 的标准是 C++11。
而任务和任务流的概念在理解和易用性上简直甩开事件机制和用循环来做多次进入的开发模式十条街(后面这种模式真的太难了,我感觉自己也并没有理解透彻,但发现 OpenSSL 的异步和 grpc 的异步 server 都是这样做的)。但是,我们一开始学习编程的时候,就知道要封装函数,而不是学习怎么做事件通知,学习的是最简单的 for 循环里执行相同的代码段,而不是用循环做多次重入实现不一样的阶段控制。而任务和任务流的封装,就是函数和循环的封装,是很贴近最基本的编程理念的。
关于 OpenSSL 中异步和 aio 的异步机制,以前写过一篇是做 mac 的 aio 模块时对 aio 各种异步通知机制的拙见,感兴趣的小伙伴可以看看,并且欢迎给我指出错误:异步I/O -- posix aio 从入门到放弃的吐血实践。
1.3 通信计算资源融为一体的解决方案
我们特别适用于重计算,而搜索的绝大部分使用场景都是重计算的 server,而网络和计算都可以用 workflow 一并解决。
workflow 认为一切资源都是可以异步调度的,因此对于目前支持对接的资源,我鶸鶸地归纳对比了如下表格:
计算这里详细说一下,原先检索模块开发小伙伴常常面临选择高吞吐网络框架的同时,自己需要面对不同计算资源比例而划分不同大小的线程池。
然而每种计算具体资源需求比例是动态变化的,重要性也不一样,后端响应时长也是动态变动,如果我们在初始化的时候创建若干个特定大小的线程池,线程资源难以共用。
Go 内部的 go routine 调度就是用来解决这种事情的。那么 C++来说,现在 workflow 可以和 go 一样解决全局计算资源共享和按需调度的需求了,并且打通网络、磁盘等等其他资源。
1.4 代码架构层次良好,易于拼装,实现二次开发
workflow 的世界里有三个原则:
串行是由任务组成的
并行是由串行组成的
并行是一种任务
于是乎,workflow 是一套完备的、可以收敛一切循环和控制的任务流模型。
以下是我的一些个人解读:
由于可以串行,我们就可以动态建流图,并且无限执行下去;
由于可以并行,并行的是各个串行流,我们可以对多个并发执行的流在完成时做收敛;
并行本身是一种任务,因此可以加到串行流图里,即每个任务都可以是一个复合任务组装而成,组装后提供给其他使用者使用,而使用者不需要关心复合任务内部细节,进一步组装。
当然 workflow 的其他优点很多,这些是公司内部使用情况的一些总结,其他的会陆续给大家介绍~今天其他点也不太写得完了,这里列个大概,后续会更新哦~
评论