乐趣区

关于算法:Thrift源码解析深度学习模型的服务器端工程化落地方案

深度学习者经常有疑难,如果有了训练好的模型,怎么用服务调用?很多人可能会想到 Flask 进行 Http 调用。

那如果是内网呢?如果心愿去掉 Http 封包解包一系列耗时操作呢?天然咱们会想到 Rpc 协定。

RPC(Remote Procedure Call)是一种近程调用协定,简略地说就是,能使利用像调用本地办法一样,调用近程的过程或服务,能够利用在分布式服务、分布式计算、近程服务调用等许多场景。

有很多优良的 Rpc 框架,如 gRpc、Thrift、Dubbo、Hessian 等,本文来介绍一下 Thrift 框架中的服务模型。

为什么须要理解服务模型?因为为了增大 Rpc 服务端的并发解决能力,须要抉择更适合的 Thrift 服务模型,这就须要咱们理解各个服务模型的个性。

上面对反对 Python 的各个服务模型做具体介绍:

一、TSimpleServer

TSimpleServer 的工作模式采纳最简略的阻塞 IO,实现办法简洁明了,便于了解,然而一次只能接管和解决一个 socket 连贯,效率比拟低。

1、解决流程

2、源码剖析

设置 TServerSocket 的 listen() 办法启动连贯监听。

以阻塞的形式承受客户端的连贯申请,每进入一个连贯即为其创立一个 TSocket 对象(封装 socket 连贯)。

为客户端创立输出传输通道对象、输入传输通道对象、输出协定对象和输入协定对象。

processor 对象为服务模型创立之前创立的,用来解决具体的业务申请。

二、TNonblockingServer TThreadPoolServer TThreadedServer

这三个服务模型放在一起讲,是因为 python 中多线程有点鸡肋。而这三种模型都是利用了多线程技术。

1、首先来看 TThreadedServer,目标是为每个 client 申请创立独自的线程进行业务解决

2、而后是 TThreadPoolServer,服务启动时先创立好 self.threads 个线程,每个线程负责从队列 clients 中获取客户端连贯 TSocket 对象。而主线程负责 accept 客户端的连贯并创立 TSocket 对象,放入 clients 队列。

3、最初是 TNonblockingServer,这个略微简单一点。相似于 java 版 thrift 中的 THsHaServer,思路是服务启动时创立 threads 个线程负责解决 task 队列中的工作音讯。而主线程利用 io 多路复用技术将筹备好的可读音讯放入 task 队列供业务线程解决,同时在解决完结后可写时间接将后果返回给客户端。

三、TForkingServer TProcessPoolServer

这两个服务模型在 java 中并没有发现,目标也是躲避 python 的 gil 锁问题。

其中 TForkingServer,服务端每次监听到 client 申请,会 os.fork 一个子过程进行业务解决。

而这显然 fork 会耗费肯定工夫,而且服务端资源不是有限的,举荐还是用上面这个,TProcessPoolServer。服务启动时创立指定个数的过程,负责监听同一个端口的客户端申请,并进行业务解决。

以上就是次要的 python 版 thrift 服务模型介绍。须要留神的是 socket.accept() 从全连贯队列拿连贯,连贯队列(全连贯和半连贯)总大小在 thrfit 里默认是 128,可批改。

四、理论利用

测试环境:

64 核 CPU

测试后果:

无 GPU 操作,单次解决 0.3s 左右,100 次申请

1、客户端单个 client 串行发送 100 次,或者 10 线程别离发送 10 次,共享同一个 client,后果均为 33 秒多。可见对于单个 client 连贯服务器解决均是串行,与代码显示相符。

2、客户端 10 线程别离发送 10 次,每个线程创立 1 个 client,服务器端过程池模型(TProcessPoolServer),过程数 10。用时 3 秒多。同样阐明对于单个 client 连贯服务器解决均是串行。

3、客户端 100 线程别离发送 1 次,每个线程创立 1 个 client,服务器端过程池模型(TProcessPoolServer),过程数 10。用时 3 秒多,比测试 2 略多一点,能够预感服务端创立销毁 client,占据了一点工夫。

4、客户端 10 线程别离发送 10 次,每个线程创立 1 个 client,服务器端 non-blocking 模型(TNonblockingServer),解决线程数 10。后果和测试 1、2 差不多时长,阐明 cpu 密集型工作,python 不适宜多线程。

5、客户端 10 线程别离发送 10 次,每个线程创立 1 个 client,服务器端过程模型(TForkingServer),为每个 client 创立 fork 过程。用时 4 秒多。阐明 fork 子过程耗时显著。

6、客户端 100 线程别离发送 1 次,每个线程创立 1 个 client,服务器端过程模型(TForkingServer),为每个 client 创立 fork 过程。用时 11 秒多,同样阐明 fork 子过程耗时显著。

文章起源:https://zhuanlan.zhihu.com/p/…

退出移动版