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

bto*_*own 6 database postgresql couchdb mongodb throughput

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

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

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

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

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

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

Cra*_*ger 11

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

"客户愿意等待几秒钟的确认 - 足够长的时间来进行多次磁盘搜索和写入"

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

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

如果您期望大量数据并且您的查询通常具有时间元素,请考虑将表划分为(例如)第1年1个月的块,将超过12个月的所有内容合并到按年划分的表中.Pg只有有限的内置分区(它使用继承和约束排除一起被黑客攻击)所以你必须使用触发器手动/脚本来完成它,但它完成了这项工作.

看到: