2017-04-13 42 views
1

私はData Lake Storeからファイルを読み込むためにDataLakeStoreFileSystemManagementClientクラスを使用します。このようなコードでファイルを開くと、それをバイト単位で読み込んで処理します。データ処理にU-SQLを使用できない場合があります。Azure Data Lake Store - 既存の接続はリモートホストによって強制的に閉じられました

m_adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(…); 
return m_adlsFileSystemClient.FileSystem.OpenAsync(m_connection.AccountName, path); 

このプロセスは、ファイルの読み取りと処理に最大60分かかります。 問題は次のとおりです。ストリームの読み取り処理中に「リモートホストによって強制的に既存の接続が強制終了されました」という例外が頻繁に発生しています。特に読書に20分以上かかる場合。私は正しいクライアントタイムアウト設定でDataLakeStoreFileSystemManagementClientを作成するので、タイムアウトではありません。以下に例外の詳細があります。例外は無作為に見えるので、いつ取得するのか予測するのは難しいです。処理時間の15分と50分になります。

Data Lake Storeからファイルを読み取るのは通常の状況ですか?データレイクストアのファイルをオープンストリームにしておく時間の制限(または推奨)はありますか?

例外:

System.AggregateException: One or more errors occurred. - 
--> System.IO.IOException: Unable to read data from the transport connection: An 
existing connection was forcibly closed by the remote host. ---> System.Net.Soc 
kets.SocketException: An existing connection was forcibly closed by the remote h 
ost 
    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, 
SocketFlags socketFlags) 
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s 
ize) 
    --- End of inner exception stack trace --- 
    at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) 
    at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.Read(Byte[] bu 
ffer, Int32 offset, Int32 count) 
    at System.Net.Http.DelegatingStream.Read(Byte[] buffer, Int32 offset, Int32 c 
ount) 
    at DataLake.Timeout.Research.FileDownloader.CopyStream(Stream input, Stream o 
utput) in C:\TFS-SED\Main\Platform\DataNode\DataLake\DataLake.Timeout.Research\F 
ileDownloader.cs:line 107 
    at DataLake.Timeout.Research.FileDownloader.<DownloadFileAsync>d__6.MoveNext(
) in C:\TFS-SED\Main\Platform\DataNode\DataLake\DataLake.Timeout.Research\FileDo 
wnloader.cs:line 96 

答えて

3

は、この種の問題を回避するためには、以下が推奨されます:

  • 読む小さく、再試行塊で。私の経験では、 の4MBのチャンクが最高のパフォーマンスを発揮することがわかりました。さらに、 を少しずつ増分して読み取ることで、失敗した場合に同じ再試行を再試行するロジックに を組み込むことができます。あなたのストリームがどのように大きなわからない場合は

、あなたはのペイロードでのRemoteExceptionと400エラーの を確認することができます(例えば、それはあなたが読んでいる間に、別の作業者に追加され です) "BadOffsetException"。これは、ファイルの末尾を超えたオフセットである で開始したことを示します。

const int MAX_BYTES_TO_READ = 4 * 1024 * 1024; //4MB 
… 
long offset = 0; 
while(notDone) 
{ 
try 
{ 
       var myStream = client.Read(accountName, offset, MAX_BYTES_TO_READ) 
       // do stuff with stream 
} 
catch(WebException ex) 
{ 
       // read the web exception response 
       If (response.contains(“BadOffsetException”)) 
           noteDone = false; 
} 
} 
0

ありがとうございました。あなたの助言がついに私を助けました。 これは私のバージョンです。サンプルは、リトライロジックを使用してバイトのバッチを読み取ります。私は4MBのバッファを持つBufferedSteamで使用しています。したがって、クライアントはストリームオブジェクトをオブジェクトで読み取ることができますが、4MBのバッチでサービスを要求します。

while (!m_endOfFile) 
{ 
    try 
    { 
     var inputStream = m_client.OpenReadFile(
      m_filePath, 
      length: count, 
      offset: m_position); 

      var memoryStream = new MemoryStream(count); 
      inputStream.CopyTo(memoryStream); 
      m_position += memoryStream.Length; 
      result = memoryStream.ToArray(); 
      break; 
    } 
    catch (CloudException ex) 
    { 
     if (ex.Response.Content.ToString().Contains("Invalid offset value")) 
     { 
      m_endOfFile = true; 
     } 
     else 
     { 
      throw; 
     } 
     } 
    catch (IOException) 
    { 
     repeats++; 
     if (repeats >= RepeatCount) 
     { 
      throw; 
     } 
    } 
} 
関連する問題