【问题标题】:DB with best inserts/sec performance? [closed]具有最佳插入/秒性能的数据库? [关闭]
【发布时间】:2011-04-01 00:04:25
【问题描述】:

我们部署了一个由 Comet 服务器提供服务的(基于 AJAX 的)即时通讯工具。为了满足法律保留要求,我们需要将发送的消息存储在数据库中以供长期存档。

哪个数据库引擎在这种一次写入、从不读取(极少数例外)要求中提供最佳性能?

我们需要至少 5000 次插入/秒。我假设既不是 MySQL 也不是 PostgreSQL 可以满足这些要求。

有更高性能解决方案的建议吗? HamsterDB、SQLite、MongoDB ...?

【问题讨论】:

  • 我正在将一些应用程序重组为 mongoDB。您在列表中忘记了 CouchDB,但根据我所学到的,我也会选择 mongoDB...
  • 谢谢,这意味着我会以正确的方式使用 MongoDB,还有更多的 MongoDB 投票吗? :-)
  • 在我最近的测试中,我在四核服务器上使用 MySQL/Innodb 实现了 14K tps,并且吞吐量在 python 中是 cpu-bound,而不是 mysql。换句话说,您对 MySQL 的假设是完全错误的。我的交易是非常简单的测试和插入,有争用,想想在许多用户之间玩的“King of the Hill”。
  • 如果您需要数据一致性、密钥访问、故障转移、临时查询支持等,数据库是正确的解决方案。您的问题没有这些要求。因此,数据库是一个糟糕的选择。有一些免费或低成本的开源日志记录解决方案,但在您的性能级别上,将数据写入平面文件(可能以逗号分隔格式)是最佳选择。 JSON 或任何键值对格式将使存储需求增加大约一倍,并且由于键将重复数百万次,因此会产生大量冗余。
  • 我见过 100KB 插入/秒 gce mysql 4CPU 内存 12GB 和 200GB ssd 磁盘。

标签: mysql sqlite postgresql mongodb


【解决方案1】:

请忽略上面的 Benchmark,我们有一个 bug。

我们插入了 1M 条记录,其中包含以下列:id (int)、status (int)、message (140 char, random)。 所有测试均在具有 500 GB SATA 磁盘的台式 PC i5 上使用 C++ 驱动程序完成。

MongoDB 基准测试:

1M 记录插入无索引

time: 23s, insert/s: 43478

1M 记录插入 索引 在 Id 上

time: 50s, insert/s: 20000

接下来我们将 1M 记录添加到具有 Index 和 1M 记录的同一个表中

time: 78s, insert/s: 12820

这一切都会导致 fs 上接近 4gb 的文件。

MySQL 基准测试:

1M 记录插入无索引

time: 49s, insert/s: 20408

1M 记录插入带索引

time: 56s, insert/s: 17857

接下来我们将 1M 记录添加到具有 Index 和 1M 记录的同一个表中

time: 56s, insert/s: 17857

完全一样的性能,增长时mysql没有损失

我们看到 Mongo 在这次测试中吃了大约 384 MB 的内存并加载了 3 个 CPU 核心,而 MySQL 很满意 14 MB 并且只加载了 1 个核心。

Edorian 的提议是正确的,我会做更多的基准测试,我相信我们可以达到 2x 四核服务器 50K 插入/秒。

我认为 MySQL 将是正确的选择。

【讨论】:

  • 哇...这些数据很棒。请问,这些是批量插入还是...?
  • 这并没有告诉我这些是否是并发插入,是否使用了批量操作,或者缓存的状态是什么。一分钟的基准测试几乎毫无用处,尤其是在比较两种根本不同的数据库类型时。
  • 在将 json 发布到 php api 时,我们刚刚在 MySQL 中达到了 28,000/s 的混合插入和更新。时间包括身份验证、2 个查询以确定传入数据是应该插入还是更新,并确定要包含在语句中的列。客户数据表的传入数据是 2000 行,大约 30 列。使用 Apache Benchmark 测试,2000 个请求,100 个并发。规格:512G​​B 内存,24 核,5 SSD RAID
  • 这确实是一个旧答案。现在,NoSQL(例如 MongoDB)处于领先地位。 stackoverflow.com/questions/9447034/…
