Azure (6)


EventHubからStreamAnalyticsへ流してTableStorageに出力する

EventHubへのデータの流し方については前の記事を参考にしてください。

まずはStreamAnalyticsを作成し、入力の項目に作成したEventHubを設定します。

出力にはTableStorageを指定します。(あらかじめTableStorageを作成しておいてください)

パーティションキーと行キーについては、イベント要素を一意に決定する2つのキーを指定します。

この2つのキーはEventHubに挿入するイベントのjsonに含まれているキーである必要があります。

入力と出力が設定できたら、クエリを指定します。

INTOには出力の名前、FROMには入力の名前、SELECTは今回そのままデータを出力に流すので*としておきます。

ここまでできたら概要から[開始]を押し、StreamAnalyticsを実行します。

StreamAnalyticsを実行できたら、StorageExplorerを使ってTableStorageを見ましょう。

TableStorageの中身をみることができたらOKです。

 

続いでデータを挿入しましょう。

EventHubへのデータの挿入の仕方については前の記事を参考にしてください。

今回はこのようなデータを投げます。

データをEventHubに投げたら、TableStorageを見ましょう。

無事、StreamAnalyticsを介してデータの挿入ができました




Azure EventHubにHttpでイベントを投げる

Azure EventHubは入力のプロトコルとしてAMQPとHttpsをサポートしています。AMQPは永続通信なので通信が頻繁に発生する場合はAMQPのほうがいいのですがAMQPがすべてのデバイスにSDKが提供されているわけではないので、IoTなどを考えたときHttpでEventHubに投げたくなります。

今回はその手順をnode.jsでやってみました。

すでにEventHubが作成されていてnode.jsを実行できる環境を想定しています。

SAS Tokenを作成する

httpでEventHubに投げるには、まずSAS Tokenを作成する必要があります。

詳しくはこちらのドキュメントをみてください。

今回はnode.jsのサンプルコードを記載しておきます。

endpoint、sharedAccessKeyName、sharedAccessKeyの3つのパラメータについてはEventhub名前空間の接続文字列に記載されています。

上記コードを実行して得られたSharedAccessSignatureから始まる文字列がSAS Tokenです。

node.jsからイベントを送信する

requestパッケージを利用するのでnpm install requestをしておいてください。

http通信ですが、基本的にheaderのContentTypeに下記コード参照のパラメータを、Authorizationにsas tokenを乗せて、送りたいイベントをjsonとしてpostすればOKです。

詳しくは公式のドキュメントをみてください。

EventHubに送信されたことを確認する

EventHubにデータが送信されていることを確認するには、Azureポータルからではなかなか難しいです。

そこでサードパーティのツールを利用します。

ServiceBusExplorerというものを利用することでEventHubに流れてくるイベントをリッスンすることができます。

次回はStreamAnalyticsとつなげます




Azure設計プラクティス4: MySQLレプリケーション

MySQLにはレプリケーションという同じ内容のデータベースを複数冗長に持つ設定をすることができる機能があります。

Microsoft Azureには現在(2017/5/9)MySQLのレプリケーション機能をサポートするサービスは存在しませんがLinux VirtualMachine内にMySQLを稼働させることで同じ機能を実現することができます。

今回はMySQLのレプリケーションをAzureで行っていきたいと思います。

今回の構成はこのようにします。

同一VirtualNet、同一ネットワーク・セキュリティグループ内にUbuntuOSのVMを2台、MasterとSlaveとして配置します。

レプリケーションについて

MySQLレプリケーションに関してはこちらの記事がとても詳しくまとまっているので参考にしていきます。

MySQL入門 レプリケーション編
http://qiita.com/Tocyuki/items/c224cef57493f536a941

通常、データベースを1台で運用すると1台のDBに負荷が集中してサービスのボトルネックや可用性の低下へとつながります。

そこで同じ内容のデータベースを複数作成(レプリケーション)しアクセスを分散することで1台あたりのデータベースの負荷を減らします。また、1台のDBが使えなくなったとしてももう一台のDBが継続的に稼働し続けることで高可用性を実現します。

しかしDBを複数持つと1台に書き込んだ瞬間にすべてのDBを更新しなければいけません。

