Azure に OAuth 2.0 Device Flow でログインする

この前az loginでログイン出来なくなった時に、azure cli 2.0 のコードを見ていたら、Azureのドキュメントには出てこない(見慣れない)使い方をしてたので確認も兼ねて生REST、OAuth 2.0 Device Flow[1]でAzrueにloginして Beare Tokenを取得するコンソールプログラムazlogin[2]を書いてみた。

curry

使い方

azloginを実行すると、azure cli 2.0 と同じように、デバイスコードと入力用のURLが表示される。この画面のメッセージがazure cli 2.0と一文一句違わず同じなのは、AIPが返して来るメッセージをそのまま表示してるからだ。

ログインに成功すると、アカウントに紐づいたテナントを全部取得して、テナントのアクセストークンを取得し、それを使ってサブスクリプションの情報を取得。結果をJSONで出力する。

$ .\azlogin
To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code G9HFZ4NCY to authenticate.
....
[
   {
     "tenantId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionName": "Developer Program Benefit",
     "bearer": "********************************************a"
   },
   {
     "tenantId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionName": "foo",
     "bearer": "********************************************a"
   },
   {
     "tenantId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionName": "kinmugi",
     "bearer": "********************************************a"
   }
]

このJSONから、Bearer token を取得し変数に保存するして置き、APIの呼び出しをしてみよう。

まずは、jp (JMESPath) の式を用意する。短いのでコマンドラインにそのまま書きたいところだが、Windowsだとエスケープ関係が難しすぎる(cmd.exeや、powershellでは)ので、諦めてファイルに書く。

この例だと、subscriptionName が ‘kinmugi’のサブスクリプションのBearer tokenを取り出している。Windowsだと素直にPowerShellで書いたほうが楽な気がする。最近、JMESPath が気に入っているので、あえてjpを使う。

ここでは、本物のcurlを使って、リソースグループの一覧を取得している。PowerShellだとcurlでaliasが切ってあるが使えないので、本物を入れてalias を切った方が良い。

$ cat filter.jp
[?subscriptionName == 'kinmugi'].bearer|[0]

$ $bearer = (.\azlogin | jp -u -e filter.jp)

$ curl -H  "Authorization: Bearer $bearer" "https://management.azure.com/subscriptions/xxxxxxxx-.../resourcegroups?api-version=2017-05-10"

Bearer tokenさえ手に入れれば、こんな感じでサクッと管理APIが呼べる。

最後に

Azureのドキュメントだとごちゃごちゃしてて良くわからないが、認証は基本普通のOAuth 2.0 なのでそれほど難しくない。このあたりで困ったら、OAuth2.0 のドキュメント(Googleのとか 、翻訳もある[3])を読むと良い。Azure固有の問題は、松崎さんのブログ[4]がお勧めだ。

今回は、生RESTだけで構築したが、認証だけならそれほど難しいことはない。本格的にAzureを触ろうと思うとモデルが欲しくなり。触っていくと大量のモデルが出てくるので自前で作るのはとてもメンドクサイ。その場合はAzureSDKを使うと既にモデルが用意去れているので便利だ。

参考

[1]Using OAuth 2.0 to Access Google APIs,OAuth 2.0 for TV and Limited-Input Device Applications,
[2]Azure Login OAuth 2.0 Device Flow Console Program.
[3]OAuth 2.0 Flow: DevicesYouTube Data APIのドキュメントだが、翻訳されている。
[4]Login UI が出せない Client の OAuth フロー (Azure AD)この記事より松崎さんのブログを読んだほうが良いだろう。

下記のコードも参考になる

Azure PowerShellのインストール事情

最近のAzure PowerShellのインストール事情が少々メンドクサイことになっているのでメモ代わりに書き留める。

基本は、Azure テクニカル サポート チームがAzure PowerShell 最新版のインストール手順 (v3.8.0 現在)に書いている状況だが、いろいろあるので書いた。

2017/5/19、Azure PowerShell 4.0.1 時点の情報です

sky

推薦されるインストール方法

以前は、WebPI経由でAzure PowerShellをインストールしていたが、現在では PowerShell Gallery 経由のインストールが推薦だ。公式ドキュメント、Install and configure Azure PowerShellにも、下記のように書かれている。(ちょっと翻訳が追いついていないようで、サイトは英語のまま)

