boto3低级客户端对S3线程安全吗?文档没有明确说明。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#client
在Github中讨论了类似的问题
https://github.com/boto/botocore/issues/1246
但是维护者仍然没有答案。
答案 0 :(得分:6)
如果您查看boto3的Multithreading/Processing文档,您会发现他们建议每个会话一个客户端,因为实例之间存在共享数据,这些数据可以由各个线程进行更改。
对于这个确切的问题,似乎还有一个开放的github问题。 https://github.com/boto/botocore/issues/1246
答案 1 :(得分:2)
我最近尝试使用concurrent.futures.ThreadPoolExecutor
使用单个boto客户端实例。我遇到了来自boto的异常。我认为在这种情况下,boto客户端不是线程安全的。
我遇到的异常
File "xxx/python3.7/site-packages/boto3/session.py", line 263, in client
aws_session_token=aws_session_token, config=config)
File "xxx/python3.7/site-packages/botocore/session.py", line 827, in create_client
endpoint_resolver = self._get_internal_component('endpoint_resolver')
File "xxx/python3.7/site-packages/botocore/session.py", line 694, in _get_internal_component
return self._internal_components.get_component(name)
File "xxx/python3.7/site-packages/botocore/session.py", line 906, in get_component
del self._deferred[name]
答案 2 :(得分:2)
低级客户端是线程安全的。使用低级客户端时,建议实例化客户端,然后将该客户端对象传递给每个线程。
实例是安全的,客户端的实例不是线程安全的。为了使事情在多线程环境中工作,请将实例化放在如下所示的全局Lock中:
boto3_client_lock = threading.Lock()
def create_client():
with boto3_client_lock:
return boto3.client('s3', aws_access_key_id='your key id', aws_secret_access_key='your access key')
答案 3 :(得分:0)
您可以成功创建多个线程,但是必须为每个线程/进程实例化一个新会话,从而可以从例如S3存储桶异步下载。
以下示例:
import concurrent.futures
import boto3
import json
files = ["path-to-file.json", "path-to-file2.json"]
def download_from_s3(file_path):
# setup a new session
sess = boto3.session.Session()
client = sess.client("s3")
# download a file
obj = client.get_object(Bucket="<your-bucket>", Key=file_path)
resp = json.loads(obj["Body"].read())
return resp
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.map(download_from_s3, files)