Month: December 2015

Azure Media Services(以下AMS)公式PHP SDK(正確にはazure-sdk-for-phpに含まれるMedia Services用ライブラリ)を使って条件指定でアセット一覧情報を取得するための方法について簡単に説明したい。2015年12月の時点でAMS PHP SDKが持っているBuilt-inのアセット一覧情報取得インターフェースはgetAssetList() のみとなっており様々な条件指定でアセット一覧情報を取得するための機能が存在しないためここでの説明は今回新しく用意したカスタム関数の追加を前提としている。

追加カスタム関数

上述のとおり2015年12月の時点でAMS PHP SDKが持っているBuild-inインターフェースでは条件指定によるアセット一覧の取得ができない。例えば次のような取得ができない:

– オフセット指定
– フィールド名の完全、前方、後方一致といったフィルター条件指定(AMS REST APIはOData v3をベースとしている)
– 一度に取得するアセット数やソート条件指定

よって、ここではMediaServicesRestProxy.phpに下記のgetAssetListByParam()関数を追加して条件指定によるアセット一覧取得を実現する。尚、この修正は既にGithub上の個人開発用ブランチにコミット済みでありマスターブランチとの差分はこちら。この修正についてはPull Req#766でプルリクエスト中なので無事通れば将来的にはマスターブランチに反映されるかもしれません。

    /**
    * Get asset list by params
    *
    * @param array of parameters to be added to request URL as query string
    * such as $skip, $filter, $top, and so on
    *
    * @return array of Models\Asset
    */

    public function getAssetListByParams($params)
    {
        $p = array();
        foreach($params as $k => $v){
            $p[] = $k.'='.$v;
        }
        $paramstr = implode('&', $p);
        $propertyList = $this->_getEntityList("Assets()?" . $paramstr );
        $result       = array();
        foreach ($propertyList as $properties) {
            $result[] = Asset::createFromOptions($properties);
        }
        return $result;
    }

使用例

例1: 1000件目以降の一覧情報取得
以前「TIPS: Azure Media Servicesでの利用アカウントの全アセット一覧の取得」で触れたとおりAzure Media Servicesではパフォーマンス上の理由から一度に返却できるアセット数の制限が1000に設定されている。よって、アセット数が1000以上ある場合、1000件以降のアセット一覧情報を取得するためにはオフセットの位置を調整する必要がある。ここでは$skipパラメータを使用してオフセット位置を調整している。

例2: アセット名が完全一致する一覧情報取得
$filterパラメータを使用してアセット名(Nameフィールド)が指定した名前と完全マッチするアセット情報一覧を取得する。

例3: アセット名が前方部分一致する最初のアセット情報を取得
$filterパラメータを使用してアセット名(Nameフィールド)が指定した名前と前方一致するアセット情報一覧を取得する。ここではさらに$topパラメータで最初の1件のみを取得している。

LINKS

I’ve just noticed that some of patents, which I was involved in for its publishing process while I was at Yahoo! JAPAN, have been granted. Well, what I’ve done for them is just a tiny part but patent is patent, it’s good news anyway.

これはElasticsearch Advent Calendar 2015の17日目のエントリー

ARMテンプレートと呼ばれるデプロイ手法を使ってAzure上にElasticsearchクラスタをさくっと構築する方法についてのお話で、主にAzure界隈のElasticsearchユーザ向けの内容となっている。タイトルにある3分でというのは実際に計ったわけではないがそれくらい簡単且つ短時間でできることを強調したく使わせていただいている・・・ということを前もって補足しておく(汗)。

ARMテンプレートとは?

ARMテンプレートの前にARMについて少し解説する。ARMはAzure Resource Managerの略で、アプリケーション構築に必要な
リソース(ストレージ、ネットワーク、コンピュート/仮想マシンなど)をデプロイし管理するための仕組みである。どんなソリューションのデプロイにおいても少なからず仮想ネットワーク、仮想マシン、ストレージ、LBなどのインフラの構築が必要で旧来のやり方ではこれらを1つ1つデプロイしていたかと思う。一方ARMの世界では必要な構築要素をリソースという単位にして、これらリソースを個別にデプロイするのではなく全てのリソースをグループ化してまとめてデプロイし、それらを管理・監視することができる。そして、それら複数のリソースはJSON形式のテンプレートで表現・展開できるようになっていて、このテンプレートのことをARMテンプレートと呼ぶ。Infrastructure as Codeなんて言葉がはやっていたりするが、まさにそれをAzureで実現するための公式な仕組みがARMであり、ARMテンプレートなのである。

ちなみにこのARMテンプレート、手でいちから作る必要はなく、Azureクイックスタートテンプレートにさまざまなテンプレートが公開されているのでまずは自分の目的に似たようなことを実現しているテンプレートを選んでデプロイしてみることをお勧めする。完成されたものを見ることでお作法が学べるし、それをベースにカスタマイズしていくのが効率的である。

