【问题标题】:Poor performance from SQLite, big writes bring little reads to a crawlSQLite 的性能不佳,大写操作带来的读操作很少
【发布时间】:2013-01-10 06:18:27
【问题描述】:

相关问题How to use SQLite in a multi-threaded application.

我一直试图在多线程程序中从 SQLite3 中获得不错的性能。除了写入延迟外,它的性能给我留下了深刻的印象。这不是它的错,它必须等待磁盘旋转才能提交数据。但是在这些写入过程中阻止读取,即使它们可以从缓存中读取,也是非常不能容忍的。

我的用例涉及大量小型读取操作,以通过索引字段获取一个小对象,但延迟对于这些操作很重要,因为它们有很多。写入量很大,并累积到单个事务中。我不希望由于完成写入而导致读取有很大的延迟。

我首先只是使用了一个带有互斥锁的连接来保护它。但是,当写入线程等待事务完成时,读取器在磁盘 I/O 上被阻塞,因为在写入器释放它之前他们无法获取互斥锁。我尝试使用多个连接,但后来我从sqlite3_step 得到SQLITE_LOCKED,这意味着必须重新设计所有读取代码。

我的写逻辑目前是这样的:

  1. 获取连接互斥锁。
  2. START TRANSACTION
  3. 执行所有写入。 (通常是 10 到 100 个小的。)
  4. END TRANSACTION -- 这里是阻塞的地方
  5. 释放互斥锁。

是否有一些我不知道的解决方案?如果条目在缓存中,是否有一种简单的方法可以让我的读者不必等待磁盘完成旋转,而不必重写我所有的阅读代码来处理SQLITE_LOCKED、重置和重试?

【问题讨论】:

  • PRAGMA synchronous = OFF 将大大提高您的写入性能,但如果在写入数据之前出现问题,则会以数据损坏为代价。我在当前不是这样的问题的项目中使用它。
  • 不幸的是,数据很重要,预计可以在进程崩溃、断电等情况下幸存下来。它被复制了,但每个节点都应该将它视为宝贵的。当我们等待操作系统完成写入同步时,延迟读取(可能来自缓存)似乎毫无意义。

标签: multithreading sqlite


【解决方案1】:

要允许多个读取器和一个写入器同时访问数据库,请启用write-ahead logging

WAL 适用于小型事务,因此您不需要累积写入。

请注意,WAL 不适用于网络文件系统,为了获得最佳性能,需要定期检查点。

【讨论】:

  • 打开它,事情就提高了大约 20 倍。该死的。
  • @Arash 因为它有一些限制。
【解决方案2】:

首先,sqlite 自己提供多线程支持。您不必使用自己的互斥锁,因为您只会减慢整个程序的速度。如有任何疑问,请咨询sqlite thread options

使用预写日志可能会解决您的问题,但它是一把双刃剑。只要正在进行读取,插入的数据就不会写入主数据库文件,WAL 日志就会增长。这在Write-Ahead Logging中有详细介绍

我在我的一个应用程序中以 WAL 模式使用 sqlite。对于少量数据,它运行良好。但是,当有大量数据时(每秒数百次插入,峰值甚至更多),我会遇到一些问题,我似乎无法通过任何干预 sqlite 配置来解决这些问题。

您可能会考虑使用多个数据库文件,每个文件都分配给特定的时间跨度。这仅适用于您的查询取决于时间。

我可能跑得太快了。 WAL 日志应该会有所帮助:)

【讨论】:

  • 我找不到避免我自己的互斥体的方法。如果我不使用它们,我会得到SQLITE_LOCKED 返回并且必须实现重试。 (这可能是值得做的。在实施 WAL 之前,我的直觉告诉我代码的延迟大约是它应该的 100 倍。使用 WAL,我的直觉告诉我它应该是它的大约 5 倍。)
  • 我不知道您的应用程序的详细信息以及它是如何工作的。如果您需要使用自己的互斥体并且它可以使代码运行得更好——就这样吧。在这种情况下,您可以在某些条件下一起禁用 sqlite 互斥锁。在您展示互斥锁使用的情况下,将显着减慢读取操作,因为一次只能读取一次。使用 sqlite 内部互斥体可以进行多次读取。
  • 有没有办法获得多次读取,使用 SQLite 执行互斥锁的单个写入器,而无需实现 SQLITE_LOCKED 重试?
  • 这是readers-writer lock的已知问题。有一些实现,但通常存在读取器/写入器饥饿的风险。
猜你喜欢
  • 2021-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多