Installing Azure PowerShell from the PowerShell Gallery is the preferred method of installation.

Windows 10、Windows Server 2016より古いOSではデフォルトでPowerShellGetが使えないので、Windows Management Framework (WMF) 5.0 を入れる必要がある[1]

PowerShellGetでPowerShell Galleryから方法は簡単だ。(以下、Install-Moduleで入れると記載)

$ Install-Module AzureRm

MSIからのインストール

Install-Moduleで入れる方法の他に。Web Platform Installer (WebPI) やVisual Studio 2017のVisual Studio Installer での、Azure「Azure development」の選択、GitHubからMSIファイルをダウンロード[2]などの方法で、MSIファイルからインストールすることができる。MSIファイルからインストールは推薦されていないが、VS経由の時にように選択の余地なくMSI経路でインストールされてしまうこともある。

また、ググって出てくる日本語の公式ページがその他のインストール方法で、その他の方法としてMSIでのインストール方法を紹介している。ここには推薦は、Install-Moduleを使うことだと書いてあるが、よく読まないで書いてある通りに操作するとMSIで入れてしまうという落とし穴もある。今のところVisual Studio 2017 で入るのは 2.1.0と大分古いバージョンだというのがいろいろな問題を面倒にしている。

問題点:MSI -> Install-Module でエラー

PowerShell Gallery と、MSI 経由のインストールには互換性が無く、MSI経由でAzure PowerShellが入った環境に PowerShell Gallery で新しいものを入れたりInstall-Module AzureRM、アップデートUpdate-Module AzureRmすることはできない。

例えば、Visual Studio 2017のインストールで、Azure PowerShellが入っている状態で、Install-Module AzureRMを やると下記のようなエラーになる。

$ install-module AzureRm

PackageManagement\Install-Package : The following commands are already available on this system:'Get-AzureStorageContainerAcl,Start-CopyAzureStorageBlob,Stop-CopyAzureStorageBlob'. This module 'Azure.Storage' may override the existing commands. If you still want to install this module 'Azure.Storage', use -AllowClobber parameter.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1809 char:21
+ ...          $null = PackageManagement\Install-Package @PSBoundParameters
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Package], Exception
    + FullyQualifiedErrorId : CommandAlreadyAvailable,Validate-ModuleCommandAlreadyAvailable,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage

つまり、MSIインストールとInstall-Moduleは互換性が無く、「混ぜるな危険」という状況だ。

解決策

もし混ざってしまったからどうするか。

MSIで入れたものを、設定画面の、「アプリと機能」、あるいはコントロールパネルの「プログラムのアンインストールまたは変更」からアンイストール後、再度 Install-Moduleで PowerShell Gallery からインストールする。

下記は、PowerShellからアンインストールする方法。実行には、Admin権限が必要。

$ $app = Get-WmiObject -Class Win32_Product -Filter "Name like '%Azure PowerShell%'"
$ $app

IdentifyingNumber : {CB3F8A12-1570-4964-8206-17274AB9EF4D}
Name              : Microsoft Azure PowerShell - September 2016
Vendor            : Microsoft Corporation
Version           : 2.1.0
Caption           : Microsoft Azure PowerShell - September 2016

$ $app.Uninstall()

これで下記のように入れ直すと入る。

$ Install-Module AzureRM

原因

MSIで入れた場合とInstall-Moduleで入れた場合、モジュールは別の場所に入る。

MSIの場合は、下記のPSModulePathに入り

C:Program Files (x86)Microsoft SDKsAzurePowerShellResourceManagerAzureResourceManager
C:Program Files (x86)Microsoft SDKsAzurePowerShellServiceManagement
C:Program Files (x86)Microsoft SDKsAzurePowerShellStorage

Install-Moduleの場合は下記に入る

C:Program FilesWindowsPowerShellModules

MSIで入れた後にInstall-Moduleで入れた場合、MSIで入れたものを認識せずにインストールが進み、途中で別のバージョンのモジュールをロードして前記のエラーになる。Install-Moduleで入れた後に、MSIで入れると次のような問題が起きる。

MSIインストールの問題点

