Azure Functions を使用したサーバーレスなイベント処理Serverless event processing using Azure Functions

この参照アーキテクチャは、データ ストリームの取り込み、データ処理、およびバックエンド データベースへの結果の書き込みを行うサーバーレスなイベント ドリブン アーキテクチャを示しています。This reference architecture shows a serverless, event-driven architecture that ingests a stream of data, processes the data, and writes the results to a back-end database.

GitHub ロゴ このアーキテクチャのリファレンス実装は、GitHub で入手できます。GitHub logo A reference implementation for this architecture is available on GitHub.

Azure Functions を使用したサーバーレスなイベント処理の参照アーキテクチャ

ArchitectureArchitecture

Event Hubs は、データ ストリームを取り込みます。Event Hubs ingests the data stream. Event Hubs は、高スループットのデータ ストリーミング シナリオ用に設計されています。Event Hubs is designed for high-throughput data streaming scenarios.

注意

IoT シナリオの場合は、IoT Hub をお勧めします。For IoT scenarios, we recommend IoT Hub. IoT Hub には、Azure Event Hubs API と互換性がある組み込みのエンドポイントが含まれているため、このアーキテクチャではどちらのサービスも使用できます。その際、バックエンド処理に大きな変更は必要ありません。IoT Hub has a built-in endpoint that’s compatible with the Azure Event Hubs API, so you can use either service in this architecture with no major changes in the backend processing. 詳細については、「IoT デバイスを Azure に接続する:IoT Hub と Event Hubs」を参照してください。For more information, see Connecting IoT Devices to Azure: IoT Hub and Event Hubs.

Function AppFunction App. Azure Functions はサーバーレス コンピューティングの 1 つのオプションです。Azure Functions is a serverless compute option. ひとまとまりのコード ("関数") がトリガーによって呼び出されるイベント ドリブン モデルが使用されます。It uses an event-driven model, where a piece of code (a “function”) is invoked by a trigger. このアーキテクチャでは、イベントが Event Hubs に到達したとき、そのイベントを処理し、結果をストレージに書き込む関数がトリガーされます。In this architecture, when events arrive at Event Hubs, they trigger a function that processes the events and writes the results to storage.

Function App は、Event Hubs からの個々のレコードを処理するのに適しています。Function Apps are suitable for processing individual records from Event Hubs. ストリーム処理シナリオが複雑な場合は、Azure Databricks を使用した Apache Spark、または Azure Stream Analytics を検討してください。For more complex stream processing scenarios, consider Apache Spark using Azure Databricks, or Azure Stream Analytics.

Cosmos DBCosmos DB. Cosmos DB は、マルチモデル データベース サービスです。Cosmos DB is a multi-model database service. このシナリオでは、Cosmos DB SQL API を使用して、イベント処理関数に JSON レコードが格納されます。For this scenario, the event-processing function stores JSON records, using the Cosmos DB SQL API.

Queue StorageQueue storage. Queue Storage は、配信不能メッセージに使用されます。Queue storage is used for dead letter messages. イベントの処理中にエラーが発生した場合、イベント データは後で処理できるように、関数によって配信不能キューに格納されます。If an error occurs while processing an event, the function stores the event data in a dead letter queue for later processing. 詳細については、「回復性に関する考慮事項」を参照してください。For more information, see Resiliency Considerations.

Azure MonitorAzure Monitor. Monitor は、ソリューションにデプロイされた Azure サービスに関するパフォーマンス メトリックを収集します。Monitor collects performance metrics about the Azure services deployed in the solution. ダッシュボードでこれらを視覚化することで、ソリューションの正常性を把握できます。By visualizing these in a dashboard, you can get visibility into the health of the solution.

Azure PipelinesAzure Pipelines. Pipelines は、アプリケーションをビルド、テスト、デプロイする継続的インテグレーション (CI) および継続的デリバリー (CD) サービスです。Pipelines is a continuous integration (CI) and continuous delivery (CD) service that builds, tests, and deploys the application.

スケーラビリティに関する考慮事項Scalability considerations

Event HubsEvent Hubs

