鸣叫分析:如何设计

时间:2013-04-13 11:14:26

标签: java multithreading twitter4j

我在设计用于推文分析的系统时需要建议。

目标:对于给定的主题标签,找出与其他哈希标签共现的频率。找出每小时模式。我们应该能够回答这种格式的查询:对于给定日期(例如2013年4月13日)和给定的一小时时间段(比如说下午3:00-4:00),前5个共同发生的是什么带有“#iPhone”的#标签。

我的方法:我使用“twitter4j”liabrary来访问Twitter数据。我可以查询并获得100个推文进行一次通话(Twitter仅允许那些多个推文)。我可以提取时间和其他相关数据。我计划有一个线程,每隔5分钟就会查询一下twitter。这是针对观察者的每小时模式。这是我被击中的地方:我应该如何将这些信息存储在数据库中?我应该维护一个带有键值的hashmap,以及使用“#iPhone”发生频率的值。或者我应该将未聚合的数据直接存储在数据库中?查询“twitter”到观察者每小时模式的最佳方法是什么?我应该将时间以“epoch”格式存储在DB中,还是作为日期一列和小时存储在DB中的另一列中?

非常感谢您的宝贵意见。

3 个答案:

答案 0 :(得分:2)

我建议您使用the Streaming API in Twitter。这将允许您保持与Twitter的持久HTTP连接,以便您可以搜索推文。 Twitter推荐使用Streaming API推文分析类型应用程序。

但您必须预处理某些数据,以便分析更快。另请查看twitter4j's inherent Streaming API支持。

有关示例,请查看以下Github code

答案 1 :(得分:1)

如ay89所说,使用key-tag和value-freq,在存储到DB之前聚合,并使用纪元。

此外,由于这是一个多线程程序,因此您有两种同步选项:

选项1是使用ConcurrentHashMap。当聚合器运行时,它将使用:

(for Key key : hashMap.keySet()) {
    Database.save(key, hashMap.get(key));
    hashMap.replace(key, 0);
}

换句话说,在将标记写入数据库后将其设置为0。添加推文数据的方法将使用

public void increment(Key key) {
    boolean done = false;
    while(!done) {
        int current = hashMap.get(key);
        int newValue = current + 1;
        done = hashMap.replace(key, current, newValue);
    }
}

这是一种增加频率的线程安全方法。

选项2可能更有意义。您的聚合器将使用新实例替换hashmap。

class DataStore {
    Map map = new HashMap();

    public void add(Key key, Value value) {
        // called by the method querying tweet data
    }

    public void aggregate() {
       // called by the aggregator thread every five minutes
       Map oldMap = map;
       map = new HashMap();
       DataBase.save(oldMap);
   }
}

最重要的是,当聚合器将其保存到数据库时,您不希望以不受控制的方式修改散列映射。第二个选项更简单,因为它只是为查询线程创建一个新的hashmap,而聚合器将旧的hashmap保存到数据库中。

答案 2 :(得分:0)

因为您只需要检索频率,最好将其存储在散列(key-tag,value-freq)中,因为存储在db中的非聚合数据会占用更多空间(并且主要用于不是必要的)最终你必须稍后聚合。

纪元时间是存储时间的好方法。因为你可以根据时区使用它进行本地化,如果以后需要的话。