使用boto3将S3对象写入SharedMemory报错,如何解决?
用户尝试将S3对象内容写入SharedMemory时使用了以下代码:
MB=100 mem = SharedMemory(create=True, size=MB*2**20) response = s3_client.get_object(Bucket='my_bucket', Key='path/to/obj') mem.buf[:] = response['Body'].read()
执行后出现错误:
memoryview assignment: lvalue and rvalue have different structure
打印mem.buf的形状得到(105906176,),尝试修改为单位置赋值时:
mem.buf[0] = response['Body'].read()
又出现错误:
memoryview: invalid type for format 'B'
问题原因
- 第一个错误是读取的S3对象字节长度与SharedMemory容量不匹配:创建的SharedMemory大小为100MB(104857600字节),但实际读取的对象内容为105906176字节,超出SharedMemory容量,导致切片赋值时两边长度不一致。
- 第二个错误是
mem.buf[0]指向单个字节的内存位置,而response['Body'].read()返回整个字节对象,类型不匹配。
解决方案
要在不写入磁盘的情况下完成写入,需确保读取的字节长度与SharedMemory可用空间匹配,具体步骤如下:
方法1:根据S3对象大小创建匹配的SharedMemory
先获取S3对象实际大小,再创建对应容量的SharedMemory,避免空间不足:
import boto3 from multiprocessing import shared_memory s3_client = boto3.client('s3') bucket_name = 'my_bucket' object_key = 'path/to/obj' # 获取S3对象的实际大小 obj_info = s3_client.head_object(Bucket=bucket_name, Key=object_key) obj_size = obj_info['ContentLength'] # 创建对应大小的SharedMemory mem = shared_memory.SharedMemory(create=True, size=obj_size) # 读取对象内容并写入SharedMemory response = s3_client.get_object(Bucket=bucket_name, Key=object_key) data = response['Body'].read() mem.buf[:obj_size] = data
方法2:限制读取长度适配已有SharedMemory
如果需要固定大小的SharedMemory,读取时限制字节长度到SharedMemory容量,避免超出:
import boto3 from multiprocessing import shared_memory MB = 100 mem_size = MB * 2**20 mem = shared_memory.SharedMemory(create=True, size=mem_size) s3_client = boto3.client('s3') response = s3_client.get_object(Bucket='my_bucket', Key='path/to/obj') # 读取不超过SharedMemory容量的字节数据 data = response['Body'].read(mem_size) # 将数据写入SharedMemory的对应长度切片 mem.buf[:len(data)] = data
注意事项
- 写入完成后,需在所有进程使用完SharedMemory后调用
mem.close()和mem.unlink()释放资源。 - 如果S3对象过大,超出系统可用SharedMemory资源,建议分块读取写入,避免内存溢出。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

