DocumentDB

これは9/29 Azure Web Seminar 「Azure サービスを活用して作るフルマネージドな全文検索アプリケーション」のフォローアップ記事です。なかなか暇ができず少々時間が経過してしまいました。


Azure サービスを活用して作るフルマネージドな全文検索アプリケーション from Yoichi Kawasaki

Sample Application & Source Code

セミナーで紹介したサンプルアプリはAzure公式サイトに載せてある代表的なサービスのFAQデータを元にしたHTML/CSS/JavascriptによるQ&Aナレジッジベース検索のシングルページアプリケーションです。検索エンジンにAzure Searchを使い、データソースにCosmos DBを使いAzure SearchのCosmosDB Indexerでクローリングする構成にしてます。ソースコードと設定手順は以下Githubプロジェクトにアップしてあります。もしバグや設定手順等でご質問があればGithubでIssue登録いただければ時間を見つけて対応させていただきます。


Source Code: https://github.com/yokawasa/azure-search-qna-demo/

Demo: AI Digital Media Search

セミナー中に紹介した非構造化データの全文検索デモとして紹介したAI Digital Media Searchアプリケーション。メディア x 音声認識 x 機械翻訳 x 全文検索全てを絡めた面白いアプリケーションなのでこちらでデモ動画とソースコードを共有します。またこのアプリはAzure PaaSサービスを組み合わせてプレゼンテーションレイヤー(Web App for Container)のみならずデータ生成部分(AMS, Functions, Logic App)も全てサーバレスで実現しているのでこのエリアのサンプルアプリとしてもとても良いものになっていると思います。

Source Code: https://github.com/shigeyf/ai-digitalmedia

AzureSearch.js – Azure Search UIライブラリ

AzureSearch.jsはAzure SearchのUIライブラリで、Azure Searchプロダクトチーム主要開発者により開始されたOSSライブラリです。TypeScriptで書かれているのでとても読みやすく、また、ライブラリが提供するオブジェクト操作により非常に短いコードでサーチボックス、結果出力、ページネーション、ファセット、サジェスションなどで構成されるサーチ用UIを簡単に組み立てることが可能です。なかなかいけているライブラリにもかかわらず、あまり世の中に知られていないのはもったいないと思いセミナーの最後で紹介させていただきました。これ使わない手はないです。手っ取り早くは、下記のAzureSearch.jsアプリテンプレートジェネレータページで皆さんのAzure SearchアカウントのQueryKeyとインデックススキーマ(JSONフォーマット)を入力するとAzureSearch.jsアプリの雛形が生成されますので、そこから始めるのがよいかと思います。

END

I’d like to announce fluent-plugin-documentdb finally supports Azure DocumentDB Partitioned collections for higher storage and throughput. If you’re not familiar with fluent-plugin-documentdb, read my previous article before move on.

Partitioned collections is kick-ass feature that I had wanted to support in fluent-plugin-documentdb since the feature came out public (see the announcement). For big fan of fluent-plugin-documentdb, sorry for keeping you waiting for such a long time 🙂 If I may make excuses, I would say I haven’t had as much time on the project, and I had to do ruby client implementation of Partitioned collections by myself as there is no official DocumentDB Ruby SDK that supports it (As a result I’ve created tiny Ruby DocumentDB client libraries that support the feature. Check this out if you’re interested).


fluentd-azure-documentdb-collection

What are Partitioned collections?

According to official documentation, Partitioned collections can span multiple partitions and support very large amounts of storage and throughput. You must specify a partition key for the collection. Partitioned collections can support larger data volumes and process more requests compared to Single-partitioned collection. Partitioned collections support up to 250 GB of storage and 250,000 request units per second of provisioned throughput [Updated Aug 21, 2016] (@arkramac pointed that out for me) Partitioned collections support unlimited storage and throughput. 250GB storage and 250k req/sec are soft cap. You can increase these limits by contacting and asking Azure support.

On the other hand, Single-partition collections have lower price options and the ability to query and perform transactions across all collection data. They have the scalability and storage limits of a single partition. You do not have to specify a partition key for these collections.

Creation of Partitioned collections

You can create Partitioned collections via the Azure portal, REST API ( >= version 2015-12-16), and client SDKs in .NET, Node.js, Java, and Python. In addition, you let fluent-plugin-documentdb create Partitioned collections automatically by adding the following configuration options upon the ones for single-partitioned collection in fluentd.conf:

It creates a partitioned collection as you configure in starting the plugin if not exist at that time.

Configuration Example

Suppose that you want to read Apache access log as source for fluentd, and that you pick “host” as a partition Key for the collection, you can configure the plugin like this following:

