可以持久保存到磁盘的 memcached 的替代品

Posted

技术标签:

【中文标题】可以持久保存到磁盘的 memcached 的替代品【英文标题】:alternative to memcached that can persist to disk 【发布时间】:2010-11-21 22:59:13 【问题描述】:

我目前正在将 memcached 与我的 java 应用程序一起使用,总的来说它运行良好。

memcached 对我来说最重要的特性是:

速度很快,因为读取和写入都在内存中,不会触及磁盘 它只是一个键/值存储(因为这就是我的应用程序所需要的全部) 已分发 它通过让每个对象恰好位于一台服务器上来有效地使用内存 它不假定对象来自数据库(因为我的对象不是数据库对象)

但是,我想做的一件事是 memcached 做不到的。我想定期(可能每天一次)将缓存内容保存到磁盘。我希望能够从保存的磁盘映像中恢复缓存。

磁盘保存不需要非常复杂。如果在保存时添加了新的键/值,我不在乎它是否包含在保存中。如果在保存时修改了现有键/值,则保存的值应该是旧值或新值,但我不在乎哪一个。

谁能推荐另一种缓存解决方案(免费或商业),它具有所有(或很大比例)对我很重要的 memcached 功能,并且还允许从磁盘保存和恢复整个缓存?

【问题讨论】:

只是好奇,为什么要保存内容并恢复回来? 感谢您的回复。我可能会先尝试 Redis,因为它最接近我的需要,但我需要做一些测试来验证它的稳健性。我们想做一个日常保存,我们几乎永远不会使用它。如果缓存被清除,我们只会从磁盘进行恢复,这可能只有在服务器重新启动时才会发生。从磁盘恢复比重新生成对象更可取,因为除了延迟之外,我们还会访问第三方服务器,并且在短时间内重新生成大量对象可能会导致我们超过第三方服务器的使用上限-派对服务器。 次要的 nitpick:memcache 并没有像通常使用的术语那样真正分布;它是分片的。分布通常意味着实例之间存在某种程度的协调,而 meccached 明确避免了这种协调。 @MikeW MIke,进展如何?我希望您对测试提供意见,因为我面临同样的情况。如果您可以分享您的测试结果以及您采取了哪些选择,那就太好了。谢谢。 【参考方案1】:

我从未尝试过,但是 redis 呢? 它的主页说(引用):

Redis 是一个键值对数据库。它是 类似于 memcached 但数据集 不是易失性的,并且值可以是 字符串,就像在 memcached 中一样, 但也可以列出和设置原子 推送/弹出元素的操作。

为了非常快但在 同时持久化整个数据集 被记在记忆中,不时地 时间和/或当一些变化 对数据集执行它是 异步写入磁盘。你 可能会丢失最后几个查询 在许多应用中可以接受,但它 与内存数据库一样快(Redis 支持非阻塞主从 复制以解决此问题 冗余问题)。

它似乎回答了你谈到的一些观点,所以对你来说也许它可能会有所帮助?

如果你尝试一下,我对你的发现很感兴趣,顺便说一句;-)

附带说明:如果您需要将所有这些写入磁盘,也许 cache 系统并不是您真正需要的......毕竟,如果您使用 memcached 作为 cache,您应该能够在必要时按需重新填充它——不过,我承认,如果您的整个 memcached 集群同时崩溃,可能会出现一些性能问题......

那么,也许一些“更多”的面向键/值存储的软件会有所帮助?例如CouchDB 之类的东西? 它可能不会像 memcached 那样快,因为数据不是存储在 RAM 中,而是存储在磁盘上...

【讨论】:

您当然可以在启动时重新填充缓存,但是对于高流量的大型数据集来说,加热它们的成本很高。 CouchDB 很慢,所以我认为它不会在这里工作。 Redis 是具有持久性的出色单节点缓存,但不支持分布式设置。【参考方案2】:

你看过BerkeleyDB吗?

快速、嵌入式、进程内数据管理。 键/值存储,非关系型。 永久存储。 免费、开源。

但是,它不符合您的条件之一:

BDB 支持分布式复制,但数据未分区。每个节点都存储完整的数据集。

【讨论】:

BDB 被用作支持分区的 Oracle NoSQL 产品的基础。【参考方案3】:

看看Apache Java Caching System (JCS)

