我们部署一个(基于AJAX的)即时通讯工具,由Comet服务器提供服务。我们要求将已发送的消息存储在数据库中以进行长期存档,以满足法律保留要求。
哪种数据库引擎在此一次写入,从不读取(极少数例外)要求中提供最佳性能?
我们需要至少5000插入/秒。我既不假设MySQL也不假设PostgreSQL 可以满足这些要求。
有关更高性能解决方案的任何建议吗? HamsterDB,SQLite,MongoDB ......?
答案 0 :(得分:35)
请忽略上面的Benchmark,我们内部有一个错误。
我们有以下列插入1M记录:id(int),status(int),message(140 char,random)。 所有测试都是在带有500 GB Sata Disk的台式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 Ram,加载了cpu的3个核心,MySQL很满意14 MB并且只加载了1个核心。
Edorian提出了他的建议正确的方法,我将做更多的Benchmark,我相信我们可以达到2x四核服务器50K插件/秒。
我认为MySQL将是正确的选择。
答案 1 :(得分:20)
如果您永远不会查询数据,那么我根本不会将它存储到数据库中,您永远不会超过将它们写入平面文件的性能。
您可能需要考虑的是缩放问题,当将数据写入平面文件时会发生什么变化,您是否会投资更快的磁盘或其他内容。
要考虑的另一件事是如何扩展服务,以便您可以添加更多服务器,而无需协调每个服务器的日志并手动合并它们。
编辑:您写道,您希望将其置于数据库中,然后我还会考虑安全问题,因为您的服务遭到入侵后会发生什么,您希望攻击者能够改变吗?已经说过的历史了吗?
将它临时存储到文件中可能更为明智,然后将其转储到异地,如果您的互联网前端被黑客攻击,则无法访问该位置。
答案 2 :(得分:10)
如果您不需要进行查询,那么数据库就不是您所需要的。使用日志文件。
答案 3 :(得分:5)
它仅出于法律原因而存储。
详细要求怎么样?你提到NoSQL解决方案,但是这些不能保证数据真的存储在磁盘上。在PostgreSQL中,一切都是事务安全的,因此您100%确定数据在磁盘上并且可用。 (只是不要转向fsync)
速度与您的硬件,配置和应用程序有很大关系。 PostgreSQL每秒可以在良好的硬件上插入数千条记录并使用正确的配置,使用相同的硬件但在应用程序中使用简单的愚蠢配置和/或错误的方法可能会非常慢。单个INSERT很慢,单个事务中的许多INSERT都快得多,准备好的语句甚至更快,COPY在你需要速度时也很神奇。这取决于你。
答案 4 :(得分:4)
如果表没有索引,Firebird可以轻松处理5000个插入/秒。
答案 5 :(得分:4)
我不知道你为什么要排除MySQL。它可以处理每秒高插入量。如果您确实需要高插入,请使用带有复制的BLACK HOLE表类型。它本质上是写入一个最终被复制到常规数据库表的日志文件。您甚至可以在不影响插入速度的情况下查询从站。
答案 6 :(得分:2)
根据您的系统设置,MySql每秒可以轻松处理超过50,000次插入。
对于我正在进行的当前系统的测试,我们每秒可以进行超过20万次插入。在10个表上有100个并发连接(只是一些值)。
并不是说这是最好的选择,因为像沙发这样的其他系统可以使复制/备份/扩展更容易,但仅仅因为它无法处理如此少量的数据而忽略了mysql。
我想有更好的解决方案(阅读:更便宜,更易于管理)解决方案。
答案 7 :(得分:1)
使用事件存储(https://eventstore.org),您可以阅读(https://eventstore.org/docs/getting-started/which-api-sdk/index.html),即使用TCP客户端时,每秒可以实现15000-20000次写入。如果您需要对数据做任何事情,则可以使用投影或基于流进行转换以填充所需的任何其他数据存储。 您甚至可以创建集群。
答案 8 :(得分:0)
如果钱没有任何作用,你可以使用TimesTen。 http://www.oracle.com/timesten/index.html
完整的内存数据库,速度惊人。
答案 9 :(得分:0)
我会使用日志文件,但如果你必须使用数据库,我强烈推荐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是开源的,即使是商业项目也完全免费。
答案 10 :(得分:0)
我相信答案还取决于硬盘类型(SSD与否)以及您插入的数据大小。我在双核Ubuntu机器上将单个字段数据插入到MongoDB中,并且每秒钟超过100条记录。我向一个字段引入了一些非常大的数据,它下降到大约9ps,CPU运行在大约175%!盒子没有固态硬盘,所以我想知道我是否已经做得更好。
我也运行了MySQL,只需要50秒就可以在一个有20m记录的表上插入50条记录(大约有4个不错的索引),所以对MySQL来说,它取决于你有多少索引。 / p>