【解决方案2】:

如果您永远不会查询数据,那么我根本不会将其存储到数据库中,您将永远无法击败仅将它们写入平面文件的性能。

您可能要考虑的是扩展问题,当将数据写入平面文件速度变慢时会发生什么情况,您是否会投资于更快的磁盘或其他方面。

要考虑的另一件事是如何扩展服务,以便您可以添加更多服务器,而无需协调每个服务器的日志并手动整合它们。

编辑:您写道您希望将其保存在数据库中,然后我还会考虑在线保存数据的安全问题,当您的服务受到威胁时会发生什么,您是否希望您的攻击者能够更改曾经说过什么?

将其临时存储到文件中可能更聪明,然后将其转储到如果您的 Internet 前端被黑客入侵则无法访问的异​​地位置。

【讨论】:

  • 这更多是一个数据库系统的原因,它们中的大多数将有助于能够毫无问题地扩展它们。目前我最喜欢的是 MongoDB,但我想知道另一个数据库系统是否可以提供更多的插入/秒
  • 真的,带有日志轮换的日志文件是一门已解决的艺术。可靠的数据库扩展只能在市场的高价端解决,即便如此,我的个人经验表明它通常配置错误并且无法正常工作。平面文件总是会大大加快速度。
  • 旧,但前 5 个结果在 google.. 我正在考虑这个项目,类似的设置.. 不要忘记,数据库在一天结束时只是一个平面文件同样,只要您知道如何分散负载..找到并访问您自己的存储方法..这是一个非常可行的选择..所以我必须同意上述说法。现在的常见做法是存储 JSON 数据,这样您就可以序列化并轻松访问结构化信息。数据库有它们的位置,但如果你要做一个存档......这就是这样做的方法。
  • +1 关于使用平面文件,归根结底,它只是一个缺少索引或元数据签证的文件——通过数据库。您必须能够阅读存档或不符合法律要求。我会 RX 将 [primary key][rec_num] 写入内存映射文件,您可以 qsort() 获取索引。这个想法是有一个存档文件和它的索引写入特定时间段,例如:24 小时,然后为下一个时间段打开一对新文件。一旦 T0 被写入,qsort() T-1 的索引。使用 4xSSD ~ 2GBs 除以记录大小的 RAID 性能。平均 256 个字符允许 8,388,608 次插入/秒。
  • 一旦你写入这对 T0 文件,并且你的 T-1 索引的 qsort() 完成后,你可以对这对 T-1 文件进行 7-Zip 压缩以节省空间。这个问题几乎完全取决于 I/O 带宽。
【解决方案3】:

如果您不需要进行查询,那么数据库不是您所需要的。使用日志文件。

【讨论】:

  • 我发现我们可以使用数据库系统更轻松地处理数据,我们不会查询我们的网络应用程序的数据,但如果有一些法律调查,我们需要能够交付请求数据,意味着它将花费更少的时间来收集它。
  • 我也会选择基于文本文件的解决方案。要搜索它们,您可以使用命令行工具,例如 grep 或简单的文本处理。您为这项工作扩展 DBMS 所花费的时间将远远超过编写一些小脚本来分析日志文件,特别是如果您有一个结构良好的日志文件。如果是出于法律目的:CD/DVD 上的文本文件在 10 年内仍然可以读取(前提是磁盘本身没有损坏),您确定您的数据库转储可以吗?
  • 了解权衡。最后一个查询可能发生一次,或者根本不发生。考虑到您甚至可能不知道确切的请求,您想花多少时间优化它?拥有所有必要的数据并在警方请求到达时手动查询这些数据通常是可行且合法的。
  • @a_horse_with_no_name - 我理解你的观点,但我已经准备好维护一个 DBMS,以便我们可以在需要时轻松地从中收集数据。 @MSalters - 没错,但是根据请求查询数据库对我来说比 grep 一些日志文件更容易。