Event Hubs のスループット容量は、スループット ユニットで測定されます。The throughput capacity of Event Hubs is measured in throughput units. 自動インフレを有効にすると、イベント ハブを自動スケーリングできます。自動インフレでは、トラフィックに基づいて、スループット ユニットが構成済みの最大値まで自動的にスケーリングされます。You can autoscale an event hub by enabling auto-inflate, which automatically scales the throughput units based on traffic, up to a configured maximum.

関数アプリの Event Hub トリガーは、イベント ハブ内のパーティション数に従ってスケーリングされます。The Event Hub trigger in the function app scales according to the number of partitions in the event hub. 各パーティションには、関数インスタンスが 1 つずつ割り当てられます。Each partition is assigned one function instance at a time. スループットを最大化するには、イベントは 1 つずつではなくバッチで受信します。To maximize throughput, receive the events in a batch, instead of one at a time.

Cosmos DBCosmos DB

Cosmos DB のスループット容量は、要求ユニット (RU) で測定されます。Throughput capacity for Cosmos DB is measured in Request Units (RU). Cosmos DB コンテナーを 10,000 RU を超えてスケーリングするには、コンテナーの作成時にパーティション キーを指定し、作成するすべてのドキュメントにパーティション キーを含める必要があります。In order to scale a Cosmos DB container past 10,000 RU, you must specify a partition key when you create the container, and include the partition key in every document that you create.

適切なパーティション キーの特徴をいくつか次に示します。Here are some characteristics of a good partition key:

  • キー値のスペースが大きい。The key value space is large.
  • キー値ごとに読み取り/書き込みが均等に分散され、ホット キーが発生しない。There will be an even distribution of reads/writes per key value, avoiding hot keys.
  • 任意の単一キー値の最大格納データが、物理パーティションの最大サイズ (10 GB) を超えない。The maximum data stored for any single key value will not exceed the maximum physical partition size (10 GB).
  • ドキュメントのパーティション キーが変更されない。The partition key for a document won't change. 既存のドキュメントでパーティション キーを更新することはできません。You can't update the partition key on an existing document.

この参照アーキテクチャのシナリオでは、関数に格納されるドキュメントは、データを送信するデバイスごとに 1 つだけです。In the scenario for this reference architecture, the function stores exactly one document per device that is sending data. 関数は、upsert 操作を使用して、最新のデバイスの状態でドキュメントを継続的に更新します。The function continually updates the documents with latest device status, using an upsert operation. このシナリオでは、書き込みがキーの間で均等に分散されるため、パーティション キーにはデバイス ID が適しています。また、キー値ごと 1 つのドキュメントが存在するため、各パーティションのサイズは厳密にバインドされています。Device ID is a good partition key for this scenario, because writes will be evenly distributed across the keys, and the size of each partition will be strictly bounded, because there is a single document for each key value. パーティション キーの詳細については、「Azure Cosmos DB でのパーティション分割とスケーリング」を参照してください。For more information about partition keys, see Partition and scale in Azure Cosmos DB.

回復性に関する考慮事項Resiliency considerations

Functions と共に Event Hubs トリガーを使用する場合、お使いの処理ループ内で例外がキャッチされます。When using the Event Hubs trigger with Functions, catch exceptions within your processing loop. ハンドルされない例外が発生すると、Functions ランタイムではメッセージの再試行は行われません。If an unhandled exception occurs, the Functions runtime does not retry the messages. 処理できないメッセージは、配信不能キューに配置されます。If a message cannot be processed, put the message into a dead letter queue. そのメッセージは、帯域外のプロセスを使用して調べられ、是正措置が決定されます。Use an out-of-band process to examine the messages and determine corrective action.

次のコードは、どのようにインジェスト関数が例外をキャッチし、未処理のメッセージを配信不能キューに書き込むかを示しています。The following code shows how the ingestion function catches exceptions and puts unprocessed messages onto a dead letter queue.

