2017-10-17 51 views
0

現在、1つのプロジェクトに対してGoogle Cloud SpannerをMySQLの代替としてテスト中です。時間が経つにつれて行の数が数億に増加すると予想しています。 DBは非常に高速に応答し、数秒でクエリ結果を返す必要があるため、私はSpannerに試してみると思いました。私は私のスパナDBへのバルク・ロードのサンプルデータに試してみましたGoogle Cloud Spannerの一括挿入中の一時的な例外の例外

は、しかし、私はこのエラーを取得しておいてください。

Unhandled Exception: System.AggregateException: One or more errors occurred. ---> Google.Cloud.Spanner.Data.SpannerException: The operation was aborted. ---> Grpc.Core.RpcException: Status(StatusCode=Aborted, Detail="Aborted due to transient fault")

私はここからslighly変更されたコードを使用しています:ここでhttps://github.com/GoogleCloudPlatform/dotnet-docs-samples/blob/master/spanner/api/Program.cs

は、コード変更でありますInsertSampleDataに:

public static object InsertSampleData(string projectId, 
     string instanceId, string databaseId) 
    { 
     // I get about 100k rows here 
     List<Data> data = get_data(); 

     // how many runs I need to make if I split the data by 100 rows 
     int rows = 100; 
     double cnt = (double)data.Count/rows; 
     cnt = Math.Ceiling(cnt); 

     // process the data part by part 
     for (int i = 0; i < cnt; i++) 
     { 
      // returns part of the data based on offset and amount 
      List<Data> data_part = get_part(data, i, rows); 

      var response = InsertTradesAsync(
      projectId, instanceId, databaseId, data_part); 
      s_logger.Info("Waiting for operation to complete..."); 
      response.Wait(); 
      s_logger.Info($"Operation status: {response.Status}"); 
     } 

     return ExitCode.Success; 
    } 

InsertTradesAsync(当然のパラメータリストを除く)レポと同じです。

私は、私は常に、次のエラーが出るのコードを実行します。

Unhandled Exception: System.AggregateException: One or more errors occurred. ---> Google.Cloud.Spanner.Data.SpannerException: The operation was aborted. ---> Grpc.Core.RpcException: Status(StatusCode=Aborted, Detail="Aborted due to transient fault") 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) 
    at Google.Api.Gax.Grpc.ApiCallRetryExtensions.<>c__DisplayClass0_0`2.<<WithRetry>b__0>d.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Google.Cloud.Spanner.V1.Internal.ExecuteHelper.<WithSessionChecking>d__0`1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Google.Cloud.Spanner.V1.TransactionPool.<RunFinalMethodAsync>d__9`1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Google.Cloud.Spanner.Data.SpannerTransaction.<<CommitAsync>b__29_0>d.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Google.Cloud.Spanner.Data.ExecuteHelper.<WithErrorTranslationAndProfiling>d__2`1.MoveNext() 
    --- End of inner exception stack trace --- 
    at Google.Cloud.Spanner.Data.ExecuteHelper.<WithErrorTranslationAndProfiling>d__2`1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Google.Cloud.Spanner.Data.EphemeralTransaction.<>c__DisplayClass2_0.<<ExecuteMutationsAsync>b__1>d.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Google.Cloud.Spanner.Data.ExecuteHelper.<WithErrorTranslationAndProfiling>d__2`1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Google.Cloud.Spanner.Data.SpannerCommand.<ExecuteMutationsAsync>d__49.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at GoogleCloudSamples.Spanner.Program.<InsertTradesAsync>d__25.MoveNext() in c:\Users\user\Documents\Dev\spanner\api\Program.cs:line 1298 
    --- End of inner exception stack trace --- 
    at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) 
    at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) 
    at System.Threading.Tasks.Task.Wait() 
    at GoogleCloudSamples.Spanner.Program.InsertSampleData(String projectId, String instanceId, String databaseId) in c:\Users\user\Documents\Dev\spanner\api\Program.cs:line 1585 
    at GoogleCloudSamples.Spanner.Program.<>c__DisplayClass45_0.<Main>b__2(InsertSampleDataOptions opts) in c:\Users\user\Documents\Dev\spanner\api\Program.cs:line 1932 
    at CommandLine.ParserResultExtensions.MapResult[T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult](ParserResult`1 result, Func`2 parsedFunc1, Func`2 parsedFunc2, Func`2 parsedFunc3, Func`2 parsedFunc4, Func`2 parsedFunc5, Func`2 parsedFunc6, Func`2 parsedFunc7, Func`2 parsedFunc8, Func`2 parsedFunc9, Func`2 parsedFunc10, Func`2 parsedFunc11, Func`2 parsedFunc12, Func`2 parsedFunc13, Func`2 parsedFunc14, Func`2 parsedFunc15, Func`2 parsedFunc16, Func`2 notParsedFunc) 
    at GoogleCloudSamples.Spanner.Program.Main(String[] args) in c:\Users\user\Documents\Dev\spanner\api\Program.cs:line 1910 