【解决方案4】:

仅出于法律原因存储。

那么详细的要求呢?您提到了 NoSQL 解决方案,但这些不能保证数据确实存储在磁盘上。在 PostgreSQL 中,一切都是事务安全的,因此您 100% 确定数据在磁盘上并且可用。 (只是不要关闭 fsync)

速度与您的硬件、配置和应用程序有很大关系。 PostgreSQL 可以在良好的硬件上每秒插入数千条记录并使用正确的配置,使用相同的硬件但在应用程序中使用简单愚蠢的配置和/或错误的方法可能会非常缓慢。单个 INSERT 很慢,单个事务中的许多 INSERT 速度要快得多,准备好的语句甚至更快,而 COPY 会在您需要速度时发挥作用。这取决于你。

【讨论】:

  • 100% 确定出于法律原因可能不需要磁盘。如果您可以证明您发生了磁盘崩溃,并且特别是因为它无法遵守特定的法律要求,那么该崩溃可以被视为天灾。
  • 谁知道呢。但是上帝的作为?在法庭上会是一个很好的陈述,但你很有可能松懈。只需检查要求,然后找到解决方案。
  • @Frank Heikens - 数据来自约会网站的 IM,无需将其存储为交易安全。当然,我希望我们不会丢失任何数据。由于我们的预算有限,我们将这个彗星服务器放在一个专门处理 IM 对话的机器上,同时我们将存储数据。我知道 PostgreSQL 的好处,但在这个实际场景中,我认为它无法与 MongoDB 的性能相提并论,除非我们花很多钱购买 48 核服务器、ssd 阵列和大量内存。
  • @Frank Heikens:除非您在受监管的行业工作,否则不会对日志保留有严格的要求。在那种情况下,法律规范可以概括为“有理智的人通常会做什么”。您甚至可以指出 SO 是合理的。
  • "在 PostgreSQL 中,一切都是事务安全的,因此您 100% 确定数据在磁盘上并且可用。" - 哈哈,不。即使使用 fsync,如果在提交和确认阶段之间出现网络问题,两阶段提交也会使您处于不确定状态。
【解决方案5】:

我不知道你为什么要排除 MySQL。它可以每秒处理高插入。如果您真的想要高插入,请使用带有复制的 BLACK HOLE 表类型。它本质上是写入一个最终被复制到常规数据库表的日志文件。您甚至可以在不影响插入速度的情况下查询从属设备。

【讨论】:

  • 我所做的基准测试表明 MySQL 确实是一个严肃的 RDBMS。
  • BLACKHOLE 存储引擎充当“黑洞”,接受数据但将其丢弃而不存储。检索总是返回空结果:
  • 这就是您在副本上使用不同表类型设置复制的原因。复制然后充当缓冲区,尽管会发生 replag。
【解决方案6】:

如果表没有索引,Firebird 可以轻松处理 5000 次插入/秒。

【讨论】:

  • 我可以使用 MongoDB 获得 5000 次插入/秒
【解决方案7】:

根据您的系统设置,MySql 每秒可以轻松处理超过 50.000 次插入。

对于我正在处理的当前系统上的测试,我们每秒插入超过 20 万次。在 10 个表上有 100 个并发连接(只是一些值)。

并不是说这是最好的选择,因为像沙发这样的其他系统可以使复制/备份/扩展更容易,但仅仅因为 mysql 无法处理如此少量的数据而忽略了它。

p>

我想有更好的解决方案(阅读:更便宜、更易于管理)的解决方案。

【讨论】:

  • 您能告诉我您当前系统的硬件规格吗?
  • 我不能告诉你确切的规格(制造商等),但总的来说,它是一台 8 核、16gb ram 机器,带有运行 ~8-12 600gb 驱动器和 raid 10 的附加存储
  • 我知道这是旧的,但如果你还在……这些是批量插入吗?
  • 单插入查询
