在判断分片是否全部完成上传前,加锁是必须的吧。
怎么加 用啥加好呢?我现在用的数据库锁,为此专门建了一个表,就一个 id 字段,为每个用户的 id,在判断分片是否全部完成上传的前,去查当前用户 id 对应新建表的那条数据然后加 for update,可用倒是可用,但是感觉有点僵硬啊,大佬们能不能点拨点拨
1 h4de5 2020-04-23 14:38:02 +08:00 可以参考一下阿里云 oss 的 sdk 的代码。 |
![]() | 2 mlxj 2020-04-23 14:49:28 +08:00 1.每个分片=>暂存 2.分片=>总数,根据总数来判断是否上传完成。 |
3 MilletChili OP @h4de5 好的,我去看一下 |
4 MilletChili OP @mlxj 但请求是异步的啊,在判断<当前分片数==总数> 前,得加锁,不加的话,可能出现多个分片上传的请求中判断<当前分片数==总数>都成立或不成立的情况 |
5 MilletChili OP @MilletChili 我说的是最后几个分片哈 |
6 MilletChili OP @h4de5 阿里云 oss 的 sdk 都是安顺序一个一个分片传的,我开几个线程异步着传分片的情况呢 |
![]() | 7 netnr 2020-04-23 16:54:55 +08:00 保存分片时,完成分片计量+1 (全局缓存) ,再判断等于总片数就合并 百度的 webuploader 分片包含 chunk chunks 两个变量 |
![]() | 8 mlxj 2020-04-24 09:58:05 +08:00 还是不用加锁。 每次上传的时候带两个参数: 1.文件 id 2.chunk 第 N 个 |
9 MilletChili OP @mlxj 文件 id 指的是啥? MD5 值吗 |
10 h4de5 2020-04-24 14:03:37 +08:00 @MilletChili https://i.loli.net/2020/04/24/fj69irBU4ZJvekg.png 这个是我的 oss 上传日志。部分分片上传失败的话,后面不一定是顺序上传的。 |
11 MilletChili OP @h4de5 嗯,我之前说的不太清楚,应该是阿里云 oss 都是同步着传的,不会有并发的问题。我这边找到一个比较好的方案了,用 redis 的 incr,每保存一个分片就 incr 一下分片数,redis 单进程的不受并发影响,而且基于内存还快,比关系数据库开事务加锁快多了 |
12 MilletChili OP 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) |
13 MilletChili OP @MilletChili 说错了,redis 单线程 |