16

我们有一个存储(个位数)数百万张图像的系统,大小从 8KB 到 500KB 不等,中位数约为 15KB,平均为 30KB。总数据集目前约为 100GB。我们希望基于图像的哈希访问图像(这可以更改,但它需要可以从图像计算,以便有效地检查图像是否已经在数据存储中 - 图像被处理,使得两个如果图像是逐字节相同的,则图像是逐像素相同的)。坚持(显然)很重要。

目前我们将它们全部作为文件存储在一个目录中——目录列表被内核缓存,实际的文件读取是根据需要完成的。据我了解,键值存储(与使用文件系统相比)的主要优点是读取较小的值,因为可以缓存整个页面,而不仅仅是单个值。当前所有访问都来自与数据位于同一服务器上的 Web 服务器(在 Intranet 上),尽管我们可能会检查是否存在来自远程机器的密钥(主要通过 10GbE 连接)。

没有任何特别的理由来改变它,尽管随着系统的其他主要部分发生变化,重新考虑当前的方法似乎是值得的。

给定一个工作负载,其读取主要是(单次)按插入顺序读取和随机(尽管很可能重复)访问任意键,除了频繁的写入(大约 1:10 的写入:读取),是否有可能从文件系统迁移到键值存储有多大优势?

4

4 回答 4

14

摘要: 为了满足您对数据完整性、持久性、大小和速度的要求,我推荐Redis

在这里可以看到一个很好的介绍演示:
https ://simonwillison.net/static/2010/redis-tutorial/

nb 更多信息会有所帮助,但根据您提供的内容+我所知道的,这里有一些主要参与者:

Memcached:
https
://memcached.org/ 一个免费、开源、高性能的分布式内存对象缓存系统,适用于加速动态 Web 应用程序。
+适用于 Web 应用程序,免费,开源。
-如果服务器宕机(memcached 进程失败或系统重新启动),所有会话都将丢失。较高(商业用途)级别的性能限制。

Redis:
https
://redis.io/ 与 memcached 类似,但具有数据持久性,支持多种值类型,具有原子增量/减量的计数器和内置键过期。
+将数据保存到磁盘因此永远不会丢失,非常简单,速度,灵活性(键可以包含字符串,散列,列表,集合和排序集合),分片,由 vmware 而不是个人维护。
-有限的聚类。

LevelDB:
https
://google-opensource.blogspot.com/2011/07/leveldb-fast-persistent-key-value-store.html Google 编写的快速键值存储引擎,可将字符串键映射到字符串值。
+谷歌。
-?可以使用 Google + ;)

TokoyoCabinet:
https
://fallabs.com/tokyocabinet/ 包括对锁定、ACID 事务、二进制数组数据类型的支持。
+ 速度和效率。
- 在某些地区鲜为人知,例如美国

Project Voldemort:
https
://project-voldemort.com/ 一个高级键值存储,用 Java 编写。为更新提供多版本并发控制 (MVCC)。对副本的更新是异步完成的,因此不能保证数据一致。
+功能
-一致性

MongoDB:
https
://www.mongodb.org/ 一个可扩展的、高性能的、开源的、面向文档的数据库。用 C++ 编写,具有复制和高可用性,具有跨 LAN 和 WAN 的镜像以及自动分片。在 Ruby on Rails 社区中很受欢迎。
+易于安装,良好的文档,支持。
-相对较新。

Couch: http:
//www.couchdb.org/
类似于 Mongo,针对文档数据库。
+复制、高级查询。
-集群,磁盘空间管理。

Cassandra:
https
://cassandra.apache.org/ Apache Cassandra 具有容错性和分散性,并在 Netflix、Twitter 和 Reddit 等网站上使用。
+集群和复制。
-需要更多设置知识。

由于时间不够,我无法提供所有参考资料,但希望这至少会有所帮助。

于 2011-11-25T14:24:09.823 回答
11

根据

  • 文件数
  • 你如何在 FS 上构建它们
  • 您正在使用哪个 FS
  • 您正在使用哪种存储设备

您可能最终会用完 inode,或者再次访问文件的时间可能很慢(例如,如果您在单个目录中放置了太多条目)。

您还必须小心以原子方式访问文件(和/或创建目录),而 KV 存储通常会为您处理这些。

过去,我在使用 fs-as-key-value-store 方法时遇到了所有这些问题:)。

但它可以做到,例如Bigdis,它是 redis KV 协议的实现,作为文件上的文件,来自 redis 作者自己,但你必须小心你的操作。

根据您的问题,您可能会发现MogileFS或直云 S3 是更好的解决方案。

于 2011-11-26T10:02:14.823 回答
2

您提供的信息太少,无法给出具体答案 - 因此只是与您描述的内容相关的一些方面:

  • 数据完整性
    这可以是任何东西 - 即应禁止未经授权的数据更改和/或至少应检测到任何此类事件......或者它可能只是“RAID 和/或备份......”领域中的东西。

  • “相同图像”
    图像文件包含多个元数据字段/区域...如果一个具有元数据而另一个没有(或某些元数据字段不同),您的方法会导致看到两个逐像素相同的图像是不同的...是那你想要什么?
    该领域的另一个方面是文件格式(PNG 与 BMP 与 JPEG 等)和压缩...相同的图像和不同的格式和/或压缩算法(甚至像 ZIP 与 LZW 之类的无损算法,JPEG 等更糟)可能导致将相同的图像归类为不同的图像 - 这是你想要的吗?

  • “成千上万的图像”和“2 KB - 10 MB”
    并没有说太多......即中位数与平均图像/文件大小是多少?

  • 访问
    对这些文件/图像的访问是否已分发(如在 CDN 中)?还是基于局域网?

还有许多其他方面与您描述的内容相关......

如果没有任何进一步和真正具体的信息,我会认为任何统计数据/基准/建议充其量都是幸运的。

可能的解决方案包括例如分布式系统(可以是基于文件系统/内存/数据库的)和/或基于 SSD 和/或 RAID 和/或 SAN 等的存储。

您感兴趣的“KeyValueStore”点可能是相关的,但在大多数情况下,处理我遇到的此类商店的大量图像不会添加任何独特的功能(在某些情况下甚至会受到伤害)。

于 2011-11-23T11:36:17.907 回答
0

如果您的数据小于 1TB,则您可能不需要高可用性 NoSQL 数据库,并且大多数 NoSQL 数据库都要求将数据保存在 RAM 中。我是否可以建议使用沼泽标准关系数据库并使用哈希作为主键并使用您的数据创建一个 blob 表?您会惊讶于它的性能,而且您不必担心 inode 会用完。

如果您的数据是文本/可压缩的,则关系数据库会更好。根据我的经验,很少有 NoSQL 数据库会为您压缩数据,您必须在客户端进行压缩。但是 MySQL/MariaDB 提供透明压缩。

另一种选择是 RocksDB。对于某些用例,它非常适合磁盘空间,因为它支持使用自定义字典进行 zstd 压缩。

于 2019-12-25T00:17:42.047 回答