Apache Kafka®とは？

<font color="Grey">*[What is Apache Kafka®?](https://aiven.io/blog/what-is-apache-kafka)の翻訳です。*</font>

2022年6月9日

# Apache Kafka®とは？

Kafkaやストリーミングの話題で混乱したことはありませんか？情報やリソースが満載のこの投稿で、基本的なことを学びましょう。

このページは **Apache Kafka® 入門** です。


* Apache Kafkaとは？
* イベントストリーミングとは何ですか？
* イベント駆動型アーキテクチャとは？
* マイクロサービスとは？
* Apache Kafkaはどこに位置するのか？
* Apache Kafkaはどのように機能するのか？
* Apache Kafkaのアプローチの利点は？
* Apache Kafka中心のアーキテクチャを構築するには？


......そして、おそらくまだ考えていないことがもっとある！



> ![](/build/_assets/shape-quote-WGSAHX4E.svg)
> もし時間がないのであれば、無料の電子書籍もお持ち帰りいただけます（上司に見せることもできます）！[Apache Kafkaとは何か、どのように機能するのか、そして技術リーダーはどのようにビジネスに活用することができるのか、[Apache Kafkaの概要を知るには](https://aiven.io/ebook/apache-kafka-for-tech-leaders)をご覧ください。
>
>
>


この投稿で


1.[Apache Kafka: 基本](#apache-kafka-the-basics)
2.[イベント駆動型アーキテクチャにおけるApache Kafkaのメリット](#benefits-of-apache-kafka-in-an-event-driven-architecture)
3.[Kafkaの仕組み](#how-does-kafka-work)
4.[イベントストリーミングとは何か](#what-is-event-streaming)
5.[あなたのアーキテクチャにおけるApache Kafka](#apache-kafka-in-your-architecture)
6.[Apache Kafka API](#apache-kafka-apis)
7.[Apache Kafkaでマイクロサービスを構築する](#building-microservices-with-apache-kafka)
8.[Apache Kafkaによるイベント駆動型アーキテクチャ：バリエーション](#event-driven-architecture-with-apache-kafka-variations)
9.[Apache Kafkaによるレガシーアーキテクチャの更新](#updating-legacy-architecture-with-apache-kafka)
10.[Apache Kafkaの管理](#managing-apache-kafka)
11.[Kafkaとデータの安全性](#kafka-and-data-safety)
12.[AivenでApache Kafkaを始める](#getting-started-with-apache-kafka-on-aiven)


## Apache Kafka: 基礎編


### 定義と用途


Apache Kafkaはよくイベントストリーミングプラットフォームとして説明される（それが何かわからない場合は、[これが役に立つかもしれない](#what-is-event-streaming)）。Apache Kafkaは、ある場所から別の場所にデータを移動させるための単なる手段なのだ。それこそが、Apache Kafkaをデータ・インフラストラクチャーのスイスアーミーナイフにしているのだ。


自分のアプリケーション間、アプリケーションとデータストア（PostgreSQLやAmazon S3など）間、あるいはデータストア間のデータ移動に使用できる。Apache Kafkaはアプリケーション同士を独立させるので、あるアプリケーションは他のアプリケーションの処理を待つことなくデータを渡すことができる。


Apache Kafkaを試す最も簡単な方法は、マネージド・サービスにサインアップして試してみることだ。そのためには、[Getting started with Apache Kafka on Aiven](#getting-started-with-apache-kafka-on-aiven)に直接アクセスしてください。


### Apache Kafkaはシンプルな接着剤？


基本的に、Apache Kafkaはアーキテクチャの非常にシンプルな部分ですが、それが強力な理由です - 複雑さを追加するのではなく、きれいなアーキテクチャの境界を出現させることができます。広く使われているオープンソースの製品として、Apache Kafkaには多くのクライアントやツールのオプションもあります。独自のアプリケーションを構築するのに役立つ高レベルのAPIやライブラリであれ、データストア間の既製の「接着剤」であれ、Apache Kafkaの内部で何が起こっているかを示す便利な管理インターフェースであれ、エコシステムにはすでに利用可能なものがあります。(そして、これらの管理インターフェイスは重要だ。Apache Kafkaは規模が大きくなると管理が難しくなることで悪名高いため、よくできたPaaSは安心感を与え、アプリケーション自体に集中させることができる)


ある意味では、Apache Kafkaはむしろ[メッセージングシステムとデータベースのクロス](https://aiven.io/blog/apache-kafka-and-the-great-database-debate)のようなものだ。両方の機能を共有しているが、メッセージキュー以上であり、データベースとも異なる。ほとんどすべてのシステムがプロデューサやコンシューマとして動作できるという事実は、Apache Kafkaの中心的な用途が、システム同士が会話してデータを共有するためのコンジットであることを意味する。システム間の複雑なコネクターやパイプラインのネットワークは必要ない。このことは、データ配信のスピードと信頼性だけでなく、Kafkaが適用できる[ユースケースの幅広さ](https://www.aiven.io/blog/use-cases-for-apache-kafka)にも大きな意味を持つ。


[Apache Kafkaの概念と用語](https://images.ctfassets.net/q3u27v6lpki8/6pNr86mlAD5j7tYDDLLJhj/f78046f6afd7df6de9bfde7965af82bd/box-concepts.png)


(もっと用語集が欲しいですか？[Apache Kafkaのキーコンセプト](https://www.aiven.io/blog/apache-kafka-key-concepts)をチェックしてください！)


## イベント駆動型アーキテクチャにおけるApache Kafkaの利点


[以前、[Aiven BlogでApache Kafkaの利点について少し触れました](https://aiven.io/blog/5-benefits-of-a-kafka-centric-microservice-architecture)が、イベントベースのデータアーキテクチャにApache Kafkaを使いたい理由を簡単に説明しましょう。


### 構造によるスピードアップ


昔々は、高速なメッセージング・プラットフォームか耐久性のあるメッセージング・プラットフォームのどちらかを選ばなければならなかった。というのも、"高速 "はしばしば "メッセージがメモリ上にしかない "として実装され、メッセージをディスクに書き込むことは遅すぎると揶揄されていたからだ。Apache Kafkaは、ストレージの使用方法を再考することで、そのすべてを変えた。メッセージがトピックに配置され、トピックがアペンドのみのパーティションに配置されると、**高速で耐久性のある**メッセージング・プラットフォームを持つことが可能になる。


### そして圧縮


Kafkaのスループットが速いもう一つの理由は、Kafka自身がデータの構造を気にしないことだ。しかし、プロデューサとコンシューマはデータの構造について合意しておく必要がある。これは多くの場合、*スキーマ・レジストリ*（例えば[Karapace](https://github.com/aiven/karapace/blob/master/README.rst)）と呼ばれる別のコンポーネントによって処理される。ここで、プロデューサ（あるいはシステム・アーキテクト）はメッセージの構造を保存することができ、コンシューマはその構造を読んで、どのフィールドなどが与えられたトピックのメッセージに含まれるかを予想することができる。可能であれば、これはメッセージの圧縮にもなる。フィールド名がすでにスキーマレジストリにあれば、各メッセージと一緒に送信する必要はない。


その結果、Kafkaのスケーラブルでフォールトトレラントなパブリッシュ・サブスクライブのメッセージング・プラットフォームは、Spotify、LinkedIn、Square、Twitterのような巨大なインターネット・プロパティでほぼユビキタスになっている。


### 素早くイン、素早くアウト


Kafkaはデータの書き込みと読み込みを分離しているため、スループットも速い。データは最終目的地で受信する必要はなく、プロデューサーがブローカーに書き込むだけでよい。同様に、コンシューマーは自分の都合の良い時にデータを読むことができ、プロデューサーの障害となることはない。


### スケーラビリティによる将来性


Kafkaの**スケーラビリティ**は、具体的な[ビジネス](https://aiven.io/case-studies/mirakl-goes-cloud-native-with-aiven) [メリット](https://aiven.io/case-studies/goto-financial-goes-far-with-aiven)を提供する。そのパーティショニングされたログモデルは、データを複数のブローカーに分散することを可能にし、膨大な量のデータを同じプラットフォームに、しかし異なるサーバーに常駐させることを可能にする。また、[MirrorMaker 2を使ってKafkaを地理的に耐障害性のあるものにする](https://www.aiven.io/blog/5-reasons-why-you-should-be-using-mirrormaker-2)のは簡単で、2つの異なるクラスタ（異なる地域、あるいは異なるクラウドにある可能性さえある）間でデータをレプリケートする。


### コピーによる安全性


Kafkaはサーバー、データセンター、クラウド間でデータをレプリケートするため、適切な設定を行えば、サーバーやリージョンに障害が発生してもデータは安全です。トピックごとにレプリケーションを設定することで、Kafkaはどのサーバーがデータの「所有者」で、どのサーバーが障害時に使用するレプリカコピーを持っているかを追跡します。問題発生後にKafkaのデータを手動でリストアすることは意味のない概念かもしれませんが、「レプリケーション係数」などの設定が要件に合っているかどうかには注意が必要です。  

詳しくは[データとディザスタリカバリ](https://aiven.io/blog/data-and-disaster-recovery)をご覧ください。


## Kafka はどのように機能するのか？


イベントドリブンの世界で使用する場合、Kafkaは各イベントを異なるメッセージと見なします。この場合、イベントは常に特定の時間（タイムスタンプ）に発生し、特定の事柄（キー）に関係し、その事柄（値）について何が起こったかを述べる。また、追加情報（メタデータ・ヘッダ）を含むこともある。


例えば


* 2022年2月2日16:37（タイムスタンプ）、Tania's Deli（メタデータ）でプルオ ートサンドイッチ（キー）が購入された（値）。
* 2022年2月3日（タイムスタンプ）、Tania's Deli（メタデータ）でプルオ ートサンドイッチ（キー）が10個（値）配達された。


### パブ/サブ


イベントは、**producers** と呼ばれるクライアントアプリケーションによって Kafka に書き込まれる、つまり発行される。他のアプリケーションは **consumers** と呼ばれ、Kafka からイベントを読み込む。


これは、**パブリッシュ・サブスクライブ・モデル（pub/sub**）と呼ばれ、プロデューサーは、イベントを読み込んでいるコンシューマーのことを意識したり、気にしたりすることはありません。  

Kafkaは、イベントのストリームをいくつかのトピックに整理する。トピックは基本的にカテゴリ名の付いたデータフィードであり、通常はスケーリングのためにパーティションに分割される。プロデューサーは、指定されたトピック内のイベントシーケンスにイベントレコードを追加して書き込む。


### トピックからの消費 - オフセットの重要性


コンシューマは、指定されたオフセット（トピック内のレコード番号）を起点として、特定のトピックからレコードを消費します。これにより、正しい順序を保持したままレコードを非同期に消費することが容易になります。あるコンシューマー（またはコンシューマーのグループ）の最後に知られていたオフセットも通常Apache Kafkaに保存されるため、コンシューマーが何らかの中断の後に再接続したときに、中断した場所からシームレスに再開することができます。


Kafkaトピックの構造。トピックはカテゴリ名の付いたデータフィードで、[ここではスループットを高速化するためにパーティションに分割して示している](https://images.ctfassets.net/q3u27v6lpki8/34ozH7TSA3ALLhLMMjHLnz/ac5054056a87769beac13f18158feff0/anatomy_of_a_topic.jpg)


プロデューサーは常にトピックキューの最後に書き込む。次にコンシューマは、設定されたオフセットに従ってデータを読み込み、[イベントの順序を保つ](https://images.ctfassets.net/q3u27v6lpki8/HAMxgTZRwn4izL2onEMBW/5297a074aeda78163e638254611d35e1/producers.jpg)


## イベントストリーミングとは？


Kafkaがイベント・ストリーミング・プラットフォームだとすると、イベント・ストリーミングとは何だろうか？イベントストリーミングとは、その箱に書いてある通り、他のシステムが他の場所で読んで処理できるように、サービスがイベントを連続的なストリームで公開することだ。重要なのは、イベントは順番に発生し、イベントのプロデューサは、誰が、何を読んでいるのか気にしないことだ。これは、異なるアプリケーションを互いに切り離す素晴らしい方法であり、どのアプリケーションも、そのアプリケーションが最も得意とすることに集中することができる。


つまり、リビングルームで『キャッツ』のブロードウェイ・ライブを観ているわけではない。イベント・ストリーミングは、イベント・ドリブン・アーキテクチャーが自宅で行うものだ。


### イベント・ストリーミングは何に使われるのか？


イベントストリーミングは、能動的にタスクを実行しているアプリケーション（センサーからの読み取りやクレジットカードのチャージなど）と、そのタスクの結果を観察して行動しているアプリケーション（エアコンのスイッチを切る、荷物を発送するなど）を分離するために使用されます。一般的な使い方をいくつか紹介しよう：


* インフラを監視し、異常を検出する。([Aivenのやり方を見る](https://aiven.io/case-studies/open-source-tools-provide-observability-for-aiven)!)
* 関連するビジネスプロセスのトリガー - 例えば、誰かが新しいアカウントを登録すると、バックグラウンドで不正検出器をトリガーします。
* リアルタイム・カウンター、移動平均などのメトリクス - フィンテックや気候変動アプリケーションなどでの応用例
* ダッシュボードの作成 - トラフィック監視やリーダーボードのように、人間が数字に目を走らせたい場所ならどこでも。
* 受信したイベント・ストリームから、オフライン分析やクエリのための長期ストレージへのデータ移動。
* イベント駆動型アーキテクチャ（EDA）の実現


### イベント駆動型アーキテクチャーの使用例


イベント・ドリブン・アーキテクチャは、大量のデータが素早く入ってくるアプリケーションによく使われる。ソーシャルメディア、オンラインショッピング、[IoTアプリケーション](https://aiven.io/blog/3-considerations-for-building-an-enterprise-iot-solution)などが良い例ですが、規模によっては在庫管理なども含まれます。


[Kafka中心のアーキテクチャを採用したケーススタディ](https://www.aiven.io/blog/use-cases-for-apache-kafka)のページをご覧ください。


## アーキテクチャにおけるApache Kafka


Apache Kafkaはどこに位置するのか？簡単に言うと、すべてのシステムの真ん中に位置します。プロデューサとコンシューマには複数のオープンソースオプションがあり、その多くはKafkaへの既存のコネクタを持っています。Kafka自身はアプリケーション・ロジックを実行しているわけではなく、単にメッセージの順序付けられたストアであることを覚えておいてほしい。


通常、Apache Kafkaは一種のパイプラインとして動作し、ある場所から別の場所（または他の多くの場所）にデータをストリーミングする。コンシューマは、トピックの最新のメッセージから始めるか（それ以降の新しいメッセージだけを取得する）、トピックの先頭から始めるか（トピックに残っているメッセージの数だけ取得する）、あるいはその中間を選択できる。Kafkaは、"オフセット "と呼ばれるトピック上のメッセージの位置を追跡し、新しいメッセージを最後に追加する。コンシューマは、最後に見た（あるいは次に見たい）オフセットを追跡するが、その詳細はクライアントが使用するライブラリの中に隠されていることが多い。


[あなたのアーキテクチャにおけるApache Kafka](https://images.ctfassets.net/q3u27v6lpki8/27plzs2p5wJTpfkGwTaNvq/a5ee6574acdf2b805be9ba1c56e50339/Apache_Kafka_in_your_architecture.png)


[Apache Kafkaエコシステムとconnect02 B](https://images.ctfassets.net/q3u27v6lpki8/2Rsdc8qQifnr8jHCAUgLpW/8f3fbae3f0fec1006733b381b7da0c06/Apache_Kafka_ecosystem_with_connect02_B.png)


## Apache Kafka API: Kafkaへの接続


まったく驚くことではないが、KafkaはAPIを介して他のシステムとのインターフェイスを提供する。KafkaのJavaクライアントは、5つのコアAPIを提供している：


* トピックやブローカーのようなKafkaオブジェクトの検査と管理を行う[Admin API](https://kafka.apache.org/documentation.html#adminapi)
* トピックへの書き込み（パブリッシング）を行う[Producer API](https://kafka.apache.org/documentation.html#producerapi)。
* トピックを読む（購読する）ための[Consumer API](https://kafka.apache.org/documentation.html#consumerapi)
* [Kafka Streams API](https://kafka.apache.org/documentation/streams) は、アプリケーションやマイクロサービスに対して、より高度なストリーム処理機能へのアクセスを提供する。
* [Kafka Connect API](https://kafka.apache.org/documentation.html#connect) 外部システムやアプリケーションへのインポート・エクスポート・コネクタを作成します。


Apache Kafkaに接続するためにどのAPIを使うか、そしてそれをどのように行うかは、使用している技術、どのようなアクティビティ（メッセージの生成、メッセージの消費、Kafkaブローカーの管理など）、接続をどの程度 "ハイレベル "にしたいか（メッセージ/パーティション/ヘッダーなどに関する個々の詳細をすべてコードに指定させたいか、コンシューマーに最新のオフセットを追跡させたいのか、ストリームがどのように処理されるべきかを記述し、ライブラリにメッセージフローを設定させたいのか、コードを一切書かず、Kafkaを使って他のデータストアを結合させたいのか。).


### いくつかのプロデューサーとコンシューマー


#### 低レベルのライブラリ


Kafkaトピックへのデータの流入と流出を完全に制御するために、さまざまなプログラミング言語で利用可能なクライアントライブラリが用意されている。Apache Kafkaプロジェクト自体がJava APIを管理しているが、他の言語でもよく使われるライブラリには以下のようなものがある：


* [Go 用 Sarama](https://github.com/Shopify/sarama)
* [Go 用 Kafka-go](https://github.com/segmentio/kafka-go)
* [Kafka-python（Python用）](https://github.com/dpkp/kafka-python)
* [C/C++用Librdkafka](https://docs.confluent.io/clients-librdkafka/current/overview.html) (および[Go](https://docs.confluent.io/clients-confluent-kafka-go/current/overview.html)、[Python](https://docs.confluent.io/clients-confluent-kafka-python/current/overview.html)などのラッパー)


これらのコンシューマーは、特定のパーティションをメッセージのターゲットにしたり、任意のバイトをメッセージボディに送ったり、任意のデータ構造をキーに使ったりすることができる。これらのほとんどは、プロデューサとコンシューマの間で注意深く同期させる必要があることに注意してください。そうしないと、コンシューマはメッセージを誤解してしまう可能性があります（例えば、予期しないパーティションにあったり、期待された構造になっていなかったりするかもしれません）。


### 高位レベルのクライアント・ライブラリ


少し高度になると、これらのライブラリは一般に、より標準的なオプションを使用 することができるようになる。例えば、メッセージ・キーのハッシュに基づいてパーティションを自動的に選択したり、[スキーマ・レジストリ](https://www.aiven.io/blog/what-is-karapace)を使用してメッセージの構造が期待値に適合していることを確認したりします。


コンシューマにとって、大きな関心事は、コンシューマが処理したメッセージのストリー ムのどこにあるのかを追跡することです。低レベルのコンシューマは、自分のオフセットをどこかに保存するかもしれない(例えばZooKeeperに保存する。[Kafka自身はZooKeeperから離れつつある](https://aiven.io/blog/broker-communication-in-kafka-2-7-and-beyond))が、Kafkaに管理させる方が普通である。デフォルトでは、Kafkaはこのために**consumer_offsets**という専用のトピックを使う。


### さらに高レベルのクライアントライブラリ


さらに高度なレベルになると、アプリケーションを実行するサーバーが多数あっても、各メッセージが一度しか処理されないように、アプリケーションの多数の異なるインスタンスを調整することが一般的なニーズになります。どのアプリケーションがどのトピックから消費しているのか、どのオフセットまで消費しているのかを調整し、アプリケーションに障害が発生した場合に負荷を分散するために、Kafkaではコンシューマーのグループを1つのエンティティとしてモデル化することができます。


アプリケーションがKafkaに接続し、指定されたトピックからのコンシューマを要求すると、特定の[コンシューマグループ](https://kafka.apache.org/documentation/#consumerconfigs_group.id) --またはコンシューマグループセクションへのリンク--のメンバーであることを宣言することができ、そのコンシューマグループに属する他のアプリケーションの数に応じて、パーティションのサブセット内の適切なオフセットからメッセージが渡されます。


### 本当に高レベルのクライアント


各メッセージの個々の詳細を処理する代わりに、メッセージプロセス全体を簡素化する高レベルのクライアントを選択することができます。


#### ストリーム処理


[Kafka Streams](https://kafka.apache.org/documentation/streams/)はJavaライブラリで、アプリケーションでメッセージのストリームをどのように処理したいかをモデル化することができる。コード内で流暢なパイプラインを作成し、変換のストリームを定義します（例えば、「メッセージからこれらのフィールドを抽出する」、「メッセージをDBテーブルからのルックアップと組み合わせる」、「このフィールドに10より大きな数値が含まれている場合、メッセージを別のストリームにパブリッシュしてアラートを発生させる」など）。


#### Apache Kafka Connect


Apache Kafka Connectを使用すると、Kafkaへの単一のソースパイプラインとKafkaからの単一のシンクパイプラインを作成できます。Kafka ConnectはKafkaから見ると特別なものではなく、単にメッセージを生成・消費する外部アプリケーションだが、外部データストア（例えばPostgreSQLデータベース）にデータを取り込んだり、外部データストアからデータを取り出したりする便利な方法であることに注意する必要がある。


[Apache Kafka Connect](https://aiven.io/kafka-connect)は、1つまたは複数の "コネクタ "をホストするアプリケーションであり、それ自体は2つのカテゴリのいずれかに分類される。"コネクタ "は、外部ソースからデータを抽出し、Kafkaトピックにパブリッシュする "ソース"、またはKafkaトピックからデータを消費し、外部の何かにプッシュする "シンク "である。2つの外部データストア間でデータを移動させるために、Kafkaを純粋に2つのコネクタ間のトランジットとして使用することもある。


Kafka Connectを使えば、個々のメッセージのメッセージフィールドに対して簡単な変換を行うこともできる。


(Aivenが提供するKafkaコネクターについて知りたいですか？開発者向けドキュメントの[AivenのApache Kafkaコネクタ一覧](https://help.aiven.io/en/articles/1231452-kafka-connect-connectors)をご覧ください。


##### ソースコネクタの例


* リレーショナル・データベースからデータを取り出します。これには様々な実装があり、一般的なものとしては、読み取り専用のレプリカデータベースのふりをするDebezium(例えば[CDC](https://developer.aiven.io/docs/products/kafka/kafka-connect/howto/debezium-source-connector-pg.html)を使用)や、[AivenのJDBCソース](https://github.com/aiven/jdbc-connector-for-apache-kafka)がある。一度にテーブル全体を繰り返し浚渫したり、IDやタイムスタンプのようなインクリメントされるカラムをたどって、何が変更されたかを把握することができる。
* AWS S3 バケットの変更を監視する。
* 例えば、Lenses.io の [Stream Reactor MQTT コネクタ](https://docs.lenses.io/5.0/integrations/connectors/stream-reactor/sources/mqttsourceconnector/) など。


##### シンクコネクターの例


* リレーショナル・データベースへのデータ書き込み
* 外部APIの呼び出し
* 何かが起こったことをクライアントに通知するためのWebhookの送信
* イベントのデータウェアハウスへのストリーミング保存と分析


Kafkaに接続したいシステムに既製のコネクターがない場合は

Kafka Connect APIを使って作ることができる。


### メッセージスキーマの調整


Kafkaはプロデューサーとコンシューマーを切り離すツールなので、メッセージの構造について合意する機会もなくなる。プロデューサーは、コンシューマーが公開しているメッセージを理解できることをどうやって知るのだろうか？


様々なアプリケーションが、どのフィールドを期待しているのか、あるいは特定のフィールドが実際の整数であることを期待しているのか、あるいは整数を含む文字列であることを期待しているのかを調整する機会はない。


この問題を解決するために、[Karapace](https://aiven.io/blog/what-is-karapace) のような外部ツールを使うのが一般的です。このツールは、特定のトピックに発行されるメッセージのスキーマのリポジトリとして機能します。パブリッシャーは、すべてのフィールドとそのデータタイプを含むメッセージスキーマをレジストリに書き込み、コンシューマーはスキーマを読み、それに応じて期待値を調整することができます。


もしスキーマが期待通りでなければ、例外を発生させ、そのトピックからのメッセー ジを消費しないようにすることもできるし、スキーマが進化しているので、ソフトウェアの バージョンアップが必要かもしれないというフラグを立てることもできる。


#### メッセージ・スキーマを持つその他の利点


メッセージスキーマを持つことの利点は他にもある。スキーマが進化することは必要なことであり、あるソフトウェアを最初に書いたときに、将来の要求がすべてわかっていることはめったにありませんが、スキーマレジストリは新しいスキーマが前のバージョンと互換性があるかどうかを知らせてくれます（あるいは強制してくれます！）。例えば、新しいスキーマのバージョンがフィールドを追加するだけで、削除はしないのであれば、コンシューマが新しいフィールドの扱い方をまだ知らないとしても、メッセージを理解できる可能性は高い。


もう一つの利点は、コンシューマがすべてのメッセージでフィールド名を送信する必要がなくなることである。フィールドの順序を保持するシリアライズフォーマット（たとえばJSONの代わりにAvro）を使用する場合、プロデューサはレジストリに、たとえば「最初のフィールドは数値IDで、2番目のフィールドはユーザー名です」と伝えることができる。


最初のフィールドがユーザー名であることはないことをコンシューマーはすでに知っています。フィールドが順番に並んでいることを必要としないフォーマットとは対照的です。スキーマレジストリを使用できるKafkaクライアントは、メッセージ内のデータとレジストリのスキーマに基づいて、アプリケーションに対して透過的でありながら、完全なメッセージ構造を再作成します。


一般的なスキーマ・レジストリには、オープンソースの Karapace や Confluent Schema Registry がある。


## Apache Kafkaでマイクロサービスを構築する


Apache Kafkaはアプリケーション同士を切り離すことに長けているため、一般的に[マイクロサービスアーキテクチャ](https://aiven.io/blog/5-benefits-of-a-kafka-centric-microservice-architecture)の中心に置かれることが多い。これは、アプリケーションがいくつかの小さなアプリケーションに分割されていることを意味し、各アプリケーションは全体像の一部として独自のタスクに集中するが、一般的に他の部分には気づかない。Kafkaを使用するマイクロサービスは、コンシューマーまたはプロデューサーのいずれか、あるいは多くの場合その両方になることができ、Kafkaを使用してデータや命令を受信し、その結果をKafkaにパブリッシュして他のアプリケーションで使用したり、データウェアハウスに保存したりします。


マイクロサービス・アーキテクチャ（https://aiven.io/case-studies/aiven-for-apache-kafka-helps-alef-education）は、個々のアプリケーションをよりシンプルにし、それぞれを必要に応じて拡張できるという点で [利点をもたらす](https://aiven.io/case-studies/aiven-for-apache-kafka-helps-alef-education) と同時に、全体像に複雑さをもたらす。今や、単一のソフトウェアではなく、多くの異なるアプリケーションが存在する可能性がある。個別にテストするのは簡単だが、それらの間の相互作用には、統合テストのしっかりしたセットが必要だ。注意深く計画しなければ、切り離されたアプリケーションと思われていたものが、すぐに偶然に依存し合うようになり、1つのアプリケーションが苦戦し始めたり、致命的なバグが発生したりすると、その周りの他のアプリケーションがドミノ倒しのように倒れてしまう。このような状況をコントロールし直すのは複雑なので、各マイクロサービスの独立性が保たれるように努力する必要がある。


しかし、Apache Kafkaをうまく使うことで、見た目よりも簡単にこれを行うことができる。[Karapace](https://karapace.io)のようなスキーマレジストリと組み合わせることで、予期しないメッセージがマイクロサービスに届く可能性をコントロール下に置き、優れた統合テストによってアプリケーションの動作をよく理解した状態に保つことができます。


マイクロサービスアーキテクチャを構築する際の課題と機会についてもっと読むには、[How are your microservices talking](https://aiven.io/blog/how-are-your-microservices-talking)を参照してください。


## Apache Kafkaによるイベント駆動型アーキテクチャ：バリエーション


Apache Kafkaは非常に多くのアプリケーションと連携しているため、Kafka中心のアーキテクチャには様々なバリエーションがあります。例えば、以下のケースを見てみましょう：


* [FlinkとKafkaによるストリーミングSQLパイプラインの構築](https://aiven.io/blog/build-a-streaming-sql-pipeline-with-flink-and-kafka)
* [Kafka + SnowflakeによるニアリアルタイムELT](https://aiven.io/blog/near-real-time-elt-with-apache-kafka-and-snowflake)
* [データストリーミングパイプラインの最適化](https://aiven.io/blog/optimizing-data-streaming-pipelines)


[[Kafka-pillar-piece-video-link-frame](https://images.ctfassets.net/q3u27v6lpki8/2Cd1h0f87ZbqoSIwJaukCN/628ebb52121b259428fad8480d530edc/Kafka-pillar-piece-video-link-frame.png)[](https://youtu.be/Ca3TlklRhfs)


## Apache Kafkaでレガシーアーキテクチャを更新する


Kafkaは[データベースのマイグレーション](https://aiven.io/developer/db-technology-migration-with-apache-kafka-and-kafka-connect)に対応するための良い選択肢だ。しかし、Kafkaを使えるのはマイグレーションだけではありません：Kafkaは古いアーキテクチャの要素をシームレスに結合し、拡張やスケーリングを可能にします。また、新しいタイプの要素を既存の要素に結合するのも簡単だ。


以下は、私たちが以前に準備したものです...


* [古いアプリからデータベースへのアーキテクチャをKafka用に更新する](https://aiven.io/blog/using-kafka-connect-jdbc-source-a-postgresql-example)
* [レガシーアーキテクチャを近代化しながらイベントデータをストリーミング](https://aiven.io/case-studies/building-event-driven-architecture-with-aiven)
* [機械式スロットマシンのプロバイダーからオンライン・ハイブリッド・ゲーム・インフラへの移行](https://aiven.io/case-studies/aiven-for-apache-kafka-helps-paf)
* [クラウドベースの統一データモデルによるサプライチェーンと在庫管理システム](https://aiven.io/case-studies/aiven-cloud-helps-adeo)


## Apache Kafkaの管理


初期起動時の設定ファイル以外にも、Apache Kafkaを実行中に管理するために必要なさまざまなアクティビティがある（新しいトピックの作成、コンシューマーグループのオフセットの更新、どのブローカーがパーティションのリーダーであるかについての新しい選挙のトリガーなど）。その代わりに、Apache Kafkaの[Admin API](https://kafka.apache.org/documentation.html#adminapi)とJavaクライアントライブラリ、そして様々な管理タスクのためにAPIを呼び出すのに役立つコマンドラインスクリプトのセットがある。


ApacheのウェブサイトからKafkaをダウンロードした場合は、"bin/"ディレクトリの中に、様々な管理タスクをカバーする便利なシェルスクリプトがある。


## 観測可能性と Apache Kafka


Apache Kafkaは、トピックに流れる大量のデータや、ディスクに書き込まれるすべてのデータに対応するために、さまざまな設定を調整する必要があるため、スケール時の管理が難しいことで有名です。Kafkaの内部をよく理解しなければ、どのダイヤルを調整すべきかを知ることは不可能であり、オペレーターはKafkaのスムーズな稼働を維持するために盲目的な運に頼ることになる。Javaエコシステムは、アプリケーションの内部に関するメトリクスを公開するための標準的なインターフェースであるJMXを提供しており、KafkaはJMXを使用して、何が起こっているのかについての有用な情報を多数公開している。


Apache Kafkaから時系列データベース（例えばM3）にメトリクスをインジェストし、Grafanaのような可視化ツールを使って経時的な傾向を見るのが一般的だ。


## Kafkaとデータの安全性


Kafkaはデータのバックアップを行いません。なぜなら、Kafkaに含まれるデータは本質的に刹那的だからです。そのため、クラスタがオフラインになった場合、中断されたり失われたりしないことをどうやって確認できるのでしょうか？


その答えがレプリケーションで、Apache Kafkaには独自のレプリケーションツールMirrorMaker 2がある。[MirrorMaker 2を使う理由はたくさんある](https://aiven.io/blog/5-reasons-why-you-should-be-using-mirrormaker-2)が、データを安全に保つことが最も重要だろう。MirrorMakerは、ソースとシンクがそれぞれ異なるKafkaブローカーに接続されている、特別なKafka Connectのセットアップに似ていると考えてください。MirrorMakerは、Kafkaトピックからメッセージを引き出すコンシューマーと、それらのメッセージを別のKafkaトピック（通常は別のブローカー）に即座に送信するプロデューサーに過ぎない。KafkaコンシューマーはKafkaにオフセット状態を保存させることができるので、MirrorMakerは完全に独立した2つのKafkaブローカー間でメッセージをシャベルする方法を提供する。これを使用して、"バックアップ "Kafkaクラスタを作成するのが一般的で、"メイン "Kafkaクラスタに影響を与えることなく、まったく別の場所に作成することもよくある。


## データは力なり


Apache Kafkaのようなストリーミング・アーキテクチャは、非常に大量のデータにアクセスできる。データをよくても使い捨て、悪くても面倒なものと考え始めるのは簡単だ。しかし実際には、データはあなたが所有する最も価値のある資産であり、あるいはそうなりうるものなのです。


データを切り刻むことで、サービスがどのように利用され、どのようなパフォーマンスを発揮しているかをより詳細に調べることができる。モニタリング、スケーリング、訪問者の行動、セキュリティ、自動化......データでできることは[たくさんある](https://aiven.io/blog/easy-real-time-streaming-insights)。


## Kafkaのセットアップと管理は単純ではない


Apache Kafkaは、デプロイの規模が小さくても大きくても、どんな規模でも驚くほどうまく機能する。常に少なくとも3つのブローカーを持つべきで、1つのブローカーが故障しても、ワークロードを処理するために利用可能なブローカーが多数存在する。しかし、この柔軟性には代償が伴う。与えられたスケールで最適に動作するように慎重にチューニングする必要がある。


Apache Kafka用のAivenのようなマネージド・プラットフォームを使用する場合でも、クライアント側で決定しなければならないことがある：


* トピックはどのように使用するのか？
* トピックはどのように使用されるか？
* レプリカの数は？
* どの保存期間を使うか？
* どのようなコンパクション・ポリシーを使用するのか？


これらの決定を正しく行うことは非常に重要である。というのも、クライアントにかなりの動揺を与えない限り、後日変更することは容易ではないからである。例えば、トピック内のパーティション数を増減させることで、キーからパーティションへの分散（ひいては順序保証）が変わりますが、与えられたブローカー・サイズに対してパーティション数が多すぎると、最大スループットに影響を及ぼします。適切にチューニングされたセットアップを行うには、障害シナリオやその場での運用変更など、本番レベルの負荷でテストを行うことが重要です。


## オーケストレーションと自動化について


複雑なシステム（Apache Kafkaを含むあらゆるシステムのような）の設定、管理、調整を容易にするために、オーケストレーションシステムを実装することができます。[Kubernetes](https://developer.aiven.io/docs/tools/kubernetes.html)のようなオーケストレーションツールは、多段階のプロセスを自動的に実行するように設定できる。これは、定期的または繰り返し実行する必要があるワークフローを合理化し、最適化するのに役立つ。必要なのはコンテナで実行することだけだ。


関連はするが別のメモとして、[Terraform](https://developer.aiven.io/docs/tools/terraform/index.html)ではインフラをコードとして定義できるため、プロビジョニングや管理が簡単になる。あなたは構成を指定し、Terraformは依存関係とネットワーキングの面倒を見る。


両ツールとその機能について詳しくは、[Kubernetes vs Terraform](https://aiven.io/blog/kubernetes-vs-terraform)のブログ記事をご覧ください。


## AivenでApache Kafkaを始める


マネージドKafkaと同じプロバイダーのマネージドDBaaSを使うメリットは何でしょうか？ひとつは、マルチサービスパイプラインの構築と管理が容易なことです。


[Aiven for Apache Kafka](https://aiven.io/kafka)をご利用ください。


[Aivenの開発者向けドキュメント](https://developer.aiven.io/docs/products/kafka/index.html)をご覧いただき、Kafkaの世界で最初の一歩を踏み出してください。また、[無料トライアルにサインアップ](https://console.aiven.io/signup)して、遊んでみてください。