1. 安装环境要求
1.1. 网络环境要求
因为Coherence在运行时,对网络环境要求比较高,网络越快越好。Coherence 建议部署在千兆网或者万兆以太网中,最好是万兆网中,并保证Multicast可用。最好给集群指定一个唯一的Multicast地址,防止网络中的其他Coherence节点自动加入到集群中。
如果Multicast不可用,可采用WellKnown Addresses (WKA)方式,该方式采用unicast进行节点间的通讯。
通常,同一个集群中的所有Coherence服务器共享一个可靠的,全交换网络(fully switched network),意味着共享一个交换机(理想情况是,两台并行的交换机,每台服务器配置双网卡以提供高可用性)。有两个原因:一是采用多个交换机会降低网络速度,另一个原因是多个交换机的网络环境更有可能有网络分区事件(network partitioning events)产生,局部的网络失败,会导致服务器之间的网络连接中断。
如上说明,Coherence集群一般部署在一个局域网中,如果需要跨越城域网或广域网,一般是配置成不同的集群,集群之间可用通过Proxy方式或Push Replication Pattern方式进行通讯。
如果网络环境是IPV6和IPV4的混合环境,需要设置在JVM的启动参数设置:
-Djava.net.preferIPv4Stack=true,在AIX环境下,不同的集群要配置不同的MULTICAST地址和端口。
更详细的信息请参见:Oracle® Coherence Administrator's Guide.pdf。
部署时,可先做下网络性能测试,具体可参考:Oracle® Coherence Administrator's Guide.pdf。
1.2. 硬件环境要求
采用经过Coherence测试认证过的硬件,操作系统及JVM.
在Intel X86平台上最好采用JRockit JVM.
如果对性能的要求比较高,可考虑选择Oracle Exalogic中间件云服务器.
1.3. 软件环境要求
采用经过Coherence测试认证过的操作系统及JVM,操作系统,JDK需要打的补丁要打上,Coherence采用最新的稳定版本.
2. 容量估算
对coherence应用实际部署时所需要的内存大小,节点个数,服务器数量进行估算,并给出硬件,网络的参考建议。并介绍如何通过配置限制Cache对内存的消耗,防止OUT OF MEMORY。
2.1. Cache占用内存大小估算
首先,让我们看下CoherenceJVM内存是如何被用掉的?
JVM本身大概需要消耗200-300M的内存,用于JVM本身的运行所需。Coherence本身在运行时也需要内存,用于处理各种操作,如对象的反序列化,查询,统计,侦听事件,数据的重新分布,节点之间的通讯等。余下的内存才可用来Cache数据,创建索引。
另外为了使Coherence应用运行的比较稳定,不要把heap size 100%用满,最好平均使用的内存不要超时分配的75% 到 80%。留有余地,以应对业务高峰。此外,GC等也需要有些冗余。通常是: 1/3 给JVM, 2/3 cache数据(其中PRIMARY 1/3,BACKUP 1/3)。
Cache数据在Coherence中以key,value的方式保存,其中的value一般是POF对象。具体的一条存储的记录,包括key,value及其他元数据,叫一个Entry。
通常的保存方式是一份主数据,一份备份数据。所以需要的内存为:
Cache 容量 = Entry个数 * 2 * Entry 大小
其中:
Entry 大小 = 序列化后的key+ 序列化后的Value + 150 bytes(每个 entry需要150 bytes的元数据)
举个例子,考虑有个Cache里面有五百万个对象,序列化后的key和value大小分别为100字节和2KB.
每个entry的大小为:
100bytes + 2048 bytes + 150 bytes = 2298 bytes
整个Cache的大小为:
5000000* 2 * 2298 bytes = 21,915 MB
如果采用了索引,索引的大小也要考虑进去.没有排序的索引(Un-ordered cache indexes)由序列化后的属性和key组成. 排序过的索引(Orderedindexes)还要加上向前或向后的导航信息.
索引被保存在内存中. 每个节点需要有2个map (java.util.HashMap
的实例
) 用于索引: 一个反向索引(reverse index),一个正向索引(forward index). 每个HashMap
需要30个字节
. 每个索引除了属性本身的大小外,还需要加上12 bytes (the object reference size).
举个例子, 如果value是Long
类型的,
需要加20 bytes (12 bytes + 8 bytes) ,如果是字符串类型的,需要加12bytes +字符串的长度.所以,具体某个索引的长度为:
Index size = forward index map +backward index map + reference +value size
如果索引对应的值是Long类型的,大小大约为:
30bytes + 30 bytes + 12 bytes + 8 bytes = 80 bytes
如果索引对应的值是String类型的,该值的平均长度为20个字符,那个索引大小大约为:
30bytes + 30 bytes + 12 bytes + (20 bytes * 2) = 112 bytes
对于比较小的对象,索引所占用的空间比例相对比较高,对象本身越大,索引所占用整个空间的比较越小.
确定一个Cache所需要的空间,不是一个精确的科学。设想每个entry的大小,和最多要放多少个对象进去。下面是一个完整的例子:
· 估计每个entry 平均大小 = 1k
· 估计最多会cache的对象个数= 100k
· 估计字符串(平均长度为20个字符)类型的索引个数= 5
计算索引所需要的内存空间:
5 * 112 bytes * 100k = 56MB
计算Cache所需要的内存空间:
100k* 2 * 1k + 56MB = ~312MB
每个JVM除了保存Cache数据外,还要有多余的内存来处理这些Cache中的数据. 1GB 的heap内存大约需要300MB或更多. 对JVM, heap内存之外还需要大概200MB内存用于JVM本身. 所以,在一个有2个节点的集群中,保存312MB的数据,每个节点需要的内存如下:
312MB
(fordata) + 300MB
(working JVM heap) + 200MB
(JVMexecutable)= 812MB
(of physical memory)
注意这是所需要的最小heap空间. 明智的做法是加多一点的空间, 大约10%以上,因为考虑到前面你的估算可能不准确, 也考虑未来容量的增长.
考虑JVM本身工作所需要的内存,完整的计算公式如下:
Cache 所需内存= ((cacheentries大小 + indexes大小) * 2 (primary和备份)) + JVM working memory (~30% of 1GB JVM)
2.2. 如何查看某个CACHE占用的内存大小
可通过JConsole工具,精确查看某个CACHE占用的内存。
或者用Oracle的JRMC查看。