[FunctionName("RawTelemetryFunction")]
[StorageAccount("DeadLetterStorage")]
public static async Task RunAsync(
    [EventHubTrigger("%EventHubName%", Connection = "EventHubConnection", ConsumerGroup ="%EventHubConsumerGroup%")]EventData[] messages,
    [Queue("deadletterqueue")] IAsyncCollector<DeadLetterMessage> deadLetterMessages,
    ILogger logger)
{
    foreach (var message in messages)
    {
        DeviceState deviceState = null;

        try
        {
            deviceState = telemetryProcessor.Deserialize(message.Body.Array, logger);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error deserializing message", message.SystemProperties.PartitionKey, message.SystemProperties.SequenceNumber);
            await deadLetterMessages.AddAsync(new DeadLetterMessage { Issue = ex.Message, EventData = message });
        }

        try
        {
            await stateChangeProcessor.UpdateState(deviceState, logger);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error updating status document", deviceState);
            await deadLetterMessages.AddAsync(new DeadLetterMessage { Issue = ex.Message, EventData = message, DeviceState = deviceState });
        }
    }
}

関数がキュー ストレージの出力バインドを使用して、項目をキューに配置していることに注意してください。Notice that the function uses the Queue storage output binding to put items in the queue.

また、上記のコードにより、例外が Application Insights にログ記録されます。The code shown above also logs exceptions to Application Insights. パーティション キーとシーケンス番号を使用すると、配信不能メッセージを、ログの例外に関連付けることができます。You can use the partition key and sequence number to correlate dead letter messages with the exceptions in the logs.

配信不能キューのメッセージには、エラーのコンテキストを把握するのに十分な情報が記載されているはずです。Messages in the dead letter queue should have enough information so that you can understand the context of error. この例の DeadLetterMessage クラスには、例外メッセージ、元のイベント データ、および逆シリアル化されたイベント メッセージ (使用可能な場合) が含まれています。In this example, the DeadLetterMessage class contains the exception message, the original event data, and the deserialized event message (if available).

public class DeadLetterMessage
{
    public string Issue { get; set; }
    public EventData EventData { get; set; }
    public DeviceState DeviceState { get; set; }
}

Azure Monitor を使用して、イベント ハブを監視します。Use Azure Monitor to monitor the event hub. 入力があり、出力がない場合は、メッセージが処理されていないことを意味します。If you see there is input but no output, it means that messages are not being processed. その場合は、Log Analytics に移動し、例外またはその他のエラーを探します。In that case, go into Log Analytics and look for exceptions or other errors.

ディザスター リカバリーの考慮事項Disaster recovery considerations

ここに示したデプロイは単一の Azure リージョンに存在します。The deployment shown here resides in a single Azure region. ディザスター リカバリーでより回復性に優れたアプローチを実現するには、さまざまなサービスで地理的分散機能を利用します。For a more resilient approach to disaster-recovery, take advantage of geo-distribution features in the various services:

  • Event HubsEvent Hubs. プライマリ (アクティブ) 名前空間とセカンダリ (パッシブ) 名前空間の 2 つの Event Hubs 名前空間を作成します。Create two Event Hubs namespaces, a primary (active) namespace and a secondary (passive) namespace. メッセージは、セカンダリ名前空間にフェールオーバーしない限り、アクティブな名前空間に自動的にルーティングされます。Messages are automatically routed to the active namespace unless you fail over to the secondary namespace. 詳細については、「Azure Event Hubs geo ディザスター リカバリー」を参照してください。For more information, see Azure Event Hubs Geo-disaster recovery.

  • Function AppFunction App. セカンダリ Event Hubs 名前空間からの読み取りを待っている 2 つ目の関数アプリをデプロイします。Deploy a second function app that is waiting to read from the secondary Event Hubs namespace. この関数は、配信不能キュー用にセカンダリ ストレージ アカウントに書き込みます。This function writes to a secondary storage account for dead letter queue.

  • Cosmos DBCosmos DB. Cosmos DB では複数のマスター リージョンがサポートされています。これにより、Cosmos DB アカウントに追加した任意のリージョンに書き込むことができます。Cosmos DB supports multiple master regions, which enables writes to any region that you add to your Cosmos DB account. マルチマスターを有効にしなくても、プライマリ書き込みリージョンにはフェールオーバーできます。If you don’t enable multi-master, you can still fail over the primary write region. フェールオーバーは、Cosmos DB クライアント SDK と Azure Functions のバインディングによって自動的に処理されるため、アプリケーション構成設定を更新する必要はありません。The Cosmos DB client SDKs and the Azure Function bindings automatically handle the failover, so you don’t need to update any application configuration settings.

  • Azure StorageAzure Storage. 配信不能キューに対して RA-GRS ストレージを使用します。Use RA-GRS storage for the dead letter queue. これにより、別のリージョンに読み取り専用レプリカが作成されます。This creates a read-only replica in another region. プライマリ リージョンが利用不可になると、現在キューにある項目を読み取ることができます。If the primary region becomes unavailable, you can read the items currently in the queue. さらに、セカンダリ リージョンに別のストレージ アカウントをプロビジョニングします。これには、フェールオーバー後に関数が書き込むことができます。In addition, provision another storage account in the secondary region that the function can write to after a fail-over.

