GraphX 图数据建模和存储
背景
简单分析一下GraphX是怎么为图数据建模和存储的。
入口
能够看GraphLoader的函数。
def edgeListFile(
sc: SparkContext,
path: String,
canonicalOrientation: Boolean = false,
numEdgePartitions: Int = -1,
edgeStorageLevel: StorageLevel = StorageLevel.MEMORY_ONLY,
vertexStorageLevel: StorageLevel = StorageLevel.MEMORY_ONLY)
: Graph[Int, Int]
- path能够是本地路径(文件或目录),也能够是hdfs路径,本质上是使用sc.textFile来生成HadoopRDD的,numEdgePartitions是分区数。
- Graph的存储是分EdgeRDD和VertexRDD两块,能够分别设置StorageLevel。默认是内存。
- 这个函数接受边文件。即’1 2’, ‘4 1’这种点到点的数据对组成的文件。
把这份文件按分区数和存储level转化成一个能够操作的图。
流程
- sc.textFile读文件。生成原始的RDD
- 每一个分区(的计算节点)把每条记录放进PrimitiveVector里,这个结构是spark里为primitive数据优化的存储结构。
- 把PrimitiveVector里的数据一条条取出。转化成EdgePartition,即EdgeRDD的分区实现。这个过程中生成了面向列存的结构:src点的array,dst点的array。edge的属性array,以及两个正反向map(用于相应点的local id和global id)。
- 对EdgeRDD 做一次count触发这次边建模任务,真正persist起来。
- 用EdgePartition去生成一个RoutingTablePartition,里面是vertexId到partitionId的相应关系。借助RoutingTablePartition生成VertexRDD。
- 由EdgeRDD和VertexRDD生成Graph。前者维护了边的属性、边两头顶点的属性、两头顶点各自的global vertexID、两头顶点各自的local Id(在一个edge分区里的array index)、用于寻址array的正反向map。
后者维护了点存在于哪个边的分区上的Map。
下面是代码,比較清晰地展现了内部存储结构。
private[graphx]
class EdgePartition[
@specialized(Char, Int, Boolean, Byte, Long, Float, Double) ED: ClassTag, VD: ClassTag](
localSrcIds: Array[Int],
localDstIds: Array[Int],
data: Array[ED],
index: GraphXPrimitiveKeyOpenHashMap[VertexId, Int],
global2local: GraphXPrimitiveKeyOpenHashMap[VertexId, Int],
local2global: Array[VertexId],
vertexAttrs: Array[VD],
activeSet: Option[VertexSet])
extends Serializable {
/**
* Stores the locations of edge-partition join sites for each vertex attribute in a particular
* vertex partition. This provides routing information for shipping vertex attributes to edge
* partitions.
*/
private[graphx]
class RoutingTablePartition(
private val routingTable: Array[(Array[VertexId], BitSet, BitSet)]) extends Serializable {
细节
分区摆放
EdgeRDD的分区怎么切分的呢?由于数据是依据HadoopRDD从文件中依据offset扫出来的。能够理解为对边数据的切分是没有不论什么处理的。由于文件也没有特殊排列过,所以切分成多少个分区应该就是随机的。
VertexRDD的分区怎么切分的呢?EdgeRDD生成的vertexIdToPartitionId这份RDD数据是RDD[VertexId, Int]型,它依据hash分区规则,分成和EdgeRDD分区数一样大。
所以VertexRDD的分区数和Edge一样。分区规则是Long取hash。
所以我能够想象的计算过程是:
对点操作的时候,首先对vertexId(是个Long)进行hash,找到相应分区的位置,在这个分区上,假设是内存存储的VertexRDD,那非常快能够查到它的边所在的几个Edge分区的所在位置,然后把计算分到这几个Edge所在的分区上去计算。
第一步依据点hash后找边分区位置的过程就相似一次建好索引的查询。
配官方图方面理解:
高效数据结构
对原生类型的存储和读写有比較好的数据结构支持,典型的是EdgePartition里使用的map:
/**
* A fast hash map implementation for primitive, non-null keys. This hash map supports
* insertions and updates, but not deletions. This map is about an order of magnitude
* faster than java.util.HashMap, while using much less space overhead.
*
* Under the hood, it uses our OpenHashSet implementation.
*/
private[graphx]
class GraphXPrimitiveKeyOpenHashMap[@specialized(Long, Int) K: ClassTag,
@specialized(Long, Int, Double) V: ClassTag](
以及之前提到的vector
/**
* An append-only, non-threadsafe, array-backed vector that is optimized for primitive types.
*/
private[spark]
class PrimitiveVector[@specialized(Long, Int, Double) V: ClassTag](initialSize: Int = 64) {
private var _numElements = 0
private var _array: Array[V] = _
全文完 :)
GraphX 图数据建模和存储的更多相关文章
- 【mysql的设计与优化专题(1)】ER图,数据建模与数据字典
需求分析是做项目中的极为重要的一环,而作为整个项目中的'血液'--数据,更是重中之重.viso,workbench,phpmyadmin等软件可以帮我们更好的处理数据分析问题. ER图 E-R方法是& ...
- 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型
第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...
- 《驾驭Core Data》 第三章 数据建模
本文由海水的味道编译整理,请勿转载,请勿用于商业用途. 当前版本号:0.1.2 第三章数据建模 Core Data栈配置好之后,接下来的工作就是设计对象图,在Core Data框架中,对象图被表 ...
- NoSQL 数据建模技术(转)
本文转载自:http://coolshell.cn/articles/7270.html ================================================ 全文译自墙外 ...
- NoSQL数据建模技术
原文来自“NoSQL Data Modeling Techniques”,由酷壳网陈皓编译<NoSQL数据建模技术>.这篇文章看完之后,你可能会对NoSQL的数据结构会有些感觉.我的感觉是 ...
- kityminder-editor + MongoDB 思维导图数据自动实时保存方案
最近开始做自己的第一个开源项目:一个基于思维导图的测试用例管理系统MinderCase,在做了一周的技术调研后,决定采用kityminder-editor作为思维导图编辑器,为了支持实时存储,当思维导 ...
- Cassandra数据建模中最重要的事情:主键
Cassandra数据建模中要了解的最重要的事情:主键 使用关系数据建模,您可以从主键开始,但是RDBMS中的有效数据模型更多地是关于表之间的外键关系和关系约束.由于Cassandra无法使用JOIN ...
- Cassandra数据建模
1. 概述 Apache Cassandra将数据存储在表中,每个表都由行和列组成.CQL(Cassandra查询语言)用于查询存储在表中的数据.Apache Cassandra数据模型基于查询并针 ...
- 【翻译】ScyllaDB数据建模的最佳实践
文章翻译自Scylla官方文档:https://www.scylladb.com/2019/08/20/best-practices-for-data-modeling/ 转载请注明出处:https: ...
随机推荐
- BZOJ2020: [Usaco2010 Jan]Buying Feed II
[传送门:BZOJ2020] 简要题意: 约翰开车回家,遇到了双十一节,那么就顺路买点饲料吧.回家的路程一共有E 公里,这一路上会经过N 家商店,第i 家店里有Fi 吨饲料,售价为每吨Ci 元.约翰打 ...
- ajax处理错误(六)
使用ajax时必须留心两类错误,他们之间的区别源于视角不同. 一.第一类错误是从XMLHttpRequest对象的角度看到的问题:某些因素阻例如止了请求发送到服务器,例如DNS无法解析主机名,连接请求 ...
- 【Codeforces Round #459 (Div. 2) B】 Radio Station
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用map模拟一下映射就好了. [代码] #include <bits/stdc++.h> using namespace ...
- 【Uva 10723】Cyborg Genes
[Link]: [Description] 给你两个串s1,s2; 让你生成一个串S; 使得s1和s2都是S的子列; 要求S最短; 求S的不同方案个数; [Solution] 设两个串的长度分别为n1 ...
- js插件---10个免费开源的JS音乐播放器插件
js插件---10个免费开源的JS音乐播放器插件 一.总结 一句话总结:各种插件都有很多,多去找. 二.js插件---10个免费开源的JS音乐播放器插件 亲测可用 音乐播放器在网页设计中有时候会用到, ...
- 用Vue.js来实现城市三级联动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- UVA 12075 Counting Triangles
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- AIX查看HBA卡的WWN号
1,获得AIX主机连接的光纤设备: # lsdev -Cc adapter -S a | grep fcs fcs0 Available 09-08 FC Ad ...
- 从excel 获取内容 模块:xlrd
import xlrd # 获取表的对象 excel = xlrd.open_workbook(‘a.excel’) # 获取所有excel里的所有表 table_list = excel.sheet ...
- 数据库事务及其EF中如何处理事务
一.基础知识 1) 使用事务级别ReadUnCommited 会产生脏读现像,意味着读取到的为UnCommited(未提交)的数据.怎么理解呢?在使用该隔离级别的事务开始后.更新了数据 ...