現在のMSIインストールで把握している問題点は3点ある(増えるかも)、そのうち深刻なのは1つ目の問題だ。

  1. Install-Moduleのモジュールを無条件上書きする
  2. Import-Module AzureRMでエラー
  3. WebPIでのリリースが遅い

1. Install-Moduleのモジュールを無条件上書

現在のMSIインストールは、Install-Moduleで入れたModuleがあれば削除してから、モジュールのインストールを行う。そのとき既存のモジュールのバージョンは見ていないので、Install-Moduleで4.0.1などのあたらしいバージョンを入れていても、VS 2017 を入れると、2.1.0になってしまうなどの現象が起きる。削除処理は、setup/Setup/RemoveGalleryModules.ps1のあたり。 Scope CurrentUserで入れた場合は考慮されておらず、なかなか残念なコードだ。

MSIだけで、バージョンアップを重ねている場合は、Windowsのインストールの仕組みでバージョンチャックされて古いバージョンは入らないので問題がないが、Install-Module(psget)で入れたものとの共存は考えられておらず、いきなり古いバージョンで上書きされるというわけだ。[3]

これは非常にメンドクサイ

2. Import-Module AzureRMでエラー

MSIで入れると、Import-Module AzureRmがエラーになる。これは、AzureRMというマニフェストモジュールが無いのが原因。Azure Poshの説明のあちこちで、Import-Module AzureRMが出て来るが、実はあまり意味がなく、モジュールはインストール時にModule Path配下に配置され、自動的にロードされるので、マニフェストモジュールが無くても動作上の不都合は無い。ただ、ドキュメントに書いてあるものがエラーになるのはちょと混乱する。ちなみに、Install-Module経由で入れてた場合は、AzureRM マニフェストモジュールが入り、Import-Module AzureRMも成功する。

$ import-module azurerm
import-module : The specified module 'azurerm' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ import-module azurerm
+ ~~~~~~~~~~~~~~~~~~~~~
   + CategoryInfo          : ResourceUnavailable: (azurerm:String) [Import-Module], FileNotFoundException
   + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

3. WebPIでのリリースが遅い

なかなか、WebPIにリリースされない。今回だと、Managed Diskの機能がサポートされたバージョンはしばらく放置され、5/10にやっとリリースされた。最新版を使いたい場合は、Install-Module経由で入れるしかない。WebPIに頼らずに、GitHubからMSIをダウンロードして入れるという方法もある。[2]

まとめ

Azure PowerShell を使う場合、Install-Module AzureRMで入れる、VS 2017や以前WebPIで入れている場合は、一度コンパネからアンインストールしてから入れる。Windows 10より古い環境では、WMF 5.0を入れよう。

今のVS 2017は、リリースのたびにAzure PowerShellの古いバージョンを入れてくるが、挫けずにアンインストールしてから入れ直す。

現状だとGitHubからダウンロードして、MSIインストールで運用という手もあるが、推薦インストール方法がInstall-Module経由なので、そちらを取った方が無難だろう。VS 2017が原因で面倒なことになっているのは残念だ。

参考

[1]How to get PowerShellGetWMF 5.0 を入れようという話が書いてある
[2](1, 2) azure-powershell.4.0.1.msiリリースのとこに、msiへのリンクがある。
[3]VS Installer overwrite with old version Azure PowerShell.すぐTriaged になったけど、その後の動きがない。

Azure Cosmos DB がやってきた

DocumentDB の記事を書いていたら[15]、//Build 2017で、Azure Cosmos DB が発表[1]された。 Cosmos DBは、Multi-model database and multi-APIのGlobally Distributed データベース・サービスだ。

Azure Cosmos DB in KeyNote

//Build 2017 Keynote より [1]

「DocumentDB何処行った、名前が変わったの?」と思ったら、そんなに簡単な話では無かった、Azure Cosmos DBは、DocumentDB、MongoDB, Azure Table,Gremlin などの複数のAPIをサポートしたマルチモデルの分散データベース[2]で Document DBはそのAPIの一つという位置づけになった。従来の Document DBで使ってた分散データベース基盤の部分は、ある程度汎用的に出来ていてJSON以外のデータモデルも扱えるので、今回はKey-Value と GraphのデータモデルにAPIを付けてブランディングも新たにお披露目したよという話だ。素晴らしい。

