- 主题:pajamax,高性能grpc服务端框架
我最近在写一个服务程序,先是用的tonic grpc框架。但压测下来发现性能没有想象的好。
抓火焰图分析了下,除了网络io系统调用外,剩下大部分是在 tokio运行时 和 http2协议解析上的消耗。
于是我自己写了个grpc框架,pajamax,采用线程模型的同步方式,另外自己实现了适合grpc的http2协议子集。性能比tonic最高快10倍。
发出来,希望得到大家的反馈和建议。
(貌似文章里有链接的话就发不出来。感兴趣的去 docs.rs 里搜索 pajamax 吧。)
--
FROM 122.231.190.*
大佬,支持客户端吗?
【 在 hellowub (wub) 的大作中提到: 】
: 我最近在写一个服务程序,先是用的tonic grpc框架。但压测下来发现性能没有想象的好。
:
: 抓火焰图分析了下,除了网络io系统调用外,剩下大部分是在 tokio运行时 和 http2协议解析上的消耗。
:
--
FROM 39.144.154.*
暂时没这个计划。因为我感觉客户端可能不太适合这种方式。
对于服务端,同步框架是有意义的,因为有的场景下,就是可以立即处理完请求并响应。
但对于客户端,在发送请求到收到响应之间,就是要等待的,所以可能更适合异步编程模式。如果是同步模式,那就只能是callback的方式了。
你是有类似的客户端的同步请求的需求场景吗?
【 在 ensonmj 的大作中提到: 】
: 大佬,支持客户端吗?
--
FROM 122.231.190.*
对,目前有个项目正在考察。客户端需要等待没问题,但async和await是没有运行时就不能跑,而我希望的是在一个独立线程中loop处理事务,包括请求外部服务,外部服务返回立马处理。这儿引入运行时,loop处理latency可能就不可控。 当然我还不确定这儿的latency是不是过度担心。
【 在 hellowub (wub) 的大作中提到: 】
: 暂时没这个计划。因为我感觉客户端可能不太适合这种方式。
:
: 对于服务端,同步框架是有意义的,因为有的场景下,就是可以立即处理完请求并响应。
:
--
FROM 39.144.154.*
我本来的计划是用ureq先试试。如果pajamax同时支持客户端和服务端,那就更合适了。
【 在 hellowub (wub) 的大作中提到: 】
: 暂时没这个计划。因为我感觉客户端可能不太适合这种方式。
:
: 对于服务端,同步框架是有意义的,因为有的场景下,就是可以立即处理完请求并响应。
:
--
FROM 39.144.154.*
没太明白你的意思。
你说的loop线程 请求外部服务的话,那从 发出请求 到 收到响应,这段时间的延迟应该是很大的(取决于网络和服务端处理)。这个跟 是否async异步编程没关系吧。无论同步还是异步都要有这个延迟。
你说的,“引入运行时带来latency”,是指的 我上面说的请求外部服务的延迟,还是 运行时带来的延迟?
前者是外部延迟,我认为是很大的也不可控的;后者是cpu执行延迟,我认为是相对很小的。
【 在 ensonmj 的大作中提到: 】
: 对,目前有个项目正在考察。客户端需要等待没问题,但async和await是没有运行时就不能跑,而我希望的是在一个独立线程中loop处理事务,包括请求外部服务,外部服务返回立马处理。这儿引入运行时,loop处理latency可能就不可控。 当然我还不确定这儿的latency是不是过度担心。
--
FROM 122.231.190.*
外部延时不用管,重要的是响应回来后立刻能处理。async异步运行时对于协程总是有调度的,所以用异步不能保证立马被调度到,也就是外部处理完了,我这边并不能立刻处理。
另外还有个更大的潜在问题 ,像tokio里面是有过类似公平调度的计数器的,如果把这个loop线程用异步的方式来写,很可能会因为loop线程里面其他耗时的处理导致yield出去之后需要更长时间才能调度回来。
【 在 hellowub (wub) 的大作中提到: 】
: 没太明白你的意思。
:
: 你说的loop线程 请求外部服务的话,那从 发出请求 到 收到响应,这段时间的延迟应该是很大的(取决于网络和服务端处理)。这个跟 是否async异步编程没关系吧。无论同步还是异步都要有这个延迟。
:
--
FROM 116.237.206.*
不用管 外部延迟(长且波动大),而在意 调度延迟(短且波动小)?能不能说下具体的需求?我比较好奇。
另外,我想了下,做同步的客户端线程可能比较麻烦。因为这个线程至少要监听两个地方:读tcp连接 和 读接收业务线程发来请求的管道。纯同步的代码应该是不能同时监听两个地方的。只能上多路复用(epoll之类)。实现比较复杂,性价比不如直接用tokio。
你如果担心tokio上其他任务的影响,可以单独起一个tokio的实例,专门负责网络请求,而跟其他业务task独立开来。
【 在 ensonmj 的大作中提到: 】
: 外部延时不用管,重要的是响应回来后立刻能处理。async异步运行时对于协程总是有调度的,所以用异步不能保证立马被调度到,也就是外部处理完了,我这边并不能立刻处理。
: 另外还有个更大的潜在问题 ,像tokio里面是有过类似公平调度的计数器的,如果把这个loop线程用异步的方式来写,很可能会因为loop线程里面其他耗时的处理导致yield出去之后需要更长时间才能调度回来。
--
FROM 122.231.190.*
我现在就是单独起一个tokio,接受外部请求,预处理。然后通过channel提交给这个loop线程。loop 线程每次try recv外部请求,有就加进来,没有继续计算。计算过程就是就是组建一个大的batch,然后交给外部gpu去算。然后阻塞等待gpu返回结果。 gpu worker那边可以起一个同步的grpc server,因为gpu的请求永远是1,追求的不是高并发,而是低延迟。
概括地讲,就是一个llm 请求调度器 。
【 在 hellowub (wub) 的大作中提到: 】
: 不用管 外部延迟(长且波动大),而在意 调度延迟(短且波动小)?能不能说下具体的需求?我比较好奇。
:
: 另外,我想了下,做同步的客户端线程可能比较麻烦。因为这个线程至少要监听两个地方:读tcp连接 和 读接收业务线程发来请求的管道。纯同步的代码应该是不能同时监听两个地方的。只能上多路复用(epoll之类)。实现比较复杂,性价比不如直接用tokio。
:
--
FROM 39.144.103.*
感觉很牛啊,厉害
【 在 hellowub 的大作中提到: 】
: 我最近在写一个服务程序,先是用的tonic grpc框架。但压测下来发现性能没有想象的好。
: 抓火焰图分析了下,除了网络io系统调用外,剩下大部分是在 tokio运行时 和 http2协议解析上的消耗。
: 于是我自己写了个grpc框架,pajamax,采用线程模型的同步方式,另外自己实现了适合grpc的http2协议子集。性能比tonic最高快10倍。
: ...................
--
FROM 123.127.159.*