【发布时间】:2013-01-10 06:18:27
【问题描述】:
相关问题:How to use SQLite in a multi-threaded application.
我一直试图在多线程程序中从 SQLite3 中获得不错的性能。除了写入延迟外,它的性能给我留下了深刻的印象。这不是它的错,它必须等待磁盘旋转才能提交数据。但是在这些写入过程中阻止读取,即使它们可以从缓存中读取,也是非常不能容忍的。
我的用例涉及大量小型读取操作,以通过索引字段获取一个小对象,但延迟对于这些操作很重要,因为它们有很多。写入量很大,并累积到单个事务中。我不希望由于完成写入而导致读取有很大的延迟。
我首先只是使用了一个带有互斥锁的连接来保护它。但是,当写入线程等待事务完成时,读取器在磁盘 I/O 上被阻塞,因为在写入器释放它之前他们无法获取互斥锁。我尝试使用多个连接,但后来我从sqlite3_step 得到SQLITE_LOCKED,这意味着必须重新设计所有读取代码。
我的写逻辑目前是这样的:
- 获取连接互斥锁。
START TRANSACTION- 执行所有写入。 (通常是 10 到 100 个小的。)
-
END TRANSACTION-- 这里是阻塞的地方 - 释放互斥锁。
是否有一些我不知道的解决方案?如果条目在缓存中,是否有一种简单的方法可以让我的读者不必等待磁盘完成旋转,而不必重写我所有的阅读代码来处理SQLITE_LOCKED、重置和重试?
【问题讨论】:
-
PRAGMA synchronous = OFF将大大提高您的写入性能,但如果在写入数据之前出现问题,则会以数据损坏为代价。我在当前不是这样的问题的项目中使用它。 -
不幸的是,数据很重要,预计可以在进程崩溃、断电等情况下幸存下来。它被复制了,但每个节点都应该将它视为宝贵的。当我们等待操作系统完成写入同步时,延迟读取(可能来自缓存)似乎毫无意义。
标签: multithreading sqlite