ざっくりまとめると、下図のような感じになってる。Cosmos 分散データベース基盤に、データモデルが乗っていて、それぞれAPIを提供するといった感じだ。AzureTable(Key-Value), Gremlin(Graph) は、Preview(既に試すことができる)で、Splark は、アナウンスだけ、DocumentDBとMongoDB APIはGAのままだ。この2つがGAのままなのは、Cosmos DBになっても基本的な実装は同じだからだろう。

Azure Cosmos DB in KeyNote

Azure Cosmos DB スタック

Breakout Session

//Build 2017のCosmos DBの2つのBreakout Session、B8047[3]と、T6058[4]では、もう少し詳細に触れられている。

Table API in Azure Cosmos DB

//Build 2017 B8047 より [3]

その中でも興味深いのは、B8047 のTable APIの下りだ(動画だと35:50あたり[5])。超訳すると。

Cosmos DB に、既存のTable Storage(以下Standard Storage)互換のTable API(以下Premium Table)を実装した。もう、Premium Table SDK[6]をダウンロードして試せる。アプリケーションの変更は必要ない(SDKでを切り替えるだけ)で、ローレイテンシー、5つの一貫性、グローバルディストリビューション、セカンダリーインデックス等、数々のCosmos DBの特性が得られる。

特に重要なのは、これに続く部分だ。

現在「storage optimized offer」に向けて作業中、現在の Cosmos DB は、スループットの最適化、ローレイテンシーなどのpremium experience にフォーカスしているが、hot work load 以外の場合でも選択肢にできるように取り組んでいる。

現在のCosmos DB(旧DocumentDB)の料金体系は、基本hot work load向けだ。アクセス頻度が低いデータが多くなってくるとAzure Storageとのコスト差がどんどん大きくなっていく。データ全体の中で一部だけのアクセス頻度が高く、殆どのデータはアクセス頻度が低い場合は、Cosmos DBだけでなく、なんからの外部データストアとの連繫を検討する必要がある。これは特に、Standard Table(これからは、Azure Table StorageのことはStandard Tableと呼ぼう)からの移行を考えた時に重要な検討課題だろう。それがうまく解決できるなら、かなり有り難い。

同時に公開されたBlogから

Cosmos DBも発表共に公開されたBlogもなかなか面白い。Azure Cosmos DB: The industry’s first globally-distributed, multi-model database service[7]の A Brief History of Cosmosには簡単なCosmos DBの歴史が書いてあった。それによると、

Azure Cosmos DBは、2010年に「Project Florence」で開始、グローバルディストリビューションの課題を解決するためにMSの社内で使っていたが、他の皆にも役に立つと思い、2015年にAzure DocumentDBの形でこのテクノロジの第1世代を利用できるようにした。

云々だそうだ。世界中で展開するサービスの下りをみて連想したのは、AzurePortal。「最近ポータルが速くなってきてるのはエンドポイントを日本に持ってきたからかな、でもUSのリソースも普通に見れて操作できるしどうなっているのだろう」と思っていたが。Cosmos DBのようなグローバルディストリビューションの仕組みがあれば実装イメージが湧いてくる。実際のところはどうなっているかはわからないが。なかなか興味深い。

あとA technical overview of Azure Cosmos DB[8]に、Leslie Lamport 博士が出てきて、Cosmos DBの一貫性の設計、実装にTLA+[9]のCosmosでの活用の話をしていたのが興味深かった。[9]

「正しく動く分散システムを作るのはなかなか難しい、そんな中で形式手法が有効だ。Cosmos DBは設計、実装で、TLA+が複数の一貫性のサポートやSLAの提供に貢献した」的なことを言っている(超訳過ぎるので原文参照)。AWSでは、2011年からFormal Methodsを使って、重要な分散システムのアルゴリズム設計を行っている[10]と話題になったが、MSが分散システムの設計に使っている公言したのは初めてな気がする。利用者サイドからの一貫性の検証は難しいので設計、実装の取り組みがわかるのは有り難い。

この記事には、Azure Cosmos DBのデータベースエンジンの中身についても少し書いてあった。以下超訳