を、私は、行の異なる量が中に挿入した後ただし、例外がスローされ、これは制限とクォータ(https://cloud.google.com/spanner/quotas)に関連するかもしれないと思ったが私のテーブル(それは無作為であるように見えますが、時々68行が100行ずつ、その後28x100、52x100などで実行されます)。テーブルには30列とPKが2列(インデックスなし)で構成されており、データを100ずつ処理していますので、限界に達しているとは思われません。

私がcmd.CommandTimeoutを非常に高い数値に設定すると、挿入された行(約400x100)がかなり上がります。クライアントライブラリが接続を再利用していると仮定します。しかし、私はそれに関する情報やC#ライブラリのためのpooolingを見つけることができませんでした。さらに多くの行が挿入されても、エラーは引き続き発生します。

ご協力いただければ幸いです。

ありがとうございます!

答えて

0

Googleデベロッパーはこちら。 私はあなたに役立ついくつかの提案があります。

最初に、1つのトランザクションを使用して、できるだけ多くの書き込みを追加する必要があります。一度に100を行うように見えますか?しかし、あなたはもっとやることができます。第二の提案は、直接あなたの質問に対処し

https://github.com/GoogleCloudPlatform/dotnet-docs-samples/blob/master/spanner/api/Program.cs#L1242

:あなたはここにバッチ処理することができますどのように多くの書き込みの限界を(私はそれが20,000だと信じて)見ることができます。 、あなたはここで例に示すように、あなたの取引の周りに再試行を使用する必要がどのようにスパナの作品のため:

https://github.com/GoogleCloudPlatform/dotnet-docs-samples/blob/master/spanner/api/Program.cs#L1259

(ここでは、過渡障害アプリケーションnugetをダウンロードしてください): https://www.nuget.org/packages/EnterpriseLibrary.TransientFaultHandling/

あなたはこのために必要スパナが時々デッドロックを経験することがあります。デッドロックが発生すると、トランザクション全体が再実行されます。私たちは、それが簡単のように、あなたの再試行ポリシーを構築できるようにする例外の拡張メソッド「IsTransientSpannerFault」を提供:

internal class CustomTransientErrorDetectionStrategy 
     : ITransientErrorDetectionStrategy 
    { 
     public bool IsTransient(Exception ex) => 
      ex.IsTransientSpannerFault(); 
    } 

・ホープ、このことができます!

EDIT:InsertTradesAsyncへの非同期呼び出しの結果を待っていないことに気付きました。あなたは少なくとも最後にTask.WaitAllをしたいと思うかもしれません。 100回の書き込みの各バッチは、前のバッチと並行してバックグラウンドで実行されていることに注意してください。これは、再試行を強制するデッドロックの可能性を増やしている可能性が最も高いです。

あなたはパフォーマンスを向上させる目的でこれをやっている場合は、舞台裏でプール内のスパナADO.NETライブラリますオープン複数の接続はSpannerConnection.SpannerOptions.MaximumGrpcChannelsに等しいです。だから、あなたは一点までの利益を見るでしょう。この値を大きくすると、パフォーマンスを調整できます。

について

+0

ありがとう、とても助かりました。これで、最後まで正確に実行されます。タスクはまだ私にとってはかなり新しいですが、私は結果を待っていると信じています - 応答で。待ってください。 –

+0

あなたは正しいです。私は完全にそれを逃した!あなたは通常、非同期でダウンしたいと思っています。したがって、若干優れた実装は次のようになります。 public static asyncタスク InsertSampleData(string projectId、 string instanceId、string databaseId) { 。 。 。 (int i = 0; i

関連する問題