そこでDB1台のみに書き込み、読み込みを許可しその他のDBには読み込みのみを許可することでDBの読み込みのトラフィックを分散することができます。上記の書き込み、読み込みを許可するDBをMaster、読み込みのみを許可するDBをSlaveと呼びます。

さらに、Masterが落ちた時はSlaveをMasterへと昇格することでサービスの継続稼働をサポートします。

インスタンスを作成する

今回の本題はMySQLの設定になるので上図の構成のインスタンスをさくっと作ってしまいます。

まずVirtualNetを作成します。アドレス空間はIPv4のクラスCとしましたが別になんでも大丈夫です。

続いて2つのVMを包むネットワーク・セキュリティグループを作成します。こちらも特に問題はありません。

MasterDB用のVirtualMachineを作成します。

OSはUbuntu 16.04LTS

VirtualNetworkとネットワーク・セキュリティグループは先程作成下ものを指定してください。

Slave用のVMを作成します。

OSはMasterと同じUbuntu 16.04LTS、VNet、セキュリティグループもMasterと同じ、先ほど作成したものとします。

VMに紐付いているネットワークインターフェースカードの設定を開き、IPアドレスの割当を静的にし、上図の構成通り、Masterに192.168.0.4、Slaveに192.168.0.5を設定します。

ネットワーク・セキュリティグループの設定を開き、SSHの22番の受信許可をします。

 

これで上図の設定をすることができました。

MySQLにレプリケーションの設定をする

今回はGTIDの使用はなしの方向でいきます。

まずMasterのVMにsshでログインします。

DB、テーブルの作成、データの挿入までを行います。

レプリケーション用のユーザーを作成します。

 

MasterDBの設定を行います。サーバーIDは任意のものを設定します。

SlaveのMysqlインストールと設定を行います。

 

続いてMasterDBでバイナリログの名前とイベント開始位置をめもります。

MasterDBのバックアップをとります。

scpでslaveへと転送します。

SlaveのDBでリストアします。

SlaveでMasterの登録を行います。

レプリケーションをスタートします。

 

レプリケーションの確認を行う

では本当にレプリケーションできたか確認をしてみましょう。

slaveのDBでitemsテーブルを表示してみます。

 

とりあえずレプリケーション登録時点ではMasterと同じ内容が入っています。

ではMasterにデータを追加してみます。

 

ではslaveで変更を確認してみます。

正しくレプリケーションできていました。

master側のステータスを見たいときは

slave側のステータスを見たいときは

でOK

 

感想

思ったよりめんどくさかったという感じはありますがAWSのようなマネージドなMySQLならボタンポチーでできるのだろうか?Azureも早くMySQLのマネージドサービスほしいですね(ClearDBではない)




Azure設計プラクティス3: Traffic ManagerによるApp ServiceとVM間での負荷分散

前回に引き続き設計プラクティスです。

今回は前々回にLoadBalancerで複数のVMの負荷分散を行ったのに対し、TrafficManagerというものを利用してApp ServiceとVirtualMachine間で負荷分散を行います。

今回の構成はこのようになっています。

WebAppsとVirtualMachineの2つのWebホストへのアクセスをTrafficManagerによって分散します。

TrafficManagerはDNSレベルで動作し、*.trafficmanager.netに来たDNS要求に対し、ルールに基づいて決定したCNAMEを返します。

例えばgariweb1.azurewebsites.netにトラフィックをさばくべきだとTrafficManagerが判断すれば、DNSの名前解決要求が来た時にCNAMEレコードにgariweb1.azurewebsites.netを入れて返信します。

TrafficManagerの分散ルールは公式サイトにあるとおりです。

  • 優先順位: すべてのトラフィックにプライマリ サービス エンドポイントを使用し、プライマリ エンドポイントまたはバックアップ エンドポイントが使用できない場合に備えてバックアップを用意する場合は、”優先順位” を選択します。
  • 重み付け: 一連のエンドポイントに、均等にまたは定義した重みに従ってトラフィックを分散させる場合は、”重み付け” を選択します。
  • パフォーマンス: 複数のエンドポイントが地理的に異なる場所にあり、エンド ユーザーが、ネットワーク待ち時間が最も短いという意味で “最も近い” エンドポイントを使用できるようにする場合は、”パフォーマンス” を選択します。
  • 地理的: DNS クエリの発信元の地理的な場所に基づいてユーザーを特定のエンドポイント (Azure、外部または入れ子になっている) に割り当てる場合に “地理的” を選択します。 こうすることで、Traffic Manager の利用者は、ユーザーのリージョンを把握し、そのリージョンに基づいてユーザーをルーティングすることが重要なシナリオを実現できます。 データ主権規制、コンテンツおよびユーザー エクスペリエンスのローカライズ、さまざまなリージョンからのトラフィックの測定がその例に挙げられます。