Azure Cosmos DBのデータベースエンジンのコアタイプシステムは、汎用的にどのようなデータにも対応するatom-record-sequence (ARS)と呼ばれる構造となっている。Atomは、文字列、論理型、数値などのprimitive型、recordは構造体、sequence はatom、record、sequenceの配列である。また、Azure Cosmos DBのデータベースエンジンは、JSONなどのAPIが利用するデータモデルとARSベースのコアデータモデルの効率的な変換と投影を実装し、動的型付き言語(dynamically typed programming languages)からコアデータモデルへのネイティブアクセスをサポートする。このデータベースエンジンを使うことで、Cosmos DBのAPIは、battle-tested でフルマネージドな、グローバル分散型データベースシステムのすべての利点を得ることができる。

ARSは、プリミティブ型を単純に並べただけの構造なのでJSONをそのまま保存するよりは効率は良いだろうし、別のデータモデルを実装し易いだろう。コアデータ・モデルを扱うデータベースとしての基本的な部分、整合性、リプリケーション、バックアップなどは共通の仕組みが使えるというわけだ。

Premium Tableの現況

大分長くなってしまったので、最後に、Premium Tableをちょっと動かしてみた感想を書いて終わりにする。

GitHubに、Getting started with Azure Cosmos DB: Table API[11]というサンプルコードがある。Premium/Standard Table に繋いで簡単な速度を測るようなコードだ。それを動かしてみた。まずは結果から。※Premium Table の測定は、2000 RU/秒のパーテーション無しコレクションで行った。

Premium/Standard Table のレイテンシー
Title 操作 p0 p50 p90 p99
Premium 作成 5.2 7.2 9.0 13.0
Standard 作成 4.2 11.9 20.7 26.2
S/P 比   81% 164% 229% 201%
Premium ID検索 1.3 2.0 3.2 5.7
Standard ID検索 2.4 3.4 5.2 11.2
S/P 比   184% 170% 162% 197%
Premium プロパティ検索 2.9 4.8 6.9 10.8
Standard プロパティ検索 49.4 55.7 67.0 78.3
S/P 比   1683% 1166% 965% 726%
Premium 置換 5.0 7.6 9.3 13.2
Standard 置換 4.7 12.2 20.6 25.4
S/P 比   94% 161% 221% 192%
Premium 削除 4.5 6.0 7.2 9.4
Standard 削除 2.8 3.6 4.9 10.0
S/P 比   62% 60% 68% 106%

1万エンティティで1度だけしか測っていないので、数値の絶対値は参考程度にしかならない。注意して欲しい。それでも傾向ぐらいはわかる。

ID検索の部分が、パーテーションキー、ローキーによる検索。プロパティ検索は、Standard Tableだとインデックスの効かずにフルスキャンになるが、Premium Tableでは全てのプロパティに自動的にインデックスが作成されるので、この場合もインデックスが利用される。

全体的な傾向を見ると、50パーセンタイルでは、プロパティ検索以外は、Premium が1.5から1.6倍程度Premiumが速い。プロパティ検索はセカンダリーインデックスの効果を見る項目で、Standardだとフルスキャン、Premiumだとインデックスが使われる。セカンダリーインデックスの効果は絶大で10倍以上Premiumが速くなる。データ件数が多くなればさらに差が出るだろう。

99パーセンタイルでは、2つの差は広がり、2倍程度の差になる。今回は件数が少ないので、この程度の差になったが、件数を増やして調査時間を長くすれば差は大きくなると思われる。

数字だけ見ると、Standard Tableが意外と奮戦している、前に調べて時より少し速くなっているようだ。Premium Tableはまだプレビューという点を差し引いても、一貫してレイテンシーが低いというのは魅力的だ。セカンダリーインデックスを更新する分、更新系は不利なはずだが、それでもStandardより速いのも今後が期待できる。

総じて、Premiumが速く、特にセカンダリーインデックスが効くと劇的に速くなる。全体的にPremiumのレイテンシーはバラツキが小さく一貫してレイテンシーが低いのは好印象だ。

Premium Table SDK