コストに関する考慮事項Cost considerations

コストを見積もるには、Azure 料金計算ツールを使用します。Use the Azure Pricing calculator to estimates costs. その他の考慮事項のいくつかを次に示します。Here are some other considerations.

Azure FunctionsAzure Functions

Azure Functions では 2 つのホスティング モデルがサポートされています。Azure Functions supports two hosting models.

  • 従量課金プランConsumption plan.

    コードの実行時にコンピューティング能力が自動的に割り当てられます。Compute power is automatically allocated when your code is running.

  • App Service プラン。App Service plan.

    一連の VM がお使いのコードに対して割り当てられます。A set of VMs are allocated for your code. App Service プランで定義されるのは VM の数とサイズです。The App Service plan defines the number of VMs and the VM size.

このアーキテクチャでは、Event Hubs に到着するイベントごとに、そのイベントを処理する関数がトリガーされます。In this architecture, each event that arrives on Event Hubs, triggers a function that processes that event. 従量課金プランでは使用したコンピューティング リソースにしか支払いが発生しないため、コストの観点から、こちらのプランを使用することをお勧めします。From a cost perspective, the recommendation is to use consumption plan because you pay only for the compute resources you use.

Azure Cosmos DBAzure Cosmos DB

Azure Cosmos DB では、プロビジョニングされたスループットと消費されたストレージに対して時間単位で課金されます。Azure Cosmos DB bills for provisioned throughput and consumed storage by hour. プロビジョニングされたスループットは要求ユニット/秒 (RU/秒) で表され、挿入、読み取りなどの一般的なデータベース操作に使用できます。Provisioned throughput is expressed in Request Units per second (RU/s), which can be used for typical database operations, such as inserts, reads. 価格は、予約した RU/秒の容量に基づいています。The price is based on the capacity in RU/s that you reserve. また、1 KB のドキュメントの同時読み取りで 1 RU が消費される場合は、コンテナーあたり少なくとも 400 RU を予約する必要があります。Also, you have to reserve a minimum of 400 RUs per container, where a concurrent read of 1KB document consumes 1 RU. コンテナーごとに固定費がかかるため、アプリでこのように多くの処理を実行する必要がない場合は、1 つのコンテナーを使用することを検討してください。If your app does not need to be this intensive, consider using a single container because each container has a fixed cost.

この参照アーキテクチャでは、関数に格納されるドキュメントは、データを送信するデバイスごとに 1 つだけです。In this reference architecture, the function stores exactly one document per device that is sending data. 関数は、upsert 操作を使用して、最新のデバイスの状態でドキュメントを継続的に更新します。これはストレージ使用の点でコスト効率に優れています。The function continually updates the documents with latest device status, using an upsert operation, which is cost effective in terms of consumed storage. 詳細については、Cosmos DB の価格モデルに関するページを参照してください。For more information, see Cosmos DB pricing model.

ストレージへの課金は、格納データとインデックスに使用される GB ごとに行われます。Storage is billed for each GB used for your stored data and index.

ワークロード コストをすばやく見積もるには、Cosmos DB 容量計算ツールを使用します。Use the Cosmos DB capacity calculator to get a quick estimate of the workload cost.

詳細については、「Microsoft Azure Well-Architected Framework」のコストのセクションを参照してください。For more information, see the Cost section in Microsoft Azure Well-Architected Framework.

ソリューションのデプロイ方法Deploy the solution

この参照アーキテクチャをデプロイするには、GitHub の Readme をご覧ください。To deploy this reference architecture, view the GitHub readme.

次のステップNext steps

リファレンス実装について詳しくは、「コードのチュートリアル: Azure Functions を使用したサーバーレス アプリケーション」をご覧ください。To learn more about the reference implementation, read Code walkthrough: Serverless application with Azure Functions.