Azure DataFactory Tips タイムスライスの再実行

Microsoft Azure Advent Calendar 2016 3日目として書きました。

Azure DataFactory(以下ADF)は、データの移動や変換を自動化するクラウドベースのデータインテグレーションサービスです。 ADFには、コピーアクティビティとデータ変換アクティビティの2種類があります。このうちコピーアクティビティは、単純なETLツールで優れたパフォーマンスとリーズナブルな価格で魅力的なサービスです。個人的にはコピーアクティビティはシンプルでなかなかよく出来ており、お気にいりました。データ変換アクティビティはクラスタを上げて変換処理をするのが利点でもあり難点でもあるって感じですね。

今回は、スクリプトからのエラーリカバリ、タイムスライスの再実行について記述します。ADFでは実行はタイムスライス単位で行われデータソースの問題で複数のタイムスライスが失敗した時などエラーの数が多くなり勝ちです。エラーが多くなるとポータルの画面から再実行をするのはポチポチが多くなってとても面倒になります。そんな時にはということで、Azure PowerShell から、失敗したタイムスライスを再実行してみます。

参照: この記事の基本は概ね、Azure Data Factory のパイプラインの監視と管理に書いてありますので、そちらもどうぞ。

原因究明

まずは、エラーの原因を確認します。エラーが大量に出ていると面倒なので、下記のようなスクリプトでエラーメッセージでサマります。やっていることは、 ログのsort | uniq -cです。

エラーの確認を実行

下記の様に実行すると、DatasetName, ErrorMessage でサマった数が表示されます。下記の例だとエラーメッセージが長過ぎて最後まで見れませんが、コマンド行に、| Out-String -Width 4096[1]を追加すると最後まで表示されます。(幅は随時変更してください)

$ .\adferror1.ps1 -ResourceGroupName "TestADF01" -DataFactoryName "APITutorial" -StartDateTime 2016-08-09T10:00:00 -EndDateTime 2016-08-09T11:00:00

Count DatasetName                ErrorMessage
----- -----------                ------------
    7 DatasetAzureSqlDestination Copy activity encountered a user error at Sink:tcp:kinmugisql01.database.windows.net,1433 s...

簡単にスクリプトの説明をします。Get-AzureRmDataFactorySlice でエラーになっているタイムスライスを取得して Get-AzureRmDataFactoryRun で、そのタイムスライスの詳細な情報を取得し、最後にエラーメッセージでグルーピングしてカウントしています。

再実行

これでエラーが分かるので問題を修正して、再実行します。

Azure DataFactoryのタイムスライスの再実行には、スライスの状態遷移を理解しなければなりません。そんなに複雑なことは無く、タイムスライスの状態遷移図は下記のようになっており、再実行は、Failed 状態から Waiting に変更することで行います。

https://docs.microsoft.com/ja-jp/azure/data-factory/media/data-factory-monitor-manage-pipelines/state-diagram.png

問題の修正が完了したら、下記のスクリプトで、失敗したタイムスライスを再実行します、スクリプトでは失敗したタイムスライスを古いものから順にWaitingにするだけです。タイムスライス毎に設定をしているので、pipelineで指定したバックフィルの順序が反映されません。タイムスライス間に依存関係がある場合は問題が出るかもしれませんので注意してください。

実行には、上記で確認したエラーになったデータセットを指定します。再実行になったタイムスライスを表示します。

$ .\\adfrerun.ps1 -ResourceGroupName "TestADF01" -DataFactoryName "APITutorial" -DatasetName "DatasetAzureSqlDestination" -StartDateTime 2016-08-09T10:00:00 -EndDateTime 2016-08-09T11:00:00

DatasetName                Start
-----------                -----
DatasetAzureSqlDestination 2016/08/09 9:00:00
DatasetAzureSqlDestination 2016/08/09 10:00:00
DatasetAzureSqlDestination 2016/08/09 11:00:00
DatasetAzureSqlDestination 2016/08/09 22:00:00
DatasetAzureSqlDestination 2016/08/09 23:00:00

下記のようなコマンドで、タイムスライスの状態を確認することができます。ここでは、Ready以外を表示しています。