サンプルコードを見ると、PremiumとStandardの切替は接続文字列[12]の設定だけだ。Premium Tableには、DocumentDBと同じように、Consistencyや接続モードの設定がある、それをどうやってやるのかと言うと、現状では、AppSettings に書く[13]。 AppSettingsには下記の設定ができるようだ。基本的にはDocumentClient関連の設定だ。この方法だと、Standard Tableのコードを修正せずに動かしたいという目的は果たせるが、Premium Tableに最適化されたコードを書きたい場合には、あまり適さない。コードで変更できるようにして欲しい。

AppSettings での設定項目
設定名
TableConnectionMode
TableConnectionProtocol
TableConsistencyLevel
TableDisableRUPerMinuteUsage
TableIndexingPolicy
TableIsRUPerMinuteEnabled
TableMaxConnectionLimit
TablePreferredLocations
TableQueryContinuationTokenLimitInKb
TableQueryEnableScan
TableQueryMaxDegreeOfParallelism
TableQueryMaxItemCount
TableThroughput

現在のSDKだと、スロットリングがかかったときのリトライのハンドリングが怪しいようだ。それにサンプルコードではスロットリングエラーになった場合の処理が考慮されていない。そのため今回の測定ではスロットリングがかからないように2000RU/秒に設定した。

AppSetting設定やスロットリング対策からも言えることは、Premium Tableに最適化したコードが必要な場合は、そのためのコードが必要になるということだ。例えば、レスポンスヘッダーのRequestChargeを見てアプリケーションで消費RUを制御するなどのコードはスロットリングの仕組みが違うので、Standard TableとPremium Tableでは互換性が無い。ある程度SDKで吸収できるだろうが、プロダクションコードでは、ある程度アプリケーション側で対応する必要があるだろう。

Fidderで通信を覗いてみたところ、Premium Table SDKは、Premiumに繋ぐときは、x-ms-version: 2017-02-22 を、Standardのときは、x-ms-version: 2016-05-31 を使ってた。Premium の場合は、パーテーションマップの取得など、DocumentDBでお馴染みのやつが最初に入るなど、wired protocal としては全く互換性が無い別プロトコルだ。エンティティの作成も、今のStandardではレスポンスは空になるが、Premiumではしっかり中身が入っている。

リクエストとレスポンスはこんな感じだ

ちょっと見 DocumentDBとウリ2つだ。Premium Table SDK が、DocumentDB Client SDK を参照していることからも、実際の通信はDocumentDBと同じプロトコルを使っていることが伺える。このままGAになるかどうかは分からないが、この仕組だとプロトコルレベルではStandardとPremiumは別物になるので、既存のStandard Table Storage向けのライブラリは作り直す必要がある。最初に聞いたときは、REST APIレベルで互換なのかと思ったので、ちょっと肩透かしだ。しかし、パフォーマンスを考えた場合、今のStandardのREST APIよりDocumentDB形式の方が将来性がある気もする。なかなか面白いアプローチではある。

まとめ

つらつらと書いていたら随分長くなってしまった。これで、Graph APIの話とかTLA+の話も書きたかったが疲れたので、この辺で一旦終わる。最初、Premium Tableを聞いた時は、DocumentDB時代の価格体系だとちょと用途が限定される気がして、どうなのかとも思ったが、B8047[5]の話を聞いて、今はとても期待している。

今の気分は、「Cosmos DBはいいぞ」と言う感じだ。

追記 (2017/5/15)

現在のTable APIではパーテーション無しコレクションしか作成できず、コレクションの容量は10GBだ。これはプレビューの制限だと思われる。10GB以上のデータで評価したい場合は要注意だ。現時点でもスループットは、10万 RU/秒まで設定でき、Standardのストレージアカウント全体のパフォーマンスターゲット(1Kエンティティで毎秒20,000トランザクション)[14]を上回る。また、Table StorageのTableがCosmos DBのコレクションになるので、Table単位で課金される。Standardだと割りと気軽にTableを作れたのでこれも設計変更の要因になるだろう。

脚注

