比如识别图片有三个步骤,分为三个网络请求
第一个请求接口是上传图片,返回 uuid
第二个请求接口是根据 uuid 获取图像识别的结果
第三个请求接口根据 uuid 删除服务端的图片
此时如果本地有 10000 张需要批量识别的图片,应该如何提高整个过程的效率呢?
使用 aiohttp 写三个请求方法依次完成三个请求接口算可行的方案吗?
1
warcraft1236 2020-12-03 16:18:28 +08:00
比较简单的:协程或者多线程读取图片,然后同步去依次请求三个接口
稍微麻烦一点:利用队列,生产者将图片往一个队列里边丢,消费者消费队列,然后请求传图片的接口,拿到 uuid 之后丢到另一个队列里边,然后这个队列的消费者消费,根据 uuid 获取图片结果,然后丢到另一个队列里边,然后消费者消费,去删除图片 |
2
est 2020-12-03 16:18:35 +08:00
要效率就一个接口搞定所有事情
要 KPI 就建 1000 个接口 |
3
Zhuzhuchenyan 2020-12-03 16:26:14 +08:00
个人感觉有两种方案,
第一种是 async.gather(所有上传图片请求) async.gather(所有图像识别请求) async.gather(所有图像删除请求) 适合图片上传时间差别不大,服务端能存下这么多图片,以及图片识别时间差别不大的情况 第二种是定义一个函数 async job(image): await 上传图片 await 图像识别 await 图像删除 然后 async.gather(所有的 job) 我的话应该会选择第二种吧,总体的执行时间理论上是一样的 |
4
Zhuzhuchenyan 2020-12-03 16:28:07 +08:00
哦补充下,如果根据 UUID 获取识别结果有可能是等待中( PENDING )的话,那只能走第二种方案添加一个定时轮询了。
|
5
jdhao 2020-12-03 16:28:21 +08:00
每张图片这三个请求是有先后顺序吧,1 -> 2 -> 3,10000 张图片是相互独立的,可以搞个多线程,每个线程处理一张图片。
|
6
xiaoqiao24 2020-12-03 16:47:02 +08:00
我觉得用队列比较好,第一个接口可以多线程(协程)一次处理 100 张图片,处理完的丢到 A 队列中
第二个接口多线程(协程)读取 A 队列的 uuid,图像识别的结果丢到 B 队列 第三个接口多线程(协程)读取 B 队列的结果,然后删除服务端的图片 这样就同步进行,10000 张图片很快就能搞定 |
7
hq 2020-12-04 08:49:20 +08:00
我出个 Serverless 方案:
1. 创建一个对象存储 bucket,比如 OSS 2. 写一个图像识别函数,创建 trigger,关联 1 中的 bucket 3. 调用 OSS 上传图片,上传时设置 TTL 为 1 小时,过期图片自动删除 4. 下载识别结果到本地 可以看看这个示例: https://help.aliyun.com/document_detail/74761.html |
8
black11black 2020-12-05 18:52:53 +08:00 via Android
一定要分步骤就不可避免的有状态了吧,要不然接数据库把状态转移出去,要不然合并消除状态本身,有状态没法部署啊
|