Elasticsearchクラスタのデプロイ

上記で説明したARMテンプレートを利用してElasticsearchクラスタのデプロイを行う。ここで使うARMテンプレートはAzureクイック・スタートテンプレートギャラリーにあるElasticsearchテンプレートを利用する。ARMテンプレートを使ったデプロイには複数の方法があるがここではLinux上でAzure CLIを使った方法で行う。ここでの実行OSはUbuntu 14.10。

最新版のAzure CLIをインストールしてからAzureサブスクリプションに接続する

$ sudo npm install -g azure-cli
$ azure --version
$ azure login

Azure コマンド ライン インターフェイス (Azure CLI) からの Azure サブスクリプションへの接続」に書かれているように、Azure CLI バージョン 0.9.10 以降では、対話型の azure login コマンドを使用して、任意の ID でアカウントにログインできる。尚、バージョン 0.9.9 以降は、多要素認証をサポートしている。

デプロイ用のリソースグループを作成する
ここでは西日本(Japan West)リージョンにResource-ES-JapanWestという名前のリソースグループを作成する。

# azure group create -n "<リソースグループ名>" -l "<リージョン名>"
$ azure group create -n "Resource-ES-JapanWest" -l "Japan West"

ARMテンプレートのダウンロードとパラメータの編集
Githubよりazure-quickstart-templatesをコピーして、Elasticsearch用テンプレートディレクトリに移動する

$ git clone https://github.com/Azure/azure-quickstart-templates.git
$ cd azure-quickstart-template/elasticsearch

azuredeploy.parameters.jsonを編集してデプロイ用パラメータを入力する。ここでの入力内容は下記のとおり

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "value": "yoichika"       # 管理用ユーザ名
    },
    "adminPassword": {
      "value": "*********"      # 上記管理ユーザパスワード
    },
    "vmDataNodeCount": {
      "value": 3                # データノード数
    },
    "virtualNetworkName": {
      "value": "esvnet"         # 仮想ネットワーク名
    },
    "esClusterName": {
      "value": "elasticsearch"  # ESクラスタ名
    },
    "loadBalancerType": {
      "value": "internal"       # LBタイプ external or internal
    },
    "vmSizeDataNodes": {      
      "value": "Standard_D1"    # データノード用のVMインスタンスサイズ
    },
    "vmClientNodeCount": {
      "value": 0               #クライアントノード数
    },
    "marvel": {
      "value": "no"             # Marvel有効化: yes or no
    },
    "kibana": {
      "value": "yes"            # Kibana有効化: yes or no
    },
    "OS": {
      "value": "ubuntu"        
    }
  }
}

ARMテンプレートを元にクラスタのデプロイ

一通り準備が整ったのでARMテンプレートを元に上記で作成したリソースグループにESクラスタをデプロイする。

# azure group create "<resource group名>" "<リージョン>" \
#    -f <azuredeploy.jsonファイル>
#    -d "<deploy名>"
#    -e <azuredeploy.parameters.jsonファイル>

$ azure group create "Resource-ES-JapanWest" "JapanWest" \
   -f azuredeploy.json \
   -d "Deploy-ES-JapanWest" \
   -e azuredeploy.parameters.json

途中のデプロイメント状況は次のコマンドで確認することができる。

# azure group deployment show "<Resource group名>" "<deployment名>"
$ azure group deployment show  "Resource-ES-JapanWest" "Deploy-ES-JapanWest"

上記コマンドの処理が完了すればデプロイ完了。たったこれだけ。出来上がった構成だが、手っ取り早くはAzureポータルで確認することができる。デプロイ用に作成したリソースグループ(ここではResource-ES-JapanWest)の中身を見ていただくとデプロイされた様々なリソース一覧(ストレージ、仮想ネットワーク、ロードバランサー、仮想マシン、ネットワークセキュリティグループ、パブリック用IP・・・など)が出来上がっていることが分かる。尚、出来上がったESクラスタは合計8VMで構成されており、ESマスターノード用に3つ、ESデータノード用に3つ、Kibana用に1つ、踏み台サーバ用に1つとなっている。仮想ネットワーク内のVMの配置状況を図にすると次のようになる。


ES-cluster-deployment

テスト実行

テスト用のデータセットを投入して、問題なくクラスタが動作するのかを確認してみる。データはこちらでテストに提供されている shakespeare.jsonを利用する。shakespeare.jsonをダウンロード済みであること前提に下記のようにESクラスタにデータを投入する。

まずはshakespeareデータセットのためにフィールドのMappingを実行