[1](1, 2) [1:22:26]Azure Cosmos DB Introduction
[2][1:27:20]Rimma Nehme, Azure Cosmos DB demonstration
[3](1, 2) B8047 How to build globally-distributed, fast, billion-user applications with Azure Cosmos DB
[4]T6058 Azure Cosmos DB: NoSQL capabilities everyone should know about
[5](1, 2) [0:35:50]B8047 のTable APIの部分
[6]Premium Table SDKソースは未公開
[7]Azure Cosmos DB: The industry’s first globally-distributed, multi-model database service
[8]A technical overview of Azure Cosmos DB
[9](1, 2) Foundations of Azure Cosmos DB with Dr. Leslie Lamport, longレスリー ランポート先生のインタビュー、お勧めです。
[10]How Amazon Web Services Uses Formal Methods
[11]Getting started with Azure Cosmos DB: Table API
[12]接続文字列の切替部分
[13]AppSettingsでの設定箇所
[14]Blob、キュー、テーブル、およびファイルのスケーラビリティ ターゲットサンプルコードでは、IDでの読込が1 RU/秒程度、エンティティ作成が10 RU/秒程度を消費していた。それをベースに試算すると、読込はStandard Tableのストレージアカウントの10倍、書込は同等のスループットということになる。ここでは、Read/Write混合を想定して「上回る」という表現にした。
[15]日経クラウドファースト 2016年6月号Azure DocumentDB 予約性能と実測値がほぼ一致 応答時間はデータストアーで最高レベル

その他の参考リンク

PsEnv への TabExpansion の実装

git-poshのコードを見ていたら、PowerShell 3.0 から導入された TabExtentionを使ってタブ補完を実装していた。[1]仕組みはシンプルで便利な機能だったので、いつも使っているPsEnv[2]に実装してみた。[3]簡単なコードだが知らないテクニックが使われていて面白かったので軽く紹介。

Piccolo

TabExtentionの基本

「コマンドラインで、タブを押したときに Function:TabExtention が呼ばれ、コマンドラインと最後のワードが渡される、TabExtention の関数で文字列の配列を返すとコマンドラインでは補完文字列として扱われる」

基本、これだけなので、非常にシンプルでわかり易い。[4]git-poshのコードを見ながら実装してみたら、こんな感じになった。

コード解説

L33で現在のTabExpansionの関数をリネームして保存しておく、補完処理が自分と関係無い場合は、このコードにフォールバックする。(関数名を変更できるのは知らなかった)コールバックチェーンの実装方法の一つらしい。TabExpansion は、Globalな名前空間にExportされてるが、TabExpansionBackup はExportされておらず、名前が衝突する心配は無い。タブが押されると、L37 TabExpansion関数が呼ばれる。正規表現で引っ掛けて、補完処理対象のコマンドラインならPsEnvTabExpansionへ、その他はTabExpansionBackupへフォールバックする。

L19 PsEnvTabExpansionは、コマンドラインのラストブロックを貰って、正規表現で引っ掛けて対象の補完文字列を返す。switch と正規表現を使うとスッキリ書けて気持ちいい。

DynamicParamとの比較

TabExtention では、仕組みがコマンドライン文字列のパターンマッチングなので PowerShell Cmdlet 以外のWin32 EXE などの補完も実装できる。PsEnvはCmdletなので、DynamicParamでも良かったかなという気もするが、実装を比べると.NETのクラス出まくりのDynamicParamに比べTabExtentionは綺麗に書ける。しかし、TabExpansion はGlobalなキー入力をフックするので下手に作るとキー入力のレスポンスが悪くなるという欠点がある。どっちも、デバックし辛いのは欠点。

PsEvnの紹介

あまり知られていない気がするので、PsEnvの紹介を簡単に書いておく。Windowsでは環境変数の取り合いになって、うまく共存できない環境がママある。linuxや、Macだと、rubyや、pythonの仮想的に切り替える仕組みだけで足りたりするのだが、Windowsだと駄目だったり。cygwin, msys さらにそのバージョン違いでコンパイルされていたりして混ざって動かなくなったりすることがある。そのため、標準の環境変数はなるべくクリーンにしておいて環境によって必要な環境変数を設定するようにしている。PsEnvは環境変数を設定するのに便利なCmdletだ。

使い方は、PsEnvを見てもらうとして、使ってる設定ファイルpsenv.jsonを参考までに上げておく。ゴミが多くて少々長い申し訳無い。

最後に

これを書いている途中で、TabExtention++ が、PSReadlineと同時に WMF5の標準機能として取り込まれている[5]のを知った。共存しても問題無いのだろうか。このあたり[6]には、PowerTab(?)対応のコードが入ってるので余計気になる。