V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
fushshanpupil
V2EX  ›  问与答

100w 个小文件存储问题

  •  
  •   fushshanpupil · 2018-01-22 13:56:32 +08:00 · 2776 次点击
    这是一个创建于 2497 天前的主题,其中的信息可能已经有所发展或是发生改变。

    爬了 100w 个平均每个 100KB 的文件放在 HDD 上,现在要按文件名读取,发现每秒才 7 个文件。

    需要爬的数据有点复杂,所以我分了 2 步,先把网页原始数据保存,回头再一个个读出来提取数据。明明爬的时候我还能开 32 线程每秒 70+个,现在开 2 个线程根据文件名读文件,磁盘就满速了最多 2 兆字节每秒(资源管理器写的),7 个文件每秒。

    配置:Windows7 x64,SSD + HDD,i7-6700HQ

    问题:

    1. 怎么会出现写入的时候能 70+个每秒,读出来才 7 个每秒。
    2. 100w 个小文件放 HDD 上是有点问题,估计随机读写都受影响,是否另写个脚本跑一晚上存进 sqlite 会提高读写性能?
    14 条回复    2018-01-22 18:42:05 +08:00
    rrfeng
        1
    rrfeng  
       2018-01-22 14:32:03 +08:00
    为什么不爬下来直接处理完?

    要么写成一个大文件,强行变成顺序读写。
    em70
        2
    em70  
       2018-01-22 14:36:08 +08:00
    很简单,保存的时候,用文件名首字母创建目录,同首字母文件名都放该目录下
    swulling
        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 看看效果
    gclove
        4
    gclove  
       2018-01-22 14:44:34 +08:00
    100 万个 ?

    可以用的上小文件存储系统了吧 . 例如 taobao tfs
    这种系统会把每个文件拆分合并成固定大小的一个文件

    再按索引和长度读取文件
    ovear
        5
    ovear  
       2018-01-22 14:44:46 +08:00
    不要在一个文件夹下放太多文件。
    yingfengi
        6
    yingfengi  
       2018-01-22 14:46:40 +08:00 via Android
    上数据库?
    gclove
        7
    gclove  
       2018-01-22 14:48:40 +08:00
    @fushshanpupil

    这种问题就需要把小文件合并成一个大文件存储

    https://www.zhihu.com/question/26504749
    fushshanpupil
        8
    fushshanpupil  
    OP
       2018-01-22 14:59:01 +08:00
    @ovear 确实全扔一个文件夹下了。。
    fushshanpupil
        9
    fushshanpupil  
    OP
       2018-01-22 14:59:52 +08:00
    @em70 怪不得,scrapy 的 cache 就是取 hash 后的前两位创建了一层目录
    fushshanpupil
        10
    fushshanpupil  
    OP
       2018-01-22 15:01:31 +08:00
    @rrfeng 提取数据的逻辑随时可能变,不可能每次都再去请求的吧,肯定得保存下来
    fushshanpupil
        11
    fushshanpupil  
    OP
       2018-01-22 15:02:15 +08:00
    @swulling 对顺序没要求,每个网页都有个 id 的,用 id 选的,我参考下 sqlite blob
    swulling
        12
    swulling  
       2018-01-22 15:24:33 +08:00
    @fushshanpupil 文件夹要改一下,一般的做法是对文件做 sha1,比如是
    adc83b19e793491b1c6ea0fd8b46cd9f32e592fc

    那么就存放为 a/d/c/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc

    三级目录,这样平均一个目录只存放 1w 个文件
    fushshanpupil
        13
    fushshanpupil  
    OP
       2018-01-22 17:34:26 +08:00
    @swulling 最新调试结果,最后发现还是由于坑爹的 GIL+threading 库,导致我程序实际上是 IO 密集了,改用 multiprocessing 就跟爬的时候一样 70 个每秒了。

    另外感谢各位,提供了很多其他思路,确实还有改进的地方。
    WinMain
        14
    WinMain  
       2018-01-22 18:42:05 +08:00
    TFS
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1069 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:15 · PVG 03:15 · LAX 11:15 · JFK 14:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.