选择/配置数据库以实现高吞吐量,可靠,一致的写入吞吐量,从而牺牲延迟

时间:2012-10-11 05:30:48

标签: mongodb postgresql couchdb throughput database

我正在开发具有以下特征的实时应用程序:

  • 数百个客户端将同时插入行/文档,每隔几秒插入一行。
  • 大部分仅追加;几乎所有插入的行/文档都不会更改。
  • 客户端只应在数据已刷新到磁盘时才能看到成功,此后应保持读写一致性。
  • 客户愿意等待的命令进行确认 - 足够长时间来进行多次磁盘搜索和写入。
  • 有太多数据无法容纳在RAM中(排除Redis等选项)。但很久以前就很少访问过很久以前的行,因此不能将它们放在内存中是可以接受的。
  • 理想情况下,这些写入不应阻止读取
  • 键值存储很好,但至少需要一个可靠的自动递增索引。

换句话说(和tl; dr),客户端可以容忍延迟,但是它们需要大量可靠的写入吞吐量 - 比“一次写入是一次磁盘操作”更多的吞吐量。

我正在设想一个可以实现这样的数据库:接受一个(理论上受文件描述符数量限制)TCP连接数,缓冲那些写入内存,尽可能多地将它们批量记录到磁盘(以及对自动递增索引的更新),并且仅在关联的磁盘写入操作完成时才响应这些TCP连接。或者它可以像懒惰写入数据库那样简单地发布消息,它已经完成了磁盘写入(客户端等待惰性响应,然后等待写入消息报告成功)。

我认为具有如此高的延迟容忍度,这并不是要求太多。而且我认为其他人遇到过这个问题,例如金融公司不能丢失数据,但可以延迟对任何一个客户的响应。

像Postgres,CouchDB / Couchbase或MongoDB这样经过实战考验的数据库解决方案是否支持这样的操作模式?

1 个答案:

答案 0 :(得分:11)

PostgreSQL应该很好地适应这个工作量;几乎所有你指定的内容都在其正常的功能集中。 Pg符合ACID,支持组提交以减少同步开销,编写器不阻止读取器,并且它使用操作系统进行缓存,因此它自然倾向于仅将热数据集保留在内存中。

  

“客户愿意等待几秒钟的确认    - 足够多的磁盘搜索和写入发生“

如果考虑使用PostgreSQL,您的应用程序非常适合非常大的commit_delay,这将极大地提高写入吞吐量。您无法使用synchronous_commit = off,因为您需要在回复之前确认提交,但您可以将提交排队等待几秒钟,以节省同步费用。

如果您将Pg用于此类作业,需要调整检查点以确保检查点不会停止I / O.确保bgwriter积极地写出脏缓冲区。确保autovaccum经常运行 - 您不是从表中删除,但索引仍然需要维护,表统计信息也是如此。

如果您期望批次数据并且您的查询通常具有时间元素,请将partitioning the table考虑​​为(比如说)第1年1个月的块,合并早于按年划分的表格有12个月。 Pg只有有限的内置分区(它使用继承和约束排除一起被黑客攻击)所以你必须使用触发器手动/脚本来完成它,但是它可以完成这项工作。

见: