使用Python进行基于时间的数据分析

7

我有一个项目,其中物理传感器向服务器发送数据。数据是不规律发送的 - 在传感器被激活后发送,但不会少于20分钟。在服务器上,数据存储在Posgresql数据库中。

数据结构如下:

Sensor Table
    sensor name - string
    sensor serial no - string
    sensor type - foreign key to types table

Sensor Data Table
    sensor - foreign key
    timestamp
    value 1 - boolean
    value 2 - boolean
    value 3 - integer
    value 4 - float
    ...

预计每秒请求数不超过100。数据库中的数据记录应该持久保存90天或更长时间(而不仅仅是我之前想到的2周)。因此,记录的总数不会超过120 960 000/14天。这是一种“安全”的估计。实际上可能小10倍(10个请求/秒,12,960,000条记录)。
我需要对数据进行一些分析,例如:
1.当新记录出现并且它的“值2”为真时,执行某些操作
2.当传感器X的“值2”为真的时间超过某个声明的时间(50分钟,1小时或更多其他时间)时,执行某些操作
3.当传感器X在24小时内的“值2”总真实时间超过某个声明的时间时,执行某些操作
4.当传感器X的“值3”为真的时间超过某个声明的时间,并且在此期间没有其他类型为XYZ的传感器处于活动状态时,执行某些操作…
上述“声明的时间”大于或等于1秒。
整个服务器部分是用Django(和django-rest-framework来收集数据)开发的。
问题是如何有效地进行这样的数据分析,假设应该实时或接近实时(1秒)监视数据和时间段以触发所需的操作。
我的想法:
1.运行一个处理进程,每秒查询符合标准的记录的数据库,并调用特定的操作(这可能需要更多的时间)
2.运行一些单独的进程(eventlet?)每种分析类型一个,然后每1秒查询数据库并触发特定的操作。
3.为每个传感器运行一个进程,其不断向其订阅者报告:我在“值2”上持续x秒等。在该传感器的新数据到达后,重置进程。这里可以使用一些发布-订阅解决方案,例如zeromq?
4.使用其他/更快的解决方案
MongoDB-问题可能是mongodb的文件在删除数据(2周)后没有压缩。
Hadoop-对于这类问题来说太大太复杂了吗?
Pandas和某些HDF5存储-问题可能是它是否能够执行我上面描述的分析,还可能进行写入文件。但是..也可以与mongo一起使用。
提示?
更新。
目前,对我而言,看起来简单有效的解决方案是:
  1. 当数据到达传感器A时,运行所有测试,并将测试结果以以下方式存储在某个“tests”表格(或redis)中:
    • 今天下午1:15执行操作“传感器打开时间长”
    • 今天下午1:30执行操作“24小时内传感器打开时间长”...
  2. 持续扫描上述“tests”表格,并在今天下午1:15时运行所需的操作,等等。
  3. 当传感器A有新信号到达时,再次运行所有测试,并重置“tests”表格中的数据。

这需要我每次请求特定传感器时都要触发测试,但另一方面,我只需每秒钟扫描“tests”表格。

更新2:

我发现PyTables (http://www.pytables.org/moin/PyTables) 很适合作为我的数据存储用例。

4个回答

2
我的第一次尝试是在“传感器数据表”上创建一个多列索引,例如:
sensor->timestamp->value1 //Index 1
sensor->timestamp->value2 //Index 2
sensor->timestamp->value3 //Index 3
sensor->timestamp->value4 //Index 4

看一下你的SQL查询是否足够快。你可以通过事件或定时任务进行查询。从性能角度来看,只要这个查询足够快,使用哪种方法都无所谓,因为它很可能是你的瓶颈。
另一个建议是尝试使用MySQL内存表,或者相应的PostgreSQL内存表(PostgreSQL中的内存表)。
还有一个建议是尝试使用Redis。你可以将“传感器数据”存储为一组排序集合;每个传感器ID和值字段对应一个排序集合,并按时间戳排序数据。
 ZADD sensor_id:value1 timestamp value
 ZADD sensor_id:value2 timestamp value

Redis需要一些应用逻辑来累积数据,但如果所有数据都适合RAM,它将非常快。
关于MongoDB。只要可查询的数据+索引可以适合RAM并且没有太多写锁,你就可以获得良好的性能。尽管运行两个提供重叠功能的重量级数据库是一项管理(和编码)负担。考虑到这一点,压缩实际上不是一个问题。您可以在传感器数据上创建TTL索引,mongo将在后台线程中删除旧数据。文件大小一段时间后将保持不变。
希望这有所帮助。

谢谢,这些解决方案非常有价值。我会先选择 SQL 看看它的速度如何。 - eXt
上一条评论回复得太快了,所以: 我会先使用 SQL 看看速度如何。 内存表会很快,但我必须持久化数据。Redis…有趣,但我不确定是否适合:
  1. 在那里存储这么多数据(必须持久化)
  2. 过滤这些数据,例如我必须计算 24 小时内的不活动总时间(我还对收集到的数据进行其他分析,但这并不经常发生)
Mongo。100 次/秒的请求足以引起写锁吗?我可能需要测试 mongo 的速度,并将其与 sql 数据库的结果进行比较。
- eXt
太好了!很高兴你欣赏它。Redis与Memcache不同,可以持久存储数据。它尽可能多地存储在RAM中,并在需要时进行页面输入/输出。鉴于此,我认为您的要求更适合SQL。关于Mongo。请求数量与锁定无关。Mongo在只读方面表现出色,在只写方面表现良好,在读写方面不太好,因为写锁会阻塞整个数据库(没有其他读取/写入操作可以发生),因此过多的写入将导致读取超时。如果您的数据+索引适合RAM,则会很愉快。正如您所说,只有尝试才能知道。 - Adil

0
你考虑过按问题进行分组并流式处理输入数据吗?
这种类型的示例方法可能是:
for event in new_events: # new events to be written from the RESTful service
    for test in tests: # known tests you need to perform
        increment/decrement <test.bucket>.<sensor>.<valueX> # update the bucket as necessary
        # e.g. seconds_since_changed.sensor1.value3 += 1
     # additionally, save each record to a standard database for long-term purposes
     # and to be able to rebuild/redo tests as necessary.

对于这种交易流的理想存储机制是那些适合低延迟写入/更新的。NoSQL解决方案非常适合这种工作(我个人曾经使用Redis进行类似类型的分析,但你并不一定要使用这个特定的解决方案)。


0

如果您的规则很简单或很少,您可以尝试使用SQL触发器来更新存储的视图,这样可以快速查询。例如,假设您想检测某个传感器已经激活了一定时间,您可以有一个包含当前激活传感器的激活时间的表。每当您存储原始事件时,触发器会更新这样的表。

对于类型3的规则,这将更加困难。除非它们很少,您可以为每个规则设置一组触发器和视图,或者允许的时间段事先已知。


0

第四个选择。关系型数据库是明显的瓶颈。安排以某种更简单的形式交付数据(目录中的文件,按传感器名称或唯一键命名)。你可以更快地处理,检查时间戳和读取-然后在分析后将数据推送到后端的关系型数据库。


我不能期望整天都有包含数据的文件。数据不断地发送到服务器。因此,我必须接收并保存它。 另外,我不能说我不需要重新分析这些数据 - 例如当创建新的监控查询时,比如:现在我想在传感器开启超过一周时得到通知。因此,我的系统必须分析最多一周之前的数据。 - eXt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接