<source>
    @type tail                          # input plugin
    path /var/log/apache2/access.log   # monitoring file
    pos_file /tmp/fluentd_pos_file     # position file
    format apache                      # format
    tag documentdb.access              # tag
</source>

<match documentdb.*>
    @type documentdb
    docdb_endpoint https://yoichikademo.documents.azure.com:443/
    docdb_account_key Tl1xykQxnExUisJ+BXwbbaC8NtUqYVE9kUDXCNust5aYBduhui29Xtxz3DLP88PayjtgtnARc1PW+2wlA6jCJw==
    docdb_database mydb
    docdb_collection my-partitioned-collection
    auto_create_database true
    auto_create_collection true
    partitioned_collection true
    partition_key host
    offer_throughput 10100
    localtime true
    time_format %Y%m%d-%H:%M:%S
    add_time_field true
    time_field_name time
    add_tag_field true
    tag_field_name tag
</match>

Basically that’s all additional configuration for Partitioned collections. Please refer to my previous article for the rest of setup and running work for the plugin.

Happy log collections with fluent-plugin-documentdb!!

LINKS

In this article, I’d like to introduces a solution to collect logs and store them into Azure DocumentDB using fluentd and its plugin, fluent-plugin-documentdb.

Azure DocumentDB is a managed NoSQL database service provided by Microsoft Azure. It’s schemaless, natively support JSON, very easy-to-use, very fast, highly reliable, and enables rapid deployment, you name it. Fluentd is an open source data collector, which lets you unify the data collection and consumption for a better use and understanding of data. fluent-plugin-documentdb is fluentd output plugin that enables to store event collections into Azure DocumentDB.

This article shows how to

UPDATED:

Here is a list of fluentd plugins for Microsoft Azure Services.

Plugin NameTarget Azure ServicesNote
fluent-plugin-azurestorageBlob StorageAzure Storate output plugin buffers logs in local file and upload them to Azure Storage periodicall
fluent-plugin-azureeventhubsEvent HubsAzure Event Hubs buffered output plugin for Fluentd. Currently it supports only HTTPS (not AMQP)
fluent-plugin-azuretablesAzure TablesFluent plugin to add event record into Azure Tables Storage
fluent-plugin-azuresearchAzure SearchFluent plugin to add event record into Azure Search
fluent-plugin-documentdbDocumentDBFluent plugin to add event record into Azure DocumentDB
fluent-plugin-azurefunctionsAzure FunctionsAzure Functions (HTTP Trigger) output plugin for Fluentd. The plugin aggregates semi-structured data in real-time and writes the buffered data via HTTPS request to HTTP Trigger Function.
fluent-plugin-azure-loganalyticsLog AnalyticsAzure Log Analytics output plugin for Fluentd. The plugin aggregates semi-structured data in real-time and writes the buffered data via HTTPS request to Azure Log Analytics.

(as of Nov 23, 2016)



fluentd

Azure Searchのインデックス更新方法には大きく分けてPUSHとPULLの2種類ある。PUSHは直接Indexing APIを使ってAzure SearchにコンテンツをPOSTして更新。PULLは特定データソースに対してポーリングして更新で、Azure Searchの場合、DocumentDBとSQL Databaseの2種類のデータソースを対象にワンタイムもしくは定期的なスケジュール実行が可能となっている。ここではDocumentDBをデータソースとしてインデックスを更新する方法を紹介する。

サンプル構成と処理フローの説明

データソースにDocumentDBを利用する。データ「DOCUMENTDB PYTHON SDKとFEEDPARSERで作る簡易クローラー」においてクローリングされDocumentDBに保存されたブログ記事データを使用する。そしてDocumentDBを定期的にポーリングを行い更新があったレコードのみをAzure Searchインデックスに反映するためにDocumentDBインデクサーを設定する。全体構成としては下記の通りとなる。


documentdb-indexer

DocumentDBと更新先検索インデックスのフィールドのマッピング

DocumentDBをデータソースとしてAzure Searchインデックスに更新を行うためDocumentDBの参照先コレクションのフィールドと更新先Azure Searchインデックスのフィールドをマッピングを行う。マッピングはデータソース定義中のDocumentDB参照用Queryで行う。Azure SearchインデックスにインジェストするフィールドをDocumentDBのSELECTクエリー指定するのだが、Azure SearchとDocumentDBのフィールドが異なる場合は下図のようにSELECT “Docdbフィールド名” AS “Searchフィールド名”でインジェスト先フィールド名を指定する。データソース定義については後述の設定内容を確認ください。


documentdb-azuresearch-mapping

Configuration

