【问题标题】:SQLite and concurrency [closed]SQLite 和并发 [关闭]
【发布时间】:2013-01-08 14:33:40
【问题描述】:

我需要在我们的一个产品中集成一个数据库,我想知道哪个更适合我们的需求(易于自动部署、无需管理、良好的性能),sqlite 似乎是一个很好的解决方案。问题是数据库可能会面临高并发问题:每次客户端连接到运行数据库的服务器时,都会通过 PHP (Apache) 访问它。一个客户端大约每 10 秒连接一次(并执行一个 INSERT 查询)到服务器,它可能有超过 100 个客户端在运行。

执行 INSERT 查询时,sqlite 在特定时间锁定整个数据库一段时间。有没有办法计算这个持续时间?如果这不可行,您认为 sqlite (v3.3.7) 仍然适应上述条件吗?

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    我尽量避免情绪化的回复和夸张,但我真的惊讶对此页面上显示的关于 sqlite 的知识缺乏了解。不同的数据库实现满足不同的需求,从您提供的操作规范来看,sqlite3 似乎非常适合您的需求。详细说明:

    sqlite3 完全符合 ACID,这意味着它可以确保原子提交,这是 MySQL(尽管它可能很好)和 Oracle 都不能吹嘘的。查看更多here

    此外,sqlite3 有一个看似简单的机制来确保最大并发性(这也是线程安全的),如他们的File locking and Concurrency document 中所述。

    根据他们(sqlite3 开发人员)自己的估计,sqlite3 每秒最多可以插入 50,000 次 - 这是受磁盘旋转速度限制的理论最大值。 ACID 合规性要求 sqlite3 确认数据库提交已写入磁盘,因此 INSERT、UPDATE 或 DELETE 事务需要两次完整的磁盘旋转,从而有效地将事务数减少到 7200rpm 磁盘驱动器上的 60/s。这在另一个答案中链接的 sqlite FAQ 中进行了概述,事实给出了引擎在生产中的数据吞吐量能力的一些想法。但是并发读写呢?

    前面链接的文件锁定和并发文档解释了 sqlite3 如何避免“writer startvation” - 大量数据库读取访问会阻止寻求写入数据库的进程/线程获取锁的情况。锁定状态从 SHARED 到 PENDING 到 EXCLUSIVE 的升级发生在 sqlite3 遇到 INSERT(或 UPDATE 或 DELETE)语句,然后在 COMMIT 时再次发生,这意味着完整的数据库锁定被延迟到执行实际写入之前的最后一刻。 sqlite 处理文件锁定的巧妙机制的结果意味着,如果写入者加入队列(PENDING 锁),现有读取(共享锁)将完成,向写入者进程授予独占锁,然后继续读取。这只需要几毫秒,这意味着有效的事务吞吐量几乎不会从上面引用的 60/s 速率移动。

    我相信 EXCLUSIVE 锁上的默认 sqlite3 等待时间是 3 秒,所以考虑到每秒 60 个事务是一个合理的预期,并且您平均每 10 秒写入一次数据库 - 我会说sqlite3 可以很好地完成任务,只有在您的流量增加 500 倍时才需要引入集群。

    不错,非常适合您的要求。

    【讨论】:

    • 如果一个冗长的选择查询(比如 15 秒持续时间)正在进行,并且应该在第十秒发生 INSERT,会发生什么?插入会失败吗?
    • 在默认的 sqlite3 安装和设置(以及多线程数据库访问)中,它会失败,是的,因为您等待释放锁的默认超时是 5 秒。但是,您可以通过以下方式处理这种极端情况(15 秒事务):1)在 sqlite3 连接代码中设置更长的超时时间和/或 2)在代码中捕获 SQLITE_BUSY 超时错误并重新执行事务。
    • OP 没有提到报告,只提到并发插入查询,如果我们狭义地定义他的要求并排除报告,我必须同意你的看法。 Apache 服务器可能有 100 个客户端,但只有一个 db 客户端。但是对于一个大型数据库,并且一些用户正在实时查询数据库,即使其他小的(单行)插入像雨滴撞击人行道一样撞击数据库,“极端”情况也很常见。如果这是他的场景,OP 应该忘记零维护和零安装,并使用真正的后端 DBMS。
    • 我明白你的意思,正如你所说,虽然没有提到读取负载,但如果用户群增加或项目范围扩大,它可能会迅速升级。在这种情况下,我建议使用 postgresql。不过,我很想知道 sqlite3 的运营能力上限......将在这里发布我发现的内容
    • 好的,有成果的研究时间:来自 sqlite 网站的两个非常有用的文档:sqlite.org/speed.htmlsqlite.org/whentouse.html。调查结果:sqlite 牺牲了复杂的特性来换取速度和简单性。在大多数情况下 sqlite3 比企业级数据库引擎更快。 sqlite 可以驱动高达 140TB 的 db,允许多个同时读取,并且像其他数据库一样将数据存储在磁盘上的文件中。 sqlite3 可以集群到一个数据库场。并发不是它的强项。链接的文档包含有关哪些上下文最适合 sqlite 并值得一读的有价值信息。
    【解决方案2】:

    我认为 SQLite 不是满足这些要求的好解决方案。 SQLite 专为本地和轻量级使用而设计,而不是为数百个请求提供服务。

    我会推荐一些其他的解决方案,例如MySQLPostgreSQL,两者都可以很好地编写脚本。所以,如果我是你,我会努力编写设置脚本。

    为了避免 SQLite 的支持者和仇恨者之间的激烈战争,让我提请您注意经常提到的 SQLite When-To-Use 文档(我相信它被认为是可靠的来源)。他们在此声明如下:

    客户端/服务器 RDBMS 可能更好地工作的情况

    高并发

    SQLite 支持无限数量的同时读取器,但它在任何时刻只允许一个写入器。对于许多情况,这不是问题。作家排队。每个应用程序都快速完成其数据库工作并继续前进,没有任何锁定持续超过几十毫秒。但是有些应用程序需要更多的并发性,这些应用程序可能需要寻求不同的解决方案。

    我认为在提到的问题中涉及许多写入,如果 OP 选择 SQLite,它将导致不可扩展的解决方案。

    【讨论】:

      【解决方案3】:

      除了上面关于 sqlite3 的讨论之外,在 sqlite v 3.7.0 中引入的另一个 awesome 功能是 WAL 模式,您可以在其中读取多个进程和可以同时写入一个进程。

      看看http://www.sqlite.org/wal.html

      【讨论】:

        【解决方案4】:

        SQLite FAQ 涵盖了这个主题:http://www.sqlite.org/faq.html(参见:“(5) 多个应用程序或同一应用程序的多个实例可以同时访问单个数据库文件吗?”)

        但对于您的特定用途,您可能需要进行一些压力测试以验证它是否满足您的需求。 100 个并发用户对于 SQLite 来说可能有点多。

        【讨论】:

          【解决方案5】:

          我通读了常见问题解答,似乎 SQLite 对并发有一些相当不错的支持,但可能需要使用事务才能确定一切顺利。

          上面关于 Apache 并发的 cmets 是正确的:一个 Apache 服务器可以提供多个请求,数量取决于运行的进程数。我运行的大多数服务器,它设置为 3-5 个进程,而在较大的安装中,它可能达到 20 个。这里的重点是 SQLite 不仅可以处理中小型流量网站,因为它可以执行数千次插入一秒钟。

          我计划在我当前的项目中使用 SQLite,但为了安全起见,我完全打算对任何写作或并发敏感部分使用 BEGIN TRANSACTION 和 COMMIT。

          底线,像往常一样,阅读手册。

          【讨论】:

            【解决方案6】:

            以下是 SQLite 对 SQLite 的适当使用的看法:http://www.sqlite.org/whentouse.html 特别是,该页面说 SQLite 适用于低流量的网站,正是您正在考虑的那种应用程序。

            似乎 SQLite 对你有用,除非你期望大幅增长。根据您在每个请求中执行的操作,我希望每秒 0.17 次查询的查询率在 SQLite 的能力范围内。

            为了获得良好的用户体验,您应该设计您的网站,以便为单个请求提供服务所需的查询大约需要 200 毫秒。为了实现这一点,结果集可能不应该超过几个分数行;并且应该依赖于索引,而不是全表扫描。如果你做到了,那么你将有足够的空间来每秒处理 5 个查询(在峰值时)。这是您在问题中陈述的要求的 30 倍。

            【讨论】:

              猜你喜欢
              • 2010-09-07
              • 1970-01-01
              • 2020-06-09
              • 2014-05-07
              • 1970-01-01
              • 1970-01-01
              • 2010-10-08
              • 2012-07-27
              • 1970-01-01
              相关资源
              最近更新 更多