今回は優先順位のルールを用いて負荷分散を行います。

AppServiceを作る

負荷分散されるインスタンスの1つを作ります。

今回はWebAppsにPHPのアプリを作るということとします。

Virtual Machineを作る

続いて負荷分散されるもう片方のインスタンスであるVirtualMachineを作成します。

UbuntuのVirtualMachineを作成します。

LoadBalancerではVirtualMachineのスペックは負荷分散が書いてあるものでないとダメでしたがTrafficManagerでは必要ありません。

今回はA0としました。

仮想ネットワーク、セキュリティグループ等、デフォルトでOKです。

VirtualMachineを作成できたら、紐付いているパブリックIPにDNS名をつけましょう。

パブリックIPの構成から好きなDNS名をつけます。

さらに紐付いているネットワークセキュリティグループの受信ルールからhttpの80番ポートを許可します。

TrafficManagerを作成する

続いて上記の2つのインスタンスの負荷分散を行うTrafficManagerを作成しましょう。

TrafficManagerはAzureで「TrafficManagerプロファイル」と検索すると出てきます。

ルーティング方法は今回は「優先度」とします。

TrafficManagerを作成することができたら、エンドポイントを追加します。

エンドポイントとはTrafficManagerが負荷分散した先のインスタンスとなります。

ですので作成したWebAppsとVirtualMachineを指定しましょう。

ターゲットリソースはWebAppsの場合「AppService」

VirtualMachineの場合、VMに紐付いているパブリックIPとしましょう。

(TrafficManagerはDNSレベルで動作するため、パブリックIPにDNS名をつけていないとここで指定することができません)

以上でTrafficManagerの設定は完了です。

アプリをデプロイする

ではWebアプリを配置していきましょう。

まずはAppServiceからです。

AppServiceの場合、様々なデプロイ方法がありますが今回はローカルgitリポジトリから配置します。

WebAppsの「デプロイオプション」からローカルGitリポジトリを選択します。

するとWebAppsの「概要」の部分にGitクローンURLというものができるのでこのURLをgit cloneしましょう。

その上にあるGit/デプロイメントユーザー名が何も表示されていない人は資格情報からデプロイユーザーを作成しましょう。

クローンできたら中にindex.phpを作成し、中身をこのようにしましょう。

index.phpを作成できたら git pushします。

WebAppsにアクセスしてこのように表示されればOKです。

つづいてVMに同じアプリをデプロイしましょう。

VMにsshでログインし、下記のコマンドを実行し、lamp環境を整えましょう。

lamp環境を整えることができたらindex.phpを作成しましょう。

index.phpの中身は以下のようにします。

VMのDNS名にアクセスすると以下のように表示されたらOKです。

TrafficManagerにアクセスする

ではアプリを配置できたので負荷分散ができているか試してみましょう。

VMの方のページが表示されました。

これは現在のTrafficManagerのルーティングルールが「優先度」であり、WebAppsの優先度が1、VMの優先度が2であるため、優先度が高いVMのほうが表示されています。

 




Azure設計プラクティス2: SQL Databaseのgeoレプリケーションによる冗長構成

Azure SQL Databaseはgeoレプリケーションをサポートしており管理ポータルから数クリックで冗長構成を実現できます。

レプリケーションとは同じデータを持つデータベース(レプリカ)を2つ以上別のデータセンターなどに配置しておくことによって、データを保証したり可用性を実現するものです。

例えば1つのデータベースに障害が発生したとき、同じデータを持つデータベースが別のサーバーにあれば即座に元のデータを復元できます。

さらに、データベースに障害が発生した時にレプリカのデータベースが障害が発生したデータベースの代わりにマスターDBになることでフェールオーバーを実現します。