以下1~4のステップでデータソースの作成、検索インデックスの作成、インデクサーの作成、インデクサーの実行を行う。

  1. データソースの作成
  2. credential.connectionStringで接続先DocumentDB文字列と対象データベースの指定を行う。container.(name|query)で対象コレクション名と参照用SELECT文を指定する。SELECT文はDocumentDBとインジェスト先Azure Searchのフィールドセット(フィールド名と数)が同じであれば省略可。詳細はこちらを参照。

  3. インデックスの作成
  4. 下記のスキーマでAzure Searchインデックスを作成する。

    {
        "name": "articles-test",
        "fields": [
            { "name":"itemno", "type":"Edm.String", "key": true, "searchable": false },
            { "name":"subject", "type":"Edm.String", "filterable":false, "sortable":false, "facetable":false},
            { "name":"body", "type":"Edm.String","filterable":false,"sortable":false, "facetable":false, "analyzer":"ja.lucene"},
            { "name":"url", "type":"Edm.String", "sortable":false, "facetable":false },
            { "name":"date", "type":"Edm.DateTimeOffset", "facetable":false}
         ]
    }
  5. DocumentDBインデクサーの作成
  6. DocumentDBインデクサー作成のための設定。DatSourceNameとtargetIndexNameにそれぞれ1で作成したデータソース名とインジェスト先のインデックス名を指定する。スケジュール実行させたい場合は下記の通りscheduleを設定する。ここではintervalをPT5Mとしているがこれは5分毎実行を意味する。詳しくはこちらを参照。

  7. インデクサーの明示的に実行
  8. スケジュール実行ではなくインデクサーをすぐに実行したい場合は下記のフォーマットでPOSTリクエストを送信する。

    POST https://[Search service name].search.windows.net/indexers/[indexer name]/run?api-version=[api-version]
    api-key: [Search service admin key]

実行結果確認方法


AzureSearchIndexerStatus

上記イメージの通りAzureポータル(preview)よりAzure Search → indexersタイルをたどることでインデクサーの実行結果や過去の履歴を確認することができる。ただし、ここではAPI経由で取得する方法を紹介する。
下記フォーマットでGETリクエストすることでインデクサーの現在の稼働状態と実行履歴を取得することができる。実行履歴は最後の実行結果だけではなく最近完了した50件の実行内容が含まれる。

GET https://[Search service name].search.windows.net/indexers/[indexer name]/status?api-version=[api-version]
api-key: [Search service admin key]

以下実行結果。executionHistoryが履歴、lastResultが最後の実行結果、statusが現在のインデクサーのステータスとなっている。

{
    "@odata.context": "https://yoichidemo.search.windows.net/$metadata#Microsoft.Azure.Search.V2015_02_28_Preview.IndexerExecutionInfo",
    "executionHistory": [
        {
            "endTime": "2015-06-25T05:55:01.393Z",
            "errorMessage": "Data source 'docdbds-article' does not exist",
            "errors": [],
            "finalTrackingState": null,
            "initialTrackingState": null,
            "itemsFailed": 0,
            "itemsProcessed": 0,
            "startTime": "2015-06-25T05:55:01.393Z",
            "status": "transientFailure"
        },
        ...(omit)...
        {
            "endTime": "2015-06-25T02:15:02.155Z",
            "errorMessage": null,
            "errors": [],
            "finalTrackingState": "1434871500",
            "initialTrackingState": "1434871500",
            "itemsFailed": 0,
            "itemsProcessed": 0,
            "startTime": "2015-06-25T02:15:01.452Z",
            "status": "success"
        },
        {
            "endTime": "2015-06-25T02:10:01.144Z",
            "errorMessage": null,
            "errors": [],
            "finalTrackingState": "1434871500",
            "initialTrackingState": "1434871500",
            "itemsFailed": 0,
            "itemsProcessed": 0,
            "startTime": "2015-06-25T02:10:00.022Z",
            "status": "success"
        }
    ],
    "lastResult": {
        "endTime": "2015-06-25T05:59:02.016Z",
        "errorMessage": "Data source 'docdbds-article' does not exist",
        "errors": [],
        "finalTrackingState": null,
        "initialTrackingState": null,
        "itemsFailed": 0,
        "itemsProcessed": 0,
        "startTime": "2015-06-25T05:59:02.016Z",
        "status": "transientFailure"
    },
    "name": "docdbindexer",
    "status": "running"
}

Content DBの有効性について

ここではAzure SearchのfeedingソリューションとしてDocumentDBを使用したPULLインデックス更新方法を紹介した。このようにクローリングされたデータを直接Azure SearchのIndex APIを使ってインデックスを更新するのではなく、今回のDocumentDBのように所謂Content DBに格納してからそれを元にインデックスを更新するのにはいくつか意味がある。例えば、インデックス構造を変更したい場合、再フィードが必要になるがContent DBがあれば再度クローリングする必要がない。通常クローリング(特にフルクローリング)のコストは大きい。また、Content DBがあれば別アカウント、リージョンにインデックスのレプリカの構築、他に、同一のデータを使って別構造のインデックを構築するといったことも容易に可能になる。
さらに、現時点でAzure Searchがデータ加工のためのパイプラインの仕組み(Lucene/Solr, ElasticSearchでいうところのカスタムAnalyzer)がないことから、インデックスに放り込む前の一時データ加工用のデータベースとしても有効であると考えている。

