我是否使用 sqlite 破坏了我的磁盘?
Am I ruining my disk by using sqlite?
所以我时常 运行 网络爬虫。有时数据库是不可避免的,我更喜欢sqlite,因为它易于使用。但是,我担心我的最新项目对我的 SSD 造成压力;看一看。
我有单独的进程,每个进程都在数据库中查询 URL 以进行抓取,然后将结果写入磁盘并提交。如果可能的话,我想避免不必要的抓取,所以我在每个结果后提交,这样其他进程就知道不要抓取那个结果。
我担心的是每次提交都是实际写入磁盘。有了大约一百万个查询,我的 SSD 就会过早老化:/
所以基本上,有两个问题:
这真的意味着 1 次提交 = 1 次物理磁盘写入吗?或者 SQLite 中是否有缓冲,或者 Linux 做类似的事情,或者 SSD 控制器本身将数据库的副本保存在 RAM(或控制器内存)中并且很少与驱动器同步?数据库本身小于20MB.
如果这是我所担心的,我可以对 sqlite3 做任何调整,或者服务器-客户端数据库是不可避免的吗?我的理解是数据库服务器将独占访问数据库,因此它可以将工作版本保留在 RAM 中并定期同步到磁盘。
很抱歉这个问题更像是一个讨论:/
评论有点长。而且,我对 SSD 技术的最新进展并不十分熟悉。但是,你有一个合理的担忧。
我看不出如何避免这个问题。您想要抓取网站然后存储数据 "permanently"。该过程需要写入某种形式的长期存储。如果唯一的存储是 SSD,那么您将需要写入磁盘。这与使用数据库无关。
数据库可能会产生额外的写入,这取决于它们的设计方式 -- 索引页、日志记录、页面拆分等的额外写入。
你能做什么?我的建议是虔诚地备份数据库,监控您的硬件,并在必要时更新硬件。顺便说一句,该建议与使用数据库或 SSD 无关。
一次提交确实会导致至少一次磁盘写入,或者说不止一次,因为 table 结构和数据库头以及文件系统的元数据很可能位于其他页面中。
然后在数据表中查看您的 SSD 的写入耐久性。然后意识到你所做的一百万次写入 "from time to time" 是完全无害的。
为了使您的数据库写入对 SSD 更友好,您可以启用 WAL mode。但除非您连续 运行 数据库 24/7,否则您不会注意到任何差异。
从那以后,我想出了一个适合我的解决方法:在 RAM 上设置数据库(在 linux 中,/dev/shm 就是这样一个地方,我相信 Windows有
等效的实用程序)。
显然,我们希望它在某个时候写入磁盘,所以我所做的是 运行 bash 中的一个循环,定期将虚拟数据库文件复制到磁盘,如下所示:
while true; do sleep 20; cp /dev/shm/results.db ~/project/results.db; done
这不是一个完美的长期解决方案,但它绝对可以在不进行任何修改的情况下工作,并且可以极大地提高速度。
所以我时常 运行 网络爬虫。有时数据库是不可避免的,我更喜欢sqlite,因为它易于使用。但是,我担心我的最新项目对我的 SSD 造成压力;看一看。
我有单独的进程,每个进程都在数据库中查询 URL 以进行抓取,然后将结果写入磁盘并提交。如果可能的话,我想避免不必要的抓取,所以我在每个结果后提交,这样其他进程就知道不要抓取那个结果。
我担心的是每次提交都是实际写入磁盘。有了大约一百万个查询,我的 SSD 就会过早老化:/ 所以基本上,有两个问题:
这真的意味着 1 次提交 = 1 次物理磁盘写入吗?或者 SQLite 中是否有缓冲,或者 Linux 做类似的事情,或者 SSD 控制器本身将数据库的副本保存在 RAM(或控制器内存)中并且很少与驱动器同步?数据库本身小于20MB.
如果这是我所担心的,我可以对 sqlite3 做任何调整,或者服务器-客户端数据库是不可避免的吗?我的理解是数据库服务器将独占访问数据库,因此它可以将工作版本保留在 RAM 中并定期同步到磁盘。
很抱歉这个问题更像是一个讨论:/
评论有点长。而且,我对 SSD 技术的最新进展并不十分熟悉。但是,你有一个合理的担忧。
我看不出如何避免这个问题。您想要抓取网站然后存储数据 "permanently"。该过程需要写入某种形式的长期存储。如果唯一的存储是 SSD,那么您将需要写入磁盘。这与使用数据库无关。
数据库可能会产生额外的写入,这取决于它们的设计方式 -- 索引页、日志记录、页面拆分等的额外写入。
你能做什么?我的建议是虔诚地备份数据库,监控您的硬件,并在必要时更新硬件。顺便说一句,该建议与使用数据库或 SSD 无关。
一次提交确实会导致至少一次磁盘写入,或者说不止一次,因为 table 结构和数据库头以及文件系统的元数据很可能位于其他页面中。
然后在数据表中查看您的 SSD 的写入耐久性。然后意识到你所做的一百万次写入 "from time to time" 是完全无害的。
为了使您的数据库写入对 SSD 更友好,您可以启用 WAL mode。但除非您连续 运行 数据库 24/7,否则您不会注意到任何差异。
从那以后,我想出了一个适合我的解决方法:在 RAM 上设置数据库(在 linux 中,/dev/shm 就是这样一个地方,我相信 Windows有 等效的实用程序)。
显然,我们希望它在某个时候写入磁盘,所以我所做的是 运行 bash 中的一个循环,定期将虚拟数据库文件复制到磁盘,如下所示:
while true; do sleep 20; cp /dev/shm/results.db ~/project/results.db; done
这不是一个完美的长期解决方案,但它绝对可以在不进行任何修改的情况下工作,并且可以极大地提高速度。