最近研究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,那么此时经过网卡的流量就跟实际正常。

ehcache同步原理的更多相关文章

  1. rsync 文件校验及同步原理

    rsync 文件校验及同步原理 参考:http://rsync.samba.org/how-rsync-works.html 我们关注的是其发送与接收校验文件的算法,这里附上原文和我老婆(^_^)的翻 ...

  2. 10-openldap同步原理

    openldap同步原理 阅读视图 openldap同步原理 syncrepl.slurpd同步机制优缺点 OpenLDAP同步条件 OpenLDAP同步参数 1. openldap同步原理 Open ...

  3. AlwaysOn的数据同步原理

    摘抄自<SQL Server 2012实施与管理实战指南> 镜像的工作原理: 那么主体数据库和镜像数据库是如何同步数据的呢?SQL数据库中任何的数据变化都会先记录到事务日志中,然后才会真正 ...

  4. Mysql 主从同步原理简析

    在开始讲述原理的情况下,我们先来做个知识汇总,究竟什么是主从,为什么要搞主从,可以怎么实现主从,mysql主从同步的原理1.什么是主从其实主从这个概念非常简单主机就是我们平常主要用来读写的服务,我们称 ...

  5. 架构师必备:MySQL主从同步原理和应用

    日常工作中,MySQL数据库是必不可少的存储,其中读写分离基本是标配,而这背后需要MySQL开启主从同步,形成一主一从.或一主多从的架构,掌握主从同步的原理和知道如何实际应用,是一个架构师的必备技能. ...

  6. MongoDB副本集配置系列十一:MongoDB 数据同步原理和自动故障转移的原理

    1:数据同步的原理: 当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步: 1:检查自己local库的oplog.rs集合找出最近的时间戳. 2:检查Primary ...

  7. Java的多线程机制系列:(三)synchronized的同步原理

    synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在字节码上编译为 ...

  8. java 线程同步 原理 sleep和wait区别

    java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...

  9. MySQL主从同步原理 部署【转】

    一.主从的作用:1.可以当做一种备份方式2.用来实现读写分离,缓解一个数据库的压力二.MySQL主从备份原理master 上提供binlog ,slave 通过 I/O线程从 master拿取 bin ...

随机推荐

  1. python图像处理之PIL库

    PIL库是python语言第三方库,需要通过pip工具安装,安装库的名字是pillow. PIL库支持图像存储,显示和处理,它能够处理几乎所有图片格式,可以完成对图像的缩放,裁剪,叠加以及向图像添加线 ...

  2. foreach数组并直接改变数组内容

    <?php $arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } // $arr is ...

  3. Pyhton网络爬虫之CrawlSpider

    一.什么是CrawlSpider? 在学习CrawlSpider之前如果我们想爬取某网站前100页的内容的话,我们可以使用的方法是通过Request模块手动发起请求,递归调用parse方法,写起来非常 ...

  4. Python3.8更新特性

    Python 3.8.0稳定版 部分新特性: • PEP 572,赋值+表达式 :=可以将一个表达式或者一个 if (n := len(a)) > 10:#表达式仍然用,赋值也放一起,后面不用多 ...

  5. abp中将SqlServer切换为MySQL

    一.移除默认SQL Server相关包 在EntityFrameworkCore项目下移除包Microsoft.EntityFrameworkCore.SqlServer.Microsoft.Enti ...

  6. html中<button>标签的type

    HTML的<button>标签的type主要有三种可选值,reset.submit.button. 其中reset为重置按钮,用于清除form表单的数据:submit为提交按钮,点击后会对 ...

  7. 学习笔记26_MVC前台强类型参数

    *一般在MVC中,aspx后台要往前台传递参数,使用ViewData["Key"] = obj; 前台就要 <%=(ViewData["key"] as ...

  8. Linux下修改文件权限,所有权

    Linux与Unix是多用户操作系统,所以文件的权限与所有权的实现就显得很有必要:每个文件主要与三组权限打交道,分别是用户(user),用户组(group),其他用户(other) 用户(u)是文件的 ...

  9. Maven配置setting.xml详细说明

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  10. AndroidOS体系结构

    首先上图一张 对照着图,我们再来看Android 系统的体系结构就爽多了.我们从底层向上进行分析. 一.Linux 内核层 Linux Kernel 基于linux2.6.其核心系统服务如安全性.内存 ...