Spark 空间数据管理的一些思考

概述

Spark对空间数据的管理的两个重要方面:数据分区和数据索引

数据分区

数据分区有几个重要的关注点:空间邻近性、数据覆盖完整性、数据均匀分布、数据冗余

空间数据的分区方案一般使用空间索引,控制每一个索引数据项中的数据量,把每一个索引项中的数据作为一个分区,这样可以保证分区中的具有数据良好的空间邻近性。分区空间邻近性有利于使用部分分区即可完成进行空间查询、连接等操作。

为了得到具体的分区结果,需要了解数据的分布。一般使用抽样点利用空间索引进行分区,得到各个分区的范围。根据已有研究[1],1%的数据样本已经足够获取较高质量的分区结果。由于采用了数据样本获取具体的分区范围,所以得到的分区范围很有可能可能不能覆盖完整的数据范围,比如R树。而对于需要对完整数据空间划分的空间索引方法(规则网格、四叉树、KD树等),因为其索引构建时,必须要传入完整数据的空间范围,所以获取到的分区范围一定能覆盖全部数据。

分布式计算具有“木桶效应”,整个计算过程效率取决于计算最慢的节点。所以如果某一个分区的数据过多,则会导致该分区计算时间长,从而降低整个的计算效率。

空间索引方案:规则网格、四叉树、R树、KDB树、空间填充曲线。Geospark[5]实现了以上所有方法的数据分区实现。

在这里插入图片描述

  • 规则网格:数据并不能均匀分布,一些分区数据密度太高,一些数据分区密度太低。

  • 四叉树: 数据并不能均匀分布。可以解决分区密度高的问题,但是还是会有分区数据密度太低。

  • R树,一般使用STR树[2],可以保证数据的均匀分布。但是具有覆盖性问题,获取的分区范围是包含样本点的MBR,所以完整数据中可能有数据不属于已有分区,必须另设一个额外的分区保存这些数据,这就破坏了分区数据的空间邻近性。Simba[3]使用的就是STR树进行数据分区,其论文中提到获取到有样本点计算生成的分区结果后,会对分区范围进行扩展,但是具体的扩展方法并没有叙述。

  • KDB树,数据均匀分布,且不会有分区覆盖完整性问题。时空K函数的分布式优化[4],使用的是此方法进行分区。

  • 空间填充曲线,其也是需要将空间划分为规则的网格,所以其具有和规则网格一样的问题。

当处理的空间数据是非点数据时,空间对象会和多个分区范围相交。Geospark的处理方法为将空间对象复制,分发到不同分区中。这就造成了数据冗余,当进行空间查询等操作时,会在不同分区中对相同数据进行同样的操作,最后还需要对返回结果进行去重,造成空间和时间的浪费。

个人想法:分区结果得到各分区的空间范围并不是分区数据真实的MBR。当空间对象是点类型,真实的分区MBR可能比分区范围小。当空间对象是多维对象时,空间对象可能会部分超过分区范围。
在这里插入图片描述
在这里插入图片描述

即使使用R树进行数据分区,也由于使用的是样本数据,并不能保证分区范围一定就是分区所有数据的MBR。所以直接使用分区结果范围建立全局索引是不合理的,必须在每个分区中进行数据统计,发送到driver中,建立全局分区索引。

从上述可以看出分区的目的仅仅是将所有数据分发到不同分区中,并保持良好的空间邻近性,不能用于直接建立全局索引。所以可以参考STR树的处理方法,在构建分区的空间索引时,将空间对象转换为空间点进行操作,可以快速的构建索引结构。在数据分区时,也将空间对象作为转换为空间点,由于点只能属于一个空间范围,所以不会造成空间数据冗余。

数据索引

数据索引分为全局索引和局部索引。

局部索引是对RDD分区内的数据建立空间索引。一个分区中的数据不一定都符合我们的处理需求,如果在RDD 原生API中会使用filter算子继续过滤,但filter会遍历所有的数据,逐个判断,效率较低。而利用空间索引,可以直接查询到可能符合要求的数据,直接省略掉不可能的数据,提高了数据的处理效率。

但是由于RDD 分区是一个只能顺序扫描记录的集合,并不持支持随机读写。所以可以将一整个分区的所有记录转换为一条记录(利用mapPartition算子),对这一条记录进行处理。在Geospark,将分区数据转换为SpatialIndex对象(JTS库中的对象,包含数据信息和索引信息);Simba中将分区数据转换为IPartition对象,同样也包含数据信息和索引信息。所以局部索引的实现大同小异,都是讲分区数据转换为一个对象,对象中储存分区所有数据,并建立空间索引。再对分区进行操作时,根据空间索引获取对象中的分区数据。

在这里插入图片描述

由于分区具有空间邻近性,所以对于范围查询、KNN查询等操作,涉及到的数据只属于部分分区,所以不需要所有的分区都参与运算,只要求涉及的分区运算,可提高计算效率。所以需要对分区建立全局索引,以查找涉及计算的分区。

局部索引构建完毕之后,可获取整个分区的数据信息(数据范围等),可将其传到driver进程中,driver通过这些分区范围信息,建立分区的全局空间索引。计算时,通过全局索引进行分区剪枝,减少分区处理的数量。

参考文献

[1] Eldawy A, Alarabi L, Mokbel M F. Spatial partitioning techniques in SpatialHadoop[J]. Proceedings of the VLDB Endowment, 2015, 8(12): 1602-1605.

[2] Leutenegger S T, Lopez M A, Edgington J. STR: A simple and efficient algorithm for R-tree packing[C]. Proceedings 13th International Conference on Data Engineering, 1997: 497-506.

[3] Xie D, Li F, Yao B, et al. Simba: Efficient in-memory spatial analytics[C]. Proceedings of the 2016 International Conference on Management of Data, 2016: 1071-1085.

[4] 面向海量点模式分析的时空Ripley’s K函数优化与加速

[5] Yu J, Wu J, Sarwat M. GeoSpark: A Cluster Computing Framework for Processing Spatial Data[J].

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spark SQL 数据类型转换 在 Spark SQL 中,可以使用 cast 函数将一个数据类型转换为另一个数据类型。 例如,我们可以将字符串类型转换为整数类型: ``` SELECT CAST("42" AS INT) ``` 这将输出整数值 42。 类似地,我们还可以将整数类型转换为字符串类型: ``` SELECT CAST(42 AS STRING) ``` 这将输出字符串值 "42"。 除了整数和字符串类型之外,Spark SQL 还支持其他一些数据类型转换,例如日期和时间类型。 如何管理 Spark 的分区 Spark 的分区是将数据集拆分成更小的块,以便并行处理。分区的数量可以手动设置,也可以由 Spark 自动确定。 以下是一些管理 Spark 分区的常见方法: 1. 手动设置分区数量:可以使用 repartition 或 coalesce 函数来手动设置分区数量。repartition 函数将数据集重新分区,而 coalesce 函数将数据集合并为更少的分区。 2. 自动确定分区数量:Spark 可以根据数据集的大小和集群的可用资源来自动确定分区数量。可以使用 spark.sql.shuffle.partitions 属性来设置默认分区数量。 3. 控制分区大小:可以使用 mapPartitions 函数来控制每个分区的大小。此函数将应用于每个分区,并返回一个新分区。 4. 手动设置分区的键:可以使用 partitionBy 函数手动设置分区的键。这将根据指定的列将数据集分区。 5. 更改默认的分区策略:可以使用 spark.sql.execution.arrow.enabled 属性来更改默认的分区策略。Arrow 是一种高效的数据格式,它可以减少网络传输和序列化时间,从而提高性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值