爬了 100w 个平均每个 100KB 的文件放在 HDD 上,现在要按文件名读取,发现每秒才 7 个文件。
需要爬的数据有点复杂,所以我分了 2 步,先把网页原始数据保存,回头再一个个读出来提取数据。明明爬的时候我还能开 32 线程每秒 70+个,现在开 2 个线程根据文件名读文件,磁盘就满速了最多 2 兆字节每秒(资源管理器写的),7 个文件每秒。
配置:Windows7 x64,SSD + HDD,i7-6700HQ
问题:
1
rrfeng 2018-01-22 14:32:03 +08:00
为什么不爬下来直接处理完?
要么写成一个大文件,强行变成顺序读写。 |
2
em70 2018-01-22 14:36:08 +08:00
很简单,保存的时候,用文件名首字母创建目录,同首字母文件名都放该目录下
|
3
swulling 2018-01-22 14:43:25 +08:00
1. 使用 SQLITE BLOB,如果你对读取顺序没有要求的化,顺序读会好很多。
但是 https://sqlite.org/intern-v-extern-blob.html,可以看到 100KB 正好是个分界点,这个大小的 BLOB,读写效率和单独写文件差别不大。 2. HDD 也不至于每秒 7 个文件,从别的方式优化下 3. 最好换 SSD 结论是,换成 SQLITE BLOB 看看效果 |
4
gclove 2018-01-22 14:44:34 +08:00
100 万个 ?
可以用的上小文件存储系统了吧 . 例如 taobao tfs 这种系统会把每个文件拆分合并成固定大小的一个文件 再按索引和长度读取文件 |
5
ovear 2018-01-22 14:44:46 +08:00
不要在一个文件夹下放太多文件。
|
6
yingfengi 2018-01-22 14:46:40 +08:00 via Android
上数据库?
|
7
gclove 2018-01-22 14:48:40 +08:00
|
8
fushshanpupil OP @ovear 确实全扔一个文件夹下了。。
|
9
fushshanpupil OP @em70 怪不得,scrapy 的 cache 就是取 hash 后的前两位创建了一层目录
|
10
fushshanpupil OP @rrfeng 提取数据的逻辑随时可能变,不可能每次都再去请求的吧,肯定得保存下来
|
11
fushshanpupil OP @swulling 对顺序没要求,每个网页都有个 id 的,用 id 选的,我参考下 sqlite blob
|
12
swulling 2018-01-22 15:24:33 +08:00
@fushshanpupil 文件夹要改一下,一般的做法是对文件做 sha1,比如是
adc83b19e793491b1c6ea0fd8b46cd9f32e592fc 那么就存放为 a/d/c/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc 三级目录,这样平均一个目录只存放 1w 个文件 |
13
fushshanpupil OP @swulling 最新调试结果,最后发现还是由于坑爹的 GIL+threading 库,导致我程序实际上是 IO 密集了,改用 multiprocessing 就跟爬的时候一样 70 个每秒了。
另外感谢各位,提供了很多其他思路,确实还有改进的地方。 |
14
WinMain 2018-01-22 18:42:05 +08:00
TFS
|