如何存储大量的_structured_数据?


9

该应用程序将连续(大约每秒)收集用户的位置并将其存储。

该数据是结构化的。在关系数据库中,它将存储为: | user | timestamp | latitude | longitude |

但是,数据太多。每个用户每天将有60×60×24 = 86,400条记录。即使有1000个用户,这也意味着每天86,400,000条记录。

每天不仅有86,400,000条记录。因为这些记录将被处理,并且它们的处理后的版本也将被存储。因此,将该数字乘以大约2。

我打算如何使用数据

本质上,我计划对位置数据进行更粗粒度的处理,以便于使用。那是:

  1. 对接收到的带有时间戳的数据进行排序。
  2. 依次浏览此列表,确定位置是否发生了重大变化(通过查看经度和纬度发生了多少变化)
  3. 将不重要的位置更改表示为输出中的单个条目(因此,输出是位置数据的粗粒度版本)。
  4. 通过要求更大的纬度和经度更改以进行重大更改,对输出进行迭代处理。因此,从先前输出产生的输出将更加粗糙。
  5. 根据需要重复整个过程。
  6. 汇总一系列分辨率并将其发送给用户。另外,存储数据的所有分辨率以供以后使用。

我应该用什么来存储这些数据?我应该使用关系数据库还是NoSQL解决方案?设计此应用程序时,我还应考虑哪些其他事项?


3
这样的每秒2000条记录可能不会给最新的SQL引擎带来麻烦。一个简单的容量测试将是使控制台程序向要批量加载的文件随机写入一些程序。
卡雷斯(Caleth)'17

1
@Caleth但是它具有可伸缩性吗?当用户群增长100倍时呢?
Utku

3
测量您的硬件当前可以处理的内容。瓶颈可能是CPU“处理”值或原始磁盘速度。您打算如何处理所有这些数据?这将决定您选择哪种存储技术
Caleth

3
Caleth是绝对正确的。数百万条记录不会使现代数据库系统崩溃。NoSQL存储非常擅长快速写入大量数据,但是最终您想要做的事情涉及再次读取内容。您需要多少阅读量通常会决定您应该使用哪种商店。
吉莲

3
为了给出一个好的答案,我们需要知道您打算如何使用这些数据。如果您想进行临时查询,则数据库可能是一个不错的选择,而基于文件的解决方案可能更适合于整个数据集的分析。投票关闭。
kdgregory

Answers:


9

一些用于存储此数据的替代方法:

  1. 消息队列(可能是分布式的),例如Apache Kafka

这将针对写入和读取数据流进行优化。它是以易于处理的格式收集数据流的理想选择,但通常无法查询它,除非通过整体读取该流。因此,这可能是出于存档目的,或者是进入处理层的中间步骤。

  1. 关系数据库

您可以将其写入数据库,并且当卷超过数据库的处理能力时,可以分片数据库(=有多个数据子集位于不同的数据库服务器上)。好处:您可以使用关系数据库,而不必学习任何新知识。缺点:所有与数据库有关的代码都必须知道哪个数据驻留在哪个分片上,聚合查询必须在应用程序软件中完成。

  1. 分布式NoSQL数据库,例如Cassandra。

您将数据写入分布式NoSQL数据库,它将自动为您分片数据。Cassandra允许您在整个集群中进行查询,需要较少的应用程序代码来取回数据。好处:更自然地适合于大量数据,缺点:需要特定的专业知识,并对这些系统如何工作的机制有深入的了解,以实现良好的性能并根据您的需求查询数据。NoSQL并不是一个神奇的性能修复,它是一组折衷,必须理解这些折衷。

  1. Hadoop /文件

数据被附加到文件,这些文件由Hadoop平台自动分布在服务器之间,使用M / R或Apache Spark等工具在这些服务器上进行处理,最后使用Hive或Impala等Hadoop SQL引擎进行查询(作为文件)。

选择哪一个?

这些选择之间的权衡比较复杂,它们在很大程度上取决于您的写入和读取模式,因此,唯一可以决定这些权衡的人就是您。如果您缺乏时间来深入了解这些替代方法,则只需使用关系数据库并逐步了解分片解决方案即可。很可能是YAGNI


我提供了有关如何计划使用数据的更多详细信息。您想添加任何信息吗?
Utku

我仍然不太清楚“分辨率”的含义。您要汇总到地理级别(城市,州,...)还是汇总到某个坐标系(如geohash)上?还是因为要基于移动阈值构建通知而对增量数量感兴趣?简而言之:这都是为了什么?
Joeri Sebrechts

它用于跟踪用户。用户互相跟踪,然后我绘制出他们跟踪的用户最近5个小时在设备上的位置。本质上,越细越好。但是,移动设备的内存量有限,因此您不能在不降低分辨率的情况下发送数据。也就是说,假设用户A正在跟踪用户B,C和D。如果我简单地将从B,C和D接收到的任何位置数据转发到A,而无需在服务器端进行任何处理,则用户A的设备内存将很快填满。因此,我需要做一些处理。
Utku

如果要构建您要描述的内容,则将其构建为一系列通过Spark Streaming连接的kafka日志,其中位置在spark流中的各个窗口之间集成在一起,最终输出的kafka log作为pull和将Web API推送给客户端。但是...这是很多非常特殊的技术,根据您的背景和可用时间,这些选择可能对您来说是错误的。
Joeri Sebrechts

谢谢。我会牢记这一点,但是按照YAGNI原则,我现在打算使用关系数据库。当需要时,我将切换到更适合该应用程序的东西。如果愿意,请随时将任何信息编辑到您的答案中。
Utku

6

深入了解您的需求。有一种方法可以产生每秒跟踪位置的错觉。

如果您有一个知道当前GPS位置并将其写入数据库的应用,那么如果位置不变,为什么还要继续写入呢? 即使您需要数据,如果用户已经睡了7个小时,您也可以通过编程的方式在丢失的时隙中填写重复的位置,以进行计算或映射或执行其他任何操作。

如果您确实每秒跟踪一次位置,那么是否需要永远存储这些数据? 您可以将记录归档到另一个数据库,以防止当前表变得太大。或者,您甚至可以保留位置变化的记录。这在数据仓库中很常见。


2

您的数据是一组时间序列。您已经给出了随时间变化的数字集(每个用户两个)。通常,您不是在寻找任何类型的关系存储,而是在寻找RRD存储。这些存储主要集中在通过缓冲来减少大量小写操作的I / O工作。

关系存储对于这个时间序列量是一个混乱。但是,请注意,就可编程利用而言,RRD的开发并没有像SQL那样得到很好的支持。您可能正在寻找认真的集成工作,但是鉴于您的要求,这几乎是不可避免的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.