我们有一个存储(单位数字)数百万张图像的系统,大小从8KB到500KB不等,中位数大约为15KB,平均为30KB。总数据集目前约为100GB。我们希望基于图像的散列来访问图像(这个
目前我们将它们全部存储为目录中的文件 - 内核缓存目录列表,并根据需要进行实际的文件读取。据我了解,键值存储的主要优点(与使用文件系统为一体)是读取较小的值,因为整个页面可以缓存,而不是只有一个值。所有访问当前来自与数据在同一服务器上的Web服务器(在Intranet上),但我们可能会检查是否存在来自远程计算机的密钥(主要通过10GbE连接)。
没有任何特别的理由可以改变它,虽然系统的其他主要部分发生了变化,但重新考虑当前的方法似乎是值得的。
给定一个工作负载,其读取主要是(单个)读取插入顺序和随机(尽管很可能重复)访问任意键,除了频繁写入(大小为1:10写入:读取),从文件系统迁移到键值存储可能有很大的优势吗?
答案 0 :(得分:13)
摘要:满足您对数据完整性,持久性,大小和数据的要求速度我建议 Redis 。
这里可以看到一个很好的介绍演示:
https://simonwillison.net/static/2010/redis-tutorial/
n.b。更多信息会有所帮助,但根据你给出的内容+我所知道的,这里有一些主要的参与者:
<强> 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
- ?可以使用Google +;)
<强> TokoyoCabinet:强>
https://fallabs.com/tokyocabinet/
包括对锁定,ACID事务,二进制数组数据类型的支持
+速度和效率。
- 某些地区鲜为人知,例如: US
Project Voldemort:
https://project-voldemort.com/
一个用Java编写的高级键值存储。为更新提供多版本并发控制(MVCC)。副本的更新是异步完成的,因此不保证数据的一致性
+ 功能
- 一致性
<强> MongoDB的:强>
https://www.mongodb.org/
一个可扩展,高性能,开源,面向文档的数据库。用C ++编写的功能复制&amp;具有LAN和WAN镜像和自动分片功能的高可用性。受欢迎的Ruby on Rails社区。
+ 易于安装,良好的文档,支持
- 相对较新。
<强>榻:强>
http://www.couchdb.org/
与Mongo类似,针对文档数据库
+ 复制,高级查询
- 群集,磁盘空间管理。
<强>卡桑德拉:强>
https://cassandra.apache.org/
Apache Cassandra具有容错性和分散性,可用于Netflix,Twitter和Reddit等。
+ 群集和复制。
- 需要更多设置知识。
由于时间不够,我无法提供所有参考资料,但希望这至少有帮助。
答案 1 :(得分:10)
取决于
您可能最终耗尽inode,或者可能再次访问文件的速度很慢(例如,如果您在单个目录中放置了太多条目)。
您还必须小心谨慎地访问文件(和/或创建目录),而KV商店通常会为您处理。
我过去使用fs-as-key-value-store方法遇到了所有这些问题:)。
但是可以这样做,请参阅例如Bigdis这是redis KV协议的实现,作为磁盘上的文件,来自redis作者本人,但你必须对你的操作有点小心。
根据您的问题,您可能会发现MogileFS或直接混浊的S3是更好的解决方案。
答案 2 :(得分:2)
您提供的信息太少,无法提供具体答案 - 因此只是与您所描述的内容相关的一些方面:
数据完整性
这可以是任何事情 - 即应禁止未经授权的数据更改和/或至少可以检测到任何此类事件......或者它可能只是“RAID和/或备份...”区域中的某些内容。
“相同的图像”
图像文件包含多个元数据字段/区域......如果一个元素具有元数据而另一个没有(或某些元数据字段不同),您的方法会导致两个像素相同的图像看起来不同... ...就是你想要的?
该领域的另一个方面是文件格式(PNG与BMP对比JPEG等)和压缩...相同的图像和不同的格式和/或压缩算法(甚至无损的,如ZIP与LZW,更糟糕的是JPEG等)可能导致将相同的图像分类为不同的 - 是你想要的吗?
“数十万张图片”和“2 KB - 10 MB”
这并没有多说......即中位数与平均图像/文件大小是什么?
访问
是否分发了对这些文件/图像的访问(如CDN)?或者它是基于LAN的吗?
还有许多与你描述的内容相关的其他方面......
如果没有任何进一步的,非常具体的信息,我会认为任何统计/基准/推荐都是最好的幸运。
可能的解决方案包括例如分布式系统(可以是基于文件系统/内存/数据库)和/或基于SSD和/或RAID和/或SAN等的存储。
您感兴趣的“KeyValueStore”点可能是相关的,但在大多数情况下,我遇到这样一个商店的图像数量不会添加任何独特的功能(在某些情况下甚至会受到伤害)。
答案 3 :(得分:0)
如果您的数据不足1TB,则可以说不需要高可用性NoSQL数据库,并且大多数NoSQL数据库都要求将数据保留在RAM中。我是否建议使用沼泽标准的关系数据库,并创建一个以哈希作为主键,并使用数据blob的表?您会惊讶于它的性能如何,并且您不必担心会耗尽inode。
如果您的数据是文本/可压缩的,则关系数据库甚至更好。以我的经验,很少有NoSQL数据库会为您压缩数据,您必须在客户端进行压缩。但是MySQL / MariaDB提供透明的压缩。
另一个选项是RocksDB。在某些用例中,这非常适合磁盘空间,因为它支持带有自定义字典的zstd压缩。