Apache storm 风暴中的三叉戟状态是什么?

Apache storm 风暴中的三叉戟状态是什么?,apache-storm,trident,Apache Storm,Trident,我不熟悉风暴中的三叉戟。我为三叉戟州的事伤了头。据我所知,trident维护每个批次的状态(即元数据)(是否通过在数据库中维护事务id来完全处理批次中的所有元组),我不完全确定下面的语句做什么 TridentState urlToTweeters = topology.newStaticState(getUrlToTweetersState()); 有人能解释一下当我们定义上述代码时实际发生了什么吗?关于Trident state有很好的文档。您的问题的简单答案是,urlToTweete

我不熟悉风暴中的三叉戟。我为三叉戟州的事伤了头。据我所知,trident维护每个批次的状态(即元数据)(是否通过在数据库中维护事务id来完全处理批次中的所有元组),我不完全确定下面的语句做什么

TridentState urlToTweeters =
   topology.newStaticState(getUrlToTweetersState());

有人能解释一下当我们定义上述代码时实际发生了什么吗?

关于Trident state有很好的文档。您的问题的简单答案是,
urlToTweeters
是一个可以从中查询的状态对象。我假设上面的陈述来自,转载如下:

TridentState urlToTweeters = topology.newStaticState(getUrlToTweetersState());
TridentState tweetersToFollowers = topology.newStaticState(getTweeterToFollowersState());
topology.newDRPCStream("reach")
  .stateQuery(urlToTweeters, new Fields("args"), new MapGet(), new Fields("tweeters")).each(new Fields("tweeters"), new ExpandList(), new Fields("tweeter"))
  /* At this point we have the tweeters for each url passed in args */
  .shuffle()        
  .stateQuery(tweetersToFollowers, new Fields("tweeter"), new MapGet(), new Fields("followers"))
  .parallelismHint(200)
  .each(new Fields("followers"), new ExpandList(), new Fields("follower"))
  .groupBy(new Fields("follower"))
  .aggregate(new One(), new Fields("one"))
  .parallelismHint(20)
  .aggregate(new Count(), new Fields("reach"));

在本例中,
urlToTweeters
将存储URL到tweeter的映射,下一行定义的DRPC
reach
查询(将URL作为其参数)将最终生成reach。但是在路上(用注释内联标记),你会看到每个url的推特流,即,对
urlToTweeters

的查询结果。我希望现在回答永远都不会太晚,至少其他人会觉得我的回答有用:)

因此,
topology.newStaticState()
是Trident对可查询数据存储的抽象。
newStaticState()
的参数应该是
storm.trident.state.StateFactory
的实现(基于方法的契约)。反过来,工厂应该实现
makeState()
方法,返回
storm.trident.state.state
的实例。但是,如果您计划查询您的状态,则应该返回
storm.trident.state.map.ReadOnlyMapState
的距离,因为普通
storm.trident.state.state
没有查询实际数据源的方法(如果您尝试使用
ReadOnlyMapState
以外的任何方法,实际上会出现类强制转换异常)

所以,让我们试试看

虚拟状态实现:

public static class ExampleStaticState implements ReadOnlyMapState<String> {

    private final Map<String, String> dataSourceStub;

    public ExampleStaticState() {
        dataSourceStub = new HashMap<>();
        dataSourceStub.put("tuple-00", "Trident");
        dataSourceStub.put("tuple-01", "definitely");
        dataSourceStub.put("tuple-02", "lacks");
        dataSourceStub.put("tuple-03", "documentation");
    }

    @Override
    public List<String> multiGet(List<List<Object>> keys) {

        System.out.println("DEBUG: MultiGet, keys is " + keys);

        List<String> result = new ArrayList<>();

        for (List<Object> inputTuple : keys) {
            result.add(dataSourceStub.get(inputTuple.get(0)));
        }

        return result;
    }

    @Override
    public void beginCommit(Long txid) {
        // never gets executed...
        System.out.println("DEBUG: Begin commit, txid=" + txid);
    }

    @Override
    public void commit(Long txid) {
        // never gets executed...
        System.out.println("DEBUG: Commit, txid=" + txid);
    }
}
一个简单的
psvm
(又称
publicstaticvoidmain
):

最后,输出:

DEBUG: MultiGet, keys is [[tuple-00], [tuple-01], [tuple-02], [tuple-03]]
DEBUG: [tuple-00, Trident]
DEBUG: [tuple-01, definitely]
DEBUG: [tuple-02, lacks]
DEBUG: [tuple-03, documentation]
您可以看到,stateQuery()从输入批处理中获取值,并将它们映射到“数据存储”中的值

再深入一点,您可以查看
MapGet
类(其实例用于在拓扑内部查询)的源代码,并在那里找到以下内容:

public class MapGet extends BaseQueryFunction<ReadOnlyMapState, Object> {
    @Override
    public List<Object> batchRetrieve(ReadOnlyMapState map, List<TridentTuple> keys) {
        return map.multiGet((List) keys);
    }    

    @Override
    public void execute(TridentTuple tuple, Object result, TridentCollector collector) {
        collector.emit(new Values(result));
    }    
}
公共类MapGet扩展了BaseQueryFunction{
@凌驾
公共列表批检索(ReadOnlyMap,列表键){
返回map.multiGet((列表)键);
}    
@凌驾
public void execute(TridentTuple元组、对象结果、TridentCollector){
emit(新值(结果));
}    
}
因此,它只需调用
readonlympstate
实现的
multiGet()
方法,然后发出在数据存储中找到的值,将它们添加到已经存在的元组中。您可以(尽管这可能不是最好的做法)创建自己的
BaseQueryFunction
实现,做一些更复杂的事情。

您能在此上下文中定义“Trident”吗?有很多东西叫做三叉戟。上下文是“风暴”:你能帮忙吗
DEBUG: MultiGet, keys is [[tuple-00], [tuple-01], [tuple-02], [tuple-03]]
DEBUG: [tuple-00, Trident]
DEBUG: [tuple-01, definitely]
DEBUG: [tuple-02, lacks]
DEBUG: [tuple-03, documentation]
public class MapGet extends BaseQueryFunction<ReadOnlyMapState, Object> {
    @Override
    public List<Object> batchRetrieve(ReadOnlyMapState map, List<TridentTuple> keys) {
        return map.multiGet((List) keys);
    }    

    @Override
    public void execute(TridentTuple tuple, Object result, TridentCollector collector) {
        collector.emit(new Values(result));
    }    
}