他们给了我一张表格,其中存储着模式为[TimeStamp, SensorKey, SensorValue]
的传感器读数。
TimeStamp Id Value
2019-01-01 00:00:47 1 66.6
2019-01-01 00:00:47 2 0.66
2019-01-01 00:00:57 1 66.7
2019-01-01 00:00:57 2 0.68
2019-01-01 00:00:57 3 166.6
2019-01-01 00:01:07 3 146.6
请注意,它仅以有限的精度和采样率存储对传感器读数的更改,并且如果不更改,则在最后一次更改后每小时每小时重复一次该值。
当传感器Z值通过此条件时,它们查询传感器A(以及B,C,D ...)的平均值。他们想要使用Python和Spark。
因此,为了比较不同传感器的值,我获得了这些传感器键的行,并将结果旋转到模式[TimeStamp,ValueOfA,...,Z值]。
df1 = df0.groupBy("TS").pivot("Id", listOfIds).agg(F.last("Value"))
TimeStamp Sensor1 Sensor2 Sensor3
2019-01-01 00:00:47 66.6 0.66 Null
2019-01-01 00:00:57 66.7 0.68 166.6
2019-01-01 00:01:07 Null Null 146.6
然后我填补空白(始终,如果我没有较旧的数据来填补前几行,我将其丢弃)。
window1hour = Window.orderBy('TS').rowsBetween(-360, 0)
# 360 = 1 hour / 0.1 Hz sampling rate.
df2 = df1
for sid in sensorIds:
df2 = df2\
.withColumn(sid, F.last(F.column(sid), ignorenulls=True).over(window1hour))\
.filter(F.column(sid).isNotNull())
现在,逐列进行比较是不重要的。
但是,与用pandas
做同样的事相比,它要慢得多,以至于感觉我做错了。至少对于小型查询。
发生了什么事? 当查询很大时会发生什么?
关于小型和大型:我有数千种不同的传感器,每年大约有十亿条记录。因此,数据肯定适合一台服务器,而不适合RAM。实际上,他们将仅从一台服务器开始存储数据,也许在第二个Spark实例(具有多处理器和大量内存)的服务器上开始,并且希望如果看到回报,他们将投资更多的硬件。他们将开始每天进行小的查询,并且希望它们很快。但是后来他们将要在数年内进行查询,并且决不能爆炸。
想法/疑问:预处理是否在单个线程中完成?我应该自己动手并行化,还是让Spark处理它?我是否应该在很多天跨度的查询中打破跨年查询(但那为什么我要完全使用Spark)?我是否可以解决熊猫中的小查询和Spark中的大查询(我可以预先设置阈值)吗?
我还可以应用其他哪些改进?
答案 0 :(得分:2)
在“火花”以外的其他工具中,“小”数据变得更快的情况并不少见。 Spark的并行功能具有相当大的开销(当然,与旧的map-reduce范例相比,这些开销很小)。
闪耀之处在于它可以通过添加服务器来线性缩放“大”数据。在这一点上,开销变得值得了,因为它将自动在所有可用的执行程序之间分解工作。
我相信,即使只是为了简单起见,让spark处理并行化也是理想的。是否在另一个框架中实现“小”查询完全取决于您是否要维护两个代码路径,以及客户是否对它们的速度感到满意。