JCS 是一个分布式缓存系统 用java写的。它旨在 通过提供一个加速应用程序 管理各种缓存数据的方法 动态性质。像任何缓存一样 系统,JCS是最有用的高 阅读,低投入应用。潜伏 时间急剧下降和瓶颈 从数据库中移出 有效缓存系统。学习怎样 开始使用 JCS。

JCS 超越了简单的缓存 内存中的对象。它提供 许多附加功能:

* Memory management
* Disk overflow (and defragmentation)
* Thread pool controls
* Element grouping
* Minimal dependencies
* Quick nested categorical removal
* Data expiration (idle time and max life)
* Extensible framework
* Fully configurable runtime parameters
* Region data separation and configuration
* Fine grained element configuration options
* Remote synchronization
* Remote store recovery
* Non-blocking "zombie" (balking facade) pattern
* Lateral distribution of elements via HTTP, TCP, or UDP
* UDP Discovery of other caches
* Element event handling
* Remote server chaining (or clustering) and failover
* Custom event logging hooks
* Custom event queue injection
* Custom object serializer injection
* Key pattern matching retrieval
* Network efficient multi-key retrieval

【讨论】:

【参考方案4】:

我们正在使用OSCache。我认为它几乎可以满足您的所有需求,除了定期将缓存保存到磁盘,但是您应该能够创建 2 个缓存管理器(一个基于内存,一个基于硬盘)并定期运行 java cronjob 来遍历所有内存缓存键/值对并将它们放入硬盘缓存中。 OSCache 的优点在于它非常易于使用。

【讨论】:

【参考方案5】:

也许你的问题和我的一样:我只有几台机器用于 memcached,但有很多内存。即使其中之一发生故障或需要重新启动,也会严重影响系统的性能。根据最初的 memcached 理念,我应该为每台机器添加更多内存更少的机器,但这并不划算,也不完全是“绿色 IT”;)

对于我们的解决方案,我们为缓存系统构建了一个接口层,以便底层缓存系统的提供程序可以嵌套,就像您可以对流做的那样,并为 memcached 编写了一个缓存提供程序以及我们自己非常简单的 Key-Value-2-disk storage provider。然后我们为缓存项定义一个权重,表示如果无法从缓存中检索到该项,则重建该项的成本是多少。嵌套磁盘缓存仅用于权重超过某个阈值的项目,可能占所有项目的 10% 左右。

当在缓存中存储对象时,我们不会浪费时间,因为保存到一个或两个缓存中都会排队等待异步执行。所以写入磁盘缓存不需要很快。读取也一样:首先我们使用 memcached,并且只有当它不存在并且它是一个“昂贵”的对象时,我们才会检查磁盘缓存(它比 memcached 慢很多数量级,但仍然比重新计算 30 GB 的缓存要好得多单机宕机后的数据)。

通过这种方式,我们可以两全其美,而无需用任何新东西替换 memcached。

【讨论】:

缓存的好方法!喜欢你的体重想法【参考方案6】:

Terracotta 呢?

【讨论】:

【参考方案7】:

您可以使用GigaSpaces XAP,这是一个成熟的商业产品,可以满足您的需求等等。它是最快的分布式内存数据网格(cache++),完全分布式,支持多种风格的持久化方式。

Guy Nirpaz, 千兆空间

【讨论】:

【参考方案8】:

EhCache 有一个“磁盘持久化”模式,它在关机时将缓存内容转储到磁盘,并在再次启动备份时恢复数据。至于您的其他要求,在分布式模式下运行时,它会在所有节点之间复制数据,而不是仅将它们存储在一个节点上。除此之外,它应该很好地满足您的需求。它还在积极开发中,而许多其他 java 缓存框架还没有。

【讨论】:

我使用 EhCache 为 Java 构建了一组持久性集合,效果很好。 @skaffman 感谢您在当前版本中指向 EhCache,它最灵活并满足了我的需求。 容错持久性磁盘使用仅限企业,需要许可证。【参考方案9】:

根据我的经验,最好在应用程序和后端存储之间编写一个中间层。通过这种方式,您可以配对 memcached 实例,例如 sharedanced(基本相同的键值存储,但基于磁盘)。最基本的方法是,始终从 memcached 读取并故障回复到 sharedanced,并始终写入 sharedanced 和 memcached。

您可以通过在多个共享实例之间进行分片来扩展写入。 您可以使用 repcached (replicated memcached) 之类的解决方案将读取扩展 N 倍。

