GraphLoader.edgeListFile报NumberFormatException如何解决?
你猜的没错!GraphLoader.edgeListFile默认会尝试把节点ID解析为整数类型(在Spark 1.4版本中,目标类型是Long),但你遇到的节点ID116374117927631468606已经远远超出了Long类型的最大值(9223372036854775807),所以才抛出了NumberFormatException。
由于GraphX的VertexId是固定的Long类型,我们需要先把超大的字符串节点ID映射成合法的Long ID,再构建图,具体解决方案如下:
分步解决方法
1. 手动加载原始边列表
跳过GraphLoader,直接用Spark文本API读取文件,将每行分割为两个字符串类型的节点ID:
val rawEdges = sc.textFile("comb.txt").map(line => { val parts = line.split("\\s+") // 按空格分割,可根据你的文件实际分隔符调整 (parts(0), parts(1)) })
2. 为所有唯一节点分配Long ID
收集所有节点ID并去重,给每个节点分配一个唯一的Long值:
// 提取所有节点并去重 val allVertices = rawEdges.flatMap { case (src, dst) => Seq(src, dst) }.distinct() // 为每个节点分配唯一Long ID val vertexIdMap = allVertices.zipWithIndex().collectAsMap() // 广播映射表,避免每个任务重复加载 val broadcastVertexIdMap = sc.broadcast(vertexIdMap)
3. 将原始边转换为Long ID格式
把边中的字符串ID替换为对应的Long ID,同时可按需设置边属性:
val edges = rawEdges.map { case (src, dst) => val srcId = broadcastVertexIdMap.value(src) val dstId = broadcastVertexIdMap.value(dst) Edge(srcId, dstId, 1) // 这里边属性设为1,可根据业务需求调整 }
4. 构建包含原始节点ID的Graph
如果需要保留原始字符串节点ID,可以将其作为节点属性,再构建图:
// 构建顶点RDD:(Long类型ID, 原始字符串ID) val vertices = allVertices.map(id => (broadcastVertexIdMap.value(id), id)) // 最终构建Graph val graph = Graph(vertices, edges)
额外提示
- 如果你的边包含权重等自定义属性,可在步骤1分割行时一起读取,步骤3转换边时带上对应属性即可。
- 后续操作图时,若需要原始字符串节点ID,直接从节点属性中提取即可。
内容的提问来源于stack exchange,提问作者kingbol
相关产品推荐
相关产品推荐

