V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xchaoinfo
V2EX  ›  数据库

怎么存储千万级别的图片文件, 在保证尽可能节省空间的前提下,还能方便读写

  •  
  •   xchaoinfo · 2020-06-03 14:06:53 +08:00 · 7086 次点击
    这是一个创建于 1668 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前的图片都是一个个小文件放在文件夹中, 这样的问题是, 需要的存储空间比较大, 图片迁移也不方便, 而且对 I/O 的消耗非常大. 目前考虑使用数据库来存储, 方案有 lmdb sqlite 请问各位 V 友, 有其他好的方案吗? 能支持多线程读写最好.

    74 条回复    2020-06-11 04:48:50 +08:00
    cco
        1
    cco  
       2020-06-03 14:14:35 +08:00
    Hbase 也是可以的。。
    hankai17
        2
    hankai17  
       2020-06-03 14:14:43 +08:00
    小文件 io 流量大吗?
    wujieyuan
        3
    wujieyuan  
       2020-06-03 14:20:17 +08:00
    数据库也是文件存储啊,二进制存到数据库不仅费 io 还费 cpu, 文件应该是利用率最高的存储方式了吧
    Jirajine
        4
    Jirajine  
       2020-06-03 14:22:17 +08:00 via Android
    minio
    maemual
        5
    maemual  
       2020-06-03 14:23:06 +08:00   ❤️ 3
    seaweedfs
    msg7086
        6
    msg7086  
       2020-06-03 14:23:14 +08:00
    文件系统就是一个效率很高的数据库了。
    你说的这些难道不需要同等的存储空间?不需要消耗那么多 I/O ?
    reus
        7
    reus  
       2020-06-03 14:25:56 +08:00 via Android   ❤️ 4
    既然你会考虑 sqlite,我建议你放弃这个想法,信操作系统。
    djoiwhud
        8
    djoiwhud  
       2020-06-03 14:30:46 +08:00 via Android
    你不考虑一下 oss 服务?我只在学生时代见过在 db 中保存图片的。
    xchaoinfo
        9
    xchaoinfo  
    OP
       2020-06-03 14:35:41 +08:00
    @hankai17 访问量不大, 准确的说, 这个图片是用于做机器学习训练用的, 并不是提供给外网服务的.
    xchaoinfo
        10
    xchaoinfo  
    OP
       2020-06-03 14:40:38 +08:00
    @wujieyuan @reus @msg7086 考虑 sqlite 是想要把图片分批保存到 sqlite 中, 这样迁移的时候, 就复制一个 sqlite 的文件就好了, 主要是为了迁移方便, 图片主要是为了做 训练使用.
    xingyuc
        11
    xingyuc  
       2020-06-03 14:49:03 +08:00
    按照不同分类大小创建文件夹,然后文件名是 md5,每次上传先找一下有没有一样的……
    luckyrayyy
        12
    luckyrayyy  
       2020-06-03 14:51:04 +08:00
    minio
    wujieyuan
        13
    wujieyuan  
       2020-06-03 14:51:51 +08:00
    @xchaoinfo 文件系统已经是效率最高的存储方式了, 你说的只是小文件复制慢的问题, 这个完全可以在转移的时候批量压缩再复制, 你想把他们在运行期间就集中在一个数据库文件中, 性能损失更大
    rockyou12
        14
    rockyou12  
       2020-06-03 14:54:25 +08:00
    如果你方问慢,很可能是你没做好分文件夹、硬盘分区、文件命名这些,或者是你硬件遇到瓶颈。把图片放进数据来读写一般并不能提高 io……
    ladypxy
        15
    ladypxy  
       2020-06-03 14:56:49 +08:00
    用 zfs 开压缩啊
    Mithril
        16
    Mithril  
       2020-06-03 15:00:06 +08:00   ❤️ 1
    数据库不是设计来保存二进制的。保存文件已经是最经济的办法了。
    觉得零碎文件不够优化的话,你可以自己写。
    直接开一个大文件,然后把你的图片顺序写进去。另外用数据库保存图片的 offset 和大小。读取的时候直接 memory map 到对应位置。
    不过这样相当于你自己实现了部分文件系统的功能,可以感官上减少一定存储空间,并且用 HDD 的话可以较少碎片提高一定性能。
    实际上用处不大。。。
    hakono
        17
    hakono  
       2020-06-03 15:14:25 +08:00   ❤️ 12
    各位别瞎误导 LZ,硬盘分区中的文件系统的确是高效,但对于楼主这种大量零碎文件的存储的场景,直接塞硬盘的文件系统里是非常糟糕的做法。要不然你以为各个大厂都有自己专用的小文件 FS 是为了什么,吃饱了撑的吗

    之前自己开发了一个漫画管理库服务,图片做 hash,然后按照 hash 值 /ab/cd/efdghijk.jpg 的路径保存图片,才区区塞了 20w+张图片,就感觉管理维护起来是个灾难了,然后乖乖用 C 写了个最简单粗暴原始的 FileSystem,立刻性能上了 N 个台阶

    LZ 不想自己写的话,可以使用开源的一些 FS
    https://cloud.tencent.com/developer/news/137215
    PopRain
        18
    PopRain  
       2020-06-03 15:21:19 +08:00
    看文件大小了,不是特别小的文件(小于 4K), 还是放在目录里面高效; 放数据库,备份时、万一文件损坏你会哭死。。。。
    realpg
        19
    realpg  
       2020-06-03 15:41:45 +08:00
    如果文件确实很小,建议自己开发一个专用文件系统,hash 结构 树结构的

    结合你的调用方式,是按批量调用无所谓顺序(机器学习训练材料),还是什么其他的调用方式去优化访问性能

    要不 很多大厂有开源的碎文件 FS 可以试试
    aloxaf
        20
    aloxaf  
       2020-06-03 15:54:55 +08:00   ❤️ 1
    脸书针对这个问题发过一篇论文提出了 haystack 文件系统,很符合你的需求,SeaweedFS 是它的开源实现。
    keepeye
        21
    keepeye  
       2020-06-03 16:00:00 +08:00
    https://github.com/sjqzhang/go-fastdfs
    支持文件合并存储,但要通过接口存取
    sivacohan
        22
    sivacohan  
       2020-06-03 16:01:37 +08:00
    6 、7 年之前,我们处理这种情况是放 leveldb
    msg7086
        23
    msg7086  
       2020-06-03 16:01:45 +08:00
    @hakono 各个大厂的小文件 FS 难道不是为了做大型集群?
    楼主要是打算搞起一柜子存储服务器放个几百 TB 的图,那用小文件 FS 是挺好的。
    如果只是单机的话,ReiserFS 或者 Reiser4 不能胜任吗?

    @xchaoinfo 如果要考虑这种单文件迁移的话,可以看看 tar 包或者无压缩 zip 包,因为没有压缩所以串流起来很方便,可以直接定位便宜然后读数据。
    rrfeng
        24
    rrfeng  
       2020-06-03 16:01:53 +08:00 via Android
    tfs 之类的。
    hdfs 也行。

    文件系统主要是 inode 过多性能就好不到哪里去…
    hankai17
        25
    hankai17  
       2020-06-03 16:02:54 +08:00
    不是服务外网 nginx + 小文件模块 足够了
    yincrow
        26
    yincrow  
       2020-06-03 16:07:24 +08:00
    参考手机中微信的图片目录,文件 hash,切割 hash 值,分段创建层级目录
    37Y37
        27
    37Y37  
       2020-06-03 16:15:10 +08:00
    对象存储很合适啊,类似于阿里的 OSS,网易的 NOS,七牛云之类的
    sherwin008
        28
    sherwin008  
       2020-06-03 16:20:15 +08:00
    adobe bridge 可以吗?我一个非计算机领域人的建议
    matrix67
        29
    matrix67  
       2020-06-03 16:22:01 +08:00
    matrix67
        30
    matrix67  
       2020-06-03 16:22:42 +08:00
    @matrix67 #29 B 站生产就是用毛剑的 bfs 的。
    cjq8z
        31
    cjq8z  
       2020-06-03 16:30:43 +08:00 via Android
    windows server 系统有重复数据删除功能,能够解决你图片占用空间太多问题。再启用 ntfs 压缩功能,提高文件读取速度。
    XiaoxiaoPu
        32
    XiaoxiaoPu  
       2020-06-03 16:43:15 +08:00
    楼上已经提到了 LevelDB,再加一个 RocksDB 吧,支持多线程访问,不支持多进程
    tiedan
        33
    tiedan  
       2020-06-03 17:26:34 +08:00
    hdfs
    ping2
        34
    ping2  
       2020-06-03 17:53:20 +08:00
    其实看有多大了, 4K 大小的话, 直接放内存就好. 千万级也就是几十 GB 直接放内存 /dev/shm/ 就好.

    成本其实还可以接受的.

    落盘同步一下就好了. 根本不用开发, 性能超强, ... 唯一限制就是钱.

    当然下一步是高性能 SSD, XFS 参数调一下其实也还可以接受的.

    如果不接受这个成本, 还要追求性能, 建议是考虑 OSS, 内网调用的性能还可以的.

    再追求更高的性价比才会需要考虑用专门的文件系统或者特定的数据库方案. 除非真的能省很多钱, 不然不建议. 装一台 64GB 的机器省也就是几千不超过一万. 真没有必要搞的太复杂. 专门的文件系统确实好, 但水也深.
    stgmsa
        35
    stgmsa  
       2020-06-03 18:00:51 +08:00
    负责千亿级图床源站的路过,每天源站流量大约 30 亿图片请求。存储是 cassandra,前面挡了一层 12TB 的 nginx file cache 。
    但其实 hbase,甚至文件系统 都可以。
    你要求的量级,可选更是多。

    主要还是要看你有多大访问量(性能),存多久(存储扩展),有没有运维需求和 sla 要求(数据和服务可靠性)。
    love
        36
    love  
       2020-06-03 18:44:38 +08:00 via Android
    我几百万小图存在文件,感觉还行。之前用 ext4 空间没用完 inode 就耗尽了后来换了 inode 无限的 reiserfs 。
    someonedeng
        37
    someonedeng  
       2020-06-03 18:48:31 +08:00
    记得 b 站开源了个不错的 fs
    akira
        38
    akira  
       2020-06-03 19:09:15 +08:00
    对象存储服务啊。。minio 试试看吧 最近在看这个
    CODEWEA
        39
    CODEWEA  
       2020-06-03 19:10:18 +08:00
    数据库就不是 io 了? 而且数据库存储字节化的图片对 io 的操作只多不少。
    ping2
        40
    ping2  
       2020-06-03 19:35:44 +08:00
    @love ext4 inode 数量创建时可以设的, 默认的几百万文件就耗尽的话, 你可能只有 100GB 大小吧?
    cz5424
        41
    cz5424  
       2020-06-03 23:04:12 +08:00
    楼主换个 ssd 吧,提高 io,完事
    wangyzj
        42
    wangyzj  
       2020-06-03 23:11:27 +08:00
    ceph,hdfs
    mosliu
        43
    mosliu  
       2020-06-03 23:41:35 +08:00
    不建议存 db
    hdfs 存海量小文件也不太合适。
    感觉 ceph fastdfs 之类的好点
    或者 minio
    GrayXu
        44
    GrayXu  
       2020-06-03 23:45:24 +08:00
    强力推荐 ceph
    yuyuko
        45
    yuyuko  
       2020-06-04 01:52:20 +08:00 via iPhone
    @stgmsa 你们有对存储做优化吗?
    msg7086
        46
    msg7086  
       2020-06-04 04:35:01 +08:00 via Android
    @ping2 ext4 小文件本来就没有太大优势,不如直接上 reiserfs 了。
    4linuxfun
        47
    4linuxfun  
       2020-06-04 08:31:31 +08:00
    为啥没人推荐 fastdfs 了?我感觉够轻量。以前用 hdfs 存小图片,内存占用比较大,服务重启恢复时间长,自从用了 fastdfs,在也不用担心内存被吃爆、服务重启慢问题了。
    yty2012g
        48
    yty2012g  
       2020-06-04 08:43:16 +08:00
    @jackrelative #8 我居然有幸在工作的时候见过用 blob 类型把图片存 DB 的
    venster
        49
    venster  
       2020-06-04 08:57:40 +08:00 via iPhone
    @yty2012g 以前公司的 OA 系统,所有的附件都直接存数据库,接手维护时简直疯了。
    wbrobot
        50
    wbrobot  
       2020-06-04 08:58:55 +08:00
    唉,凸显年龄了,豆瓣以前有解决方案叫 beansdb 类似 file 的 memcache,后面好像没人维护根据 leveldb 改写了?后面没接着用不知道
    wbrobot
        51
    wbrobot  
       2020-06-04 09:01:39 +08:00
    @wbrobot 看了一下,没错,他们用 go 改写了一版 叫 gobeansdb https://github.com/douban/gobeansdb
    ohao
        52
    ohao  
       2020-06-04 09:10:55 +08:00   ❤️ 2
    我有一个图床,量是亿级规模了, 应该算有发言权的

    这个问题还是取决于你的规划
    比如目前规模,每天的数据增长量,未来一个周期的数据量
    以及是热数据还是冷数据
    你使用数据库存储就是下下策了

    你这种最推荐的是组存储集群 1 源数据+1 副本实现容灾
    集群的存储系统有很多 像 Ceph , GlusterFS 这些都可以

    然后就是软件 , 可以使用
    FastDFS + NGINX
    taobao 开源的 TFS + NGINX
    等等 都开源

    NGINX+imglib 类的库, 可以实现图片常见的操作, 比如改变大小,加水印,翻转 黑白 切割等等操作
    这个处理完成后给 CDN 缓存服务器,意味着后端只需要处理一次图片
    处理完成后请求都在缓存服务器中 不在耗后端性能
    当出现性能请求突发, 需要做的就是加 CDN 缓存服务器提高吞吐能力

    如果考虑成本单机存储也可以
    硬盘使用 SATA 的 8 块 16 块 组 HW 容灾, 文件系统使用 XFS, (XFS 对小文件优化性能有明显的提升)
    在选择前面说的软件搭配
    ming7435
        53
    ming7435  
       2020-06-04 10:10:30 +08:00
    我们目前存在 mongodb 中的,还是单实例,目前已经存储有 3000+kw 图片
    lenqu
        54
    lenqu  
       2020-06-04 10:22:52 +08:00
    我个人认为 Hbase 不错,之前当文件数据库使
    swulling
        55
    swulling  
       2020-06-04 10:36:17 +08:00 via iPhone
    小文件存储你可以理解为 kv,单机推荐用 rocksdb
    jones2000
        56
    jones2000  
       2020-06-04 11:27:24 +08:00
    @ohao 对于机器老化需要更替新机器,一般是如果操作的。 比如公司要求 2-3 年需要把老的机器淘汰掉替换成新的机器和新的硬盘。
    stgmsa
        57
    stgmsa  
       2020-06-04 12:43:58 +08:00
    @yuyuko 没有,meta 和 blob 一起存的。如果一定要问有优化么?那就是 后来上传的图片 key 和 meta 都在 ES 里存了一份。
    规模
    存储 22* 8T * 400 台 * 2 机房
    前端机 40 台 E5-2630v2 +128G,(其实从负载看 20 台就足够了)
    缓存 4 * DC S3510 600 G * 12 台
    shicheng1993
        58
    shicheng1993  
       2020-06-04 12:52:25 +08:00
    可以考虑 swift 对象存储
    hallDrawnel
        59
    hallDrawnel  
       2020-06-04 13:12:47 +08:00
    B 站 CTO 写过一个小文件 FS,忘记叫什么了,就是专门用来存各种小图片的。
    yuyuko
        60
    yuyuko  
       2020-06-04 13:28:04 +08:00 via iPhone
    @stgmsa 我们要做冷数据引擎,针对 hdd smr 做优化来降本。。。以为你们这个量会做优化的。。。你们不做优化的话,成本。。。机架费用就不少吧。。。。
    594duck
        61
    594duck  
       2020-06-04 13:46:53 +08:00
    @hakono 兄弟说话到位的,现在 V2EX 上一堆年轻的战狼程序 员。 你的思路是非常对的。七牛啥的都是按这个思路做的。
    aliyun75
        62
    aliyun75  
       2020-06-04 14:07:10 +08:00
    @xchaoinfo 推荐你阿里云的低频访问类型的 OSS,符合你要求的高读写和多线程读写,我这里还能给你提供优惠,有需求联系我 VX:一三一零一二三四五三九
    stgmsa
        63
    stgmsa  
       2020-06-04 14:49:53 +08:00
    @yuyuko 什么 ? SMR ? 你确定 ? 打算用消费级的硬盘吗 ?
    是你 还是 你们运维 和采购 拍 奶子做的决定?
    不管是谁只要出问题不是你背锅就行。

    如果在国内公司写代码,连硬盘选型采购 都要一个程序员推动的话,还是劝尽早解脱(如果你在 Facebook 这种公司做 SWE,当我没说)。
    我们现在有成本优化方案。不过是通过不断迁移在用数据,淘汰老数据下架来完成的。目前就在做。

    不过说实话,千万级别的图片
    100000000(按 1E 算) * 100 ( 100k 一张) / 1000 (到这是 MB ) / 1000 (到这是 GB ) / 1000 (到这是 TB ) = 10 TB...

    存储大概就是 2-4 台 1U 的小机机 ?
    stgmsa
        64
    stgmsa  
       2020-06-04 15:05:49 +08:00
    @yuyuko 上面提到的 key 信息入 ES 就是为迁移数据做准备的。
    另外作为公共服务,优化存储成本是比较坑爹的事情,业务不像你想的那么配合 那么好推动(当然存储成本甩到业务线这个事就能好办很多)

    前端机我接手之前是 160 台,通过替换缓存+k8s 署了一部分 pod 来抗量,干到 40 台 。
    然而存储一般不会轻易去优化。一来周期会很长,二来沟通人力成本很高。一般存储上架就是一步到位顶 3 年的量的。

    不过从运维角度来讲,如果你采用了不合规的硬件(也包括软件,网络 blablabla ),导致业务受影响了。这个锅可不是一般人能背得起的。轻则开除,重一点 你的直属领导 甚至总监级一起背锅滚蛋。
    不让你赔偿损失就不错了(参考下广告展示多少图,你图床高峰期宕机 1 个小时试试?)

    之前就有同事因为这个被开过(他还没过试用期呢)。优化成本固然没有错。我也是资瓷的。但是一定不要无底线的优化 (你需要清楚的知道自己到底在做什么,而不是一味地追求好数据 好绩效 而玩火)
    stgmsa
        65
    stgmsa  
       2020-06-04 15:16:49 +08:00
    @yuyuko 上面提到的 ceph glusterfs,mongo,hdfs hbase 公司各个业务线都有使用的场景。
    但是…… 不建议从 0 开始就上。

    举个例子,openstack 的虚机数据 和 io 都落在了 ceph 集群上,ceph 吃的裸盘,裸盘上面有 cache tier (好像也是 600G 的 dcs3500 3510 sata ssd,没办法,公司买了太多 消化不完),曾经出现过很多次 因为集群里 某块盘挂了 导致 整个虚拟机集群 io hang 住的情况(基础运维能力太渣的话,技术方案再怎么牛逼也不好用)

    mongo 早些年间(大概是 2015 年?)出现过业务写的太疯狂 导致一个 mongo 吃掉了一整台物理机的资源 影响其他用户的(现在这种情况应该是没有了)

    如果你们的支撑团队牛逼,我想他们会给你一个合理的方案的(比如你们的基础运维团队,在了解到你想用 fs 来搞的时候 会告诉你 XFS 还是 ext4,inode 要不要搞小一点,是走 lvm 还是直接干 ),你的 dba 团队也会根据你的 场景来告诉你 是走 hdfs 还是 走 mongo 就能搞定,还是吃个螃蟹,memorykey + optane 的解决方案。

    多问问他们,他们可能是你这个系统后续 要持续打交道的人。。(他们也不想半夜接到你电话爬起来开电脑不是)
    binux
        66
    binux  
       2020-06-04 15:16:53 +08:00 via Android
    那么多不推荐用 db 的到头来推荐一个为小文件优化过的 fs 。。。
    我说名字就那么重要吗?它是实现成 fs 和还是 db 有区别吗?
    stgmsa
        67
    stgmsa  
       2020-06-04 15:26:35 +08:00
    另外 也不是推荐跟我们一样 用 cassandra 。
    ceph glusterfs 普通的 fs,seaweed 的实现方案产品, 甚至 mongo,mysql 分个库 分个表
    都能实现你的需求。
    主要是 …… 这些东西 哪个你们最熟 出问题了能玩的转
    hankai17
        68
    hankai17  
       2020-06-04 15:43:13 +08:00
    @stgmsa 咨询一下有用过 ats 吗?
    vavava
        69
    vavava  
       2020-06-04 15:43:36 +08:00
    BerkeleyDB,然而维护可能麻烦些,不做频繁删除的话还好
    stgmsa
        70
    stgmsa  
       2020-06-04 15:50:09 +08:00
    @hankai17 apache 那个缓存么? 没用过 ……
    newmlp
        71
    newmlp  
       2020-06-04 17:30:45 +08:00
    相信文件系统就是干这个的,存数据库里纯粹脱了裤子放屁,还有合并成大文件方法也是一样,本质上文件系统也是 offset 磁盘上的物理磁道,
    P0P
        72
    P0P  
       2020-06-05 11:00:10 +08:00
    @newmlp 文件系统维护小文件 metadata 开销很大的,自己合并成大文件,然后记录 offset 的话相当于把 metadata 的维护压力放到用户端来做了
    pythonee
        73
    pythonee  
       2020-06-09 22:00:38 +08:00
    # 好场景

    如果你能说明更加具体的业务场景,读写逻辑,估计 v 站的大神能给出更具体的方案
    yuyuko
        74
    yuyuko  
       2020-06-11 04:48:50 +08:00 via iPhone
    @stgmsa dropbox 就是用的 smr,我们这里已经准备开始搞了,国内三家电商之一。。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2609 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 05:10 · PVG 13:10 · LAX 21:10 · JFK 00:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.