替代memcached,可以坚持到磁盘
我目前正在使用我的Java应用程序的memcached,总体来说它工作得很好。
memcached对我来说最重要的function是:
- 它的速度很快,因为读取和写入都在内存中,不会触及磁盘
- 这只是一个关键/价值商店(因为这是我所有的应用程序的需求)
- 它是分布式的
- 它通过使每个对象正好位于一台服务器上而高效地使用内存
- 它不假定对象来自数据库(因为我的对象不是数据库对象)
然而,memcached做不到的事情是我想要做的。 我想定期(也许每天一次)将caching内容保存到磁盘。 我希望能够从保存的磁盘映像中恢复caching。
磁盘保存不需要非常复杂。 如果在保存时添加新的键/值,我不在乎它是否包含在保存中。 如果在保存过程中现有的键/值被修改,保存的值应该是旧值或新值,但我不在乎哪一个。
任何人都可以推荐另一个caching解决scheme(无论是自由还是商业),具有所有(或相当大比例)的memcachedfunction,对我来说很重要,也允许从磁盘保存和恢复整个caching?
也许你的问题像我的:我只有几个memcached的机器,但有很多的内存。 即使其中一个出现故障或需要重新启动,也会严重影响系统的性能。 根据最初的memcached理念,我应该添加更多的机器,每个机器的内存都较less,但是这不是成本效益高的,并不完全是“绿色IT”;)
对于我们的解决scheme,我们为caching系统构build了一个接口层,这样一来,底层caching系统的提供者就可以嵌套 ,就像使用stream一样,为memcached编写caching提供程序,以及我们自己的非常简单的Key-Value -2磁盘存储提供商。 然后,我们为caching项目定义一个权重,表示如果不能从caching中检索项目,重build项目的代价是多么昂贵。 嵌套的磁盘caching仅用于权重超过一定阈值的项目,大约占所有项目的10%。
将对象存储在caching中时,我们不会将时间浪费在一个或两个caching排队等待asynchronous执行。 所以写入磁盘caching并不需要很快。 同样的读取:首先我们去memcached,只有当它不在那里,它是一个“昂贵”的对象,然后我们检查磁盘caching(这是比memcached速度慢,但仍然好得多,重新计算30 GB的单台机器掉电后的数据)。
通过这种方式,我们可以从两个世界中获得最好的效果,而不需要用新的东西替代memcached。
我从来没有尝试过,但redis呢?
它的主页(引用):
Redis是一个键值数据库。 它与memcached类似,但数据集不是volatile的,值可以是string,就像在memcached中一样,也可以用push或pop元素的primefaces操作列表和设置。
为了速度非常快,但同时持久性地将整个数据集存储在内存中,并且/或者当对数据集进行多次改变时,将其asynchronous地写入磁盘。 您可能会丢失在许多应用程序中可接受的最后几个查询,但它与内存数据库一样快(Redis支持无阻塞的主从复制以便通过冗余来解决此问题)。
这似乎回答了你提到的一些问题,所以也许这对你有帮助。
如果你尝试一下,我对你发现的东西很感兴趣,btw 😉
作为一个方面说明:如果你需要将所有这些写入磁盘,也许一个caching系统并不是你真正需要的……毕竟,如果你使用memcached作为caching ,你应该能够重新填充它 – 需要的时候,只要有必要 – 仍然,我承认,如果整个memcached集群崩溃,可能会有一些性能问题…
那么,也许一些“更多”的面向关键/价值存储的软件可以提供帮助? 像CouchDB的东西,例如?
它可能不会像memcached一样快,因为数据不是存储在RAM中,但在磁盘上,尽pipe…
EhCache有一个“磁盘永久性”模式,在关机时将caching内容转储到磁盘,并在重新开始备份时恢复数据。 至于你的其他要求,当在分布式模式下运行时,它会在所有节点上复制数据,而不是只将它们存储在一个节点上。 除此之外,它应该很好地适合你的需求。 它还处于积极的发展阶段,许多其他的javacaching框架都没有。
尝试go-memcached – 用Go编写的memcache服务器。 它将caching的数据保存到磁盘中。 Go-memcached与memcache客户端兼容。 它在原始的memcached中缺less以下function:
- 高速caching的数据在服务器崩溃和/或重新启动后仍然存在。
- 高速caching大小可能超过可用RAM大小的多个数量级。
- 密钥大小没有250字节限制。
- 价值大小没有1Mb的限制。 价值大小实际上受限于2Gb。
- 它比原来的memcached更快。 服务传入请求时,它也使用较less的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的静态链接二进制文件。
看看Apache Javacaching系统(JCS)
JCS是用java编写的分布式caching系统。 它旨在通过提供pipe理各种dynamic特性的高速caching数据的手段来加速应用程序。 像任何caching系统一样,JCS对高读取,低configuration应用程序最为有用。 延迟时间急剧下降,瓶颈在有效caching系统中远离数据库。 了解如何开始使用JCS。
JCS不仅仅是caching内存中的对象。 它提供了许多附加function:
* 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
我认为membase是你想要的。
根据我的经验,最好在应用程序和后端存储之间编写一个中间层。 这样,你可以配对memcached实例,例如sharedanced(基本上是相同的键值存储,但是基于磁盘)。 最基本的方法是,总是从memcached中读取并回退到sharedanced,并总是写入sharedanced和memcached。
您可以通过在多个共享实例之间进行分片来扩展写入。 您可以使用像repcached(复制的memcached)这样的解决scheme来缩小N倍读取。
如果这不是微不足道的,你仍然可以使用sharedanced作为memcached的基本替代品。 它很快,大部分的文件系统调用最终被caching – 使用memcached结合共享只避免从共享读取,直到某些数据在memcache中到期。 重新启动memcached服务器将导致所有客户端至less从共享实例读取一次 – 这不是一个真正的问题,除非您对同一个密钥具有极高的并发性,并且客户端争用相同的密钥。
如果你处理的是严重的高stream量环境,有一些问题,一个是文件系统的select(由于fs树的内部caching,reiserfs的性能比ext3高5-10倍),但是没有udp支持(TCP keepalive如果你仅仅使用共享,memcached的udp就是一个开销),并且扩展通常是在你的应用上进行的(通过在共享服务器的多个实例上分割数据)。
如果你可以利用这些因素,那么这可能是一个很好的解决scheme。 在我们目前的设置中,一个sharedanced / memcache服务器每天可以扩展到大约一千万个网页浏览量,但这依赖于应用程序。 我们不使用caching的一切(如Facebook),所以结果可能会有所不同,当涉及到您的应用程序。
而现在,2年过去了,Membase是一个很棒的产品。 或Redis,如果您需要其他function如哈希,列表等
怎么样兵马俑 ?
Oracle NoSQL基于BerkeleyDB(Bill Karwin指出的解决scheme),但增加了分片(数据集分割)和弹性扩展。 请参阅: http : //www.oracle.com/technetwork/products/nosqldb/overview/index.html
我认为它符合原始问题的所有要求。
为了充分披露,我在Oracle工作(但不是在Oracle NoSQL产品上)。 本文所expression的意见和看法属于我自己的观点,并不一定反映用人单位的意见或看法。
memcached可以被Couchbase替代 – 这是这个产品线的开源和商业延续。 它具有数据到磁盘的持久性(非常高效和可configuration)。 memcached的原创者也一直在研究Couchbase,并且它与memcached协议兼容 – 所以你不需要改变你的客户端应用程序代码! 它的性能非常好,内置24/7集群和交叉数据中心复制(XDCR) 。请参阅技术文档 。
你可以使用Tarantool( http://tarantool.org )。 这是一个内存数据库,具有持久性,主 – 主复制和可脚本化的密钥过期规则 – https://github.com/tarantool/expirationd
你看了BerkeleyDB吗?
- 快速的embedded式进程内数据pipe理
- 键/值存储,非关系。
- 持久存储。
- 免费,开源。
但是,它不符合你的标准之一:
- BDB支持分布式复制,但数据未分区。 每个节点都存储完整的数据集。
我们正在使用OSCache 。 我认为除了定期将caching保存到磁盘上以外,几乎可以满足所有需求,但是您应该可以创build2个cachingpipe理器(一个基于内存,一个基于hdd),并定期运行java cronjob,通过所有内存中的caching键/值对,并将其放入hddcaching。 OSCache的好处在于它非常易于使用。
您可以使用GigaSpaces XAP ,这是一个成熟的商业产品,可以满足您的要求。 它是最快的分布式内存数据网格(caching++),它是完全分布式的,支持多种types的持久化方法。
Guy Nirpaz,GigaSpaces
只是为了完成这个清单 – 我只是发现了couchbase 。 不过我还没有testing过。