Terracotta是Java生态中与Ehcache深度绑定的成熟分布式缓存方案,专门解决集群环境下数据一致性和高吞吐问题,不是简单的缓存加速器,而是一套完整的分布式数据层。
分布式缓存Terracotta到底解决了什么问题
单机缓存的瓶颈
多数Java项目早期用本地Ehcache或Guava Cache,缓存数据只在一台机器上,当应用扩展到多节点,每个节点维护自己的缓存副本,出现数据不一致,比如用户会话信息在A节点更新,B节点还是旧值,传统做法是引入集中式缓存如Redis,但Redis需要额外中间件,且序列化开销大,Terracotta的出现是为了让Java应用直接拥有集群范围的堆外或堆内缓存,无需改变编程模型。
与Ehcache的天然绑定
Terracotta最初是作为Ehcache的分布式扩展存在,通过Terracotta,Ehcache从本地缓存升级为分布式缓存,所有节点共享同一个缓存空间,业内专家指出,Terracotta使用TCP集群技术,在Java堆内实现数据一致性,延迟通常低于毫秒级,这意味着你可以在Java代码里直接使用熟悉的Ehcache API,底层自动同步到其他节点。
Terracotta分布式缓存 vs Redis:关键差异对比
很多团队在选型时纠结于分布式缓存Terracotta和Redis的区别,下面从几个核心维度拆解。
| 维度 | Terracotta + Ehcache | Redis |
|---|---|---|
| 数据模型 | Java对象(直接存储POJO) | 键值对(需序列化/反序列化) |
| 一致性 | 强一致性(通过集群锁实现) | 最终一致性(默认主从异步) |
| 延迟 | 内存访问,微秒级(本地堆内) | 网络IO,亚毫秒级(远程) |
| 持久化 | 支持(通过磁盘溢出或Terracotta DB) | RDB/AOF |
| 集群管理 | 内置节点发现,配置简单 | 需要哨兵或集群模式 |
| 适用场景 | 高频共享数据、会话、配置 | 缓存、消息队列、计数器 |
一致性模型决定应用场景
行业共识认为,Terracotta的强一致性适合金融交易、库存扣减等对数据准确要求极高的场景,Redis默认主从异步,可能丢失最近写入,但吞吐量更高,如果项目需要缓存里跑事务逻辑,Terracotta更放心。
性能与吞吐量
多数情况下,Terracotta因为数据在本地JVM堆内,读操作比Redis快一个数量级,但写操作需要同步到集群,吞吐量受网络和节点数影响,Redis单节点写入可达十万级,集群后更高。Terracotta适合读多写少或写后立即读的场景,比如实时排行榜、用户权限缓存。
实战:分布式缓存Terracotta配置步骤
这里以Ehcache 3.x + Terracotta开源版为例,演示如何搭建一个双节点集群。
安装Terracotta服务器
- 下载Terracotta服务器(建议从官网获取最新稳定版)。
- 解压并配置
tcconfig.xml,指定集群名称和数据目录。 - 启动第一个节点:
/opt/terracotta/server/bin/start-tc-server.sh -f /path/to/tc-config.xml
- 第二个节点启动时自动加入集群,无需额外配置。
配置客户端Ehcache
在项目pom.xml中添加依赖:
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.10.8</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache-clustered</artifactId>
<version>3.10.8</version>
</dependency>
创建ehcache.xml
,指定集群URI:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.ehcache.org/v3"
xmlns:terracotta="http://www.ehcache.org/v3/terracotta">
<terracotta:cluster>
<terracotta:connection url="terracotta://192.168.1.10:9510,192.168.1.11:9510/my-application"/>
</terracotta:cluster>
<cache alias="shared-cache">
<key-type>java.lang.String</key-type>
<value-type>com.example.User</value-type>
<expiry>
<ttl unit="minutes">30</ttl>
</expiry>
<terracotta:store>
<terracotta:shared/>
</terracotta:store>
</cache>
</config>
关键点:<terracotta:shared/>表示分布式缓存,数据在所有节点一致。
验证集群
启动两个应用实例,写入缓存后立即在另一个节点获取,能读到最新值,观察日志确认节点加入集群。如果出现连接失败,检查防火墙和端口(默认9510、9530)。
性能优化:让Terracotta跑得更快
调整线程池与网络参数
Terracotta服务器使用nio网络层,可调整comm.threads和worker.threads。通常将线程数设为CPU核心数×2,对于万兆网络,增大tcp.send.buffer和tcp.receive.buffer到2MB。
缓存策略选择
- 共享缓存:所有节点数据一致,适合读多写少。
- 非共享缓存:本地缓存,不复制,但支持集群锁,适合临时数据。
- 溢出策略:当内存不足时,将数据写入磁盘。注意:磁盘溢出会大幅增加延迟,建议堆内内存足够。
避免大对象
Terracotta序列化大对象(如List
)会消耗网络带宽和CPU,尽量将缓存粒度拆细,比如缓存单个用户而非整个用户列表。
常见应用场景
高频访问数据共享
比如电商商品详情页,每个节点缓存热门商品数据,使用Terracotta后,后端修改商品信息只需要更新一个节点,所有节点立即生效,避免缓存穿透。
集群会话管理
传统Tomcat Session复制很慢,改用Terracotta存储Session,每个节点本地读写,节点间实时同步,故障切换无感知,特别适合需要粘性会话的应用。
分布式缓存Terracotta常见问题解答
问题1:Terracotta分布式缓存配置复杂吗?
配置复杂度属于中等水平,你需要起一个Terracotta服务器集群,然后在客户端依赖中加上Ehcache集群模块。相比Redis哨兵模式,Terracotta不需要额外选主逻辑,节点自动发现,但需要额外维护一个Java进程,对于已有Spring Boot项目,集成相当简单,官方文档提供starter。
问题2:Terracotta集群如何扩容?
新增节点只需要修改客户端的connection url,添加新节点地址。Terracotta会自动重新平衡数据,但建议在低峰期操作,如果使用Terracotta DB商业版,支持在线扩容无需停机,开源版需要滚动重启客户端。
问题3:Terracotta持久化是否可靠?
开源版持久化依赖磁盘溢出,但非强持久化。商业版Terracotta DB提供WAL(Write Ahead Log)和快照,保证数据不丢,如果追求高可用且数据重要,建议使用Terracotta DB或结合数据库做冷备。
Terracotta作为Java原生的分布式缓存,在需要强一致性和低延迟的Java项目中,依然是值得优先考虑的方案,它不像Redis那样需要跨语言,也不像Ignite那样重,它只做一件事:让Java缓存集群化,并且做得很好。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/508090.html



