之前的图片都是一个个小文件放在文件夹中, 这样的问题是, 需要的存储空间比较大, 图片迁移也不方便, 而且对 I/O 的消耗非常大. 目前考虑使用数据库来存储, 方案有 lmdb sqlite 请问各位 V 友, 有其他好的方案吗? 能支持多线程读写最好.
|  |      1cco      2020-06-03 14:14:35 +08:00 Hbase 也是可以的。。 | 
|      2hankai17      2020-06-03 14:14:43 +08:00 小文件 io 流量大吗? | 
|  |      3wujieyuan      2020-06-03 14:20:17 +08:00 数据库也是文件存储啊,二进制存到数据库不仅费 io 还费 cpu, 文件应该是利用率最高的存储方式了吧 | 
|      4Jirajine      2020-06-03 14:22:17 +08:00 via Android minio | 
|      5maemual      2020-06-03 14:23:06 +08:00  3 seaweedfs | 
|  |      6msg7086      2020-06-03 14:23:14 +08:00 文件系统就是一个效率很高的数据库了。 你说的这些难道不需要同等的存储空间?不需要消耗那么多 I/O ? | 
|  |      7reus      2020-06-03 14:25:56 +08:00 via Android  4 既然你会考虑 sqlite,我建议你放弃这个想法,信操作系统。 | 
|      8djoiwhud      2020-06-03 14:30:46 +08:00 via Android 你不考虑一下 oss 服务?我只在学生时代见过在 db 中保存图片的。 | 
|      10xchaoinfo OP | 
|  |      11xingyuc      2020-06-03 14:49:03 +08:00 按照不同分类大小创建文件夹,然后文件名是 md5,每次上传先找一下有没有一样的…… | 
|  |      12luckyrayyy      2020-06-03 14:51:04 +08:00 minio | 
|  |      13wujieyuan      2020-06-03 14:51:51 +08:00 @xchaoinfo 文件系统已经是效率最高的存储方式了, 你说的只是小文件复制慢的问题, 这个完全可以在转移的时候批量压缩再复制, 你想把他们在运行期间就集中在一个数据库文件中, 性能损失更大 | 
|  |      14rockyou12      2020-06-03 14:54:25 +08:00 如果你方问慢,很可能是你没做好分文件夹、硬盘分区、文件命名这些,或者是你硬件遇到瓶颈。把图片放进数据来读写一般并不能提高 io…… | 
|      15Dragonish3600      2020-06-03 14:56:49 +08:00 用 zfs 开压缩啊 | 
|      16Mithril      2020-06-03 15:00:06 +08:00  1 数据库不是设计来保存二进制的。保存文件已经是最经济的办法了。 觉得零碎文件不够优化的话,你可以自己写。 直接开一个大文件,然后把你的图片顺序写进去。另外用数据库保存图片的 offset 和大小。读取的时候直接 memory map 到对应位置。 不过这样相当于你自己实现了部分文件系统的功能,可以感官上减少一定存储空间,并且用 HDD 的话可以较少碎片提高一定性能。 实际上用处不大。。。 | 
|      17hakono      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 | 
|  |      18PopRain      2020-06-03 15:21:19 +08:00 看文件大小了,不是特别小的文件(小于 4K), 还是放在目录里面高效; 放数据库,备份时、万一文件损坏你会哭死。。。。 | 
|  |      19realpg PRO 如果文件确实很小,建议自己开发一个专用文件系统,hash 结构 树结构的 结合你的调用方式,是按批量调用无所谓顺序(机器学习训练材料),还是什么其他的调用方式去优化访问性能 要不 很多大厂有开源的碎文件 FS 可以试试 | 
|      20aloxaf      2020-06-03 15:54:55 +08:00  1 脸书针对这个问题发过一篇论文提出了 haystack 文件系统,很符合你的需求,SeaweedFS 是它的开源实现。 | 
|  |      21keepeye      2020-06-03 16:00:00 +08:00 https://github.com/sjqzhang/go-fastdfs 支持文件合并存储,但要通过接口存取 | 
|  |      22sivacohan PRO 6 、7 年之前,我们处理这种情况是放 leveldb | 
|  |      23msg7086      2020-06-03 16:01:45 +08:00 | 
|  |      24rrfeng      2020-06-03 16:01:53 +08:00 via Android tfs 之类的。 hdfs 也行。 文件系统主要是 inode 过多性能就好不到哪里去… | 
|      25hankai17      2020-06-03 16:02:54 +08:00 不是服务外网 nginx + 小文件模块 足够了 | 
|  |      26yincrow      2020-06-03 16:07:24 +08:00 参考手机中微信的图片目录,文件 hash,切割 hash 值,分段创建层级目录 | 
|      2737Y37      2020-06-03 16:15:10 +08:00 对象存储很合适啊,类似于阿里的 OSS,网易的 NOS,七牛云之类的 | 
|  |      28sherwin008      2020-06-03 16:20:15 +08:00 adobe bridge 可以吗?我一个非计算机领域人的建议 | 
|  |      29matrix67      2020-06-03 16:22:01 +08:00 | 
|      31cjq8z      2020-06-03 16:30:43 +08:00 via Android windows server 系统有重复数据删除功能,能够解决你图片占用空间太多问题。再启用 ntfs 压缩功能,提高文件读取速度。 | 
|  |      32XiaoxiaoPu      2020-06-03 16:43:15 +08:00 楼上已经提到了 LevelDB,再加一个 RocksDB 吧,支持多线程访问,不支持多进程 | 
|  |      33tiedan      2020-06-03 17:26:34 +08:00 hdfs | 
|      34ping2      2020-06-03 17:53:20 +08:00 其实看有多大了, 4K 大小的话, 直接放内存就好. 千万级也就是几十 GB 直接放内存 /dev/shm/ 就好. 成本其实还可以接受的. 落盘同步一下就好了. 根本不用开发, 性能超强, ... 唯一限制就是钱. 当然下一步是高性能 SSD, XFS 参数调一下其实也还可以接受的. 如果不接受这个成本, 还要追求性能, 建议是考虑 OSS, 内网调用的性能还可以的. 再追求更高的性价比才会需要考虑用专门的文件系统或者特定的数据库方案. 除非真的能省很多钱, 不然不建议. 装一台 64GB 的机器省也就是几千不超过一万. 真没有必要搞的太复杂. 专门的文件系统确实好, 但水也深. | 
|  |      35stgmsa      2020-06-03 18:00:51 +08:00 负责千亿级图床源站的路过,每天源站流量大约 30 亿图片请求。存储是 cassandra,前面挡了一层 12TB 的 nginx file cache 。 但其实 hbase,甚至文件系统 都可以。 你要求的量级,可选更是多。 主要还是要看你有多大访问量(性能),存多久(存储扩展),有没有运维需求和 sla 要求(数据和服务可靠性)。 | 
|  |      36love      2020-06-03 18:44:38 +08:00 via Android 我几百万小图存在文件,感觉还行。之前用 ext4 空间没用完 inode 就耗尽了后来换了 inode 无限的 reiserfs 。 | 
|  |      37someonedeng      2020-06-03 18:48:31 +08:00 记得 b 站开源了个不错的 fs | 
|  |      38akira      2020-06-03 19:09:15 +08:00 对象存储服务啊。。minio 试试看吧 最近在看这个 | 
|      39CODEWEA      2020-06-03 19:10:18 +08:00 数据库就不是 io 了? 而且数据库存储字节化的图片对 io 的操作只多不少。 | 
|  |      41cz5424      2020-06-03 23:04:12 +08:00 楼主换个 ssd 吧,提高 io,完事 | 
|  |      42wangyzj      2020-06-03 23:11:27 +08:00 ceph,hdfs | 
|  |      43mosliu      2020-06-03 23:41:35 +08:00 不建议存 db hdfs 存海量小文件也不太合适。 感觉 ceph fastdfs 之类的好点 或者 minio | 
|      44GrayXu      2020-06-03 23:45:24 +08:00 强力推荐 ceph | 
|      474linuxfun      2020-06-04 08:31:31 +08:00 为啥没人推荐 fastdfs 了?我感觉够轻量。以前用 hdfs 存小图片,内存占用比较大,服务重启恢复时间长,自从用了 fastdfs,在也不用担心内存被吃爆、服务重启慢问题了。 | 
|      48yty2012g      2020-06-04 08:43:16 +08:00 @jackrelative #8 我居然有幸在工作的时候见过用 blob 类型把图片存 DB 的 | 
|  |      50wbrobot      2020-06-04 08:58:55 +08:00 唉,凸显年龄了,豆瓣以前有解决方案叫 beansdb 类似 file 的 memcache,后面好像没人维护根据 leveldb 改写了?后面没接着用不知道 | 
|  |      51wbrobot      2020-06-04 09:01:39 +08:00 @wbrobot 看了一下,没错,他们用 go 改写了一版 叫 gobeansdb https://github.com/douban/gobeansdb | 
|      52ohao      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 对小文件优化性能有明显的提升) 在选择前面说的软件搭配 | 
|      53ming7435      2020-06-04 10:10:30 +08:00 我们目前存在 mongodb 中的,还是单实例,目前已经存储有 3000+kw 图片 | 
|      54lenqu      2020-06-04 10:22:52 +08:00 我个人认为 Hbase 不错,之前当文件数据库使 | 
|  |      55swulling      2020-06-04 10:36:17 +08:00 via iPhone 小文件存储你可以理解为 kv,单机推荐用 rocksdb | 
|      56jones2000      2020-06-04 11:27:24 +08:00 @ohao 对于机器老化需要更替新机器,一般是如果操作的。 比如公司要求 2-3 年需要把老的机器淘汰掉替换成新的机器和新的硬盘。 | 
|  |      57stgmsa      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 台 | 
|      58shicheng1993      2020-06-04 12:52:25 +08:00 可以考虑 swift 对象存储 | 
|  |      59hallDrawnel      2020-06-04 13:12:47 +08:00 B 站 CTO 写过一个小文件 FS,忘记叫什么了,就是专门用来存各种小图片的。 | 
|      60yuyuko      2020-06-04 13:28:04 +08:00 via iPhone @stgmsa 我们要做冷数据引擎,针对 hdd smr 做优化来降本。。。以为你们这个量会做优化的。。。你们不做优化的话,成本。。。机架费用就不少吧。。。。 | 
|  |      61594duck      2020-06-04 13:46:53 +08:00 @hakono  兄弟说话到位的,现在 V2EX 上一堆年轻的战狼程序 员。 你的思路是非常对的。七牛啥的都是按这个思路做的。 | 
|  |      62aliyun75      2020-06-04 14:07:10 +08:00 @xchaoinfo 推荐你阿里云的低频访问类型的 OSS,符合你要求的高读写和多线程读写,我这里还能给你提供优惠,有需求联系我 VX:一三一零一二三四五三九 | 
|  |      63stgmsa      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 的小机机 ? | 
|  |      64stgmsa      2020-06-04 15:05:49 +08:00 @yuyuko 上面提到的 key 信息入 ES 就是为迁移数据做准备的。 另外作为公共服务,优化存储成本是比较坑爹的事情,业务不像你想的那么配合 那么好推动(当然存储成本甩到业务线这个事就能好办很多) 前端机我接手之前是 160 台,通过替换缓存+k8s 署了一部分 pod 来抗量,干到 40 台 。 然而存储一般不会轻易去优化。一来周期会很长,二来沟通人力成本很高。一般存储上架就是一步到位顶 3 年的量的。 不过从运维角度来讲,如果你采用了不合规的硬件(也包括软件,网络 blablabla ),导致业务受影响了。这个锅可不是一般人能背得起的。轻则开除,重一点 你的直属领导 甚至总监级一起背锅滚蛋。 不让你赔偿损失就不错了(参考下广告展示多少图,你图床高峰期宕机 1 个小时试试?) 之前就有同事因为这个被开过(他还没过试用期呢)。优化成本固然没有错。我也是资瓷的。但是一定不要无底线的优化 (你需要清楚的知道自己到底在做什么,而不是一味地追求好数据 好绩效 而玩火) | 
|  |      65stgmsa      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 的解决方案。 多问问他们,他们可能是你这个系统后续 要持续打交道的人。。(他们也不想半夜接到你电话爬起来开电脑不是) | 
|  |      66binux      2020-06-04 15:16:53 +08:00 via Android 那么多不推荐用 db 的到头来推荐一个为小文件优化过的 fs 。。。 我说名字就那么重要吗?它是实现成 fs 和还是 db 有区别吗? | 
|  |      67stgmsa      2020-06-04 15:26:35 +08:00 另外 也不是推荐跟我们一样 用 cassandra 。 ceph glusterfs 普通的 fs,seaweed 的实现方案产品, 甚至 mongo,mysql 分个库 分个表 都能实现你的需求。 主要是 …… 这些东西 哪个你们最熟 出问题了能玩的转 | 
|  |      69vavava      2020-06-04 15:43:36 +08:00 BerkeleyDB,然而维护可能麻烦些,不做频繁删除的话还好 | 
|  |      71newmlp      2020-06-04 17:30:45 +08:00 相信文件系统就是干这个的,存数据库里纯粹脱了裤子放屁,还有合并成大文件方法也是一样,本质上文件系统也是 offset 磁盘上的物理磁道, | 
|      72P0P      2020-06-05 11:00:10 +08:00 @newmlp 文件系统维护小文件 metadata 开销很大的,自己合并成大文件,然后记录 offset 的话相当于把 metadata 的维护压力放到用户端来做了 | 
|  |      73pythonee      2020-06-09 22:00:38 +08:00 # 好场景 如果你能说明更加具体的业务场景,读写逻辑,估计 v 站的大神能给出更具体的方案 |