【问题标题】:MongoDB Vs Cassandra Vs PostgreSQL Vs MySQL [closed]MongoDB Vs Cassandra Vs PostgreSQL Vs MySQL [关闭]
【发布时间】:2021-08-13 18:37:55
【问题描述】:

一般

我必须每天存储 1 亿条以这种方式组成的记录: id name time。唯一键是id,但我必须在nametime 上进行搜索。

我必须选择 MongoDb 或 Cassandra 等数据库,但我不知道它们的性能,以便将这些日志写入数据库并检索它们。

我的需要是写入操作非常非常快,也比读取/搜索要快。我希望使用索引来加快搜索速度,我可以使用一些集群来拆分数据,例如 mongoDB 中的分片。

我的硬件性能不太好,我使用的是 Docker,对于每个容器,我可以使用 SSD 技术拥有最大 8 GB 的内存和 500 GB 的硬盘。操作系统是Ubuntu。容器不能留在同一台机器上,它们与 LAN 通信。

我想知道哪个数据库最快以便写入我的日志。

数据库的架构

数据库由两个表组成:

  • 主表(名为表A)形成:
    • id 是一个最多 30 个字符的字符串,它是主键
    • name 是一个最多 60 个字符(从 30 到 60 个字符)的字符串,它有一个索引来执行搜索,它是唯一键。
    • time 是一个最多 60 个字符(从 30 到 60 个字符)的字符串,它有一个索引来执行搜索,它是唯一键。

输入是非常长的文件(1000 万条记录),并且每天都会给出这个输入文件。

一年后,此表将是 365 x 100^6 元组,两年后 到目前为止是 2 x 365 x 100^6。

  • 第二个表(名为表 B)形成:
    • field 是一个最多 60 个字符的字符串(从 30 到 60 个字符)

此表每两个或更多小时更新一次(添加或删除元组)。

查询

主要要求是:

select *
from A, B
where field = time OR field = name

并且每次更新表 B 或如果不可能每天都执行此请求。但搜索时长不能超过 1 小时。

对我来说最重要的一点是数据库在必须导入表 A 上的文件时非常非常快。我也可以接受在搜索运行时停止表 A 的插入和表 B 的更新.但是当我从文件中将新记录放在表 A 上时,我不能慢。插入新记录(或导入文件)时,我必须尽可能快。

其他信息

  • 我希望有一天也插入像 RAID 1 这样的复制数据,以确保不会丢失任何数据。

  • 在 SSD 上有新闻,以避免任何数据丢失。

  • 每秒插入的行记录数必须尽可能快。这是我的问题中最重要的关键问题。

每秒插入 120 行。他们一次到达一排吗?还是一次一整天的价值?还是别的什么?

记录来自一些文件,每个文件都有很多记录。记录数可以是 1,直到 inf。文件有时会到达,没有特定的时间段。但是我有可能在插入新文件之前等待几个小时才能处理它(也许将格式从 CSV 更改为 JSON 或对格式进行一些检查),或者如果数据库正在导入以前的文件。

它是一个“日志”文件吗?还是 CSV?或者是其他东西?请提供样本。

输入文件可以是 CSV、JSON 文件或其他文件。我有可能在导入之前修改它。文件的示例可以是:

id,              name,               time
9999999999999   AAAAAAAAAAAAAAAA     18Agust201819h90m90s
1233423434333   zzzzzzzzzzzzzzzzz    Monday18Agust201819h90m91s
000244200002    BAJDHFURI8DNCJUED    sds3444324sssdds34343ddff
0000000000003   ZXEWSFFSJFajf8392    Monday18Agust201819h90m94s
1123884000334   1AAAAAAAAAAAAAAAA    Monday18Agust101819h90m95s
3334442000005   1zz2zz244z34sASd3    fff3320000001010101011111s
  • 文件的大小可以是10Gbyte或更多或更少,没有具体的规定。但我可能要等待几个小时才能合并一些文件并导入一个大文件。
  • id是自己的id
  • name 是部门/应用程序/用户提供给数据库的日志的特殊“哈希”。

以 36-60 个字符的形式提供什么样的“时间”?请提供样本。

time 实际上是一个通用字符串,因为每个应用程序/部门/办公室都有自己的格式。但在这种情况下,也可以将其视为特殊的“哈希”。

每天 10M 行 --> 每年 500GB。那么磁盘会在一年内填满吗?需要更改哪些部分来处理您期望接收的数据?

所有这些日志都无法修剪。这个数据库是企业的一个数据湖,用来收集所有的日志。

您会在 90 天后清除数据吗? (这将解决我之前的观点,但需要一个特殊的模式来提高效率。)

所有这些行都不能被修剪。

where field = time OR field = name 不实用。请用文字描述意图是什么。我们需要以其他方式表达查询。

有时我们会收到要在TABLE A 中搜索的文件,但我们不知道该字符串是否链接到字段NAMETIME。因为这个文件是由一个非常古老的应用程序创建的。

100^6 = 100*100*100*100*100*100 = 1 万亿。我不认为你是那个意思。

