Kubernetes环境下NFS共享存储分块上传文件异常求助
问题描述
需求为开启octet-stream请求流,接收文件时实时写入文件系统。该功能在本地及Debian Linux服务器上运行正常,但部署在单Pod的Kubernetes环境中出现异常:
- 向文件追加字节时,文件大小始终显示为0,有时会在上传完成后才写入,有时完全不写入
- 暂停后恢复上传时,服务器检测到文件大小为0,会重新开始上传
- 同时存在与业务逻辑相关的多关联文件上传问题
初始化空文件函数
def _initialize_file(uid: str) -> None: if not os.path.exists(nfs_path_that_is_shared): os.makedirs(nfs_path_that_is_shared) open(os.path.join(nfs_path_that_is_shared, f"{uid}"), "a").close()
分块上传的Patch接口
@router.patch("/{uuid}", status_code=status.HTTP_204_NO_CONTENT) async def upload_chunk( response: Response, uuid: str, content_type: str = Header(None), content_length: int = Header(None), upload_offset: int = Header(None), _: bytes | None = Depends(_get_request_chunk), ) -> Response: return await _get_and_save_the_file( response, uuid, content_type, content_length, upload_offset, )
核心处理方法(Kubernetes环境下异常)
async def _get_request_chunk( request: Request, uuid: str = Path(...), post_request: bool = False, ) -> bool | None: log.info("Reading metadata") meta = _read_metadata(uuid) if not meta or not _file_exists(uuid): log.info("Metadata not found") return False path = f"{nfs_path_that_is_shared}/{uuid}" with open(path, "ab") as f: log.info("Getting chunks") async for chunk in request.stream(): if post_request and chunk is None or len(chunk) == 0: log.info("Chunk is empty") return None log.info("Checking chunk size") if _get_file_length(uuid) + len(chunk) > MAX_SIZE: log.info("Throwing HTTP_ENTITY_TO_LARGE") raise HTTP_ENTITY_TO_LARGE log.info("Writing chunk") f.write(chunk) log.info("Modifying metadata") meta.offset += len(chunk) meta.upload_chunk_size = len(chunk) meta.upload_part += 1 log.info("Writing metadata") _write_metadata(meta) log.info("Metadata written") return True
已尝试的方案
- 使用跨命名空间及Pod共享的NFS存储,问题依旧:文件通常在上传完成后才写入,本地环境则实时写入字节
- 尝试使用aiofiles异步非阻塞写入,未解决问题
- 若问题无法解决,计划引入Redis作为替代方案
恳请提供解决方案!
内容的提问来源于stack exchange,提问作者Edi
相关产品推荐
相关产品推荐

