Coherence Step by Step 第三篇 缓存(一) 介绍(翻译)
1. Cache介绍
Coherence提供的基本缓存类型的概述和比较
1.1 Distributed Cache
数据分布在集群的计算机上。为了容错和分割数据,可以配置缓存,集群上的一台或多台计算机保存数据的各个片段。Distributed Cache 是在Coherence上最常用的。
Coherence定义了一个分布式的缓存,一个数据集合被分发给集群节点中的任何一个计算机,集群中的每个节点负责缓存的一片数据。
Distributed cache有几个关键点:
- Partitioned:在分布式缓存中的数据在所有的服务器上传播,不存在两台服务器负责相同的数据片段。缓存的大小和缓存管理的处理能力能够随着集群数量的增加线性增长。也就是说,意味着在缓存中的数据操作能够在"single hop"完成,换句话说,包括最多依他另外的服务器。
- Load-Balanced:由于数据需要在服务器中平衡的传播,管理数据的责任就是自动在集群中负载均衡。
- Location Transparency:尽管数据通过集群节点传播,但是获取数据使用相同的API,每个API的方法提供相同的行为。这叫做location trasnparaency,这就意味着开发人员不需要知道缓存的拓扑结构来写代码,因为API和行为在distributed cache、replicated cache是相同的。
- Failover:所有的Coherence服务提供失效备份和失效恢复,不丢失任何数据,包含了distributed cache 服务。distributed cache 服务允许配置多个备份。如果备份的数量是一个或者多个,集群中的任何一个节点的失效都不会导致数据丢失。
要能够访问distributed cache 通常要检查去往另一个cluster节点的网络。所有其他事情等于,如果有n个cluster节点,(n-1)/n的操作检查网络。
由于每片数据只被一个集群节点管理,通过网络访问只有"single hop"的操作。这种类型的访问是极具有扩展性的,由于它能够使用点对点的交互,因此采用了可交换式网络的最佳优势。
相同的,一个缓存的更新操作使用同样的single-hop 点对点的方式,它指出了一个已知的relicated cache的局限性,需要把推送缓存到所有的集群节点。
上图中,数据被发送到primary cluster节点和一个备份cluster节点。这是为了失效备援的目的,相当于一个备份(默认的备份数量设置为1)。如果缓存数据不是关键的,也就是说它能够从disk重新加载,可以将备份的数量设置为零,如果集群中某个节点失效,将会允许部分的缓存数据丢失。如果缓存的数据极为关键,一个高一些的备份数量,如使用两个。备份数量只影响缓存修改时候的性能,如添加、修改、删除缓存条目。
对于缓存的修改直到所有的备份都接收到了修改才被认为完成。当使用分布式缓存备份的时候对性能有一点损失。然而它能够保证如果有一个集群节点出乎意料的失败,数据的一致性仍然得到保持,不会有数据丢失。
distributed cache的失效备援包含提升备份数据变成primary storage。当一个cluster节点失效,所有的其他cluster节点那个检测到自己持有的那个死亡节点主要负责的数据。这些数据成为了任何一个备份cluster负责的数据:
如果有多个等级的备份,第一个备份负责这些数据;第二个备份成为新的第一个备份,以此类推。就像replicated cache service,锁信息仍然被失效的服务器所持有;除非失效的服务器自动释放了锁。
distributed cache 服务也允许确定的cluster及诶单配置为存储数据,其他的配置为不存储数据。这个设置的名字叫做local storage enable。被配置为开启local storage的cluster节点为distributed cache提供cache storage和backup storage。忽略这个设置,所有的cluster节点有同样准确的数据视图,因为location transparency.
开启local storage选项,有几个好处:
- 如果cluster节点的java堆内存关闭了local storage,并不影响在cache中的大量数据,因为数据缓存在其它cluster节点上。这个对跑在拥有庞大java堆的就版本的jvm上的应用服务进程有一定帮助,因为这些进程忍受着垃圾回收暂停,堆的大小以指数级增长。
- Coherence 允许每个cluster节点运行在任何受支持版本的JVM上。也就是意味着开启local storage的cluster几点能够运行在较新的JVM版本上,支持大的堆,或者Coherence的 off-heap storage 使用java的NIO特性。
- local storage 启用参数允许许多cluster节点使用只用来存储缓存数据。这类cluster节点被称为Coherence cache server。Cache server通常用来增加Coherence的 分布式查询功能。
1.2 Replicated Cache
replicated cache是聚合的、容错的,数据被cluster中所有的成员复制。这种cache随着线性增长提供了最快的读取性能,但是对于写,有较差的可扩展性(因为写必须被所有的cluster成员处理)。因为数据被复制给了所有的服务器,增加服务器不会增加总体缓存的容量。
replicated cache的优秀的处理能力是处理数据复制、并发控制和失效备援,所有分发都提供了in-memory data的读取速度。cluster replicated cache明确的说就是:缓存,复制它的数据到所有的cluster节点。
建立一个可靠的relicated cache 有几个挑战。第一个是如何让它规模化,执行的更好。对于缓存的更新不得不发送给所有的cluster节点,并且所有的cluster节点必须以相同的数据结束,即使如果同一时间有多个相同数据的更新。同样,如果一个cluster节点请求了一个锁,它不得不询问所有的cluster是否同一上锁,否则的可伸缩性太差了。还有当cluster节点失效,所有的数据和锁信息必须保持安全。Coherence透明的处理所有的场景,为java程序提供了最具有扩展性和高可用的replicated cache。
replicated cache的最好的部分就是访问速度。一旦数据被复制到每个cluster节点,不用任何等待就能够使用。这个引用了"zero latency access",对于那些要求高速访问数据的引用是非常完美额。每个cluster节点从自己的内存中访问数据。
相比之下,更新replicated cache就需要把新版本的数据存到所有的cluster节点。
Coherence实现了他在replicated cache服务,通过这种方式,所有的只读操作发生在本地,所有的并发控制包含在其他所有的cluster节点,只有更新操作要求和所有的cluster节点进行通讯。最终结果是可扩展性好,和其他的coherence service服务相比,replicated cache 服务提供了透明的和完全的失效备援和失效回滚。
replicated cache service 的局限性也需要被仔细的考虑。首先,许多数据被加入服务的cluster加点的replicated cache服务管理。那也意味着每个cluster节点的内存使用将会增加,这回影响性能。第二,随着cluster的增加,replicated cache的大量更新没有线性的增长;换句话说,cluster随着节点的增加收益变小。
1.3 Optimistic Cache
optimistic cache是一个类似replicated cache实现,但是没有任何并发控制。这个实现提供了比replicated cache更高写的吞吐量。它也允许为缓存数据提供可选择的基本存储(例如,MTU/MFU-base cache).然而,如果两个cluster成员independently pruning 或者purging 基础的本地存储,每个成员存储的数据可能不同。
1.4 Near Cache
near cache是一个混合的cache;它通常面向distributed cache和有本地缓存的remote cache。使用一个配置失效策略, Near cache使缓存条目面前无效,并提供了卓越的性能和异步。Near cahce被部分缓存备份,提供零毫秒本地访问重复的数据,同事,启用了并发控制、确保一致性和故障处理,有效结合最好的复制属性和分区缓存。
near cache的目标是提供在两个最好的领域之间,即Replicated Cache的几号的性能和Distributed Cache的几号的扩展性,实现快速访问到最近最常使用(MRU)和最频繁使用(MFU)的数据。
"front cache"提供了local cache的访问。假设这是很便宜的,非常快,并且规模上有限制。"back cache"能够成为一个集中的多层次的缓存,如果本地缓存溢漏可以够按需加载。"back cache"假定是完整的、正确的,具有高容量,但是访问速度代价昂贵。没有限制Coherence*Extend使用Near Cache;它也工作于TCMP。
这种设计允许Near Cache配置缓存一致性,从最基本的expiry-based缓存和invalidation-based cache,到高级的版本数据的缓存和提供保证一致性。最后的结果是在一个在本地内存资源的保存和真实性本地缓存的性能收益之间的一个可调平衡。
常用的部署是使用local cache作为"front cache"。local cache是一个合理的选择是因为他是线程安全的,高并发的,大小限制,自动过期,并且以对象形式存储数据。"back cache",作为一个远程的,partitioned cache使用。
下面的图说明了在Near Cache中,数据的流向。如果客户端写了一个对象D进grid,这个对象被放在本地JVM的local cache里,在partitioned cache中被备份。如果客户端请求这个对象,它能够从本地获取,或者"front cache",没有延时的获取以对象的形式
如果客户端从"front cache"请求一个已经过期或者无效的对象,Coherence 自动从partitioned cache检索。在对象分发给客户端之前,"front cache"先存储对象。
1.5 Local Cache
虽然它不是一个cluster服务,Coherence local cache的实现常被用在结合不同的Coherence cluster cache服务。Coherence local cache正是:一个位于(完全包含于)部分cluster节点上的缓存。有几个本地缓存的特性是特别有趣的:
- local cache实现了cluster cache实现的相同标准接口集合,意味着使用local或者cluster cache的变成没有什么不同。正如cluster cache,local cache是更具JCache API,它自身和local cache的依据是同一个标准集合api。
- local cache能够限制大小,local cache能够限制他缓存条目的数量,当填满是自动逐出条目。此外,条目的数量和逐出规则是可以自定义的。例如,缓存能够更具缓存条目所使用的内存进行限制大小。默认的逐出规则是使用MRU和MFU的结合信息,更具对数曲线,决定逐出哪条缓存。这个算法是最好的常用的逐出算法,它适用于短时间和长时间的缓存,它平衡了最常用和最近使用,避免了内存颠簸。裁剪LRU和裁剪LFU酸液也被支持,能够插入自定义逐出规则。
- local cache支持自动过期缓存条目,意味着每个缓存条目被指定了在缓存中的存活时间。
- local cache是线程安全的且搞并发的,允许许多线程同时访问和更新local cache中的条目。
- local cache支持缓存通知。这些通知提供了增加,修改和删除的提示。这些和cluster cache所支持的缓存事件一样。
- local cache维护者命中和未命中的统计。这些run-time的统计能够精确的设计缓存的有效性,当缓存运行时,相应的调整大小限制和自动过期设置
对于cluster cache,local cache是非常重要的,有几个原因,包括作为Coherence的near cache技术的一部分,并且拥有模块化的备份映射架构。
1.6 Remote Cache
remote cache 描述了任何进程缓存之外的Coherence*Extend 客户端的访问。所有的缓存请求被发往Coherence 代理,由他们委派给缓存(Replicated, Optimistic, Partitioned)。
1.7 缓存类型的总结
数量关系:
- JVMs= number of JVMs
- DataSize= total size of cached data (measured without redundancy)
- Redundancy= number of copies of data maintained
- LocalCache= size of local cache (for near caches)
Notice:
1.粗略计算,百兆网络,网络读取通常需要20ms来读取一个100KB的对象,在gigabit以太网,网络读取一个1KB的对象通常是亚毫秒。
2.需要UDP多播或者一些UDP单播操作,取决于JVM的数量。
3.需要一些UDP单播操作,这取决于冗余的等级。
4.partitioned cache被配置为尽可能多的级别的备份更具需要,或者如果需要,配置0个。多数的安装使用一个备份(总共两个副本)。
5.本地CPU/内存性能的限制,可以忽略处理所需(通常是亚毫秒的性能)
6.Linstener-based near cache是一致的;expiry-based near cache对于非事务性读取是部分一致的,对于是事务访问是一致的。