Java整合Storm写入ElasticSearch

本文介绍如何将Java应用程序与Apache Storm结合使用,并将处理后的数据写入ElasticSearch。通过添加必要的依赖项、创建数据包装类、编写工具类及修改Bolt组件,实现了从Storm的数据流中读取单词并存入ElasticSearch的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上次写了一个Java整合Storm的一个最简单的例子https://blog.youkuaiyun.com/xxkalychen/article/details/117018310,一个数据源,一个处理中间环节,一个最终环节,一个任务拓扑。我们能看到的效果是控制台打印。根据需要,我们要把数据写入ElasticSearch。

我们在原有的项目中做一点小的调整,来实现这个需求。

当然,首先我们需要一个ElasticSearch的服务器。我已经开启了自己架设好的ES服务器,版本号7.12.0

一、pom中添加ElasticSearch和Gson依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.12.0</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.6</version>
</dependency>

这是ElasticSearch7.x以上版本官方建议使用的包,大版本要和服务器一致。Gson用于将对象构建成json,因为ElasticSearch需要将数据构建为合法的json进行存储。

二、创建一个数据包装类WordPkg。由于我们处理的最终数据都是单词,是字符串。我们需要一个类,将单词包装为有字段识别的类。

package com.chris.storm.model;

import java.io.Serializable;

/**
 * @author Chris Chan
 * Create on 2021/5/19 10:37
 * Use for:
 * Explain:
 */
public class WordPkg implements Serializable {
    private String word;

    public WordPkg() {
    }

    public WordPkg(String word) {
        this.word = word;
    }

    public String getWord() {
        return word;
    }

    public void setWord(String word) {
        this.word = word;
    }
}

三、为使用方便,我写了一个ElasticSearchUtil工具类,来简化操作

package com.chris.storm.utils;

import com.chris.storm.model.WordPkg;
import com.google.gson.Gson;
import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;

import java.io.IOException;
import java.util.UUID;

/**
 * @author Chris Chan
 * Create on 2021/5/19 7:37
 * Use for:
 * Explain:
 */
public class ElasticSearchUtil {
    private static RestHighLevelClient client = null;

    static {
        ElasticSearchUtil.client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.0.52", 9200, "http")));
    }

    public static RestHighLevelClient getClient() {
        return client;
    }

    public static void close() {
        try {
            ElasticSearchUtil.client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static boolean isIndexExists(String indexName) {
        try {
            return ElasticSearchUtil.client.indices().exists(new GetIndexRequest(indexName), RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void createIndex(String indexName) {
        if (isIndexExists(indexName)) {
            return;
        }
        try {
            ElasticSearchUtil.client.indices().create(new CreateIndexRequest(indexName), RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static IndexResponse add(WordPkg wordPkg, String indexName) {
        IndexRequest indexRequest = new IndexRequest(indexName).id(UUID.randomUUID().toString());
        indexRequest.source(new Gson().toJson(wordPkg), XContentType.JSON);

        try {
            return ElasticSearchUtil.client.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

四、修改PrintBolt。我们需要添加写入ElasticSearch的逻辑。

package com.chris.storm.bolt;

import com.chris.storm.model.WordPkg;
import com.chris.storm.utils.ElasticSearchUtil;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.tuple.Tuple;

import java.util.Map;

/**
 * @author Chris Chan
 * Create on 2021/5/19 9:44
 * Use for:
 * Explain:
 */
public class PrintBolt extends BaseRichBolt {
    //在ElasticSearch中创建的索引名称
    public static final String INDEX_NAME = "storm_word";

    static {
        ElasticSearchUtil.createIndex(INDEX_NAME);
    }

    @Override
    public void prepare(Map<String, Object> map, TopologyContext topologyContext, OutputCollector outputCollector) {
        
    }

    @Override
    public void execute(Tuple tuple) {
        String word = tuple.getStringByField("word");
        System.out.printf("%s: %s\n", "接收到单词", word);
        //输出到ElasticSearch
        ElasticSearchUtil.add(new WordPkg(word), INDEX_NAME);

    }

    /**
     * 这是流水线上的终点,不需要在发给下一环,所以无须再定义元组字段
     *
     * @param outputFieldsDeclarer
     */
    @Override
    public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {

    }
}

因为封装了工具类,所以使用看起来就特别简单。

除了这一处,其他的地方都不需要修改。直接运行测试即可。

五、运行测试

这个程序还是不能远程提交,我们还需要进行修改。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值