【问题标题】:Concurrency issues writing to multiple SQLite databases simultaneously on different app threads在不同的应用程序线程上同时写入多个 SQLite 数据库的并发问题
【发布时间】:2014-12-07 11:08:08
【问题描述】:

我对此进行了很多搜索,但运气不佳。作为测试,我编写了一个 C# WinForms 应用程序,我在其中启动了可配置数量的线程,并让每个线程将可配置数量的数据写入该线程创建的 SQLite 数据库中的多个表中。因此,每个线程都会创建自己的 SQLite 数据库,并且只有该线程与之交互。

我看到的是,由于并发性,肯定会发生一些性能下降。例如,如果我大致同时启动每个线程,则写入 SQLite 表的性能会下降,而如果我在每个线程中设置随机启动延迟以分散它们的访问权限。

SQLite 的启动速度非常快,足以满足我的测试需求,我可以在 1/3 秒内将 20,000 行插入表中,但是一旦我启动 250 个线程,同样的 20,000 行可能需要 MINUTES 才能写入每个数据库。

我已经尝试了很多东西,包括定期提交、设置 Sychronous=Off、使用参数化查询等等……所有这些都有助于缩短每条语句所花费的时间(从而减少并发活动),但没有什么能真正解决它,我希望有人能给一些建议。

谢谢! 安迪

【问题讨论】:

  • 你的意思是,多个线程同时写入磁盘上不同的地方比单个线程慢?
  • 您对这一级别的并发写入同一磁盘的性能有何期望?
  • 多个线程,每个线程都写入他们通过自己的 SQLite 连接创建的自己的 SQLite 数据库,比单个线程写入单个 SQLite 数据库要慢得多。我显然预计它会更慢,有更多的 CPU 使用率、内存使用率等......但性能肯定会出现爆炸性的争用惩罚,这似乎表明 SQLite 在内部的某个地方存在共享资源。
  • 我同意。我使用平面文件用 C# 编写了一个快速测试用例,250 名工作人员每人编写了 65k 条记录。如果没有锁定,所有写入都在大约一秒钟内完成,锁定所有写入大约在 16 秒内完成(SATA3 SSD 为 18 秒,比 WD Green 2TB 慢得多)。我希望 SQLite 案例比这慢,但不超过 2*N 或 3*N,但这只是一个毫无头绪的猜测。我假设争用发生在库本身,与使用单个进程处理 250 个数据库/事务有关。我会尝试一种多进程方法,看看你是否发现了差异。

标签: c# sqlite concurrency


【解决方案1】:

在任何关系数据库中写入过多的并发确实会导致速度变慢。根据您尝试优化的场景,您可以做各种其他事情,我能想到的很少是:

1) 创建批处理而不是并发写入,这意味着如果您期望大量用户同时写入,则收集他们的数据并将其刷新到更大的组中,尽管这意味着,当我们的队列正在收集时请注意如果应用程序出现故障,您将丢失数据,您可以对日志等非关键数据执行此操作。

2) 如果你的线程在插入数据之前还需要做其他工作,你仍然可以拥有我们的线程,然后添加一个信号量或与插入发生的代码部分等效的东西,这将限制并发性并加快整个过程。

3) 如果您尝试通过您尝试制作的工具进行批量插入,请在您的问题中提及,很多 mysql dba 会比我更好地回答我们的问题。

【讨论】:

  • 这里是对我所看到的内容的更简单解释。 1. 我想要一个 WinForms 应用程序,它可以同时创建 500 个 SQLite 数据库。 2.每个数据库有1个表。 3. 在该表中,我将在每个数据库中插入 65,000 行。 4. 为了同时创建和写入 SQLite 数据库,我的 WinForms 应用程序为每个数据库启动了一个线程。 5. 然后每个线程循环 65,000 次,每个循环向表中插入一行。
  • 我看到的是: 1. 对于 1 个线程,我获得了出色的性能。我可以在大约 300 毫秒内将 65,000 行插入到单个 SQLite 数据库中。 2. 当我增加线程数时,性能直线下降。当我执行 50 个并发线程(写入 50 个不同的 SQLite 数据库)时,插入需要 30 秒 - 1 分钟。 3. 如果我让每个线程随机等待一段时间(减少争用),性能再次飙升。所以在这个过程中肯定有一些东西引起了很多争论。我不明白为什么,因为每个线程都使用唯一的 conn 和 db。
  • 您应该将 6500 万行批处理成 1000 行(实验批量大小),完成此操作后,您应该会看到主要的性能改进,之后您应该批处理数据库创作工作也是如此。在这里,您尝试创建 500 个同时运行的连接,这些连接在循环中运行并打开并创建更多。 sql 连接池可能已用完。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
相关资源
最近更新 更多