Introduction
Distributed caching allows you to harness additional benefits of horizontal scale-out, without losing on low latency offered by local on-heap tiers.
集群可以让你获得水平拓展的好处,同时又不失去本地查找低延迟的能力。
To enable clustering with Terracotta, you will have to deploy a Terracotta server configured with clustered cache storage. For convenience Ehcache 3.1 introduced a downloadable kit that contains the Terracotta Server and also the required client libraries.
使用Terracotta部署集群你需要部署一个可配置的Terracotta服务用来存储集群信息,为了方便 Ehcache 3.1已经引入过一个可以下载的包含Terracotta 服务和必要依赖的客户端。
You will then need to configure a cache manager to have clustering capabilities such that the caches it manages can utilize the clustered storage. Finally, any caches which should be distributed should be configured with a clustered storage tier.
为了拥有集群的性能你需要配置一个缓存管理 器,它管理的缓存可以使用集群存储,任何需要分布式的缓存都需要配置在一个集群存储中
Clustering Concepts
In this section we discuss some Terracotta clustering terms and concepts that you need to understand before creating cache managers and caches with clustering support.
在建立缓存管理器和缓存集群之前我们要讨论Terracotta集群的地位和概念
Server off-heap resource 服务器的堆外资源
Server off-heap resources are storage resources defined at the server. Caches can reserve a storage area for their cluster tiers within these server off-heap resources.
服务器堆外资源是在服务器上定义的存储资源,缓存可以在这些服务器堆外资源中为它们的集群层保留一个存储区域。
Cluster Tier Manager 集群管理器
The Ehcache Cluster Tier Manager is the server-side component that gives clustering capabilities to a cache manager. Cache managers connect to it to get access to the server’s storage resources so that the clustered tiers of caches defined in them can consume those resources. An Ehcache cluster tier manager at the server side is identified by a unique identifier. Using the unique identifier of any given cluster tier manager, multiple cache managers can connect to the same cluster tier manager in order to share cache data. The cluster tier manager is also responsible for managing the storage of the cluster tier of caches, with the following different options.
Ehcache集群层管理器是向缓存管理器提供集群功能的服务器端组件。缓存管理器连接到它,以访问服务器的存储资源,以便其中定义的缓存集群层可以使用这些资源。服务器端的Ehcache集群层管理器由唯一标识符标识。使用任何给定集群层管理器的唯一标识符,多个缓存管理器可以连接到同一个集群层管理器,以便共享缓存数据。集群层管理器还负责管理缓存的集群层的存储,具有以下不同的配置项。
Dedicated pool 专用池
Dedicated pools are a fixed-amount of storage pools allocated to the cluster tiers of caches. A dedicated amount of storage is allocated directly from server off-heap resources to these pools. And this storage space is used exclusively by a given cluster tier.
专用池是分配给缓存集群层的固定数量的存储池。从服务器堆外资源直接给这些池分配专用的存储空间。这个存储空间仅由给定的集群层使用。
Shared pool 共享池
Shared pools are also fixed-amount storage pools, but can be shared by the cluster tiers of multiple caches. As in the case of dedicated pools, shared pools are also carved out from server off-heap resources. The storage available in these shared pools is strictly shared. In other words, no cluster tier can ask for a fixed-amount of storage from a shared pool.
共享池也是固定数量的存储池,但是可以由多个缓存的集群层共享。与专用池的情况一样,共享池也是从服务器堆外资源中分割出来的。这个共享池是被严格定义为共享的,换句话说,没有集群层可以从共享池中申请到一块固定大小的空间。
Sharing of storage via shared pools does not mean that the data is shared. That is, if two caches are using a shared pool as their clustered tier, the data of each cache is still isolated but the underlying storage is shared. Consequently, when resource capacity is reached and triggers eviction, the evicted mapping can come from any of the cluster tiers sharing the pool.
通过共享池共享存储并不意味着数据是共享的。也就是说,如果两个缓存使用共享池作为它们的集群层,那么每个缓存的数据仍然是独立的,但是底层存储是共享的。当资源达到回收条件,回收的映射可以来自集群层的任何一块共享池。
Here is a pictorial representation of the concepts explained above:
以下是上述概念的图示:
Starting the Terracotta Server
You can start the Terracotta Server with the following configuration. It contains the bare minimum configuration required for the samples in the rest of the document to work.
您可以使用以下配置启动Terracotta服务器。它包含文档示例所需的最低配置。
<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config"
xmlns:ohr="http://www.terracotta.org/config/offheap-resource">
<plugins>
<config>
<ohr:offheap-resources>
<ohr:resource name="primary-server-resource" unit="MB">128</ohr:resource>
<ohr:resource name="secondary-server-resource" unit="MB">96</ohr:resource>
</ohr:offheap-resources>
</config>
</plugins>
</tc-config>
The above configuration defines two named server off-heap resources:
上面的配置定义了两个命名的服务器堆外资源
| An off-heap resource of 128 MB size named |
| Another off-heap resource named |
The rest of the document explains in detail how you can configure cache managers and caches to consume the server’s off-heap resources.
本文的其余部分将详细说明如何配置缓存管理器和缓存,以使用服务器的堆外资源
Assuming that you have the clustered Ehcache kit available locally, start with extracting the ehcache-clustered kit. Change to your extracted directory and then execute the start-tc-server script as below to start the Terracotta server with the above configuration:
假设您有本地可用的集群Ehcache工具包,那么从解压的Ehcache集群工具包启动。切换到提取的目录,然后执行start-tc-server脚本(如下所示),使用上述配置启动Terracotta服务器
On Windows:windows下启动
cd <path/to/terracotta/kit>/server/bin
start-tc-server.bat -f <path/to/server/config>/tc-config.xml
On Unix/Mac:Mac启动
cd <path/to/terracotta/kit>/server/bin
./start-tc-server.sh -f <path/to/server/config>/tc-config.xml
| You will need to have |
Check for the below INFO
log to confirm if the server started successfully, Terracotta Server instance has started up as ACTIVE node on 0:0:0:0:0:0:0:0:9410 successfully, and is now ready for work.
检查是否有以下输出,确定是否启动成功
Terracotta Server instance has started up as ACTIVE node on 0:0:0:0:0:0:0:0:9410 successfully, and is now ready for work.
Creating a Cache Manager with Clustering Capabilities
创建具有集群功能的缓存管理器
After starting the Terracotta server, as described in the previous section, you can now proceed to create the cache manager. For creating the cache manager with clustering support you will need to provide the clustering service configuration. Here is a code sample that shows how to configure a cache manager with clustering service.
在启动Terracotta服务器(如前一节所述)之后,现在可以继续创建缓存管理器。要创建具有集群支持的缓存管理器,您需要提供集群服务配置。下面的代码示例演示如何使用集群服务配置缓存管理器。
CacheManagerBuilder<PersistentCacheManager> clusteredCacheManagerBuilder =
CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application"))
.autoCreate());
PersistentCacheManager cacheManager = clusteredCacheManagerBuilder.build(true);
cacheManager.close();
| Returns the 返回 |
| Use the connecting the cache manager to the clustered storage at the returns the clustering service configuration builder instance. Sample Provided in the example is pointing to the clustered storage instance named "my-application" on the Terracotta server (assuming the server is running on localhost and port 9410). 使用 到uri指定的集群存储,返回集群服务可配置建造者实例。 简单说这个例子提供的URI指定到集群存储实例在Terracotta 服务叫做"my-application"( 假设这个服务运行在你本机的9410端口) |
| Auto-create the clustered storage if it doesn’t already exist. 如果当前不存在自动创建集群存储。 |
| Returns a fully initialized cache manager that can be used to create clustered caches. 返回一个可以用来创建集群缓存的全部序列化的缓存管理器 |
| Close the cache manager. 关闭缓存管理器 |
Cache Manager Configuration and Usage of Server Side Resources
缓存管理器配置和服务器端资源的使用
This code sample demonstrates the usage of the concepts explained in the previous section in configuring a cache manager and clustered caches by using a broader clustering service configuration:
这个代码示例演示了使用更广泛的集群服务配置来配置缓存管理器和集群缓存时,在前一节中解释的概念的用法:
CacheManagerBuilder<PersistentCacheManager> clusteredCacheManagerBuilder =
CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application")).autoCreate()
.defaultServerResource("primary-server-resource")
.resourcePool("resource-pool-a", 28, MemoryUnit.MB, "secondary-server-resource")
.resourcePool("resource-pool-b", 32, MemoryUnit.MB))
.withCache("clustered-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredDedicated("primary-server-resource", 32, MemoryUnit.MB))))
.withCache("shared-cache-1", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredShared("resource-pool-a"))))
.withCache("shared-cache-2", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredShared("resource-pool-a"))));
PersistentCacheManager cacheManager = clusteredCacheManagerBuilder.build(true);
cacheManager.close();
|
sets the default server off-heap resource for the cache manager. From the example, cache manager sets its default server off-heap resource to in the server.
缓存管理器设置了默认的堆外资源。例如缓存管理器为服务中的 设置了默认的堆外资源。 |
| Adds a resource pool for the cache manager with the specified name ( and size (28MB) consumed out of the named server off-heap resource maps directly to a shared pool at the server side. 从被命名的堆外内存为缓存管理器指定名称 (
|
| Adds another resource pool for the cache manager with the specified name ( explicitly passed, this resource pool will be consumed out of default server resource provided in Step 3. This demonstrates that a cache manager with clustering support can have multiple resource pools created out of several server off-heap resources. 为缓存管理器添加另一个资源池名字叫做 ( 指定,资源池将从默认的服务使用第三步提供。这说明集群的缓存管理器 支持可以在多个资源池中创建多个堆外资源池 |
| Provide the cache configuration to be created. 一个缓存配置被创建 |
|
allocates a dedicated pool of storage to the cache from the specified server off-heap resource. In this example, a dedicated pool of 32MB is allocated for clustered-cache from
从指定堆外服务资源分配一个专用的资源池用来缓存数据。这个例子中, 从 |
|
the resource pool specifies that resources with other caches using the same resource pool ( 省略掉资源池名称 共享存储资源 |
| Configures another cache ( ( 配置另一个缓存 ( |
| Creates fully initialized cache manager with the clustered caches. 使用集群缓存创建完全初始化的缓存管理器。 |
| When a cache is allocated a block of memory from a shared pool, it is retained forever and would never get reallocated to another cache sharing the pool. 当缓存在共享池中分配了一个块,它将永远的被共享。 |
Ehcache Cluster Tier Manager Lifecycle
Ehcache集群层管理器生命周期
When configuring a cache manager to connect to a cluster tier manager there are three possible connection modes:
在配置缓存管理器以连接到集群层管理器时,有三种可能的连接模式
CacheManagerBuilder<PersistentCacheManager> autoCreate = CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application"))
.autoCreate()
.resourcePool("resource-pool", 32, MemoryUnit.MB, "primary-server-resource"))
.withCache("clustered-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredShared("resource-pool"))));
CacheManagerBuilder<PersistentCacheManager> expecting = CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application"))
.expecting()
.resourcePool("resource-pool", 32, MemoryUnit.MB, "primary-server-resource"))
.withCache("clustered-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredShared("resource-pool"))));
CacheManagerBuilder<PersistentCacheManager> configless = CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application")))
.withCache("clustered-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredShared("resource-pool"))));
| 在自动创建模式中如果不存在集群层管理器则按照提供的配置创建一个。如果存在并且它的 配置与提供的匹配,则建立一个连接,如果提供的配置与缓存管理器不匹配则初始化失败。 In auto-create mode if no cluster tier manager exists then one is created with the supplied configuration. If it exists and its configuration matches the supplied configuration then a connection is established. If the supplied configuration does not match then the cache manager will fail to initialize. |
| 在期望模式中如果一个集群层管理器存在,并且它的配置与提供的配置匹配则建立连接。 如果提供的配置不匹配,或者集群管理器不存在,则初始化失败。 In expected mode if a cluster tier manager exists and its configuration matches the supplied configuration then a connection is established. If the supplied configuration does not match or the cluster tier manager does not exist then the cache manager will fail to initialize. |
| 在少配置模式中如果集群层管理器存在则建立一个连接 In config-less mode if a cluster tier manager exists then a connection is established without regard to its configuration. If it does not exist then the cache manager will fail to initialize. |
Configuring a Clustered Cache
配置缓存集群
Clustered Storage Tier
集群存储层
CacheConfiguration<Long, String> config = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(2, MemoryUnit.MB)
.with(ClusteredResourcePoolBuilder.clusteredDedicated("primary-server-resource", 8, MemoryUnit.MB)))
.add(ClusteredStoreConfigurationBuilder.withConsistency(Consistency.STRONG))
.build();
Cache<Long, String> cache = cacheManager.createCache("clustered-cache-tiered", config);
cache.put(42L, "All you need to know!");
| Configuring the heap tier for cache. 为缓存配置堆层 |
| Configuring the cluster tier of dedicated size from server off-heap resource using
使用 |
The equivalent XML configuration is as follows:
使用一下xml配置效果相同
<cache alias="clustered-cache-tiered">
<resources>
<heap unit="MB">10</heap>
<tc:clustered-dedicated unit="MB">50</tc:clustered-dedicated>
</resources>
<tc:clustered-store consistency="strong"/>
</cache>
| Specify the heap tier for cache. 配置堆内存 |
| Specify the cluster tier for cache through a custom service configuration from the clustered namespace. 配置堆外内存 |
Specifying consistency level
一致性级别
Ehcache offers two levels of consistency:
Ehcache提供两个级别的一致性:
Eventual最终一致性
This consistency level indicates that the visibility of a write operation is not guaranteed when the operation returns. Other clients may still see a stale value for the given key. However this consistency level guarantees that for a mapping (K, V1)
updated to (K, V2)
, once a client sees (K, V2)
it will never see (K, V1)
again.
这个一致性级别无法保证一个写入,另一个客户端使用相同的key查询马上就能看到写入的结果。但是这个级别可以保证从(K, V1)
更新到(K, V2)
,
一旦查到(K, V2)
就再也不会查到(K, V1)
(言外之意不会回滚)
Strong 强一致
This consistency level provides strong visibility guarantees ensuring that when a write operation returns other clients will be able to observe it immediately. This comes with a latency penalty on the write operation required to give this guarantee.
一旦一个连接写入成功,所有的连接都能同步感知到变化。这个是需要写入端保证的。
CacheConfiguration<Long, String> config = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredDedicated("primary-server-resource", 2, MemoryUnit.MB)))
.add(ClusteredStoreConfigurationBuilder.withConsistency(Consistency.STRONG))
.build();
Cache<Long, String> cache = cacheManager.createCache("clustered-cache", config);
cache.put(42L, "All you need to know!");
| Specify the consistency level through the use of additional service configuration, using strong consistency here. 通过给服务添加额外配置条件指定一致性等级,这里使用强一致性 |
| With the consistency used above, this all other clients have had the corresponding mapping invalidated. 使用上边的一致性,这个放入操作会导致其他客户的缓存映射失效。 |
The equivalent XML configuration is as follows:
<cache alias="clustered-cache">
<resources>
<tc:clustered-dedicated unit="MB">50</tc:clustered-dedicated>
</resources>
<tc:clustered-store consistency="strong"/>
</cache>
| Specify the consistency level through a custom service configuration from the 从集群命名空间通过客户端服务配置指定一致性等级 |
Clustered Cache Expiry
缓存过期
Expiry in clustered caches work with an exception that Expiry#getExpiryForAccess
is handled on a best effort basis for cluster tiers. It may not be as accurate as in the case of local tiers.
Clustered Unspecified Inheritance
We have included an option which allows a cache to be created inside the cache manager without having to explicitly define its cluster tier resource pool allocation. In order to use this feature the cluster tier must already have been created with either a shared or dedicated resource pool.
有一个选项允许缓存在缓存管理器中创建无需显式定义其集群层资源池分配。
为了使用这一特性,集群层必须是在共享区或者是专区去创建。
In this case the definition of the cluster resource is done simply with a clustered()
resource pool. This effectively means unspecified and indicates you expect it to exist already. It will then inherit the clustered resource pool as it was configured when creating the cluster tier.
This option provides many benefits. The main benefit is it simplifies clustered configuration by allowing clustered resource pool configuration to be handled by one client, then all subsequent clients can inherit this configuration. In addition, it also reduces clustered pool allocation configuration errors. More importantly, sizing calculations only need to be done by one person and updated in one location. Thus any programmer can use the cache without having to worry about using matching resource pool allocations.
The example code below shows how this can be implemented.
CacheManagerBuilder<PersistentCacheManager> cacheManagerBuilderAutoCreate = CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application"))
.autoCreate()
.resourcePool("resource-pool", 32, MemoryUnit.MB, "primary-server-resource"));
PersistentCacheManager cacheManager1 = cacheManagerBuilderAutoCreate.build(false);
cacheManager1.init();
CacheConfiguration<Long, String> cacheConfigDedicated = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredDedicated("primary-server-resource", 8, MemoryUnit.MB)))
.add(ClusteredStoreConfigurationBuilder.withConsistency(Consistency.STRONG))
.build();
Cache<Long, String> cacheDedicated = cacheManager1.createCache("my-dedicated-cache", cacheConfigDedicated);
CacheManagerBuilder<PersistentCacheManager> cacheManagerBuilderExpecting = CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application"))
.expecting()
.resourcePool("resource-pool", 32, MemoryUnit.MB, "primary-server-resource"));
PersistentCacheManager cacheManager2 = cacheManagerBuilderExpecting.build(false);
cacheManager2.init();
CacheConfiguration<Long, String> cacheConfigUnspecified = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clustered()))
.add(ClusteredStoreConfigurationBuilder.withConsistency(Consistency.STRONG))
.build();
Cache<Long, String> cacheUnspecified = cacheManager2.createCache("my-dedicated-cache", cacheConfigUnspecified);
| Configure the first cache manager with auto create |
| Build a cache configuration for a clustered |
| Create cache |
| Configure the second cache manager as expecting (auto create off) |
| Build a cache configuration for a clustered unspecified resource pool, which will use the previously configured clustered dedicated resource pool. |
| Create cache with the same name unspecified cache configuration |
Z
CacheManagerBuilder缓存管理器建造者,通过with()方法,可以指定链接到那个集群(terracotta),并划分资源池,
通过withcache()方法可以创建chache,并指定大小和区域,以及一致性等(也可使用cacheManager.createCache(方法创建))
创建完成可以使用cacheManager.getCache("clustered-cache-tiered", Long.class, String.class);获取缓存操作对象。
也可以新指定一个配置通过chacheManager新创建个对象:
CacheConfiguration<Long, String> config = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(2, MemoryUnit.MB)//堆内两兆堆外8兆
.with(ClusteredResourcePoolBuilder.clusteredDedicated("default-resource", 8, MemoryUnit.MB)))
.add(ClusteredStoreConfigurationBuilder.withConsistency(Consistency.STRONG))
.build();
Cache<Long, String> cache = cacheManager.createCache("clustered-cache-tiered", config);