基本紹介
- Kafkaは分散ストリーミングデータ処理プラットフォームであり、主にメッセージキューやエンタープライズレベルのメッセージングシステムと同様に、ストリーミングデータのパブリッシュとサブスクライブに使用されます。
- ストームは分散リアルタイムコンピューティングシステムであり、主にリアルタイム分析、オンライン機械学習、継続的コンピューティング、分散RPC、ETLなどに使用されます。ストームチュートリアルを通じて、ストームのコアコンセプトを理解できます。
- ElasticSearchは、可用性の高いオープンソースの全文検索および分析エンジンです。
この記事では、Javaプログラムを介して3つのフレームワークの統合を実装し、Kafkaからデータを読み取り、Stormトポロジー処理の後で、最終的にElasticSearchにフローします。
統合方法
- Stormは、Kafkaと統合されたSpoutサポートを提供します。KafkaSpoutを構成して、Kafkaの指定されたトピックおよびグループから直接データを読み取ることにより、Stormトポロジーにフローします。
- Elasticsearch-stormは、Elasticが提供するESとStormを統合するための公式ツールキットです。ESクラスターにデータをバッチで追加するようにEsBoltを構成できます。
Maven依存関係構成
<dependencies>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.10</artifactId>
<version>0.8.2.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.zookeeper</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.2.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>clojure</artifactId>
<groupId>org.clojure</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-kafka</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.zookeeper</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch-storm</artifactId>
<version>6.6.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
ストームプログラムのエントリコードの例
public class StormEsDemoApplication {
public static void main(String[] args) throws Exception {
TopologyBuilder builder = new TopologyBuilder();
// set es bolt properties
Map<String, String> esConf = new HashMap<>(1);
esConf.put("es.input.json", "true");
// build topology according to topics
builder.setSpout("spoutId", new KafkaSpout(getKafkaSpoutConfig(topicName, "groupId")), 4);
// add logic bolt to the topology
builder.setBolt("logicBoltId", new LogicBolt(), 2)
.shuffleGrouping("spoutId");
// add es bolt to the topology
// new ESBolt, target is index template
EsBolt esBolt = new EsBolt("target", esConf);
builder.setBolt("esBoltId", esBolt, 2)
.addConfiguration(Config.TOPOLOGY_TICK_TUPLE_FREQ_SECS, 5)
.shuffleGrouping("logicBoltId");
Config stormConf = new Config();
stormConf.setDebug(false);
stormConf.put(Config.WORKER_HEAP_MEMORY_MB, 1024);
stormConf.put(Config.TOPOLOGY_WORKER_MAX_HEAP_SIZE_MB, 1024);
stormConf.setNumAckers(4);
stormConf.setNumWorkers(4);
stormConf.setMessageTimeoutSecs(30);
stormConf.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, 10);
// set esBolt properties to storm config
stormConf.put("es.nodes", "127.0.0.1");
stormConf.put("es.port", "5555");
stormConf.put("es.storm.bolt.flush.entries.size", 500);
// when run service on the dev env, start service with local mode
if ("dev".equals(SERVICE_ENV)) {
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("app_log_persistence", stormConf, builder.createTopology());
} else {
StormSubmitter.submitTopology("topo_name", stormConf, builder.createTopology());
}
}
/**
* init the kafka spout config
*
* @param topicName topic name
* @param groupId group id
* @return SpoutConfig
*/
private static SpoutConfig getKafkaSpoutConfig(String topicName, String groupId) {
BrokerHosts brokerHosts = new ZkHosts("kafka_ZK_SERVERs", "broker_root");
SpoutConfig spoutConf = new SpoutConfig(brokerHosts, topicName, "consumer_root", groupId);
// spout consume Kafka, consumer's offset write zk address config(default storm config zk address)
List<String> zkServers = new ArrayList<>(5);
spoutConf.zkServers = zkServers;
spoutConf.zkPort = 2189;
spoutConf.scheme = new SchemeAsMultiScheme(new StringScheme());
return spoutConf;
}
}
まとめ
StormプログラムはKafkaのデータをSpout経由で読み取り、データはさまざまなグループ化方法を設定することにより、自己実装の論理処理ユニットBoltに流れます。最後に、ES公式フレームワークによって提供されるEsBoltがトポロジに構成され、関連するパラメーターが構成されて、バッチ書き込みの効果を実現します。サンプルコードは、独自のビジネスを組み合わせて実装できるロジックボルトの実装を提供していません。プログラムが完了し、パッケージ化されてデプロイされた後、初期化されていない書き込み操作をフラッシュできないことが異常であることが判明した場合は、他のブログを参照して解決できます。