【问题标题】:Storing large amount of data in Redis / NoSQL or Relational db?在 Redis / NoSQL 或关系数据库中存储大量数据?
【发布时间】:2019-01-17 10:56:34
【问题描述】:

我需要存储和访问金融市场烛台信息。

我需要储存的蜡烛数量开始变得惊人(巨大)。有 1000 个市场,每个市场都有很多交易对,每对都有很多时间框架,每个时间框架都是一组蜡烛,如下所示。例如,下面的数组可以是每小时价格数据或每日价格数据。

我需要在任何给定时间将此信息提供给多个用户,因此需要存储它并以某种方式使其可用。

数据看起来像这样:

[
    {
        time: 1528761600,
        openPrice: 100,
        closePrice: 20,
        highestPrice: 120,
        lowesetPrice:10 
    },
    {
        time: 1528761610,
        openPrice: 100,
        closePrice: 20,
        highestPrice: 120,
        lowesetPrice:10 
    },
    {
        time: 1528761630,
        openPrice: 100,
        closePrice: 20,
        highestPrice: 120,
        lowesetPrice:10 
    }
]

数据的消费者主要是基于 JavaScript 的复杂图表应用程序,但其他消费者将是节点代码,也可能是其他后端代码。

我目前最好的想法是将烛台保存在 Redis 中,尽管我也考虑过一个 noSQL 数据库。我在这两个方面都不是很有经验,所以我不能 100% 确定 Redis 是正确的选择。虽然它似乎是性能最高的选项,但可能更难使用,因为我必须学习很多东西,而且我不相信 Redis 使用的保存和检索方法会使这变得非常容易,因为,我需要不断地为每个数组添加蜡烛。

我目前在想这样的事情:

从烛台 API 进行初始提取,然后:

  1. 创建一个带有合适标签的 Redis 哈希,并将整个蜡烛数组插入到哈希中,以便通过 Javascript 等对其进行解析

这种方法的缺点:

每次创建新蜡烛时,我都必须解析 json,添加任何新的蜡烛棒,然后将其字符串化并保存。

这种方法的优点:

我可以使用 Javascript 来管理数组并确保它已排序等

  1. 创建一个 Redis 时间戳列表,这样我就可以将新蜡烛添加到列表中并相信它的顺序正确。然后我可以做一个 Redis SCAN 吗?返回特定日期之间的时间戳,然后使用时间戳从 Redis 哈希中提取数据。在检索所有这些之后,然后构建一个类似于上面的 json 对象以传递给 Javascript。

我不得不说,这两种方法都让我将数据放入关系数据库中感觉更痛苦。我想非 SQL 数据库也可能更容易,但我对它们没有经验,所以我不能肯定。

如您所知,我有点迷茫,失去了我在这里的经验,并且希望任何人都可以给我任何建议。

谢谢:)

【问题讨论】:

  • Redis 可以准确地称为 NoSQL 数据库,fwiw

标签: redis nosql


【解决方案1】:

您的数据非常规则 - 每个烛台基本上都有 1 个 64 位长的时间戳和 4 个 32 位的价格数字。这使得它非常适合bitfield

存储数据

这是我将如何存储它 -

  1. stock-symbol:daily_prices = 具有 30 * 5 条记录的位域,假设您要存储过去 30 天的数据
  2. stock-symbol:hourly_prices = 24 * 5 条记录的位域

这样,您的内存为 (30*5 + 24*5) * 16 字节 = 每个符号 4320 字节 + 每个键的固定开销。

您不需要存储时间戳(见下文)。另外,我假设 4 个字节来存储价格。您可以通过消除小数将其存储为整数。

写入数据

要插入每小时价格,请查找当前时间(例如 07:00)。如果将位域视为 4 字节整数数组,则必须跳过 7 * 4 = 28 个整数。然后在位置 28、29、30、31(基于 0 的索引)处插入价格。

因此,要在 07:00 存储 AAPL 的价格,您需要运行命令

bitfield AAPL:hourly_prices set i32 28 <open price> i32 29 <close price> i32 30 <highest price> i32 31 <lowest price>

您也可以对每日价格执行类似的操作。

读取数据

如果您正在构建图表库,您很可能希望返回给定时间范围内多个交易品种的数据。假设您要提取过去 7 天的每日价格,您的逻辑将是 -

  1. 对于每个符号:
    1. 获取数组中的开始和结束范围
    2. 调用Get Range 命令。

如果你在管道中运行它,它会非常快。

其他提示

通常,您会按符号的某些属性进行过滤。例如,“显示过去 5 天排名前 10 位的科技公司的图表”。

符号本身就是关系数据。我建议将其存储在关系数据库中。只需从关系数据库中获取符号名称作为列表,然后从 redis 获取股票价格。

【讨论】:

    【解决方案2】:

    Redis 有它的局限性,就像任何东西一样,但它们非常高,如果你聪明,你可以从 redis 中获得惊人的性能。如果您超出了一个实例,您可以开始考虑集群,它应该相对线性地扩展到预算比性能更受关注的水平。

    如果没有真正了解您所描述的数据及其关系,听起来您正在寻找的是一个排序集,可能是按日期排序的。您可以ZSCAN 一个排序集按顺序移动,或者您也可以这样做lots of other great things against one。您的数据可能需要一些不同的东西——例如,一些数据的散列和散列本身的索引条目,甚至在几个不同的索引中。一个简单的 redis 列表也可以为您完成这项工作,因为它本质上是按插入顺序排序的(当然,这可能适用于您的情况,也可能不适用;这可能取决于您的输入是否本质上是按时间排序的)。

    归根结底,redis 的性能通常取决于数据在 redis 中存储的“好坏”程度——换句话说,本地 redis 功能映射到您的问题域的好坏程度。它非常易于使用和编程。我强烈建议你调查一下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 2011-05-08
      • 1970-01-01
      • 2018-06-08
      相关资源
      最近更新 更多