【解决方案8】:

使用事件存储(https://eventstore.org),你可以看到(https://eventstore.org/docs/getting-started/which-api-sdk/index.html)使用 TCP 客户端可以达到每秒 15000-20000 次写入。如果您需要对数据做任何事情,您可以使用投影或基于流进行转换来填充您希望的任何其他数据存储。 您甚至可以创建集群。

【讨论】:

    【解决方案9】:

    如果金钱不起作用,您可以使用 TimesTen。 http://www.oracle.com/timesten/index.html

    一个完整的内存数据库,速度惊人。

    【讨论】:

    • 我忘了说我们的预算很低 :-)
    • 嗯,如果你想要一个内存解决方案,那就省钱吧。使用类似 mysql 但指定表使用 MEMORY 存储引擎,然后设置从服务器将内存表复制到未索引的 myisam 表。问题解决了,节省了 $$。
    • 上次我尝试做一些类似的事情时,我遇到了内存表的记录限制问题,但最大的问题是当与多线程一起使用时,该表的锁定/解锁性能不足。
    【解决方案10】:

    我会为此使用日志文件,但如果您必须使用数据库,我强烈推荐Firebird。我刚刚测试了速度,它在相当普通的硬件(3 年前的台式计算机)上每秒插入大约 10k 条记录。该表有一个复合索引,所以我想如果没有它它会更快:

    milanb@kiklop:~$ fbexport -i -d test -f test.fbx -v table1 -p **
    Connecting to: 'LOCALHOST'...Connected.
    Creating and starting transaction...Done.
    Create statement...Done.
    Doing verbatim import of table: TABLE1
    Importing data...
    SQL: INSERT INTO TABLE1 (AKCIJA,DATUM,KORISNIK,PK,TABELA)  VALUES (?,?,?,?,?)
    Prepare statement...Done.
    Checkpoint at: 1000 lines.
    Checkpoint at: 2000 lines.
    Checkpoint at: 3000 lines.
    ...etc.
    Checkpoint at: 20000 lines.
    Checkpoint at: 21000 lines.
    Checkpoint at: 22000 lines.
    
    Start   : Thu Aug 19 10:43:12 2010
    End     : Thu Aug 19 10:43:14 2010
    Elapsed : 2 seconds.
    22264 rows imported from test.fbx.
    

    Firebird 是开源的,即使对于商业项目也是完全免费的。

    【讨论】:

    • 我并没有真正了解 RDBMS 系统,但上一次大约 4 年前,当我接触 Firebird 时,它是可用于插入的最慢的 RDBMS。如果我没记错的话,MongoDB 的 Inserts 速度比 firebird 快 5 倍左右。
    • Firebird 是一个不错的 DBMS,但是如果您选择 DBMS,我会随时选择 PostgreSQL 而不是 Firebird。 PostgreSQL 的社区比 Firebird 的更活跃,并且有可规划的发布周期。 Firebird 最大的缺点是非结构化的手册。如果你需要找到一个特定的特性/功能,你需要首先阅读 Interbase 手册,然后阅读每个(!)从那时起的发行说明。当前版本没有完整统一的手册,很烦人
    【解决方案11】:

    我相信答案也取决于硬盘类型(SSD 与否)以及您插入的数据大小。我在双核 Ubuntu 机器上将单个字段数据插入 MongoDB,每秒达到 100 多条记录。我在一个字段中引入了一些相当大的数据,它下降到大约 9ps,CPU 运行在大约 175%!盒子没有 SSD,所以我想知道我是否会变得更好。

    我还运行了 MySQL,仅在一个有 20m 条记录的表上插入 50 条记录就需要 50 秒(也有大约 4 个不错的索引),所以对于 MySQL,这将取决于你有多少索引。

    【讨论】:

      猜你喜欢
      • 2015-11-27
      • 2011-02-17
      • 2010-09-08
      • 2021-10-23
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 2019-03-30
      • 2023-03-24
      相关资源
      最近更新 更多