单台机器上实现TB级的数据对比之数据排序

从std::sort到TB级并行排序:C++高性能排序算法实战指南 排序算法是计算机科学的基础核心概念,其本质是通过特定规则对数据元素进行重新排列。从时间复杂度与空间复杂度的理论分析,到内存访问模式、缓存友好性等底层原理,排序算法的选择直接影响程序性能。在工程实践中,排序算法的技术价值在于高效处理海量数据,支撑大数据分析、数据库索引、科学计算等关键应用场景。随着数据规模从GB级扩展到TB级,单线程std::sort已无法满足需求,必须结合多线程并行、分布式计算及内存层次优化等策略。本文聚焦基数排序、并行归并排序等高效算法,通过分析数据特征与硬件特性,提供从单机到分布式的完整 阅读详情

在单台机器上实现TB级的数据对比之数据排序

整体流程

在上一个章节已经实现了对大型文件的拆分.今天来继续分享关于数据的排序。

文件排序的逻辑不复杂。将数据读取进内存中然后排序。写入至磁盘中。由于这些文件相互完全不关联。可以并行化处理。那先还是看下整体的一个结构吧。

在这里插入图片描述

这个主要涉及到以下内容:

  1. 并行排序控制器,它的主要作用是控制向线程池中加入任务的数量。
  2. 线程池,用来执行当前的排序任务。
  3. 排序任务。将排序中涉及的到操作,封装到一个任务中。包括从文件中读取数据到内存,再将内存中的内容进行排序,最后再将排序后的内容输出到原文件中。

并行控制器

先来聊下为什么要有并行控制器。

这是由几个方面的原因才导致需要并行控制器。

  1. 这个当然与线程池的拒绝策略有关了,线程池的一般策略为优先使用核心线程数;当核心线程数都在运行后,还有任务进来就放入到任务队列中;当任务进来将任务队列都装满了,还有任务进来就启动最大线程数;当最在线程数都在运行后,还有任务进来了,就执行拒绝策略了,就是抛出RejectedExecutionException异常。所以在放入任务时,需要对放入任务的数量进行控制。不然任务任务就被直接RejectedExecutionException给抛出来了。如果直接出异常相关于任务被中断了。所以我会使有并行控制。当然有熟悉线程池的童鞋可能会说使用CallerRunsPolicy这种策略了,这种策略就是如果最大线程都已经被启用,并且队列已经被占用,就是当前提交的线程中执行提交任务了。这其实也不好,如果提交线程还有其他事情需要执行,就被这个任务给占用了。
  2. 由于任务提交到了线程池执行了,并不知道任务什么时候执行结束。当所有的排序任务都提交到了线程池了,线程池中排序任务执行排序中,这个时候如果不控制就是开启下一个阶段。当测试不是特别大的文件时。可能就会导致文件读取到了还没有写入完成的文件,导致读取到了错误的数据。

基于这两点,我觉得需要实现一个并行的控制器。

讲完了为什么要做并行控制器。现在聊聊并行控制器如何实现?

我的方案是这样子的:

在这里插入图片描述

我还是来解释下吧

  1. 任务在提交线程池后可到得到一个future对象.
  /**
   * 异常执行
   *
   * @param fileItem 文件
   * @return 异常结果
   */
  private Future<?> runTask(File fileItem) {
    // 以线程池的方式并行运算
    Future<?> future =
        ScheduleTaskThreadPool.INSTANCE.submit(
            () -> {
              long startTime = System.currentTimeMillis();
              // 将文件转换为集合
              List oneFileList = this.fileToList(fileItem);

              // 使用插入排序,保持数据的稳定,不改前数据的前后顺序,但时间复杂度为n的平方.
              Collections.sort(oneFileList);
              // 快速排序,快速排序非稳定的排序,会改变前后顺序。
              // QuickSort.quickSortList(oneFileList);
              // 再输出至文件中
              this.listToFile(oneFileList, fileItem);

              long endTime = System.currentTimeMillis();
              return endTime - startTime;
            });

    return future;
  }
  1. 将这个任务加入到队列中,当线程池中任务到达满载状态(队列占用完和启动了最大核心数)时,将队列中的首个任务移除,并等待这个任务结束,这样就控制了线程提交的数量和速度了。千万不要忘了,提交结束了,要等任务提交结束。
