java海量数据的简单清洗

这周接到了一个对爬取数据进行清理的任务,具体需求为,有一张接近百万的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();
}

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

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,973评论 19 139
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,615评论 8 265
  • http://liuxing.info/2017/06/30/Spring%20AMQP%E4%B8%AD%E6%...
    sherlock_6981阅读 16,010评论 2 11
  • "见过发光的面条吗?" "夏白,你中华小当家看多了是吧!再不快点把你的老坛酸菜牛肉面吃完我想下节课数学刘应该很愿意...
    遇见平心阅读 300评论 0 0
  • 61 分分钟这世界可以崩塌/天幕中是坠落的火球/但它并不会/微风袭人/花谢花开的一季又一季 明年春天/你也会忘了这...
    有组织不合作阅读 131评论 0 1