geoレプリケーションとは地理的に離れたデータセンター間でデータをレプリケーションすることを指します。

今回はAzure SQL Databaseをつかってgeoレプリケーションを実現してみましょう。

今回の構成はこのようにします。

SQL Databaseは東日本リージョンと米国西部リージョンの2つでレプリケーションすることとし、App Serviceからのトランザクションをさばきます。

上記の構成では東日本リージョンにあるDBのみにデータを書き込むことができ、このようなDBをMaster(Azureの場合はプライマリ)と呼びます。

米国西部にあるリージョンは読み込み専用とし、App Serviceからの読み込みのみのトランザクションを受け付けます。このようなDBをSlave(Azureの場合はセカンダリ)と呼びます。

もし東日本リージョンで障害が発生し、Masterが機能しなくなったとき、SlaveのDBがMasterに昇格し、書き込み可能となることでフェールオーバーを実現します。

WebAppsを作る

まず最初に、DBにアクセスするためのWebアプリケーションを作成します。

リージョンは東日本とします。

Master DBを作る

東日本に置くMaster DBを作ります。

リージョンは東日本とし、サーバーも新しく作成してください。

価格レベルは一番安いもので大丈夫です。

Slave DBを作る

続いてレプリカ用のSlave DBを作ります。

先ほど作成したMaster DBの管理画面を開き、「geo レプリケーション」を選択します。

ターゲットリージョンから「米国西部」を選択します。

Slave DBの構成を聞かれますがMasterと同じ性能にしなければいけないのでそのままにします。

サーバーは米国西部に新しく作成します。

Slave DBを作成することができたらレプリケーションは完了です。

プライマリと表示されているのがMasterでセカンダリと表示されているのがSlave DBです。

ASP.net MVCから接続するアプリケーションを作る

ではこれらの冗長構成のSQL DatabaseのMaster DBにデータを入れるアプリをASP.netで作ってみます。

ASP.net MVCで新規プロジェクトを作成します。

NugetからEntityFrameworkを追加します。

Web.configを編集し、接続文字列を追加します。

接続文字列は作成したMaster DBの管理画面から取得することができます。

接続文字列の中にはユーザー名とパスワードが埋まっていないので自身のDBServerに設定したユーザー名とパスワードを設定します。

接続文字列の名前は後ほど作成するDbContextと同じものにする必要があります。今回はItemContextとしました。

Modelフォルダ内に下記のモデルを作成します。

今回はItemというモデルで1つのメッセージを管理します。

ItemContextは接続文字列と同じ名前にしてください。

下記の場合、データベースにItemsというテーブルができます。

HomeControllerを以下のようにします。

Indexは通常ページを返し、AddItemはajaxから呼び出され、DBに値を追加するアクションメソッドです。

Index.cshtmlを下記のようにします。

アクセスされるとDB内の値を表示し、buttonがクリックされるとAddItemアクションメソッドにajaxでアクセスしてデータベースに1つ値を追加します。

これでASP.netのアプリは完成です。

VisualStudioのメニューバー>[ビルド]>[{project名}の発行]から先ほど作成したWebAppsへデプロイを行いましょう。

データ追加を押すたびに[moge]が1つ増えます。

DBを見てみる

ではデータベースにデータが入っているかMaster DBを見てみましょう。

今回はDataGripというツールを使ってデータを見ていますがWindowsの方はSQL Server Management Serviceというツールを使うのが良いかと思います。

データが入っていました。

ではレプリケーション先のslaveのDBを見てみましょう。

データが入っていませんでした。

レプリケーションされているならslaveにも同じデータが入っているはずですがはいっていないのはとても気になります。

@Masayuki_Ozawa さんいわくレプリケーションには多少タイムラグがあるそうです。それが原因でまだ反映されてないと思われます。

数時間ほど待ったところ、無事レプリケーションできていました。

フェールオーバーしてみる

geoレプリケーションをしている場合、slave DBをボタン1つでMasterに昇格することができます。

セカンダリのDBの右端をクリックして「フェールオーバー」を押します。

セカンダリDBがプライマリDBへと昇格しました。

アプリケーションの接続文字列はMasterとSlaveで違うので切り替える必要があります。