雲計算

性能調優-python SDK 調優

python SDK

python 和 java 或者和 GO ,在性能上來說都不是最好的,而且 python 無法支持多核的併發,只能跑在單核上的多線程。但是 oss 也提供了相應的方法提高多線程的文件吞吐;

初始化

在初始化時 python 有兩個地方可以做調整

connect_timeout

可以增大客戶端在數據讀寫過程中的超時時間,常用在客戶端到 OSS 公網情況下上傳大文件時增長時間,防止在公網抖動或者丟包情況下出現傳輸超時;

# -*- coding: utf-8 -*-
import oss2

# 阿里雲主賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM賬號進行API訪問或日常運維,請登錄RAM控制檯創建RAM賬號。
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# Endpoint以杭州為例,其它Region請按實際情況填寫。
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'

# 設置連接超時時間為30秒。
bucket = oss2.Bucket(auth, endpoint, '<yourBucketName>', connect_timeout=30)
                    

防劫持

OSS 服務端默認支持了泛域名的證書,客戶可以用 https 協議傳輸方式出現被劫持的情況

# -*- coding: utf-8 -*-
import oss2

# 阿里雲主賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM賬號進行API訪問或日常運維,請登錄RAM控制檯創建RAM賬號。
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# Endpoint以杭州為例,其它Region請按實際情況填寫。將 http 改為 https 就是走 https 加密
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'

bucket = oss2.Bucket(auth, endpoint, '<yourBucketName>')
                    

性能調優

enable_crc

crc 的作用是校驗客戶端的文件完整性,文件越大對 cpu 計算消耗越高,上傳時間成本越高,所以一般都建議用戶端,關閉 crc 提高傳輸效率,使用 Content-Md5 的方式替代 crc64

# -*- coding: utf-8 -*-
import oss2

# 阿里雲主賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM賬號進行API訪問或日常運維,請登錄RAM控制檯創建RAM賬號。
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# Endpoint以杭州為例,其它Region請按實際情況填寫。
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'

bucket = oss2.Bucket(auth, endpoint, '<yourBucketName>', enable_crc=False)

日誌開關

OSS 的日誌採用 logging 模塊採集。通過 ossclient 初始化時 set logging 的開關和存放位置;
但是記錄日誌的同時會影響 SDK 上傳性能,一般不建議用戶開啟,排查問題時採用到;
平常客戶只要記錄 requestID 或者 OSS返回的 header 頭就足夠了;

# -*- coding: utf-8 -*-

import os
import logging
import oss2
from itertools import islice

# 初始化AccessKeyId、AccessKeySecret、Endpoint等信息。
# 請將<AccessKeyId>、<AccessKeySecret>、<Bucket>及<訪問域名>分別替換成對應的具體信息。
access_key_id = '<AccessKeyId>'
access_key_secret = '<AccessKeySecret>'
bucket_name = '<Bucket>'
endpoint = '<訪問域名>'

log_file_path = "log.log"
# 開啟日誌
oss2.set_file_logger(log_file_path, 'oss2', logging.INFO)

# 創建Bucket對象。
bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)

# 遍歷文件目錄
for b in islice(oss2.ObjectIterator(bucket), 10):
   print(b.key)
# 獲取文件元信息
object_meta = bucket.get_object_meta('object')

分片上傳下載

python SDK 在 分片的基礎上增加了斷點傳輸,既可以在分片基礎上增加併發,也支持斷點記錄的功能,在遇到網絡問題斷開時不需要每次從文件開始重傳,從記錄斷點的位置繼續傳輸;

分片大小建議
100M,1M 分片
1000M , 10M 分片
10G , 100M 分片
100G, 1G 分片
....

image.png

斷點上傳

# -*- coding: utf-8 -*-
import oss2
# 阿里雲主賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM賬號進行API訪問或日常運維,請登錄 https://ram.console.aliyun.com 創建RAM賬號。
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# Endpoint以杭州為例,其它Region請按實際情況填寫。
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
# 當文件長度大於或等於可選參數multipart_threshold(默認值為10MB)時,會使用分片上傳。如未使用參數store指定目錄,則會在HOME目錄下建立.py-oss-upload目錄來保存斷點信息。
oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>')

# 如使用store指定了目錄,則保存斷點信息在指定目錄中。如使用num_threads設置上傳併發數,請將oss2.defaults.connection_pool_size設成大於或等於線程數。默認線程數為1。
oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>',
    store=oss2.ResumableStore(root='/tmp'),
    multipart_threshold=100*1024,
    part_size=100*1024,
    num_threads=4)

斷點下載

# -*- coding: utf-8 -*-
import oss2

# 阿里雲主賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM賬號進行API訪問或日常運維,請登錄 https://ram.console.aliyun.com 創建RAM賬號。
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# Endpoint以杭州為例,其它Region請按實際情況填寫。
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')

# 請將oss2.defaults.connection_pool_size設成大於或等於線程數,並將part_size參數設成大於或等於oss2.defaults.multiget_part_size。
oss2.resumable_download(bucket, '<yourObjectName>', '<yourLocalFile>',
  store=oss2.ResumableDownloadStore(root='/tmp'),
  multiget_threshold=20*1024*1024,
  part_size=10*1024*1024,
  num_threads=3)

ending

如果發現上述方法都試過,但是吞吐率還是上不去,可以用 iftop 命令問題下,並且同時跑多個程序多進程運行將網絡帶寬打滿;
如果多進程也打不滿,那就要查自己的機器帶寬是否限制了上行流量,或者自己機器帶寬被打滿;

Leave a Reply

Your email address will not be published. Required fields are marked *