是的,我认为这是一个乐观的数字 :( 现在我的办公室每小时以多种格式(JSON、CSV 等)收集 5GB 的日志。我们正处于开发阶段。最终的情况是所有的日志都存储在这个数据库中。我认为最大选择也可能是每小时 50Gbyte。

过去所有的日志都收集在普通硬盘中。 10 年来,我的部门收集了大约 100TByte 的数据,但仅限于旧部门和办公室。现在有了新部门,所以我想我们的日志会比以前更多。

该项目的目标是在一个数据库中收集社会的所有日志,例如当用户 Alpha 打开计算机时,或者用户登录查看电子邮件等等。或者,如果用户希望创建一个特殊的日志以获得证明。但这只是该数据库应用的一个例子。另一种是db是其他db的共享db。

例如:用户 Bravo 向 Tango 发送了一封电子邮件。 Tango 声称 Bravo 没有这样做。 Bravo 可以使用他的部门日志数据库检索日志。现在 Bravo 询问我们是否有一个特定的元组,如果该元组存在于自己的数据库中,Bravo 有一个已发送邮件的证明。

【问题讨论】:

  • 请提供架构和主要 SQL 查询。有了这些,我们可以更好地了解您的应用程序并判断各种解决方案的效率。比记录数更重要的是每秒插入的行数,以及它们是必须单独插入还是可以以某种方式批量插入。
  • 如果输入是日志文件,我们允许在被记录的项目和需要在搜索中找到它之间存在多少延迟。如果时间限制是一小时而不是一秒,则可以实现更多的性能和扩展。
  • 我已经添加了@RickJames 的信息我希望我已经添加了你问我的所有信息。提前感谢您的帮助。
  • 由于社区已经关闭了这个问题,@RickJames 请看看这个问题:stackoverflow.com/questions/68787113/…

标签: mysql mongodb cassandra database-performance


【解决方案1】:

(还没有答案,但评论太长了。)

  • 每秒插入 120 行。他们一次到达一排吗?还是一次一整天的价值?还是别的什么?
  • 它是一个“日志”文件吗?还是 CSV?或者是其他东西?请提供样本。
  • 以 36-60 个字符的形式提供什么样的“时间”?请提供样本。
  • 每天 10M 行 --> 每年 500GB。那么磁盘会在一年内填满吗?需要更改哪些部分来处理您期望接收的数据?
  • 您会在 90 天后清除数据吗? (这将解决我之前的观点,但需要一个特殊的模式来提高效率。)
  • where field = time OR field = name 不实用。请用文字描述意图是什么。我们需要以其他方式表达查询。
  • 100^6 = 100*100*100*100*100*100 = 1 万亿。我不认为你是那个意思。

(解决大多数问题...)

  • RAID、驱动器“日志”等是数据丢失风险的部分解决方案。它们在较低级别进行处理; SQL 或 MySQL 配置中的任何内容都与此类无关。

  • 每个 CSV 文件(行数为 1 到 INF)最好通过 LOAD DATA 加载。 可能直接将其加载到主表中更好,或者可能将其加载到临时表中,处理数据,然后将其复制到主表中桌子。 (我没有足够的细节来预测哪个更好。)

  • 直接加载到主表中的巨大 CSV 文件可能会阻塞某些操作。在这种情况下,通过临时表可能很重要。然后,可以将行以块的形式复制到主表中,从而最大限度地减少影响。有关分块的更多信息:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks(这涉及到 DELETE,但可以很容易地适应您的应用程序所需的 SELECT。)

  • 您说time 本身就是唯一的?不能在同一秒内发生两个事件?

  • nametime 是唯一的吗?在INDEXUNIQUE 之间进行选择有利有弊。 UNIQUE 会减慢 INSERT 因为在完成插入之前需要检查唯一性。我(还)没有看到UNIQUEINDEX _为您的应用程序带来的任何好处。

  • 不正常的“时间”格式——除了=之外,不要计划进行范围或比较。正如您所说,将其视为“哈希”。

  • 没有修剪?数据在此表中存在多年?那么,如果有 500GB/年的增长率,你会怎么处理磁盘空间呢?

  • 你会有

      INDEX(name),   -- (or UNIQUE(name))
      INDEX(time)    -- (or UNIQUE(time))
    
  • 为了提高性能,您建议的查询应更改为此。 (? 将成为相同的引用“哈希”。)

      SELECT * FROM A  WHERE name = ?
      UNION ALL
      SELECT * FROM A  WHERE `time` = ?
    
  • A 可能需要基于它来自的日志文件的某种时间戳。我希望一些查询会得到数千个结果,而用户可能只想要“最近”的结果。 [好的,这与您的声明相冲突,即 nametime 是唯一的,在这种情况下,上述 Select 只能返回 1 或 2 行。]

  • 即使A 变为数 TB,上述 Select(具有上述索引)也将始终以毫秒为单位运行(假设最多 2 个结果行)。 RAM 大小基本上对速度没有影响。磁盘必须足够大以容纳整个表。此外,由于 HDD 仍然比 SSD 便宜,因此对于巨大的桌子使用 HDD 可能是值得的。 (无论配置如何,查询可能仍需要不到 1.0 秒的时间。)

  • 如果您希望表大于 32TB,我们需要做一些额外的事情。这是一个硬性限制,但有办法绕过它。如果这将是一个问题,请开始一个仅关注表大小(加上表模式和主要选择)的新问题。行数没有限制,只有字节大小。

  • 由于每小时(或任何时候)都有新的“日志”到达,因此该表本质上不是“最新的”。也就是说,Select 不会找到过去一小时左右发生的记录。因此,我不担心 CSV 的加载是否需要运行一个小时。我上面提到的“分块”增加了一点时间,同时避免了阻塞。因此,我强烈认为分块是基于数据流和其他要求的“正确”方式。

  • id 何时生成?它曾经“使用过”吗?是否包括它来自的日志的名称?我问是因为:它占用空间,它可能会减慢速度,你不需要“日志 ID”,也许它可以被扔掉,有比 varchar(60) 更好的东西作为 PK 等等。

【讨论】:

  • 我已经回答了你所有的问题:)
猜你喜欢
  • 2011-02-22
  • 2014-12-29
  • 2011-01-08
  • 1970-01-01
  • 2014-08-25
  • 2012-12-28
  • 2015-05-27
  • 2011-11-24
  • 2014-05-16
相关资源
最近更新 更多