[英]Too much time difference between receiving response from server and writing it into log while reading file from Google Cloud Storage using HttpClient
我需要從GCS下載多個文件。 為此,我使用了代碼
public class GCSStorage
{
static HttpClient httpClient;
static GoogleCredential credential = GoogleCredential.FromFile(ConfigurationManager.AppSettings["GCPCredentials"]);
if (credential.IsCreateScopedRequired)
{
credential = credential.CreateScoped(new[]
{
"https://www.googleapis.com/auth/devstorage.read_only"
});
httpClient = new Google.Apis.Http.HttpClientFactory()
.CreateHttpClient(
new Google.Apis.Http.CreateHttpClientArgs()
{
ApplicationName = "",
GZipEnabled = true,
Initializers = { credential },
});
httpClient.Timeout = new TimeSpan(0, 0, 5);
}
public string ReadObjectData(string bucketName, string location)
{
string responseBody = "";
bool isFetched = false;
try
{
Stopwatch sw = new Stopwatch();
string pathcode = System.Web.HttpUtility.UrlEncode(location);
UriBuilder uri = new UriBuilder(string.Format(googleStorageApi, bucketName, pathcode));
sw.Start();
var httpResponseMessage = httpClient.GetAsync(uri.Uri).Result;
var t = sw.ElapsedMilliseconds;
if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
{
responseBody = httpResponseMessage.Content.ReadAsStringAsync().Result;
log.Info($"Read file from location : {location} in Get() time : {t} ms , ReadAsString time : {sw.ElapsedMilliseconds - t} ms, Total time : {sw.ElapsedMilliseconds} ms");
}
isFetched = true;
}
catch (Exception ex)
{
throw ex;
}
return responseBody;
}
}
並使用多個文件
GCSStorage gcs = new GCSStorage();
ParallelOptions option = new ParallelOptions { MaxDegreeOfParallelism = options };
Parallel.ForEach(myFiles, option, ri =>
{
text = gcs.ReadObjectData(bucket, ri); ;
});
我正在記錄每個單獨文件在ReadObjectData()中花費的時間。 當我使用MaxDegreeOfParallelism作為1下載文件時,每個文件的下載時間約為100-150ms。 但是,當我將MaxDegreeOfParallelism更改為50時,時間在1-3秒之間變化。 我正在下載一堆50個文件。
我不知道為什么會這樣。 誰能幫助我了解這種行為。
另外,我嘗試使用Amazon S3進行相同操作。 在兩種情況下,S3都會提供50-100ms的恆定下載時間。
我使用提琴手分析了GCS響應。 對於耗時(〜> 200ms)的請求,“ 總體經過時間”約為100-200 ms,但是寫入日志的時間要高得多。 對於其他人來說,恰恰是在同一時間。 為什么某些請求的時間會有那么多的時間差?
提琴手統計
Request Count: 1
Bytes Sent: 439 (headers:439; body:0)
Bytes Received: 7,759 (headers:609; body:7,150)
ACTUAL PERFORMANCE
--------------
ClientConnected: 18:03:35.137
ClientBeginRequest: 18:04:13.606
GotRequestHeaders: 18:04:13.606
ClientDoneRequest: 18:04:13.606
Determine Gateway: 0ms
DNS Lookup: 0ms
TCP/IP Connect: 0ms
HTTPS Handshake: 0ms
ServerConnected: 18:03:35.152
FiddlerBeginRequest: 18:04:13.606
ServerGotRequest: 18:04:13.606
ServerBeginResponse: 18:04:13.700
GotResponseHeaders: 18:04:13.700
ServerDoneResponse: 18:04:13.700
ClientBeginResponse: 18:04:13.700
ClientDoneResponse: 18:04:13.700
Overall Elapsed: 0:00:00.093
日志文件
INFO 2018-08-25 18:04:13,606 41781ms GCSStorage ReadObjectData - Get() time : 114 ms
INFO 2018-08-25 18:04:14,512 42688ms GCSStorage ReadObjectData - Get() time : 902 ms
我可以看到
LogTime - ClientDoneResponse + Overall Elapsed is approximately equal to Total Time
18:04:14.512 - 18:04:13.700 + 0:00:00.093 = 905 ms
為什么從接收到服務器的響應並將其寫入日志會有這么多的時差b / w?
在進行並行編程時,在使用多個線程時,需要牢記一些注意事項。 首先,並行確實可以提高性能,但並不是說無限並行比順序更好。 這件事情是由很多原因導致的。 一是您受到物理核心數量以及操作系統中超線程的限制。 例如,如果您有8個核心,則使用8個線程可獲得最佳性能,如果還激活了超線程,則可能只有16個線程才具有良好的性能。
在您的示例中,將線程數從1更改為50太多了。 以第2、4、6、8、10步進行嘗試,看看何時獲得最佳性能(記錄到目前為止的時間)。
然后,該數字很可能是您的並行性的最佳數字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.