txt文件导入亿级数据

前言

  • 工作中有个需求,需要导入几个g大小的txt文件到mysql数据库中,并能按条件实时搜索。

解决方案

  1. mysql数据库分库分表
  • tddl分库分表
  1. 大txt文件拆分成小文件
  • 采用命令
    split -b
    • 第一个参数:目标文件大小,切割成的小文件一个多大。示例是800M,但是m要小写,如果是G则写g。
    • 第二个参数:被切割文件路径。
    • 第三个参数:目标文件名称。

注:拆分完之后各个文件首尾的数据可能会被分割,需要手动确认修改下。

  1. 接口导入txt文件
    拆分成的小文件可以压缩到一个压缩包里。
  • 解压获取压缩包里的所有文件
				List<File> fileList = Lists.newArrayList();
                File file = new File(multipartFile.getOriginalFilename());
                FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
                ZipFile zipFile = new ZipFile(file, UTF_8);
                Enumeration<? extends ZipEntry> entries = zipFile.entries();
                while (entries.hasMoreElements()) {
                    ZipEntry entry = entries.nextElement();
                    InputStream inputStream = zipFile.getInputStream(entry);
                    if (!entry.getName().startsWith(UNDERSCORE)) {
                        File singleFile = new File(entry.getName());
                        FileUtils.copyInputStreamToFile(inputStream, singleFile);
                        fileList.add(singleFile);
                    }
                }
                file.delete();
  • 多线程批量导入
// 防止线上报错,循环同步执行各个文件
        for (File file : fileList) {
            List<Callable<Boolean>> callables = Lists.newArrayList();
            if (file != null) {
                try (Stream<String> stream = Files.lines(Paths.get(file.getPath()))) {
                    int batchCount = (int) Math.ceil((double) stream.count() / BATCH_SIZE);
                    for (int page = 1; page <= batchCount; page++) {
                        try (Stream<String> newStream = Files.lines(Paths.get(file.getPath()))) {
                            List<DncListDTO> dncListDTOList = newStream.skip((page - 1) * BATCH_SIZE).limit(BATCH_SIZE).map(phone -> {
                                DncListDTO dncListDTO = DncListConverter.INSTANCE.toDTO(dncListUploadDTO);
                                return dncListDTO;
                            }).collect(Collectors.toList());
                            Callable<Boolean> callable = () -> dncListManager.addList(dncListDTOList);
                            callables.add(callable);
                        }
                    }
                }
                file.delete();
                ThreadPoolUtil.executeTasks(callables, ThreadPoolUtil.DEFAULT_WAIT_SECONDS);
            }
        }

采用Stream<String> stream = Files.lines(Paths.get(file.getPath()))方式把文件数据转成stream流,防止OOM

  1. 同步数据到openSearch或者es
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值