curl -XPUT http://<ESノードのアドレス>:9200/shakespeare -d '
{
 "mappings" : {
  "_default_" : {
   "properties" : {
    "speaker" : {"type": "string", "index" : "not_analyzed" },
    "play_name" : {"type": "string", "index" : "not_analyzed" },
    "line_id" : { "type" : "integer" },
    "speech_number" : { "type" : "integer" }
   }
  }
 }
}
'
;

次にshakespeareデータセットをESクラスタにロード。

curl -XPOST "<ESノードのアドレス>:9200/shakespeare/_bulk?pretty" --data-binary @shakespeare.json

上記処理完了後無事ロードが完了したかどうかインデックスのステータスを確認する。

$ curl '<ESノードのアドレス>:9200/_cat/indices?v'

(結果)
health status index               pri rep docs.count docs.deleted store.size pri.store.size
green  open   shakespeare           5   1     111396            0     36.2mb           18mb
green  open   .kibana               1   1          2            0     35.6kb         17.8kb

念のために検索クエリーを投げてみる。

$ curl -s '<ESノードのアドレス>:9200/shakespeare/_search?q=*&size=1' | \
  python -mjson.tool| perl -Xpne 's/\\u([0-9a-fA-F]{4})/chr(hex($1))/eg'

(結果)
{
    "_shards": {
        "failed": 0,
        "successful": 5,
        "total": 5
    },
    "hits": {
        "hits": [
            {
                "_id": "4904",
                "_index": "shakespeare",
                "_score": 1.0,
                "_source": {
                    "line_id": 4905,
                    "line_number": "3.3.74",
                    "play_name": "Henry VI Part 1",
                    "speaker": "JOAN LA PUCELLE",
                    "speech_number": 18,
                    "text_entry": "See, then, thou fightst against thy countrymen"
                },
                "_type": "line"
            }
        ],
        "max_score": 1.0,
        "total": 111396
    },
    "timed_out": false,
    "took": 9
}

さらにKibanaにアクセスしてESクラスタとの連携に問題がないか確認する。念のためにKibanaのエントリポイントはhttp://Kibanaアドレス:5601。特に問題なければKibana上で検索すると次のようにテストロードしたデータセットが閲覧できるはず。


Kibana-Page

elasticsearch-headでクラスタノードの状態を確認

elasticsearch-headはクラスタの構成やインデックスの中身表示、検索クエリの作成、結果取得など手軽に確認することができる便利なGUIツール。このelasticsearch-headを使ってクラスタノードの状態を確認する。インストールは次のようにプラグインコマンドで行う。

$ sudo /usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head

elasticsearch-headのエントリーポイントはhttp://<host>:9200/_plugin/headで結果は次のとおり。


elasticsearch-head-snapshot-shakespeare

これを分かりやすくトポロジーにしてみたのが下図。緑の太枠のところがプライマリーシャードで細枠がレプリカシャードを表す。


ES-Cluster-Topology

ノードdiscoveryについて

Elasticsearchはノードdiscovery方式としてデフォルトでmulticastモードを使うようになっており、ノード間でクラスタ名(ここではelasticsearch)を合わせることで内部的に勝手にクラスタ構成を組んでくれるようになっている。このクラスタ内ノード探索はzen discoveryという探索モジュールが使われている。ただし、Azureの場合は仕組み上マルチキャストが利用できない(これはAWSでも同じ)ためunicastモードを使って見つける必要がある。

ノードdiscovery方式はelasticsearchの設定ファイルelasticsearch.ymlに指定し、unicastモードの場合はdiscovery.zen.ping.unicast.hostsパラメターにノード群のIPをカンマ区切りで指定する。参考までに今回のデータノードのelasticsearch.ymlでは下記のように3つのデータノードのIPをdiscovery.zen.ping.unicast.hostsに指定している。

/etc/elasticsearch/elasticsearch.yml

cluster.name: elasticsearch
node.name: esdatavm0
path.data: /datadisks/disk2/elasticsearch/data,/datadisks/disk1/elasticsearch/data
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["10.0.0.10","10.0.0.11","10.0.0.12"]
node.master: false
node.data: true
discovery.zen.minimum_master_nodes: 2
network.host: _non_loopback_

Azure Cloud pluginの紹介
最後にAzure Cloud pluginの紹介をしたい。これはAzure APIを使って自動でAzureに展開されたノードの探索を行うことができるノードdiscoveryプラグインで、unicastモードのようにノードIPをいちいち指定する必要がない点でmulticastモードに似ている。ただし注意点としてこのプラグインはクラシックデプロイモデル管理下のリソース(V1)のみとなっている。よって、今回のようにARMテンプレートでデプロイしたESクラスタは対象外であるが、もしクラシックモデルでデプロイしたESクラスタであればノードdiscovery方式の1つとして是非お試しいただければと思う。

Enjoy Elasticsearch on Azure!!

おわり

LINKS