Workflow异步调度框架 - 性能优化上篇

原文是2020年7月底开源后po的,希望可以持续进步 (๑╹ヮ╹๑)ノ 欢迎多多交流!!

搜狗C++ workflow异步调度框架github地址:

GitHub - sogou/workflow: C++ Parallel Computing and Asynchronous Networking Engine

https://github.com/sogou/workflow

先来和大家update一下,这一周以来workflow又有哪些成长呢:

  • 新版更简洁的README.md
  • server默认使用ipv4启动(为了兼容windows与unix的行为
  • 加了全局配置项的文档about-config.md (正好和今天的话题相关!

开源了两周,备受小伙伴们关注,真的很开心~~ >_< ~~ 特别感谢各位关注和支持我们的大神们小朋友们,希望能够持续和大家交流,一起进步~

更新于2022年3月,开源一年多留个纪念~

我也在整理开源项目规范化相关的事情,如果有哪里做得不到位,希望能帮我指出~

今天这个话题是非常通用的入门话题:写完代码我们需要做什么最基本的系统性能优化。

由于workflow是个异步调度引擎,workflow的职责就是让系统各资源尽可能地利用起来,所以我的日常工作,除了写bug之外,还要配合开发小伙伴现场debug、分析用了workflow之后的各项指标是否还能进一步提升。

我还是结合具体几类资源为线索来介绍:

  1. CPU:多路复用相关的线程数、计算相关线程数、多进程
  2. 网络:长连接短连接、连接数控制、超时配置、压缩
  3. 计时器:timerfd的优化
  4. 计数器:命名计数器与匿名计数器
  5. 文件IO:实际场景用得少,先不写了
  6. GPU:目前我只做了demo版,所以没有放出来,也先不写了

其中计时器和计数器相对简单一些,我会这里介绍下内部实现,其他的内部实现做了很多优化,每个话题都值得以后单独写一下。

一、CPU

先来看看我们的配置项:

static constexpr struct WFGlobalSettings GLOBAL_SETTINGS_DEFAULT =
{
    .endpoint_params    =   ENDPOINT_PARAMS_DEFAULT,
    .dns_ttl_default    =   12 * 3600,
    .dns_ttl_min        =   180,
    .dns_threads        =   4,
    .poller_threads     =   4,
    .handler_threads    =   20,
    .compute_threads    =   -1,
};

1. 基本网络线程

一般用epoll的框架都需要对其进行类似proactor式的封装,那么就要负责做以下事情,以及决定具体哪个线程去分工:

  1. 对epoll具体某个fd进行读写
  2. 读写时把完整数据包切下来
  3. 数据包切完之后的解析(即反序列化
  4. 执行用户的操作

Workflow当前的做法,poller_threads线程是去操作epoll读写和做fd读的切消息的事情,而handler_threads是做基本用户操作的,比如callback和作为server的话,我们的process函数所在的线程。

brpc是不区分的,我个人理解有几个原因,比如:

  • 它套了一层bthread做换线程的调度;
  • fd上拉了写链表:没人在写你就写,有人在写你就把数据扔下就行了,这个人会帮你写,不存在类似handler线程还要回去管poller线程的异步写的事情;

Workflow没有做这样的优化,主要还是因为一个进程内网络读写和业务操作压力比例基本是差不多确定的,业务上线前的调优调整一下poller和handler线程比例基本足够了。而且workflow才1岁多,很多优化可能会往后放。

这里也顺带说一句,对于把数据包切下来和切完之后的解析,其实有些协议是不太能分得开的。

我鶸鶸地给大家列一下,从协议设计上,可以分以下三类:

  • 收到消息就能知道我怎么完整地切一条消息出来;
  • 收一点之后判断一下才能知道我怎么切一条消息出来;
  • 一边收数据流一边解析,不到最后一刻都不知道是不是收完。

第1种就很简单,一般做RPC协议我们都会友好地在头部告诉你大概多长。

第2种有点类似HTTP这样,大概收完头部你就知道后边还有多少了,这个时候你收header,是要自己边收边parse的。

第3种比如MySQL这种吐血的协议,大概它在设计的时候就没有想过你要多线程去操作一个fd读消息,你得根据当前哪种包的状态再判断,这种必须写个状态机去完整收完了才能交给用户。而这个收的期间,我已经把每个field和每个ResultSet给解析出来了,收完基本等于数据反序列化也做完了。
所以第2种、第3种,对于切完整消息和解析消息的反序列化操作其实并不会太分得开,workflow都会在poller_threads里做。

2. 计算线程

我们内部会有独立的计算线程池,默认是和系统cpu数一致的数量,这个是基本可以减少线程数过多而频繁切换的问题,当然如果用不到计算任务,此线程池不会创建。

和cpu数一致,那么不同时期不同类型的计算任务占比不同,这个workflow怎么解决呢?我们内部用了一个谢爷发明的多维队列调度模型,已经申请专利,以后有机会让谢爷写一篇给大家讲讲>_<

简单来说,workflow的计算任务都是带名字的,对于业务开发来说,基本只需要把同一类任务以同一个名字去创建,那么start之后是基本可以保证不同名字的任务被公平调度,并且整体尽可能用满计算线程数,这是一种比优先级和固定队列要灵活得多的做法。
P.S. 我们也有独立的DNS线程池,但是DNS目前的路由模式我觉得要并发去更新真的非常粗暴非常不喜欢,有空了路由机制是我第一个要动刀改进的地方!(认真立flag中o( ̄▽ ̄)o

3. 多进程

一般来说我们不太需要多进程,但是不可避免的情况下,先前有个场景确实需要小伙伴拆多进程:使用Intel QAT加速卡多线程会卡spinlock,这个前几篇文章有个系列已经提到过。

通用点说多进程,一般来说我们作为server的做法是先bind再listen,然后fork多个进程,然后,重点是在于,你这个时候再去epoll_create,那么操作系统来保证连进来同一个端口的连接不会惊群accept。

这个我个人的理解是:

  1. 首先我们bind并listen,是保证多个进程拿到同一个listen_fd。
  2. 然后先fork再epoll_create,意思是由多个epoll去listen同一个listen_fd。由于epoll不是用户态的,操作系统来保证同一个listen_fd的accpet只会被一个epoll来响应,所以不会有惊群。

说回workflow~workflow的server想做成多进程就很简单了:用WFServer::serve()接口,做以上fd自己bind、listen,再fork多次的事情就可以了。

也给大家列一下demo测试中多进程操作加速卡的性能。绿色的点是nginx(只能打到8w),nginx本身就是多进程单线程的,但是由于QAT只以多进程纬度来处理并发,因此我们只以进程数对比,基本轻松上10w了。并且说一下,QAT加速卡如果只做RSA计算,极限QPS也就是10w左右。

Workflow调用QAT加速卡在不同线程数下与nginx的QPS对比

以及短连接、长连接情况下多进程、多线程在我们小伙伴调用QAT加速卡每个请求做2次RSA解压时的QPS对比情况:

线程数、进程数、连接状态对Workflow调用QAT加速卡测试程序的影响

这里的短连接长连接,就当作给大家抛砖引玉网络调优话题,但今天来不及,明天继续写下篇~~~

本系列的前两篇:
C++ Workflow异步调度框架 - 基本介绍篇
C++ workflow异步调度框架 - 架构设计篇

下一篇:
C++ Workflow异步调度框架 - 性能优化网络篇

本系列其他文章:
C++ Workflow异步调度框架 - Kafka客户端
pyworkflow带你详解,那些Python调C++的大坑
SRPC架构介绍 - Sogou基于Workflow的自研RPC框架

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容