28

I need to integrate a database in one of our products and I wonder which one would be more suited to our needs (easy automatic deployment, no administration, good performance), and sqlite seems to be a good solution. The problem is that the database could potentially face high concurrency issues: it is accessed through PHP (Apache) each time a client connects to the server the database is running on. One client connects (and execute an INSERT query) approximatively every 10 seconds to the server, and it could possibly have more than 100 clients running.

When executing an INSERT query, sqlite locks the entire database at a certain time for a certain duration. Is there a way to compute that duration? If this is not possible, do you think sqlite (v3.3.7) is still adapted with the above conditions?

4

6 回答 6

71

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

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

此外,sqlite3 有一个看似简单的机制来确保最大并发性(这也是线程安全的),如他们的文件锁定和并发文档中所述。

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

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

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

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

于 2013-06-16T11:32:26.033 回答
8

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

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

为了避免 SQLite 信徒和仇恨者之间的激烈战争,让我提请您注意经常提到的SQLite 何时使用文档(我相信它被认为是可靠的来源)。他们在这里声明如下:

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

高并发

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

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

于 2013-01-08T14:45:28.087 回答
4

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

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

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

于 2013-11-12T10:57:14.053 回答
3

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

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

于 2013-01-08T14:37:25.200 回答
2

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

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

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

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

于 2013-11-13T19:42:45.513 回答
0

除了上面关于 sqlite3 的讨论之外,sqlite v 3.7.0 中引入的另一个很棒的特性是WAL 模式,您可以在其中读取多个进程并可以同时使用一个进程写入。

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

于 2016-11-18T19:03:49.637 回答