代码之家  ›  专栏  ›  技术社区  ›  Alex

存储许多缩略图的有效方法

  •  0
  • Alex  · 技术社区  · 5 年前

    因此,目前我将所有缩略图存储在一个目录中,文件名为全尺寸图像完整路径的md5哈希值。但我在这里读到,当目录达到数千个文件时,这会导致问题。它们在linux文件系统中的定位速度会越来越慢。

    考虑到我只能通过原始图像路径定位缩略图,我有什么选择?日期是最好的选择,比如 year/month/day/md5_hash.jpg ,但这需要我从某个地方存储和读取日期,因此需要添加一些额外的步骤。

    我在考虑拆分md5,就像前两个字符=子文件夹名称,rest=文件名。这会给我15*15个子文件夹,但我想听听更好的选择,谢谢!


    我刚刚想到的另一个想法是:创建一个单独的服务器来组织缩略图。服务器将跟踪缩略图计数,并在达到一定限制时创建其他文件夹,并在删除拇指时重用旧文件夹。缺点是我需要一个单独的数据库,将哈希映射到缩略图路径:(

    0 回复  |  直到 5 年前
        1
  •  6
  •   Tigger    5 年前

    我们使用FreeBSD(文件系统UFS),而不是Linux,所以一些细节可能会有所不同。

    背景

    我们在这个系统上有数百万个文件,需要尽快从网站上提供,供个人访问。我们使用的系统在过去16年里一直运行良好。

    服务器1(名为:Tom)的主用户网站具有相当标准的Apache设置和MySQL数据库。没什么特别的。

    服务器2(名为:Jerry)是存储用户文件的地方,并且经过定制,可以快速交付这些小文件。

    Jerry的硬盘在创建过程中进行了调整,以确保我们不会用完索引节点——这是创建数百万个小文件时需要考虑的问题。

    Jerry的Apache配置进行了调整,以实现非常短的连接时间和每个连接的单个文件访问。如果没有这些调整,你就会有开放的连接,浪费资源。这个Apache配置根本不适合主系统(Tom),并会导致许多问题。

    由于你提供的是“缩略图”,而不是单个请求,你可能需要一个稍微不同的结构。说实话,我对你的需求了解得还不够,无法真正建议什么最适合你的Web服务器配置。

    从历史上看,我们在多台服务器上使用了多个SCSI驱动器。目前,我们有一台配备300MB/s驱动器的服务器。该业务已经下滑了一段时间(多亏了脸书),但我们每天仍有200多万个文件请求。在我们的高峰期,每天大约有1000万。

    我们的结构(一个可能的答案)

    Jerry上的所有内容都针对小文件传输进行了调整,没有其他内容。

    Jerry是一个网络服务器,但我们更像是一个数据库。所有不需要的东西都被删除了。

    每个文件都有一个4个字符的ID。ID是字母数字(0-9,a-z,a-z)。这将为您提供61*61*61x61个组合(或13845841个ID)。

    我们也有多个域,因此每个域最多有13845841个ID。在Facebook出现之前,我们已经非常接近这个限制,我们已经准备好了允许5个字符ID的计划,但最终并不需要它。

    如果你知道文件的完整路径,文件系统查找会非常快。只有当你需要扫描文件匹配时,它才会很慢。我们充分利用了这一点。

    每个4个字符的id是一系列目录。例如, aBc9 /path/to/a/B/c/9 .

    这是一个非常多的唯一ID,仅分布在4个目录中。每个目录最多有61个子目录。在不淹没文件系统索引的情况下创建快速查找。

    位于目录中 ./9 (ID中的最后一个目录)是必要的元数据文件和原始数据文件。元数据是一个已知的文件名,数据文件也是如此。每个文件夹中还有其他已知的文件,但你会明白的。

    如果用户正在更新或检查元数据,则ID是已知的,因此会返回对元数据的请求。

    如果再次请求数据文件,则ID是已知的,因此返回数据。不进行扫描或复杂的检查。

    如果ID无效,则返回无效结果。

    没什么复杂的,一切都是为了速度。

    我们的问题

    当你谈论数百万个小文件时,可能会用完索引节点。请确保从一开始就将此因素纳入服务器的磁盘创建中。提前计划。

    我们禁用和/或编辑了许多FreeBSD系统检查。维护cronjobs不是为具有如此多文件的系统设计的。

    Apache配置是一个有点试错的过程,以使其恰到好处。当你得到它时,解脱是巨大的。Apache的 mod_status 非常有帮助。

    首先要做的是禁用所有日志文件。接下来,禁用所有内容,只添加您需要的内容。

    元数据和原始数据的交付(和保存)代码也进行了非常优化。忘记代码库。多年来,每一行代码都经过了速度检查和重新检查。

    结论

    如果你真的有很多缩略图,请拆分系统。从为此而优化的专用服务器上提供小文件。保持主系统的调整,以实现更标准的使用。

    基于目录的ID系统(可以是随机的4个字符或MD5的一部分)可以很快,只要你不需要扫描文件。

    您的基础操作系统需要调整,这样系统检查就不会占用您的系统资源。

    禁用Web服务器日志文件创建。您几乎永远不需要它,它会在文件系统上造成瓶颈。如果你需要统计数据,你可以从以下网址获得总体概述 mod_status .

    说实话,关于你的个人情况和需求,我们了解的信息还不够。我不确定我的个人经历是否会有所帮助。

    祝你好运!

        2
  •  4
  •   Jawad Al Shaikh    5 年前

    最佳、高效、最小和最简单的方法是 SeaweedFS

    自2017年以来,我一直在使用 海藻FS 每24小时存储约400万张JPEG。目前,DB拥有超过20亿条记录。我从来没有遇到过任何问题,与存储为文件系统文件相比,它节省了大量的磁盘空间。

    以下是作者简介:

    SeaweedFS是一个简单且高度可扩展的分布式文件系统。 有两个目标:

    1. 存储数十亿个文件!
    2. 快速送达文件!

    细节:

    我的项目包含每个事件的2张图片,一张是缩略图,另一张是全帧。在项目的第一阶段,我将图像存储为具有目录结构的文件 year/month/day/[thumb|full].jpg 但几天后,我不得不浏览文件,这是一场噩梦,磁盘响应很慢。如果删除大量文件(超过百万),则需要几个小时。所以我决定研究谷歌、脸书、instagram和推特等大公司是如何存储数十亿张图片的,我发现了几个youtube视频解释了部分架构,然后我遇到了 SeaweedFS 我尝试了一下,快速查看了源代码“0.76版本”,一切似乎都很好,“没有可疑代码”。
    唯一值得注意的是,徽标是通过CDN而不是本地获取的。

    美丽的 seaweedFS 在于它的简单性和稳定性,它是一种隐藏的宝石(直到现在才猜到)。除了能够存储数十亿个文件并在几毫秒内访问它们外,它还可以根据以下内容自动清除文件 TTL ,这是一个非常有用的功能,因为大多数客户的存储空间有限,因此他们无法永远保存所有数据。我喜欢它的第二点是节省了大量的存储空间,例如:

    在我的服务器中,每个文件都在消耗 Multiple of 8 KB 从磁盘空间(由于文件系统结构),即使我的大多数缩略图的大小为 1 or 2 KB 它消耗 8 KB ,所以当你把所有浪费的字节加起来时,你最终会浪费很大一部分存储空间,在SeaWeedFS中,每个文件元数据都需要额外的 40 bytes 只是,这是一笔遗产!。

    希望这能有所帮助。

        3
  •  1
  •   Faraaz Malak    5 年前

    如果你使用md5的前2个字符作为文件夹名称,并假设你有100个缩略图,其中只有2个缩略图共享前2个文件名字符,你很快就会遇到文件系统速度慢的问题。

    你能分享一下原始图像存储的目录结构吗?

    也许,您可以根据原始图像的创建日期创建缩略图目录结构?

    假设原始图像是在 3rd May 2019 ,则缩略图目录结构可以是 thumbnails/52019/abc123.jpg (考虑 abc123 成为哈希)

    因此,要定位上述缩略图,您需要:

    1. 读取原始图像的创建日期
    2. 计算原始图像完整路径的md5哈希值(在这种情况下,它是 abc123 )
    3. 前往 thumbnails 文件夹
    4. 根据原始图像的创建日期找到子文件夹。在这种情况下,它是 52019
    5. 使用原始图像完整路径的哈希值搜索文件

    希望这能很好地回答你的问题。

        4
  •  1
  •   x00    5 年前

    我读过 当目录到达时,这会导致问题 数千 文件

    1. 在我看来,优化还为时过早。你担心 数千 。但现在我有大约10000个文件 ~/.cache/thumbnails 目录,我对此没有问题。你真正需要多少个缩略图?让他们!然后测试你的表现。

    2. 你在哪里读到的?那里描述的具体问题是什么?因为从 this this 你可以想象,即使在一个目录中有50万个文件,你也可以很快地访问它们。是的,当你使用一些大型目录时,你会很难处理它们 工具 (比如 ls ),但请确保您可以更好地编写服务器。

    3. 而且,作为一种选择,您可以创建并行目录结构。因此,对于一个文件 z/y/x/image.png 缩略图转到 thumbnails/z/y/x/image.png 。这样您将获得以下好处:

      1. 人类可读性
      2. 在出现错误的情况下,轻松区分原始图像和缩略图的目录树
      3. 不需要md5哈希
      4. 更简单的代码,以防您需要一些批处理操作(例如从中删除文件的所有缩略图 z/y/x/ )

      它也可以更有效率。但我不确定——测试一下。

        5
  •  1
  •   Luctia    5 年前

    我不确定你正在构建什么样的应用程序,但根据用户数量、服务器速度和缩略图访问频率,你可能会使用类似缓存的系统?按照您的建议使用MD5哈希存储生成的缩略图,并在一定时间后将其删除。如果缩略图主要是在图像第一次放在服务器上时访问的,并且随着时间的推移,它们的使用会减少,那么你可以删除它们(在半夜,或者在使用最少的时候),如果需要再次生成它们,只要不经常这样做。

    根据原始文件的目录结构,您可能有另一种选择,即将原始文件分离到目录中,并将缩略图存储在其原始目录中的某个目录中。这样,如果你知道原始的路径,你就已经知道缩略图的大部分路径了。