最近研究ehcache同步时发现一个问题:

现有A、B两个服务器,由A服务器向B服务器同步信息,采用RMI方式手动方式进行同步

配置信息如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
monitoring="autodetect" dynamicConfig="true"> <cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName = 127.0.0.1,
port = 50001,
socketTimeoutMillis=10000" /> <cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//127.0.0.1:40001/clusterCache"/> <cache name="clusterCache" maxEntriesLocalHeap="999999999" eternal="false"
timeToIdleSeconds="1800" timeToLiveSeconds="1800" overflowToDisk="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
</cache>
</ehcache>

同步的核心代码:

String key = StringUtils.leftPad(Thread.currentThread().getName() + a, 20, "a");
Element element = new Element(key, value);
CacheInstance.cache.put(element);

其中,value全部引用的是同一个静态变量 static final byte[] bytes = new byte[1024*100];

测试发现问题:假设现有单个byte[1024*100],同步16000个,那么同步的数据大小为1.5G左右,但是同步过程中,通过监控B服务器的网卡,发现网卡上实际并没有如此大的数据

后续经过分析得知:

  RMI协议,是有java序列化和HTTP协议构成,同步时会将同步的数据全部序列化,而放入Element的value,实际上都是对静态变量value的引用,而ehcache同步时默认是同步1000个Element,所以这1000个Element实际上经过网卡的数据只有一个byte[1024*100]大小。

Ehcache同步源码:

    private void writeReplicationQueue() {
List<EventMessage> eventMessages = extractEventMessages(maximumBatchSize); if (!eventMessages.isEmpty()) {
for (CachePeer cachePeer : listRemoteCachePeers(eventMessages.get(0).getEhcache())) {
try {
cachePeer.send(eventMessages);
} catch (UnmarshalException e) {
String message = e.getMessage();
if (message.contains("Read time out") || message.contains("Read timed out")) {
LOG.warn("Unable to send message to remote peer due to socket read timeout. Consider increasing" +
" the socketTimeoutMillis setting in the cacheManagerPeerListenerFactory. " +
"Message was: " + message);
} else {
LOG.debug("Unable to send message to remote peer. Message was: " + message);
}
} catch (Throwable t) {
LOG.warn("Unable to send message to remote peer. Message was: " + t.getMessage(), t);
}
}
}
}

  其中,maximumBatchSize是本次同步Element的数量,该值可以在如下配置中进行自定义:

<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties = "asynchronousReplicationMaximumBatchSize=1"/>

  其中,asynchronousReplicationMaximumBatchSize=1表示每次同步一个Element,那么此时经过网卡的流量就跟实际正常。

最新文章

  1. [译]How to Write a Git Commit Message
  2. Jsp+ Servlet+Ajax实现点赞功能
  3. visual studio installer制作安装包——Installer 类
  4. Linux开启关闭redis
  5. 协议(Protocol)---实例
  6. 年过三十,我为什么要学习ios 与安卓App 移动端技术
  7. 本地开发时同时启动多个tomcat服务器
  8. 外语学习强烈推荐Rosetta Stone
  9. 我是实践派之mongo的一主多从
  10. 数据结构之网络流入门(Network Flow)简单小节
  11. LDA工程实践之算法篇之(一)算法实现正确性验证(转)
  12. C# DataGridView绑定List对象时,利用BindingList来实现增删查改
  13. FreeSql 新的八大骚功能,.NETCore 你必须晓得的 ORM
  14. Deepin linux Compass.app安装
  15. 二、npm scripts
  16. css预处理和bootstrap
  17. Windows 环境搭建Redis集群(win 64位)
  18. 51nod 1051 最大子矩阵和
  19. kickstart配置LINUX无人值守选项--rootpw
  20. (剑指Offer)面试题49:把字符串转换为整数

热门文章

  1. 回话技术-Cookie-记录上一次访问时间
  2. Openmp编程练习
  3. DZY Loves Math II:多重背包dp+组合数
  4. [专题总结]矩阵树定理Matrix_Tree及题目&amp;题解
  5. 差异---虐爆了yxs的 后缀数组裸题 板子题 单调栈的简单应用 字符串的基础理解考察题
  6. StringBuffer 和 StringBuilde
  7. 深入理解java虚拟机系列初篇(一):为什么要学习JVM?
  8. python、C++经典算法题:打印100以内的素数
  9. [LINQ2Dapper]最完整Dapper To Linq框架(四)---Linq和SQL并行使用
  10. [ PyQt入门教程 ] PyQt5中数据表格控件QTableWidget使用方法