1.通过util.zip带的gzip压缩程序
Coherence对象压缩程序如下
package coherencetest;
import com.tangosol.net.CacheFactory;
import java.util.zip.*; import java.io.*; import com.tangosol.net.CacheFactory; import com.tangosol.net.ConfigurableCacheFactory; import com.tangosol.net.DefaultConfigurableCacheFactory; import com.tangosol.net.NamedCache;
public class CompressObject { public CompressObject() { super(); } public static byte[] writeCompressObject(Person object) { byte[] data_=null; try { //建立字节数组输出流 ByteArrayOutputStream o = new ByteArrayOutputStream(); //建立gzip压缩输出流 GZIPOutputStream gzout=new GZIPOutputStream(o); //建立对象序列化输出流 ObjectOutputStream out = new ObjectOutputStream(gzout); out.writeObject(object); out.flush(); out.close(); gzout.close(); //返回压缩字节流 data_=o.toByteArray(); o.close(); }catch(IOException e) { System.out.println(e); } return(data_); } public static Person readCompressObject(byte[] data_) { Person object_=null; try { //建立字节数组输入流 ByteArrayInputStream i = new ByteArrayInputStream(data_); //建立gzip解压输入流 GZIPInputStream gzin=new GZIPInputStream(i); //建立对象序列化输入流 ObjectInputStream in = new ObjectInputStream(gzin); //按制定类型还原对象 object_=(Person)in.readObject(); i.close(); gzin.close(); in.close(); }catch(ClassNotFoundException e) { System.out.println(e); }catch(IOException e) { System.out.println(e); } return(object_); } public static void main (String [] args) { CompressObject co = new CompressObject(); Person person = new Person(); writeObjectToFile("zipcompress_before",person); //System.out.println(person); byte[] compressperson = writeCompressObject(person); writeBytesToFile("zipcompress_after",compressperson); String personstr = new String(compressperson); NamedCache cache = CacheFactory.getCache("POFSample"); for (int i=0;i<10000;i++) { // cache.put (i,compressperson); cache.put (Integer.toString(i),compressperson); } System.out.println("put success"); byte[] a = (byte[]) cache.get("1"); Person person1 = readCompressObject(a); System.out.println(person1.getFirstname()); System.out.println(person1.getLastname()); System.out.println(person1.getAddress()); //cache.retrieveCache(); } public static void writeObjectToFile(String Filename, Object obj) { try { FileOutputStream outStream = new FileOutputStream("c:/"+Filename); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outStream); objectOutputStream.writeObject(obj); outStream.close(); System.out.println("successful");
// if file doesnt exists, then create it } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void writeBytesToFile(String Filename, byte[] objs) { try { FileOutputStream outStream = new FileOutputStream("c:/"+Filename); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outStream); objectOutputStream.write(objs); outStream.close(); System.out.println("successful");
// if file doesnt exists, then create it } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
|
测试了一下,原来的对象3.96kb,然后经过压缩以后2.01K,还是有减少。
但通过Coherence的visualvm看了一下,发现平均对象大小是1byte.难道coherence只存放对象的指针吗?
2.通过kryo的序列化方法
package coherencetest;
import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output;
import com.tangosol.dev.assembler.New; import com.tangosol.net.CacheFactory; import com.tangosol.net.NamedCache;
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;
import org.objenesis.strategy.SerializingInstantiatorStrategy; import org.objenesis.strategy.StdInstantiatorStrategy;
import java.io.IOException; import java.io.ObjectOutputStream;
public class kryoCompress { static int BYTES_LENTH = 20000; public kryoCompress() { super(); } public static void main(String[] args) { // TODO Auto-generated method stub Person person = new Person(); writeObjectToFile("person2",person); Kryo kryo = new Kryo(); kryo.setInstantiatorStrategy(new StdInstantiatorStrategy()); byte[] scbytes = null; try { scbytes= kryocompress(person,kryo); //System.out.println(ObjectSizeFetcher.getObjectSize(scbytes)); writeBytesToFile("personcompress",scbytes); } catch (Exception e) { System.out.println("kryocompress:"+e.getMessage()); } Person backsc =kryodeserialize(scbytes,kryo); System.out.println("kryodeserialize:["+backsc.getAddress()+"]");
} public static byte[] kryocompress(Person object, Kryo kryo) throws IOException { byte[] buffer = new byte[BYTES_LENTH]; Output out = new Output(buffer); kryo.writeObject(out, object); //System.out.println("kryocompress====total:"+out.total()); //System.out.println("kryocompress====position:"+out.position()); return out.toBytes(); } public static Person kryodeserialize(byte[] bytes,Kryo kryo) { Input input = null; try { input = new Input(bytes); return (Person)kryo.readObject(input, Person.class); } catch (Exception e) { System.out.println("kryodeserialize==#==["+e.getMessage()+"]"); //System.out.println(e.getMessage()); } return null; } public static void writeObjectToFile(String Filename, Object obj) { try { FileOutputStream outStream = new FileOutputStream("c:/"+Filename); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outStream); objectOutputStream.writeObject(obj); outStream.close(); System.out.println("successful");
// if file doesnt exists, then create it } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void writeBytesToFile(String Filename, byte[] objs) { try { FileOutputStream outStream = new FileOutputStream("c:/"+Filename); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outStream); objectOutputStream.write(objs); outStream.close(); System.out.println("successful");
// if file doesnt exists, then create it } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
|
测试了一下,原来标准的3.96K的对象,经过kryo序列化后变成了3.01K.可见应该只是序列化上的优化,压缩率比较小.
计算Coherence对象大小的程序
另外附上一个计算coherence对象大小的程序
package coherencetest;
import java.text.DecimalFormat; import java.util.Map; import java.util.Set; import java.util.TreeMap;
import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.ObjectName;
import com.tangosol.net.CacheFactory;
import java.io.IOException;
import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL;
public class CalculateTheSizeOfPeopleCache { @SuppressWarnings({ "unchecked", "rawtypes" }) private void run() throws Exception { // Enable JMX support in this Coherence data grid session... System.setProperty("tangosol.coherence.management", "all"); // Create a sample cache just to access the data grid... CacheFactory.getCache(MBeanServerFactory.class.getName()); // Gets the JMX server from Coherence data grid... MBeanServer jmxServer = getJMXServer(); System.out.println(jmxServer.toString()); if (jmxServer != null) System.out.println("can not get jmxServer"); //MBeanServerConnection jmxServer = getJMXServer(); // Creates a internal data structure that would maintain // the statistics from each cache in the data grid... Map cacheList = new TreeMap(); Set jmxObjectList = jmxServer.queryNames(new ObjectName("Coherence:type=Cache,*"), null); if (jmxObjectList !=null) { System.out.println("can not get jmxOBjectList"); System.out.println(jmxObjectList.size()); } for (Object jmxObject : jmxObjectList) { System.out.println("Enter"); ObjectName jmxObjectName = (ObjectName) jmxObject; String cacheName = jmxObjectName.getKeyProperty("name"); if (cacheName.equals(MBeanServerFactory.class.getName())) { continue; } else { cacheList.put(cacheName, new Statistics(cacheName)); } } // Updates the internal data structure with statistic data // retrieved from caches inside the in-memory data grid... Set<String> cacheNames = cacheList.keySet(); for (String cacheName : cacheNames) { Set resultSet = jmxServer.queryNames( new ObjectName("Coherence:type=Cache,name=" + cacheName + ",*"), null); for (Object resultSetRef : resultSet) { ObjectName objectName = (ObjectName) resultSetRef; if (objectName.getKeyProperty("tier").equals("back")) { int unit = (Integer) jmxServer.getAttribute(objectName, "Units"); int size = (Integer) jmxServer.getAttribute(objectName, "Size"); Statistics statistics = (Statistics) cacheList.get(cacheName); statistics.incrementUnit(unit); statistics.incrementSize(size); cacheList.put(cacheName, statistics); } } } // Finally... print the objects from the internal data // structure that represents the statistics from caches... cacheNames = cacheList.keySet(); for (String cacheName : cacheNames) { Statistics estatisticas = (Statistics) cacheList.get(cacheName); System.out.println(estatisticas); } } /* public static MBeanServerConnection getJMXServer() throws IOException { JMXServiceURL url = new JMXServiceURL("service://..."); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); return jmxc.getMBeanServerConnection(); } */ public MBeanServer getJMXServer() { MBeanServer jmxServer = null; for (Object jmxServerRef : MBeanServerFactory.findMBeanServer(null)) { jmxServer = (MBeanServer) jmxServerRef; System.out.println(jmxServer.getDefaultDomain().toString()); if (jmxServer.getDefaultDomain().equals(DEFAULT_DOMAIN) || DEFAULT_DOMAIN.length() == 0) { break; } jmxServer = null; } if (jmxServer == null) { jmxServer = MBeanServerFactory.createMBeanServer(DEFAULT_DOMAIN); } return jmxServer; }
private class Statistics { private long unit; private long size; private String cacheName; public Statistics(String cacheName) { this.cacheName = cacheName; }
public void incrementUnit(long unit) { this.unit += unit; }
public void incrementSize(long size) { this.size += size; }
public long getUnit() { return unit; }
public long getSize() { return size; }
public double getUnitInMB() { return unit / (1024.0 * 1024.0); }
public double getAverageSize() { return size == 0 ? 0 : unit / size; }
public String toString() { StringBuffer sb = new StringBuffer(); sb.append("\nCache Statistics of '").append(cacheName).append("':\n"); sb.append(" - Total Entries of Cache -----> " + getSize()).append("\n"); sb.append(" - Used Memory (Bytes) --------> " + getUnit()).append("\n"); sb.append(" - Used Memory (MB) -----------> " + FORMAT.format(getUnitInMB())).append("\n"); sb.append(" - Object Average Size --------> " + FORMAT.format(getAverageSize())).append("\n"); return sb.toString(); }
} public static void main(String[] args) throws Exception { new CalculateTheSizeOfPeopleCache().run(); } public static final DecimalFormat FORMAT = new DecimalFormat("###.###"); public static final String DEFAULT_DOMAIN = "DefaultDomain"; public static final String DOMAIN_NAME = "Coherence"; //public static final String DOMAIN_NAME = "enie's cluster";
}
|
需要的条件是:
- 不能以Coherence Extend Client的方式连入集群
- 需要开启-Dtangosol.coherence.management.remote=true -Dtangosol.coherence.management=all 参数
- 需要和cluster环境保持一直,生产就是生产,开发就是开发,-Dtangosol.coherence.mode=prod
输出如下:
Cache Statistics of 'POFSample':
- Total Entries of Cache -----> 10001
- Used Memory (Bytes) --------> 10001
- Used Memory (MB) -----------> 0.01
- Object Average Size --------> 1