网络上大部分关于clip-as-service的描述都是关于它如何使用,基于它的编码功能上去计算文本相似度,根据文字推荐图片等等,只有作者的创作思路里面提及通信架构的设计。
作者博客:
链接: link
如何解决多个客户端同时请求服务端的场景?比如现在小白和小黑同时想获取文本线上推理服务。如果小白先来并且需求巨大,比如每秒发送1W条文本数据。此时服务端分配了四个worker,也就是说有四个工人工作。服务端将工作并行化为四个子任务,分别交给四个工人来完成。这时候小黑来了,小黑每秒只发送一条文本。这时候因为服务端还在处理小白的任务,所以小黑只能等了。其实有点像操作系统里面的任务调度策略。从用户体验的角度来说我们希望小任务的小黑能很快得到满足。因为任务量大,所以需要等待更长的时间这是合乎常理的,也是用户可接受的。而任务量小却要等待很长时间则会让用户体验极差。
下面看看bert-as-service项目如何解决这个问题。当服务端收到多个客户端的请求后,主要通过ventilator组件来进行批处理调度和负载均衡。当收到多个客户端请求后,ventilator首先会将这些请求划分成多个小任务,然后将这些小任务分别发送给工人们。工人们收到这些小任务后开始工作,工作内容就是使用bert进行预测,预测完之后会将结果统一发送给sink组件。sink组件会将所有工人的预测结果统一装配,同时检查ventilator组件中各个客户端请求的完整性,如果某个客户端请求的数据已经全部预测完成了,那么就返回预测结果给对应的客户端完成本次请求。通过这种方式,可以轻松解决上面小任务调度体验问题。下面是服务端和客户端通信架构图:
后来在github上面问他们哪里可以学习通信架构设计部分的代码(他们团队真的很赞,回复问题都特别及时),他们回复我
所以接下来打算看网上对于jina的逻辑是否有相关介绍,并看jina的官方文档及代码
看flow的过程中,有一个地方和我的需求貌似有一些联系,如下
代码如下
但在实际执行的过程中报如下错误
在github上询问相关人员,他们的答复是jina现在只支持基于grpc的协议,网关和(外部)执行器之间的通信都是基于grpc的协议
那这种思路就行不通,官方文档中说流将执行器编排到处理管道中以完成任务。 文档“流”通过管道,并由执行程序处理。可以将 Flow 视为配置和启动微服务架构的接口, 而繁重的工作是由服务本身完成的。 特别是,每个流还会启动一个网关服务,该服务可以通过您定义的 API 公开所有其他服务。
于是我想按官方文档的描述,把flask接口嵌入到Executor中,然后再使用flow加载生成grbc接口,那这样最终我们能提供的就是基于grbc协议的服务,我不知道新的思路是否能实现,就又去问他们的工作人员,他们说是可以的
现在我对其中executor和flow的具体细节、grbc协议的使用方式还没有看太懂,所以接下来我打算再研究一下官方文档,看他到底是怎样实现并发扩展的。