如果这对您来说并不重要,您仍然可以使用 sharedanced 作为 memcached 的基本替代品。它很快,大多数文件系统调用最终都会被缓存 - 将 memcached 与 sharedance 结合使用只会避免从 sharedanced 读取,直到某些数据在 memcache 中过期。重新启动 memcached 服务器将导致所有客户端至少从共享实例读取一次 - 这不是真正的问题,除非您对相同的密钥具有极高的并发性并且客户端竞争相同的密钥。

如果你在处理一个非常高流量的环境,有一些问题,一个是文件系统的选择(reiserfs 性能比 ext3 好 5-10 倍,因为 fs 树的一些内部缓存),它不支持 udp (如果你只使用共享,TCP keepalive 是相当大的开销,memcached 有 udp,这要归功于 facebook 团队)并且通常在你的应用程序上完成扩展(通过在多个共享服务器实例之间分片数据)。

如果您可以利用这些因素,那么这对您来说可能是一个很好的解决方案。在我们当前的设置中,单个 sharedanced/memcache 服务器每天可以扩展到大约 1000 万次页面浏览量,但这取决于应用程序。我们不会对所有内容都使用缓存(例如 facebook),因此当涉及到您的应用程序时,结果可能会有所不同。

现在,2 年后,Membase 是一个很棒的产品。或者 Redis,如果您需要额外的功能,如哈希、列表等。

【讨论】:

【参考方案10】:

我认为membase 是你想要的。

【讨论】:

【参考方案11】:

尝试go-memcached - 使用Go 编写的内存缓存服务器。它开箱即用地将缓存的数据持久保存到磁盘。 Go-memcached 与 memcache 客户端兼容。它具有原始memcached 中缺少的以下功能:

缓存数据在服务器崩溃和/或重新启动后仍然存在。 缓存大小可能会超出可用 RAM 大小多个数量级。 密钥大小没有 250 字节的限制。 值大小没有 1Mb 的限制。值大小实际上受到 2Gb 的限制。 比原来的memcached更快。在处理传入请求时,它使用的 CPU 也更少。

以下是通过go-memcached-bench获得的性能数据:

-----------------------------------------------------
|            |  go-memcached   | original memcached |
|            |      v1         |      v1.4.13       |
| workerMode ----------------------------------------
|            | Kqps | cpu time |  Kqps  | cpu time  |
|----------------------------------------------------
| GetMiss    | 648  |    17    |  468   |   33      |
| GetHit     | 195  |    16    |  180   |   17      |
| Set        | 204  |    14    |  182   |   25      |
| GetSetRand | 164  |    16    |  157   |   20      |
-----------------------------------------------------

go-memcached 和 go-memcached-bench 的静态链接二进制文件可在 downloads page 获得。

【讨论】:

你在生产服务器上使用这个吗? 我在多个高负载项目中成功使用go-memcached。【参考方案12】:

只是为了完成这个列表 - 我刚刚找到 couchbase。不过我还没有测试过。

【讨论】:

哦..我刚刚看到,“membase”(由 Benjamin Nitlehoo 提到)现在被称为“couchbase”【参考方案13】:

Oracle NoSQL 基于 BerkeleyDB(Bill Karwin 指出的解决方案),但增加了分片(数据集的分区)和弹性横向扩展。见:http://www.oracle.com/technetwork/products/nosqldb/overview/index.html

我认为它符合原始问题的所有要求。

为了全面披露,我在 Oracle 工作(但不是 Oracle NoSQL 产品)。这篇文章中表达的观点和观点是我自己的,并不一定反映我雇主的观点或观点。

【讨论】:

【参考方案14】:

memcached 可以替换为Couchbase - 这是该产品线的开源和商业延续。它具有数据到磁盘的持久性(非常高效且可配置)。 memcached 的原作者也一直在研究 Couchbase 及其与 memcached 协议的兼容性——因此您无需更改客户端应用程序代码! 它的性能非常好,并带有 24/7 集群和内置 Cross Datacenter Replication (XDCR)。请参阅 technical paper。

【讨论】:

【参考方案15】:

您可以使用 Tarantool (http://tarantool.org)。它是一个内存数据库,具有持久性、主-主复制和可编写脚本的密钥过期规则 - https://github.com/tarantool/expirationd

【讨论】:

以上是关于可以持久保存到磁盘的 memcached 的替代品的主要内容,如果未能解决你的问题,请参考以下文章

redis演练 redis持久化

redis持久化

Redis持久化

redis之持久化操作

redis 持久化RDBAOF

redis之持久化操作