$ Get-AzureRmDataFactorySlice -ResourceGroupName "TestADF01" -DataFactoryName "APITutorial" -DatasetName "DatasetAzureSqlDestination" -StartDateTime 2016-08-09T10:00:00 -EndDateTime 2016-08-09T11:00:00 | ? {$_.State -ne 'Ready'}

最後に

Azure PowerShellを使っていると、PowerShellのオブジェクトパイプランが強力さを肌で感じます。パイプで繋いで、%, ?とやるのが気に入ってしまいました。

今回ちょっと分かり辛らかったのは、 タイムスライスを返すGet-AzureRmDataFactorySliceと タイムスライス の実行結果を返すGet-AzureRmDataFactoryRunの関係でした。最初Get-AzureRmDataFactoryRunがデータセットの実行結果を取得するのかと勘違いしていたこともあり、どのようなパラメータを渡せば良いのかが分からず… このコマンドが、タイムスライスの実行結果を返すもので、タイムスライス(slice)のIDとして開始時間を渡すということに大分時間を無駄にしました。後で、マニュアル[2]見たらちゃんと書いてあったんですが、、、、

`Set-AzureRmDataFactorySliceStatus <>`_は、期間を渡せるので、個々のタイムスライスを指定するのではなく。期間をわたしてざっくり再実行でも良いかもしれません。その場合は、エラーになったタイムスライスを探して、その周辺の時間帯をざっくり再実行って感じですかね。それはそれで、実用性は高そうな気がしてきました。

締めは、Azure DataFactory はいいぞ!ということで。

脚注

[1]poshのデフォルトではコンソール出力はコンソールバッファーの幅で省略されます。この仕様は余計なお世話な気がします。そのまま出してくれれば良いのに。
[2]Get-AzureRmDataFactoryRun

.NET Fringe Japan 2016

まさかの .NET じゃない話」を、.NET Fringe Japan 2016で話してきました。 「Partitionの話とか、なかなか聞けないので面白かったです」 と言っていただけるのは有難いです。

.NET Fringe なのに、.NET 成分、OSS成分ゼロで良いのかとは迷ったのですが、快く背中を押してもらい、Azure Storageの話をすることにしました。

Azure Storageは内部構造が公開されているのにも関わらず、日本ではその構造もあまり議論されることも無く、自分でも中に溜めているだけでなかなか外で話す機会も無いという状況で、。少々もったいない気がしていたので話が出来たのは良い機会でした。

最初は、Storageを構成する3層を全部話そうとしたのですが、細部に立ち入らないと面白い話にならず、細部に入ると話が長くなり全然時間に入らず。結局、一番面白そうなパーテーション周りにフォーカスして話しました。背景的な話や、他のレイヤーの話を飛ばして話したので少々わかり辛らかったかもしれません。

シャーディングをサポートしているシステムは世の中に諸々ありますが、負荷に応じてパーテーションマップを変更しロードバランシングするシステムで上手く動いている例は多くはなく、実装例として面白いのでは無いかと思います。今回は、話の焦点をパーテーションマップを動的に負荷に応じてどう構成するか、そのときに実データの移動を伴わない実装になっているかという当たりが一番盛り上がるところだったのですが、うまく説明するのはなかなか難しく資料の作成に苦心しました。

分割(パーテーショニング)が避けられなった時、一実装例として参考になればと思います。

.NET Fringe Japan 2016 資料です。「Azure Storage Partition Internals」

2016 Microsoft MVP Award を受賞しました

2016年7月期、Microsoft Azure のカテゴリで、Microsoft MVP Award を受賞しました。

今後も、最近 Service Fabric に偏り気味ですが、Cloud Scale なサービス構築をテーマに情報発信をして行きたいと思います。

これからも、よろしくお願いいたします。

Reliable Collection の Lock の挙動

先日、5/18 に、第1回Jazug Tokyo Nightで、Azure Fabric Service の Reliable Collection 話をしました。Global Azure Boot Camp 2016 in Japanでも話をしたのですが、1時間ぐらいだと概要も話し切れない感じでなかなか厳しい。4回ぐらいに分けても少し深いところ(そんなにDeepじゃないですが)をしたいなぁと思っていたところ、ちょうど良い機会が出来たので、早速時間を貰うことにしました。

今回は、その時の補足です。まずは、その時の資料です。Lock compatibility matrixの部分を更新しました

Azure Fabric Service Reliable Collection

