使用10GB内存对十亿规模图进行算法处理:我爱DataFusion
简而言之;我使用Apache DataFusion实现了图的映射-归约。在可能的情况下,我将所有内容转移到磁盘,并设计算法依赖于批量扫描,而不是随机访问。DataFusion处理溢出、排序合并连接、聚合、规划和执行,因此我的代码非常轻量。我在严格模式下通过systemd-run进行测试,并设置了硬内存限制。它可以正常工作。当然,我遇到了一些问题:例如,在极端情况下,我经常会遇到FairSpillPool的死锁,并且我还没有找到使SMJ使用磁盘上预排序数据的方法。但它可以正常工作。我可以在具有十亿条边的有向图上计算PageRank(来自Graphalytics数据集的graph500-26),使用5GB内存。或者,我可以在具有二十亿条边的图上识别所有弱连接组件(来自同一数据集collection的twitter_mpi),使用10GB内存。无论是NetworkX还是Igraph都无法做到这一点;大多数现有图算法都要求图适合内存之前,我认为进行十亿规模图分析需要Apache Spark和GraphFrames。然而,现在我认为所需的只是一个笔记本电脑。我已经彻底改变了我对使用Apache DataFusion进行图分析的旧看法。设置我测试了两个任务。PageRank什么是PageRank?任务是在Graphalytics数据集的graph500-26上计算PageRank:关键值节点数32804978边数1051922853有向图否内存限制5GB DataFusion池大小4GB PageRank是最流行的图中心性算法之一,广泛用于搜索结果排名和反欺诈评分。我的DataFusion实现是经典的Pregel:批量同步并行算法(即Map-Reduce),我用连接和聚合表达出来。与Spark的GraphFrames库核心内容非常相似。弱连接组件什么是弱连接组件?任务是识别同一数据集上的twitter_mpi中的所有弱连接组件:关键值节点数52579682边数1963263821有向图是内存限制10GB DataFusion池大小8GB WCC是任何身份(实体)解析问题的核心部分。例如,当你需要通过传递ID从不同系统中进行数据去重时,你最终会遇到WCC问题。我的DataFusion实现基于“数据库中的连通组件分析”,Bögeholz等,arXiv 1802.09478。我已经为Spark的GraphFrames实现了相同的算法,因此这是一个显而易见的选择。结果PageRank 一个简单的部分。我使用SMJ只是为了证明可扩展性,但由于顶点很小(3200万)且PageRank状态很简单:一列排名(f64),一列出度(i64),一个参与标志(bool),也可以使用HJ。使用HJ会更快。PageRank在有向边上工作,因此不需要对称化图形。只需将边缘转移到磁盘,并通过更新状态迭代(同时也转移到磁盘以打破血统),直到收敛。计算时间很长:大约15个完整迭代花费30分钟。但是,设置与内存有关,而不是速度。给出一些更现实的数字用于十亿图分析,它会足够快(我测试过)。我检查了数字与真实值的匹配:100%的匹配(误差容忍度为0.0001)。这里还有很多优化可以进行:理论上,可以按范围对边进行分桶或进行某种范围分区,因此SMJ不需要在每次迭代中重新对最大的连接侧(边)进行排序,以获得三元组。此外,我还不确定parquet是否是最佳选择。尝试融合连接和聚合也将很有趣:每个Pregel迭代就像 edges <-[连接] nodes-state -> group by + agg -> [连接] -> nodes-state -> 更新节点状态。如果我能将前两个阶段融合在一起,从性能角度来看会是巨大的胜利。与此同时,我还不知道如何在DataFusion中做到这一点:还有很多东西需要学习。WCC 最困难的部分。2B边的twitter图已经很庞大(其边在CSV中为30GB !!!)。但是对于WCC,我们需要对边进行对称化(或在src、dst和dst作为src之间进行联合,并在顶部进行去重),因此在高峰时期,我们使用只有8GB的DataFusion池几乎处理了40亿的边。在流通过了前几次迭代后,收缩过程会显著减少边的数量,算法在10分钟内结束,并且内存压力很低。sem@fedora:~/github/graphframes-rs$ systemd-run --user --scope \ -p MemoryMax=10G -p MemorySwapMax=0 \ -p AllowedCPUs=0-1 \ --setenv=RUST_LOG=graphframes_rs=info,datafusion=warn \ ./target/release/run-algorithm twitter_mpi-v.parquet twitter_mpi-e.parquet wcc 42 file:///var/home/sem/Downloads/gf_wcc_out 8G 2 作为单元运行:run-p316509-i284528.scope ; 调用ID: 742f9296d31d426580b7ec8213422cf1 [ 2026-07-05T05:37:21Z INFO graphframes_rs::algorithm::connectivity::connected_components ] 启动WCC,运行ID 017c0a23-2b20-4ffa-ac6b-6e2cb
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