/**
   * 读取数据的流程处理
   *
   * @param dataList 文件列表
   */
  protected void fileSoft(File[] dataList) {

    System.out.println("开始执行线程池任务,信息输出");
    ScheduleTaskThreadPool.INSTANCE.outPoolInfo();

    LinkedList<Future> rsp = new LinkedList<>();
    try {
      for (File fileItem : dataList) {
        // 异步调用数据处理
        Future<?> future = this.runTask(fileItem);
        // 将数据加入队列尾部
        rsp.add(future);
        // 统计计数
        dataStatistics.dataAdd(1);

        // 优先检查线程池是否已经满载
        if (ScheduleTaskThreadPool.INSTANCE.isFull()) {
          // 获取并移除队列的头
          Future item = rsp.poll();
          // 由于此处单个任务失败,不能影响其他的,需要单个异常处理,流程继续
          try {
            Object value = item.get();
            // 打印任务信息
            System.out.println("用时:" + value);
            ScheduleTaskThreadPool.INSTANCE.outPoolInfo();

          } catch (InterruptedException e) {
            e.printStackTrace();
          } catch (ExecutionException e) {
            e.printStackTrace();
          }
        }
      }
      // 必须所有都完成
      for (Future item : rsp) {
        Object value = item.get();
        // 打印任务信息
        System.out.println("用时:" + value);
        ScheduleTaskThreadPool.INSTANCE.outPoolInfo();
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

到此并行任务控制器就做好了。

线程池

这个应该不用多说了,使用java中的线程池即可。对了,要自己根据资源的情况控制最小线程,最大线程和等待队列和拒绝策略哦。

public class ScheduleTaskThreadPool {

  /** 进行任务调度的线程池对象 */
  public static final ScheduleTaskThreadPool INSTANCE = new ScheduleTaskThreadPool();

  /**
   * 线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;
   * 如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;
   * 如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。
   */
  private static final int MIN_THREAD_NUM = 2;

  /**
   * 线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,
   *
   * <p>前提是当前线程数小于maximumPoolSize
   */
  private static final int MAX_THREAD_NUM = 4;

  /**
   * 线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,
   *
   * <p>前提是当前线程数小于maximumPoolSize
   */
  private static final int WAIT_NUM = 8;

  /**
   * 线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间。以秒为单位
   *
   * <p>默认情况下,该参数只在线程数大于corePoolSize时才有用
   */
  private static final int KEEPALIVE = 5;

  /**
   * workQueue必须是BlockingQueue阻塞队列。当线程池中的线程数超过它的corePoolSize的时候,
   *
   * <p>线程会进入阻塞队列进行阻塞等待。 通过workQueue,线程池实现了阻塞功能 1,(1)不排队,直接提交 将任务直接交给线程处理而不保持它们,可使用SynchronousQueue
   * 如果不存在可用于立即运行任务的线程(即线程池中的线程都在工作),则试图把任务加入缓冲队列将会失败,
   * 因此会构造一个新的线程来处理新添加的任务,并将其加入到线程池中(corePoolSize-->maximumPoolSize扩容)
   * Executors.newCachedThreadPool()采用的便是这种策略
   *
   * <p>(2)无界队列 可以使用LinkedBlockingQueue(基于链表的有界队列,FIFO),理论上是该队列可以对无限多的任务排队
   * 将导致在所有corePoolSize线程都工作的情况下将新任务加入到队列中。这样, 创建的线程就不会超过corePoolSize,也因此,maximumPoolSize的值也就无效了
   *
   * <p>(3)有界队列 可以使用ArrayBlockingQueue(基于数组结构的有界队列,FIFO),并指定队列的最大长度
   * 使用有界队列可以防止资源耗尽,但也会造成超过队列大小和maximumPoolSize后,提交的任务被拒绝的问题,
   *
   * <p>比较难调整和控制。
   *
   * <p>等待任务的队列
   */
  private ArrayBlockingQueue queue = new ArrayBlockingQueue(WAIT_NUM);

  /** 创建线程的工厂,通过自定义的线程工厂可以给每个新建的线程设置一个具有识别度的线程名 */
  private ThreadFactory factory = new ScheduleTaskThreadFactory();

  /**
   * 策略说明 1,ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
   *
   * <p>2,ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
   *
   * <p>3,ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
   *
   * <p>4,ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务,这个策略重试添加当前的任务,他会自动重复调用 execute() 方法,直到成功。
   */
  private ThreadPoolExecutor pool =
      new ThreadPoolExecutor(
          MIN_THREAD_NUM,
          MAX_THREAD_NUM,
          KEEPALIVE,
          TimeUnit.SECONDS,
          queue,
          factory,
          new ThreadPoolExecutor.AbortPolicy());

  /**
   * 提交带返回值的线程给线程池来运行
   *
   * @param task
   */
  public Future<?> submit(Callable task) {
    return pool.submit(task);
  }

  /**
   * 提交任务给线程池运行
   *
   * @param task
   */
  public Future<?> submit(Runnable task) {
    return pool.submit(task);
  }

  /**
   * 当前否为线程池已经满载
   *
   * @return
   */
  public boolean isFull() {
    return pool.getPoolSize() == pool.getMaximumPoolSize();
  }

  public void outPoolInfo() {
    StringBuilder outData = new StringBuilder();
    outData.append("pool Core Size:").append(pool.getCorePoolSize()).append(",");
    outData.append("curr pool size:").append(pool.getPoolSize()).append(",");
    outData.append("max pool Size:").append(pool.getMaximumPoolSize()).append(",");
    outData.append("queue size:").append(pool.getQueue().size()).append(",");
    outData.append("task completed size:").append(pool.getCompletedTaskCount()).append(",");
    outData.append("active count size:").append(pool.getActiveCount()).append(",");
    outData.append("task count size:").append(pool.getTaskCount()).append(",");
    outData.append(Symbol.LINE);
    outData.append(Symbol.LINE);

    System.out.println(outData.toString());
  }

  public void shutdown() {
    pool.shutdown();
  }
}

总结:

做完了分析是不是觉得也不复杂么,只要将并行控制器和线程池控制好了,这个做起来就没有那么难的,并行控制器,特别注意要与提交速度要与线程池的运行相匹配,不然就是发生RejectedExecutionException异常。线程池这个就相对容易了,使用java自带的线程池就可以了。

至此并行排序就做好了。如果你想查看更多代码,可查看我的github:

https://github.com/kkzfl22/datastruct/blob/master/src/main/java/com/liujun/datastruct/datacompare/bigfilecompare/common/BigFileSort.java

下一节,我将继续分享有序文件的去重和对比输出。

使用Python批量处理行、列和单元格 使用Python批量处理行、列和单元格 精确调整工作表的行高和列宽 批量更改多个工作簿的数据格式 批量更改工作簿的外观格式 设置字体格式 修改字体为宋体 修改字号 字体加粗 字体颜色 单元格填充颜色 对齐方式 添加合适粗细的边框 替换工作簿的行数据 提取指定数据 提取列数据 追加行数据 提取所有工作表的唯一值 阅读详情

相关推荐

基于 TiSpark 的大规模数据批量处理技术 TiDB

TiSpark 是 TiDB 的批量处理引擎,它基于 Apache Spark 构建,可以处理海量数据的分析和计算任务。本文将介绍基于 TiSpark 的大规模数据批量处理技术,并提供相应的源代码示例。通过编写相应的代码,我们可以在 TiDB 中进行数据的批量处理和分析操作。在执行过程中,TiSpark 会根据数据的分布情况将任务分配到不同的 TiDB 实例上进行并行处理,以提高处理速度和吞吐量。在示例代码中,我们首先创建了一个 SparkSession 对象,并设置 TiSpark 的配置参数。

FdhApps的博客 257

如何在单台8G内存机器上实现1TB日志排序?

问题: 最近在面试人的时候,我经常会问一个问题,题目如下: 现在有一批日志数据,大小为1TB,数据是某一天的生产的日志数据,现在只有一台单CPU及8G内存的机器,请使用算法对此日志数据按时间的先后顺序进行排序。 可面试了好多人,都没有回答出这个问题 针对这个问题今天来讲讲这个问题我的解法。 解决方案1:桶排序 它的原理是利用分区字段的特点,将数据分别写入到多个桶文件中...

bug_null的博客 3837

手把手教你配置C6678的SPI启动:从NorFlash烧写到多核加载的完整流程

本文详细介绍了TMS320C6678多核DSP的SPI启动全流程,包括硬件准备、镜像文件生成与转换、NorFlash烧写与验证、多核启动同步机制以及常见问题排查。通过实战演示,帮助开发者高效配置SPI启动模式,解决启动失败、多核同步异常等问题,提升嵌入式系统开发效率。

weixin_27076351的博客 151

数据分析TB级别数据量大了怎么办,不会代码模型训练怎么办?

数据分析经常会遇到数据量大的问题,比如用R语言和Python语言时经常会遇到内存溢出的问题,即使把整个机器内存全部使用,达到最大使用率,还是无济于事,比如数据量是10T,并且在大数据量下,既要保证数据能够得出结果,还要一个好的模型进行迭代训练,得到一个好的模型。这些很难。 这里有两个问题 数据量大 模型训练准确性 对于第一个问题,就算单机内存再大,也是不可能处理未来不可预知的...

gb4215287的博客 1523

洛谷 P5736 【深基7.例2】质数筛

题目描述 输入 n(n\le100)n(n≤100) 个不大于 100000 的整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。 输入格式 无 输出格式 无 输入输出样例 输入 #1 复制 5 3 4 5 6 7 输出 #1 复制 3 5 7 板子题,使用一下线性筛 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using n

qq_37978559的博客 1117

【electron】- 从零到一:在electron-vite项目中集成better-sqlite3的工程化实践

本文详细介绍了在electron-vite项目中集成better-sqlite3数据库的完整工程化实践。针对原生模块的编译挑战,提供了从环境配置、路径规划、服务封装到IPC通信的解决方案,并重点解决了开发与生产环境的数据库路径分离及打包部署等核心问题,帮助开发者构建稳定高效的Electron桌面应用数据层。

weixin_29306571的博客 203

mybatis批量处理数据的方式

文章目录foreach拼接sql的方式通用方式批量插入mysql:批量插入批量更新:oracle:批量插入批量更新:mybatis批处理方式性能测试 foreach拼接sql的方式 通用方式 批量插入 mysql和oracle都适用 INSERT INTO UNION ALL <insert id="saveRecordBatch" parameterType="java.util.List"> INSERT INTO T_FUND_OPERATE_LOG (CHANGE_R

浩然的博客 3408

python使用TensorRT报错,多线程或多进程中使用问题

python使用TensorRT报错,Cuda Runtime问题

qq_44224801的博客 747

单台机器上实现TB级的数据对比之数据合并

在单台机器上实现TB级的数据对比之数据合并 整体思路 在上一章节,我介绍了如何对切分后的数据进行并行排序,这节来到了最后的操作,数据的合并操作。将数据进行对比,找出添加的数据、修改的数据、删除的数据。需要特别处理下重复的数据。在第一章节我已经介绍了这个大致的思路,但未深入细节来讨论如何实现,这章将深入细节将数据合并的逻辑做一个完整的说明。 这个逻辑看着有点复杂吧,那我来详细的解释下吧! 在原始排序文件中读取所有文件的首行数据,并记录到以文件索引为下标的数组中。就叫它srcDataList 在目标排

bug_null的博客 497

实战避坑:示波器测量非隔离开关电源的炸机风险与隔离方案

本文详细分析了使用示波器测量非隔离开关电源时的炸机风险,揭示了地线环路导致的短路问题,并对比了四种防炸机解决方案,包括示波器隔离供电、拔掉电源地线、使用差分探头和被测板隔离供电。重点推荐使用隔离变压器方案,确保测量安全与精度,同时提供了实操建议与经验分享,帮助工程师避免常见测量事故。

weixin_29224309的博客 555

大模型多智能体协作面试题及参考答案

在多智能体系统里,代理定义自身目标或效用函数的过程与系统架构、应用场景紧密相关。从本质上讲,目标是代理行为的导向,而效用函数则是对目标达成程度的量化评估。代理通常依据自身角色、系统全局需求以及与其他代理的交互关系来确立目标。比如在合作型 MAS 中,代理目标可能需要与全局目标对齐,像多个物流机器人协作完成货物配送时,每个机器人的目标会围绕 “高效完成分配任务”“避免路径冲突” 等展开,其效用函数可能涉及任务完成时间、能耗等指标的加权求和。目标定义的方式存在多种类型。

大模型大数据攻城狮的专栏 1022

在单台机器上实现TB级的数据对比之数据切分

在单台机器上实现TB级的数据对比之数据切分 文件切分的逻辑 由于面对的原始文件可能是一堆小文件,也可能是一个很大文件,这第一步当然是对文件进行切割规整,统一大小为32M,这个32M是一个近似值,由于要保留完整的行,故这是一个接近值。那如何实现呢? 分为两部分来说吧, 第一部分是文件读取: 读取目录下的文件,获得一个文件列表。列表使用数组来存储。 将列表按文件名进行排序,获得数据读取文件的一个顺序,也就是数据的一个顺序。 声明一个索引编号,编号从0开始,这个索引编号代表的就是当前正在读取的文件。 按索引编号

bug_null的博客 304

分布式系统中的“无状态”和“有状态”详解

有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如 tomcat 中的 session。例如登录:用户登录后,我们把登录者的信息保存在服务端 session 中,并且给用户一个 cookie 值,记录对应的 session。然后下次请求,用户携带 cookie 值来,我们就能识别到对应 session,从而找到用户的信息。

AI天才研究院 2万+

在单台机器上实现TB级的数据对比

在单台机器上实现TB级的数据对比 前几天我在做公司项目的时候,需要对数据进行比较。数据量不大,也就几千条而已。当时功能完成后,我开始思考一个问题。就是当对比的文件是特别大的时候,我还能实现吗?那现在对问题做出假设: 问题: 现在有两个超大文件集,原始数据集和目标数据集,每个文件集中都有超过1亿的记录,数据中存在重复的记录,编写一个程序,可以找出两个数据集之间的差异,求解出三类数据: 原始数据集中存在,目标数据集中不存在,为待删除的数据记录。 原始数据集中存在,目标数据集中也存在,但内容不一致,为待修改的记录

bug_null的博客 418

从 AI 助手到 ADT 自动化桥梁:全面解析 Vibing Steampunk 的定位、能力边界与典型使用场合

Vibing Steampunk是一个面向SAP ABAP开发的AI自动化工具集,它通过ADT API将SAP开发能力系统化地暴露给AI助手和命令行工作流。该工具支持ECC、S/4HANA等所有启用ADT的系统,提供代码读取、修改、测试、调试等全流程自动化能力。核心功能包括AI调试、上下文压缩、ABAP语言服务、Lua脚本自动化等,并内置多重安全控制。其分层架构兼容标准ADT和WebSocket扩展,既适合AI驱动开发,也支持传统DevOps自动化,特别适用于老系统代码考古、知识接力和复杂问题诊断场景。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 150

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

hadoop的1TB排序《转》

1、1TB(或1分钟)排序的冠军 作为分布式数据处理的框架,集群的数据处理能力究竟有多快?或许1TB排序可以作为衡量的标准之一。 1TB排序,就是对1TB(1024GB,大约100亿行数据)的数据进行排序。2008年,Hadoop赢得1TB排序基准评估第一名,排序1TB数据耗时209秒。后来,1TB排序被1分钟排序所取代,1分钟排序指的是在一分钟内尽可能多的排序。2009年,在一个1406个节点组成的hadoop集群,在59秒里对500GB完成了排序;而在1460个节点的集群,排序1TB数据只花

Superxgl的专栏 578

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

4.算法进阶——外部排序,如何用有限的内存对TB级数据进行排序

内存是有限的,而所谓外部排序的这个外:指的是外部存储。 已知1GB的内存如果要处理1TB,至少要读1024次。 所以大体思路一定是:将文件分段,用常见内部排序方法进行排序完了之后,再合并。即思路上大体是归并排序1.内部排序 我们分成一段一段之后,主要目的是使得内存能够装下这一段数据。 一般来说,快速排序在大部分场景下都是最快的2.归并阶段 因为需要归并n多个段,此时的内存肯定无法装下超过一个段的内容。此时最大的时间消耗来自IO。 内存的读写操作是很快的,但是外部磁盘中读写,可能比内...

strive for the best 的博客 681

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

hadoop的1TB排序

原文链接:http://www.javaeye.com/topic/709986 1、1TB(或1分钟)排序的冠军 作为分布式数据处理的框架,集群的数据处理能力究竟有多快?或许1TB排序可以作为衡量的标准之一。 1TB排序,就是对1TB(1024GB,大约100亿行数据)的数据进行排序。2008年,Hadoop赢得1TB排序基准评估第一名,排序1TB数据耗时209秒。后来,1TB排序被1

caodaoxi的专栏 467

海量数据排序——如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?

1、外排序   传统的排序算法一般指内排序算法,针对的是数据可以一次全部载入内存中的情况。但是面对海量数据,即数据不可能一次全部载入内存,需要用到外排序的方法。外排序采用分块的方法(分而治之),首先将数据分块,对块内数据按选择一种高效的内排序策略进行排序。然后采用归并排序的思想对于所有的块进行排序,得到所有数据的一个有序序列。  例如,考虑一个1G文件,可用内存100M的排序方法。首先将文件分成

无鞋童鞋的博客 3万+

ClickHouse 数据采样:如何让 TB 级查询从分钟级降到秒级

凌晨三点,运维把你叫起来:核心报表查询跑了 8 分钟还没出结果,客户已经在看直播等数据了。你盯着这条 SQL——它需要扫描一张几百亿行的日志表,哪怕加了索引也避不开海量数据读取。这时候,"全量计算"本身可能就是问题所在。如果你的业务只需要"足够准"的近似值,ClickHouse 的数据采样(`SAMPLE` 子句)就能只读一小部分数据,用 1% 的成本换来 99% 的答案。 ## 采样为什么能又

gitblog_00365的博客 342

Apache Iceberg性能飞跃:从TB级数据湖到毫秒级查询的架构革命

当你的数据湖查询响应时间从分钟级降至秒级,当TB级数据表的维护成本大幅降低,这一切都源于Apache Iceberg带来的架构革新。本文将通过全新的视角,为你揭示Iceberg如何通过元数据驱动和隐藏分区等核心技术,实现大数据分析的性能质变。 ## 痛点直击:传统数据湖的性能瓶颈 在大数据场景中,你是否经常遇到以下问题: - 查询10TB数据表需要等待数分钟甚至更久 - 频繁的小文件导致Nam

gitblog_00219的博客 931

单机TB级数据处理:从内存瓶颈到I/O优化的实战指南

海量数据处理并非天然属于分布式系统,当数据规模达到TB量级但尚未跨节点时,单机系统工程能力成为关键分水岭。其核心原理在于正视物理约束——内存容量、磁盘带宽、CPU缓存与系统调用开销共同构成性能天花板。技术价值体现在以最小硬件成本实现确定性高吞吐:通过分块流式读取规避OOM、二进制存储压缩50%+空间、Shell管道复用OS级外部排序等手段,显著超越通用脚本语言的默认行为。典型应用场景包括日志分析、传感器数据聚合、用户行为埋点清洗及基因序列预处理。本文聚焦真实生产中反复验证的单机优化路径,覆盖wget下载参数

rongdmmap的博客 466

60TB 数据量的作业从 Hive 迁移到 Spark 在 Facebook 的实践

Facebook 经常使用分析来进行数据驱动的决策。在过去的几年里,用户和产品都得到了增长,使得我们分析引擎中单个查询的数据量达到了数十TB。我们的一些批处理分析都是基于 Hive 平台...

过往记忆大数据 866
上一篇: 在单台机器上实现TB级的数据对比之数据切分
下一篇: 单台机器上实现TB级的数据对比之数据合并
null_null_bug
博客等级 码龄7年 72粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值