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

时间:2009-08-22 19:43:01

标签: java caching persistence memcached distributed

我目前正在使用memcached和我的java应用程序,总的来说它工作得很好。

对我来说最重要的memcached的功能是:

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

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

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

任何人都可以推荐另一种缓存解决方案(免费或商业),它具有对我来说很重要的所有(或很大一部分)memcached功能,并且还允许从磁盘保存和恢复整个缓存吗?

15 个答案:

答案 0 :(得分:17)

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

  

Redis是一个键值数据库。它是   类似于memcached但数据集   不易变,价值观可以   字符串,与memcached完全一样,   还有原子的列表和集合   推送/弹出元素的操作。

     

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

它似乎回答了你所谈到的一些观点,所以在你的情况下它可能会有所帮助吗?

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


作为旁注:如果您需要将所有这些写入磁盘,可能缓存系统并不是您真正需要的...毕竟,如果您使用memcached作为缓存< / strong>,你应该能够在需要的时候按需重新填充它 - 但我承认,如果整个memcached集群立即崩溃,可能会出现一些性能问题......

那么,也许一些“更多”的键/值存储软件可以提供帮助?比如CouchDB之类的东西?
它可能没有memcached那么快,因为数据不是存储在RAM中,而是存储在磁盘上,但是...

答案 1 :(得分:15)

也许你的问题和我一样:我只有几台机器用于memcached,但内存很多。即使其中一个发生故障或需要重新启动,它也会严重影响系统的性能。根据最初的memcached哲学,我应该添加更多的内存更少的机器,但这不是成本效率,而不是“绿色IT”;)

对于我们的解决方案,我们为Cache系统构建了一个接口层,使得底层缓存系统的提供者可以嵌套,就像您可以使用流一样,并为memcached编写缓存提供程序以及我们自己非常简单的Key-Value-2磁盘存储提供商。然后我们为缓存项定义权重,表示如果无法从缓存中检索项目,则重建项目的成本是多少。嵌套磁盘缓存仅用于权重高于特定阈值的项目,可能约为所有项目的10%。

当在缓存中存储对象时,我们不会浪费时间,因为保存到一个或两个缓存无论如何都排队等待异步执行。因此写入磁盘缓存不需要很快。读取相同:首先我们选择memcached,只有当它不存在并且它是一个“昂贵”的对象时,我们检查磁盘缓存(比memcached慢一点,但仍然比重新计算30 GB更好)单台机器出现故障后的数据。)

通过这种方式,我们可以从两个世界中获得最佳效果,而无需用新的东西替换memcached。

答案 2 :(得分:13)

EhCache具有“磁盘持久性”模式,该模式在关闭时将缓存内容转储到磁盘,并在重新启动时重新启动数据。至于您的其他要求,当在分布式模式下运行时,它会跨所有节点复制数据,而不是仅将它们存储在一个节点上。除此之外,它应该很好地满足您的需求。它还处于活跃开发阶段,许多其他Java缓存框架都没有。

答案 3 :(得分:5)

尝试go-memcached - 用Go编写的memcache服务器。它将缓存的数据保持在开箱即用的磁盘上。 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-benchdownloads page的静态链接二进制文件。

答案 4 :(得分:4)

查看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

答案 5 :(得分:4)

我认为membase就是你想要的。

答案 6 :(得分:3)

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

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

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

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

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

现在,2年后的好,Membase是一个伟大的产品。或Redis,如果您需要其他功能,如哈希,列表等

答案 7 :(得分:2)

Terracotta怎么办?

答案 8 :(得分:2)

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

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

为了完全公开,我在Oracle工作(但不在Oracle NoSQL产品上)。本文中表达的观点和观点是我自己的,不一定反映我的雇主的意见或观点。

答案 9 :(得分:2)

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

答案 10 :(得分:2)

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

答案 11 :(得分:1)

你看过BerkeleyDB吗?

  • 快速,嵌入式,在线数据管理。
  • 键/值存储,非关系。
  • 持久存储。
  • 免费,开源。

但是,它无法满足您的一个标准:

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

答案 12 :(得分:1)

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

答案 13 :(得分:1)

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

Guy Nirpaz, GigaSpaces的

答案 14 :(得分:1)

只是为了完成此列表 - 我刚刚找到了couchbase。但是我还没有测试过它。