Apache Kafka は OSS の分散型メッセージングミドルウェア。 似た性質を持ったソフトウェアとしては ActiveMQ や RabbitMQ などが挙げられる。 ただし、ActiveMQ や RabbitMQ との大きな違いは、独自のバイナリプロトコルを用いてメッセージをやり取りするところ。 ActiveMQ や RabbitMQ は標準化された AMQP や MQTT を扱う場合が多い。 独自プロトコルというと、なんだか未来が無さそうなイメージがあるけど、その逆で Kafka はビッグデータ処理の場面ではほぼデファクトの位置にあるようだ。
今回は、そんな Kafka を手元の Mac でさくっと試してみることにする。 使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.12.4 BuildVersion: 16E195
インストールする
Kafka は Homebrew でインストールできる。 なので、まずは Homebrew をインストールしておく。 その上で Homebrew Cask についても使えるようにしておく。
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" $ brew tap caskroom/cask
Kafka は Java と Scala を使って書かれている。 なので、まずは動作に必要な Java の処理系をインストールする。
$ brew cask install java
あとはお目当ての Kafka をインストールするだけ。
$ brew install kafka
このとき、依存パッケージとして Apache ZooKeeper もインストールされる。
サービスを動かす
続いてはインストールした Kafka を動作させる。 これには Homebrew のサービス機能を使うと楽ができる。
インストールした直後では Kafka と ZooKeeper は動いていない。
$ brew services list Name Status User Plist kafka stopped zookeeper stopped
そこで ZooKeeper と Kafka を順番に立ち上げていく。
$ brew services start zookeeper $ brew services start kafka
両方のサービスが立ち上がればオッケー。
$ brew services list Name Status User Plist kafka started amedama /Users/amedama/Library/LaunchAgents/homebrew.mxcl.kafka.plist zookeeper started amedama /Users/amedama/Library/LaunchAgents/homebrew.mxcl.zookeeper.plist
ちなみに、上記の機能を使わなくても次のようにしてコマンドラインから起動することもできる。
$ zookeeper-server-start /usr/local/etc/kafka/zookeeper.properties $ kafka-server-start /usr/local/etc/kafka/server.properties
もし、上手く立ち上がらないときは、それぞれのログを確認しよう。
ログはデフォルトで /usr/local/var/log
に保存されている。
同梱されているコマンドで Kafka を操作してみる
Kafka には操作するためのコマンドラインツールが同梱されている。 今回は、それを使ってみる。
トピックを作る
まずは、動作確認用のトピックを作成する。 トピックは Pub/Sub 型のメッセージングミドルウェアによく登場する概念だ。 これは、例えば扱うメッセージの種類やコンポーネントごとに用意する。
$ kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test Created topic "test".
--replication-factor
オプションはクラスタ内でのメッセージのレプリケーション数を表している。
今回はシングルホスト構成なので必然的に 1
となる。
--partitions
オプションはトピックでメッセージを分散処理するための機能の指定で、これを使った例については後ほど紹介する。
まずは、これで動作確認用の test
トピックができた。
$ kafka-topics --list --zookeeper localhost:2181 test
メッセージを読み書きする
次に、作成したトピックに対してコンシューマ、つまりメッセージをトピックから読み出す存在を接続する。
$ kafka-console-consumer --bootstrap-server localhost:9092 --topic test --from-beginning
続いて、作成したトピックに対してプロデューサ、つまりメッセージをトピックに書き込む存在を接続する。 ターミナルから、何か適当にメッセージを書き込んでみよう。
$ kafka-console-producer --broker-list localhost:9092 --topic test Hello, World!
すると、先ほど接続したコンシューマに、プロデューサが書き込んだメッセージが送られる。
$ kafka-console-consumer --bootstrap-server localhost:9092 --topic test --from-beginning Hello, World!
ちなみに、Kafka のメッセージはデフォルトで永続化されている。 例えば、Ctrl-C で一旦コンシューマを停止させてから、もう一度立ち上げてみよう。
$ kafka-console-consumer --bootstrap-server localhost:9092 --topic test --from-beginning Hello, World!
ちゃんと、先ほど受信したのと同じ内容が表示された。 これは、Kafka を再起動しても同じ結果になるので試してみると面白い。
ちなみに、コマンドを --from-beginning
オプションを付けずに実行すれば、途中から受信できる。
$ kafka-console-consumer --bootstrap-server localhost:9092 --topic test
複数のコンシューマでメッセージを分散処理する
これまでの例では、トピックを作るときにパーティションを 1
に指定した動作を試してきた。
次は、複数のコンピューマでメッセージを分散処理するために、トピックに複数のパーティーションを作ってみる。
今度はトピック greet
をパーティーション数 2
で作成する。
$ kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 2 --topic greet Created topic "greet".
続いては、作成したトピックにコンシューマを接続する。
このとき、自身が受信するパーティションを --partition
オプションで指定する。
一つ目のターミナルでは、まずは 0
を指定しておく。
$ kafka-console-consumer --bootstrap-server localhost:9092 --partition 0 --topic greet --from-beginning
続いて別のターミナルを開いて、パーティーションが 1
のコンシューマを接続する。
$ kafka-console-consumer --bootstrap-server localhost:9092 --partition 1 --topic greet --from-beginning
次はトピックにプロデューサを接続して、適当にメッセージを送ってみよう。
$ kafka-console-producer --broker-list localhost:9092 --topic greet
Message1
Message2
すると、送ったメッセージがバラバラにコンシューマに届くことが分かる。
まず、最初のメッセージはパーティーション 0
のコンシューマに送られた。
$ kafka-console-consumer --bootstrap-server localhost:9092 --partition 0 --topic greet --from-beginning Message1
そして、二番目のメッセージはパーティーション 1
のコンシューマに送られている。
$ kafka-console-consumer --bootstrap-server localhost:9092 --partition 1 --topic greet --from-beginning Message2
このように、パーティーションの機能を使うことでメッセージを複数のコンシューマで分散処理できるようになっている。
まとめ
今回は Mac OS X を使って Apache Kafka を軽く触ってみた。 実運用に載せるなら色々と考えるところはあるけど、手元の検証用としてなら簡単に環境を用意して触れることが分かった。 Apache Kafka はビッグデータ処理のメッセージングミドルウェアとしてはデファクトの存在なので引き続き知見を貯めていきたい。