异步分片上传文件,我这样做合适吗?

2020-04-23 14:18:25 +08:00
 MilletChili

在判断分片是否全部完成上传前,加锁是必须的吧。

怎么加 用啥加好呢?我现在用的数据库锁,为此专门建了一个表,就一个 id 字段,为每个用户的 id,在判断分片是否全部完成上传的前,去查当前用户 id 对应新建表的那条数据然后加 for update,可用倒是可用,但是感觉有点僵硬啊,大佬们能不能点拨点拨

2024 次点击
所在节点    程序员
13 条回复
h4de5
2020-04-23 14:38:02 +08:00
可以参考一下阿里云 oss 的 sdk 的代码。
mlxj
2020-04-23 14:49:28 +08:00
1.每个分片=>暂存
2.分片=>总数,根据总数来判断是否上传完成。
MilletChili
2020-04-23 15:45:58 +08:00
@h4de5 好的,我去看一下
MilletChili
2020-04-23 16:00:13 +08:00
@mlxj 但请求是异步的啊,在判断<当前分片数==总数> 前,得加锁,不加的话,可能出现多个分片上传的请求中判断<当前分片数==总数>都成立或不成立的情况
MilletChili
2020-04-23 16:01:34 +08:00
@MilletChili 我说的是最后几个分片哈
MilletChili
2020-04-23 16:10:55 +08:00
@h4de5 阿里云 oss 的 sdk 都是安顺序一个一个分片传的,我开几个线程异步着传分片的情况呢
netnr
2020-04-23 16:54:55 +08:00
保存分片时,完成分片计量+1 (全局缓存) ,再判断等于总片数就合并
百度的 webuploader 分片包含 chunk chunks 两个变量
mlxj
2020-04-24 09:58:05 +08:00
还是不用加锁。
每次上传的时候带两个参数:
1.文件 id
2.chunk 第 N 个
MilletChili
2020-04-24 10:06:46 +08:00
@mlxj 文件 id 指的是啥? MD5 值吗
h4de5
2020-04-24 14:03:37 +08:00
@MilletChili https://i.loli.net/2020/04/24/fj69irBU4ZJvekg.png 这个是我的 oss 上传日志。部分分片上传失败的话,后面不一定是顺序上传的。
MilletChili
2020-04-26 18:26:36 +08:00
@h4de5 嗯,我之前说的不太清楚,应该是阿里云 oss 都是同步着传的,不会有并发的问题。我这边找到一个比较好的方案了,用 redis 的 incr,每保存一个分片就 incr 一下分片数,redis 单进程的不受并发影响,而且基于内存还快,比关系数据库开事务加锁快多了
MilletChili
2020-04-26 18:31:17 +08:00
python 代码
# 加锁判断当前分片是否是最后一个
is_last_slice = False
if redis_helper.incr(sign) == slice_num:
is_last_slice = True

# with transaction.atomic():
# if SliceLock.objects.select_for_update().filter(sign=sign).first():
# if slice_num == len(os.listdir(temp_dir_path)):
# is_last_slice = True
# else:
# code, msg, data = (GlobalsCode.Err, 'sign 不存在', {'slice_name': slice_f.name})
# return retCORS(code, msg, data)
MilletChili
2020-04-26 18:37:44 +08:00
@MilletChili 说错了,redis 单线程

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/665322

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX