加速 geomesa 查询

Speed up geomesa query

我一直在使用简单的空间查询测试 geomesa,并将其与 Postgis 进行比较。例如,此 SQL 查询在 Postgis 中运行 30 秒:

with series as (
select
    generate_series(0, 5000) as i
),
points as (
    select ST_Point(i, i*2) as geom from series
)
select st_distance(a.geom, b.geom) from points as a, points as b

现在,以下 geomesa 版本需要 5 分钟(使用 -Xmx10g ):

import org.apache.spark.sql.SparkSession
import org.locationtech.geomesa.spark.jts._
import org.locationtech.jts.geom._


object HelloWorld {
  def main(args: Array[String]): Unit = {

    val spark = SparkSession.builder
      .config("spark.sql.crossJoin.enabled", "true")
      .config("spark.executor.memory", "12g")
      .config("spark.driver.memory", "12g")
      .config("spark.cores.max", "4")
      .master("local")
      .appName("Geomesa")
      .getOrCreate()
    spark.withJTS
    import spark.implicits._


    val x = 0 until 5000
    val y = for (i <- x) yield i*2
    val coords = for ((i, n) <- x.zipWithIndex) yield (i, y(n))
    val points = for (i <- coords) yield new GeometryFactory().createPoint(new Coordinate(i._1, i._2))
    val points2 = for (i <- coords) yield new GeometryFactory().createPoint(new Coordinate(i._1, i._2))
    val all_points = for {
      i <- points
      j <- points2} yield (i, j)
    val df = all_points.toDF("point", "point2")
    val df2 = df.withColumn("dist", st_distance($"point", $"point2"))
    df2.show()
  }
}

我曾期望 geomesa 具有类似或更好的性能,如何调整这样的查询?

第一次编辑

正如 Emilio 所说,这实际上不是查询,而是计算。 可以在没有火花的情况下编写此查询。下面的代码运行不到两秒:

import org.locationtech.jts.geom._

object HelloWorld {
  def main(args: Array[String]): Unit = {

    val x = 0 until 5000
    val y = for (i <- x) yield i*2
    val coords = for ((i, n) <- x.zipWithIndex) yield (i, y(n))
    val points = for (i <- coords) yield new GeometryFactory().createPoint(new Coordinate(i._1, i._2))
    val points2 = for {
      i <- points
      j <- points} yield i.distance(j)

    println(points2.slice(0,30))
  }
}

对于少量数据,GeoMesa 不会像 PostGIS 那样快。 GeoMesa 专为分布式、NoSQL 数据库而设计。如果您的数据集适合 PostGIS,您可能应该只使用 PostGIS。一旦开始达到 PostGIS 的极限,就应该考虑使用 GeoMesa。 GeoMesa 确实提供与任意 GeoTools 数据存储(包括 PostGIS)的集成,这可以使 PostGIS 可以使用 GeoMesa Spark and command-line 的一些功能。

对于您的特定片段,我怀疑大部分时间都花在了启动 RDD 和 运行 循环上。并没有真正的 'query',因为您只是 运行 成对计算。如果您正在查询存储在 table 中的数据,那么 GeoMesa 有机会优化扫描。但是,GeoMesa 不是 SQL 数据库,并且没有任何对联接的本机支持。通常,连接是由 Spark 在内存中完成的,尽管您可以采取一些措施来加快速度(即 broadcast join or RDD partitioning)。如果您想进行复杂的空间连接,您可能需要查看 GeoSpark and/or Magellan,它专门从事空间 Spark 操作。