单机存储大量的小文件该如何选择? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
myzincx
V2EX    Linux

单机存储大量的小文件该如何选择?

  •  
  •   myzincx 2020-09-10 15:23:52 +08:00 7072 次点击
    这是一个创建于 1861 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求:一个小时大概有 180w 个不超过 10kb 的小文件要存储在单机设备上(只提供单机),目前直接写文件会直接造成程序性能基本不可用

    想法: 1.目前有想过的是打包成一个大文件直接建立自有索引,但是这么做的话程序需要改动很多(主要是其他部门的),而且本部门人手有限,开发维护起来可能有困难。 2.也有查过一些文件存储框架,首先大部分框架是分布式的,我们只能提供单机,不知道这个会不会造成影响;其次,因为其他部门有个功能必须是对文件进行直接读取操作的(貌似 ceph 是可以当成一个挂载卷的这种,不太了解,如理解错误希望指出),不能够通过网络 api 调用操作(如 seaweedfs)。

    所以想请教下大家,有没有那种单机适合这种小文件大量读写的。 写多,读少,不删除。

    40 条回复    2020-09-14 17:16:03 +08:00
    opengps
        1
    opengps  
       2020-09-10 15:35:57 +08:00
    单机的话,得规划下文件夹的创建,避免单个文件夹下太多文件导致的索引变慢
    另外如果 cpu 扛得住的话,可以考虑 base64 存数据库,合理设计表结构,比如分库分表配合
    myzincx
        2
    myzincx  
    OP
       2020-09-10 15:37:41 +08:00
    @opengps 创建文件夹可以考虑,数据存数据库就不太可了,其他项目组需要扫描原始文件使用。感谢回答
    wzw
        3
    wzw  
       2020-09-10 15:39:31 +08:00 via iPhone
    Ssdb 加 python/go 写个接口
    Mirana
        4
    Mirana  
       2020-09-10 15:49:50 +08:00
    写多读少不删除 最好的 io pattern 是 append only 而且不需要 gc
    感觉 tfs 会好一点
    myzincx
        5
    myzincx  
    OP
       2020-09-10 15:59:10 +08:00
    @Mirana tfs 还有在维护吗?
    myzincx
        6
    myzincx  
    OP
       2020-09-10 16:00:18 +08:00
    @wzw 这种无法表现为数据卷的通过网路通信的不可用
    drehere
        7
    drehere  
       2020-09-10 16:03:35 +08:00
    这个其实是跟 Linux 硬盘类型有关的,ext3 和 ext4 是不同的,主要要解决的就是 inode 的个数
    gfreezy
        8
    gfreezy  
       2020-09-10 16:04:12 +08:00
    sqlite
    zjyl1994
        9
    zjyl1994  
       2020-09-10 16:14:09 +08:00 via Android
    搞一个 btrfs 格式的磁盘试试?
    wangritian
        10
    wangritian  
       2020-09-10 16:34:54 +08:00
    项目中写小文件的任务改成单文件追加,设计一个简单协议,对这个大文件分段,比如前 8 字节表示段数据大小,再扫描到\0 是该小文件的路径,其余是小文件数据,积累一定时间或数据量时新建一个大文件,然后调用一个外部程序按协议拆解前一个大文件,不知道这个方案是否可行
    hakono
        11
    hakono  
       2020-09-10 16:45:49 +08:00
    虽然没用过,但也许可以考虑下无压缩 zip 。。。。
    记录下文件保存在哪个 zip 里就行了。。。。。

    不过无压缩 zip 适不适合 180w/h 写入就不知道了
    594duck
        12
    594duck  
       2020-09-10 17:33:46 +08:00
    leveldb 和 rocksdb 适合干这活,之前公司他们就是这么弄的。

    但是要知道这二个 DB 是写优化的,写起来异常的猛 ,但是读不行。
    594duck
        13
    594duck  
       2020-09-10 17:35:53 +08:00
    另外你一秒钟要写 5000 个文件,而且 IO 如此碎,一定要考虑 RAID10 了,RAID 卡的 Cache 一定要大,越大越好
    MeteorCat
        14
    MeteorCat  
       2020-09-10 17:37:40 +08:00 via Android
    单机存储小文件方案不清楚,但是缺点我遇到过一个,那就是 inode 利用达到 100 %,直接使用 df -i 看到磁盘直接把 inode 爆了,这个是你使用单机存储大量文件必须要处理的问题
    kuro1
        15
    kuro1  
       2020-09-10 17:43:00 +08:00
    ipfs 单机开启 badgerds,本质是 db
    kuro1
        16
    kuro1  
       2020-09-10 17:45:21 +08:00
    关于第二点,可以使用 ipfs mount,关闭 gateway port
    Mirana
        17
    Mirana  
       2020-09-10 18:57:57 +08:00
    @594duck 楼主不删文件,所以 rocksdb 这种 需要做 merge 的 db,写放大贼高,不太合适
    myzincx
        18
    myzincx  
    OP
       2020-09-10 19:27:30 +08:00 via Android
    思考了一下,准备使用 fuse 在外面写一层接口,主要是实现 open write read 之类的必须函数,然后通过函数在内部调用其他数据库,实现对上层应用的透明,不知道大家认为可行否?
    myzincx
        19
    myzincx  
    OP
       2020-09-10 19:29:18 +08:00 via Android
    其他数据库的话找个高吞吐量的就行,也可以用 Redis 做缓存,延后组成大文件落地。这样的话当其他项目要使用到其中的文件时,可以直接去数据库里查询到数据然后返回即可。
    oyasumi
        20
    oyasumi  
       2020-09-10 19:36:11 +08:00 via Android
    s3 挺合适的
    xupefei
        21
    xupefei  
       2020-09-10 19:50:01 +08:00 via iPhone
    ZFS 应该可以解决问题,
    livepps
        22
    livepps  
       2020-09-10 20:47:27 +08:00
    dropbox 好像是文件都做成 4m 的块,大的切割成 4m,小的多个拼接成 4m,然后维护索引
    livepps
        23
    livepps  
       2020-09-10 20:55:46 +08:00
    小文件太多,直接存硬盘,还是考虑拼接成大文件存储比较好,碎片也少。
    读取的时候分步:
    1. 其他文件读取文件的接口做个封装
    2. 每次调用,根据索引和文件长度,从 4m 快里面提取出数据拼接,创建临时文件。
    3. 然后再读取上面创建的临时文件。
    fancyhan
        24
    fancyhan  
       2020-09-10 21:11:10 +08:00 via iPhone
    每秒大概 1500iops,你的后端撑不住么?还是没有固态硬盘
    crclz
        25
    crclz  
       2020-09-10 23:20:04 +08:00
    数据库是最优解
    black11black
        26
    black11black  
       2020-09-10 23:39:12 +08:00
    感觉你这个需求,因为是小文件,直接存 sql 里就行了吧。比如用 LOB 存二进制。

    因为感觉上只有两个需求,一个是存储,另一个是根据名称读取,似乎 sql 很完美
    love
        27
    love  
       2020-09-11 00:18:06 +08:00 via Android
    @MeteorCat 有些文件系统无限 inode 的,比如 reiserfs,用 ext 存小文件是不行
    Mithril
        28
    Mithril  
       2020-09-11 00:54:57 +08:00
    直接内存映射开个大文件,然后自己往里面写小文件并且建立索引。具体实现方法随便参考个文件系统就行。
    主要是避免让操作系统去干这个事。小文件量大了 inode 不够用,大概率你得去搞不同的文件系统,迁移性很成问题。按你这个单机的需求八成软件是要安装在客户那里的,让人家去换个 OS 和 FS 不太现实。你可以参考下 FaceBook 的 Haystack,或者其 Go 的实现 weed-fs 。
    Ceph 维护是个大坑,单机你就还是不要碰了。
    Thiece
        29
    Thiece  
       2020-09-11 04:35:21 +08:00
    InfluxDB ?
    optional
        30
    optional  
       2020-09-11 08:07:41 +08:00 via iPhone
    minio s3fs 挂载到本地
    zengming00
        31
    zengming00  
       2020-09-11 08:46:17 +08:00
    存数据库是对的
    listenerri
        32
    listenerri  
       2020-09-11 08:55:49 +08:00
    好像有大厂自己实现的专门存储小文件的文件系统
    ruanimal
        33
    ruanimal  
       2020-09-11 09:37:43 +08:00
    leveldb + ssd 吧
    gotonull
        34
    gotonull  
       2020-09-11 11:29:25 +08:00
    我们公司用的 rocksdb
    firstfire
        35
    firstfire  
       2020-09-11 13:13:38 +08:00
    只要 10KB 大小的话,MongoDB 也可以存,还可以顺带的存储文件的元数据信息
    purplewall
        36
    purplewall  
       2020-09-11 19:23:49 +08:00
    这些数据好像才 18GB,要不试试看挂载 ramfs 直接写到内存里,或者直接映射一块足够大的内存。
    ungrown
        37
    ungrown  
       2020-09-12 15:19:26 +08:00
    你说的自定义 FUSE 思路可行,功能是简单的,但开发调试过程一定是痛苦的,这个没辙。
    所以在此之前,强烈建议你再试一些已经存在的工具、方法:
    ZFS 绝对值得一试,“终极文件系统”真不是凭空吹的牛逼;
    大量小文件打包成一个大文件的思路也值得一试,这事其实很多游戏都在干,就我自己玩过的,魔兽 3 、dota2,都如此。
    jones2000
        38
    jones2000  
       2020-09-12 22:06:22 +08:00
    Hadoop + Hbase
    devinmagic
        39
    devinmagic  
       2020-09-13 11:24:18 +08:00
    @MeteorCat 可以在格式化的使用-N 参数设置 inode 大小
    libook
        40
    libook  
       2020-09-14 17:16:03 +08:00
    可以尝试存在数据库里管理,比如 MongoDB 对于 16M 以上的文件可以用 GridFS,对于 16M 以下的可以用 BinData,自己没用过,感兴趣可以简单做一下压测。

    https://docs.mongodb.com/manual/core/gridfs/
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3372 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 04:43 PVG 12:43 LAX 21:43 JFK 00:43
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86