勉強会の時に、下記の Lock compatibility matrix の赤枠の部分だけ、SQL Serverと違うという話をしました。「もしかしたら、ドキュメントが間違っているのかも」というようなことをその場では言いましたが、どきょメントが間違っているわけではなく、そこはSQL Serverと動きが違うとのことでした。そのあたりの話を説明します。(公式ドキュメントでは無いので、参考程度で)

Lock compatibility matrix

Lock compatibility matrix

Reliable Collectionは、書込に最適化されていおり、matxi の赤枠の部分が、G(U)/R(S)時の動きが SQL Server とは異なっています。また、Reliable Collection では、update lockの期間は短くほとんどの場合、exclusive に昇格して終わることを前提としています。設計思想が違うという話のようです。

下図のような場合で動作を説明します。

tnx and lock
  • 上が、Reliable Collection,下がSQL Server
  • 横軸が時間で、それぞれ、2つのtransactionがある
  • 黄色線が、tnxid 2 が、shard lock を要求したタイミング

TxnId1が、update lockを掛けている時、TxnId2がShard Lockを要求した場合(垂直黄線)、Reliable CollectionではUpdate Lock が、Exclusive Lock になって更新が終わりlockが開放されるまでshard lockは待機します。それに対して、SQL Serverでは、即時にshard lockは成功します。全てのshard lockが開放されてから、exclusive lock ->更新という処理に流れになります。この違いはなかなか面白いですね。

最後に

Reliable Collection は結構手堅くしっかり作っている感じを受けます。この手のものがあると、Data Localityを健全に保てるのでレイテンシー上は非常に有利になります、いいですね。

「上記2つに更に .NET の ReaderWriterLockSlim と、Jeffrey Richter の OneManyLock を入れて、永続化の有無がどう影響するのか考察したら面白いのかな?」と一瞬思ったのですが、今回はこの辺で。勉強会の前に明確にしておけば良かったのですが、ちょっと見逃してました。でも、SQL Serverと違って、lock やwait の状態が見えないのがちょっと不便ですね。これだと、ラッシュテストしないとデッドロックとかわからないです。

BUILD/2016 Azure Cool Storage

BUILD 2016B816 Learn How to Store and Serve PBs of Object Data with Azure Block BlobsCool Storageという、とても興味深い新機能が発表されていました。Build 2016: Azure Storage announcementsに入ってなくて、見落としそうになります…

Cool Storage

Cool Storageは、アクセス頻度の低いデータを安価に保存するための新機能で、Block Blob でサポートされます。

これで、Block Blob は、2の tier に別れます。

  1. Hot - 通常利用のデータ向け (従来のBlob)
  2. Cool - あまりアクセスしないデータ向け (あたらしいやつ)

概要

  • APIは、100% 互換で、同様のスループットとレイテンシーを実現(Coolでも性能が同じなのは設計しやすくなるので有り難いことです)
  • LRS, GRS, RA-GRSの信頼性オプションを提供( 同じですね)
  • 可用性は、Coolが 99% で、Hot が 99.9%(ちょっと、Coolが低くなります)

お値段関係

Hotは、頻繁に使った場合に費用が抑えられ、Coolは、容量が大きい場合に安くなるという価格体系で構成されるようです。話の中ではちょっとはっきりしませんでしたが、トランザクションコストやデータ転送コストで差を付けるという感じなのかもしれません。

HotからCoolへの切替もできるようなので、履歴系のデータを保存するにはとても便利な気がします。next few weeks で、public preview に入るそうです。楽しみですね。

この話は、動画では、33分、パワポの資料では、30p 当たりで話が出来てますので、興味のある方はぜひ、chanel 9 をご覧ください。[1]

最後に

どうも、AWS の S3 Standard-IA とか、Google Nearline あたりと同じような領域をカバーするサービスのようです。S3 Standard-IA は、Google Nearline とは違って、レスポンスタイムが通常のBlob並ってところは良い感じです。価格の詳しい条件がわからないので、現時点でS3との比較は難しいですが、Cool Storageは、Hot/Coolの切替がアカウント単離っぽいので、実データのコピーは必要無さそうで、そのあたりで差がでてくるのでは無いかと言う気がします。

今回の、BUILDでは、 Server Siide Encription[2]も発表されて、Storage Team に活気を感じました。これからが、楽しみです。