LINKS

DocumentDB Python SDKとfeedparserを使って簡易クローラーを作りましょうというお話。ここではDocumentDBをクローリング結果の格納先データストアとして使用する。クロール対象はAzure日本語ブログRSSフィード、これをfeedparserを使ってドキュメント解析、必要データの抽出、そしてその結果を今回使用するpydocumentdbというDocumentDB Python SDKを使ってDocumentDBに格納するというワークフローになっている。

DocumentDB Python SDK – pydocumentdb

Azureで提供されているどのサービスにもあてはまることであるが、DocumentDBを操作するための全てのインターフェースはREST APIとして提供されておりREST APIを内部的に使用してマイクロソフト謹製もしくは個人のコントリビューションによる複数の言語のSDKが用意されている。その中でもpydocumentdbはPython用のDocumentDB SDKであり、オープンソースとしてソースコードは全てGithubで公開されている。

Pre-Requirementsその1: Python実行環境とライブラリ

実行環境としてPython2.7系が必要となる。また、今回クローラーが使用しているDocumentDB Python SDKであるpydocumentdbとRSSフィード解析ライブラリfeedparserの2つのライブラリのインストールが必要となる。

Pre-requirementsその2: DocumentDBアカウント

Azure新ポータルより下記イメージのフローでDocumentDBアカウントを作成する。


DocumentDB-Account-Create

DocumentDBアカウントを作成したら今度はデータを格納するためのDocumentDBデータベースとコレクションを作成する必要がある。DocumentDBデータベースとコレクションはAzure新ポータルから作成可能であるが、今回のクローラープログラムではpydocumentdbを使って作成するようにしている。

RSSクローラーとその実行結果

RSSクローラーのソースコード(rssCrawler4Docdb.py)とその実行結果は下記の通り。もしクローリングを定期的に実行する場合はこのスクリプトをジョブスケジューラー(cronなど)に登録ください。指定のRSSフィードに新しく追加された記事のみがDocumentDBに反映されるようスクリプト上は重複チェックを入れている。

[実行結果]

database is created:feeddb
collection is created:article_collection
document is added:title:業界トップのクラウド アナリストがマイクロソフトに転身した理由
document is added:title:Azure Linux VM のインフラストラクチャの監視と診断
document is added:title:Azure App Service の Web アプリ用 Support Site Extension の追加更新
document is added:title:Azure CDN でカスタムのオリジン サーバーをサポート
document is added:title:Tinfoil Security の Azure App Service 向け Web 脆弱性スキャン機能
document is added:title:Azure Site Extensions の自動更新が可能に
document is added:title:DocumentDB へのデータのインポートがより高速、簡単に
document is added:title:Query Store: データベース版フライト データ レコーダー機能
document is added:title:Azure App Service の Web アプリで使用される TLS の中間証明書
document is added:title:Azure で Cloud Foundry をお試しください
document is added:title:Azure Media Indexer の更新版 v1.2.1 をリリース: 前回からの修正点について
document is added:title:クラウド環境でエンドツーエンドのビデオ ワークフローを構築する
document is added:title:Azure Media Player の更新と UserVoice フォーラムのお知らせ
document is added:title:Microsoft Azure 関連ニュース 2015 年 5 月のまとめ
document is added:title:Azure Media Services 向け Hyperlapse のパブリック プレビューを発表
document is added:title:6 月 1 日以降の Application Insights の料金設定
document is added:title:StorSimple Update 1 を発表: Azure Government で提供開始、他社クラウドと ZRS をサポート、5000/7000 シリーズからの移行に対応
document is added:title:成功から転落の危機に直面した Sleeve Music。経験豊かな開発者と適切なツールの選択で新たなアイデアを創出
document is added:title:Azure Storage に関する Build 2015 での発表
document is added:title:Visual Studio Code と Azure App Service の連携で実現できること
document is added:title:Azure Automation でグラフィック形式とテキスト形式の作成機能を導入
document is added:title:接続性の高い安定したハイブリッド クラウドの実現に向けた新しいネットワーク機能
document is added:title:DocumentDB の新しいインポート オプション
document is added:title:Azure Site Recovery が NetApp Private Storage for Microsoft Azure をサポート
document is added:title:Application Insights で ASP.NET 5 アプリケーションをサポート