brpc icon indicating copy to clipboard operation
brpc copied to clipboard

如何使用brpc实现run-to-completion模型?

Open rpbear88 opened this issue 3 years ago • 4 comments

按我的理解,bthread是brpc设计的核心,而正如bthread or not中提到的,由于bthread本身的开销大概在10us左右,如果计算任务只要不足10us那么使用bthread就是一件不太值得的事情。

目前存储IO在闪存介质上已经进入到了10-100us的性能水平,这还是底层IO的耗时,如果使用SPDK等异步IO框架,实际上在io submit这一阶段的耗时已经远远低于10us了,所以业界普遍采用了在一个线程内使用run-to-completion的模型来处理如下某个用户请求所涉及的各个步骤:

  1. 查询RDMA接收/发送队列是否有报文要处理,如果有则在当前线程直接处理
  2. 查询SPDK的completion queue是否有任务处理, 如果有则在当前线程直接处理
  3. 任务如果有IO需求,则提交给SPDK队列后返回
  4. 任务结束后提交回应给RDMA队列后返回

整个的操作是在一个线程上运行的,虽然不能利用多核的处理能力,但单核的处理能力可以跑满,在保证上述多个步骤都以极低延迟进行时,整个请求的处理时间将非常短。

我们在使用brpc的过程中确实遇到了一些问题,在将某个任务从接入层传递给存储层时至少消耗10-20us的bthread开销,由于我们追求极低的存储延迟,这是不可接受的。而这一情况在我们使用-usercode_in_pthread后也没有好转。

所以如果我们希望在brpc框架上使用run-to-completion模型的话,官方是否有建议的方式呢?我们计划的方式是在接入层收到请求后(此时还是运行在bthread中),将创建的状态机扔进一个高性能的消息队列TaskQueue,我们会为每一个core创建一个pthread来looping这个TaskQueue,至少除了数据接收/发送(RDMA处理)部分以外的其他部分都可以运行在一个thread内采用run-to-completion的方式完成。

还有一种方式,我们想基于brpc实现一种poller的注册机制,比如braft中,各个apply的task可以注册到我们的poller thread上,当事件触发后在poller thread上进行原地调用,但是目前来看对源码的改动会比较大。

很想倾听下百度的朋友在这个问题上的解决方案,谢谢。

rpbear88 avatar Jun 15 '21 03:06 rpbear88