V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
myzincx
V2EX  ›  Linux

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

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

    需求:一个小时大概有 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   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2864 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:53 · PVG 19:53 · LAX 04:53 · JFK 07:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.