美文网首页
java海量数据的简单清洗

java海量数据的简单清洗

作者: Stalary | 来源:发表于2018-05-09 14:15 被阅读0次

    这周接到了一个对爬取数据进行清理的任务,具体需求为,有一张接近百万的key值表,每一个key对应一个对象,但是在es中存在大量的相似对象,需要按照相似度清除key值表中重复的对象。

    下面简单的介绍一下本人的思路。

    文件准备

    因为百万级数据的清理在单机模式下其实是很耗时的操作,所以我们需要考虑到一些异常的发生,并且要暂存一下重复的key值,所以需要构建三个临时文件

    touch out.json set.json error.json

    分别代表输出文件,key值暂存文件,以及错误文件

    重试机制的简单实现

    有时调用es进行查询会出现超时的情况,为了防止服务的直接停止,我们需要捕获异常进行处理。

    对于重试,思路如下:

    catch (Exception e) {
        // 重试超过三次后退出并写入错误文件中
        if (map.getOrDefault(key, 0) >= 3) {
        FileWriter fw2 = new FileWriter(errorFile, true);
        fw2.write("\"" + key + "\"" + ",");
        fw2.close();
        continue;
        }
        log.warn("error!", e);
        // 当失败时放入队列头部
        list.addFirst(key);
        map.put(key,map.getOrDefault(key, 0) + 1);
        }
    

    我们使用一个map来统计当前key的失败次数,进入异常后判断一下当前失败次数,当超过3次后,写入错误文件,并跳到下一个key,未达到三次时,放入队列头部,下次继续重试

    开始清洗

    首先将数据读取到队列中

    String content = FileUtils.readFileToString(file, "UTF-8");
    // 提取json的values
    JSONObject jsonObject = JSONObject.fromObject(content);
    LinkedList<String> list = new LinkedList<>(jsonObject.values());
    

    然后通过当前key去es中查找唯一的对象,再通过对象值去查找与之相似的key,存入set中。

    删除队列中存在的相似key

    list.removeAll(set);
    

    最好统计一下当前运行的进度,比如每一千个输出一次

    if (count % 1000 == 0) {
        // 已清洗数据量
        log.info("count: " + count);
        // 已删除数据量
        log.info("cleanCount: " + cleanCount);
        FileWriter fw1 = new FileWriter(setFile, true);
        fw1.write("\"" + count + "\":" + "\"" + cleanCount + "\"" + ",");
        fw1.close();
    }
    

    今天的介绍就到这里了,如有问题,请联系博主

    付出不到,就不要想着收获

    相关文章

      网友评论

          本文标题:java海量数据的简单清洗

          本文链接:https://www.haomeiwen.com/subject/flwnrftx.html