When I define one replicated cluster, and Setup the unit-calculator to binary. hopefully, from the Coherence Mbeans, I should be able to see the object size vs units. By default, size is the same with unit. When I put some data to the replicated cluster. From the cluster jvm console, I get the following Errors. the cache extend client didn’t get any error. But when you query the cluster, No objects founds. they are all gone.
2010-07-09 15:50:47.790/300.414 Oracle Coherence GE 3.5.3/465 <Error> (thread=ReplicatedCache, member=1): java.lang.IllegalArgumentException: Unsupported key or value: Key=9, Value=ID 9PMName PM9PoAmount 135.0PoNumber null at com.tangosol.net.cache.BinaryMemoryCalculator.calculateUnits(BinaryMemoryCalculator.java:43) at com.tangosol.net.cache.OldCache$Entry.calculateUnits(OldCache.java:2397) at com.tangosol.net.cache.OldCache$Entry.onAdd(OldCache.java:1990) at com.tangosol.util.SafeHashMap.put(SafeHashMap.java:244) at com.tangosol.net.cache.OldCache.put(OldCache.java:266) at com.tangosol.coherence.component.util.CacheHandler.onLeaseUpdate(CacheHandler.CDB:45) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache.performUpdate(Replic atedCache.CDB:11) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache.onLeaseUpdateRequest (ReplicatedCache.CDB:22) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache$LeaseUpdateRequest.o nReceived(ReplicatedCache.CDB:5) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.onMessage(Grid.CDB:9) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.onNotify(Grid.CDB:136) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache.onNotify(ReplicatedC ache.CDB:3) at com.tangosol.coherence.component.util.Daemon.run(Daemon.CDB:42) at java.lang.Thread.run(Thread.java:619) |
What does this error means? it looks like there are something wrong with the BinaryMemoryCalculator.calculateUnits
what’s the logic in this method. we can turn to JD-GUI [ java decompilers, like the .net reflector. ] I get the code here
/* */ public int calculateUnits(Object oKey, Object oValue) /* */ { /* 35 */ if ((oKey instanceof Binary) && (oValue instanceof Binary)) /* */ { /* 37 */ return padMemorySize(SIZE_ENTRY + 2 * SIZE_BINARY + ((Binary)oKey).length() + ((Binary)oValue).length()); /* */ } /* */ /* 43 */ throw new IllegalArgumentException("Unsupported key or value: Key=" + oKey + ", Value=" + oValue); /* */ } |
cache configuration
<replicated-scheme> <scheme-name>repl-default</scheme-name> <service-name>ReplicatedCache</service-name> <serializer> <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name> </serializer> <lease-granularity>member</lease-granularity> <backing-map-scheme> <local-scheme> <unit-calculator>BINARY</unit-calculator> </local-scheme> </backing-map-scheme> <autostart>true</autostart> </replicated-scheme> |
So the error means either Key or Object is not a Binary type. How comes it is not a Binary? the system controls the internal storage.
how about dumping out the class type of key and the value?
BTrace is my friend then , basically, I want to print out the class of okey/ovalue before the method get called.
here is the Btrace script
/* BTrace Script Template */ import com.sun.btrace.BTraceUtils; import com.sun.btrace.annotations.*; import com.tangosol.net.cache.*; import static com.sun.btrace.BTraceUtils.*; @BTrace public class TracingScript { /* put your code here */ @OnMethod(clazz="com.tangosol.net.cache.BinaryMemoryCalculator",method="calculateUnits",location=@Location(where=Where.BEFORE)) public static void oncalculateUnits(@Self com.tangosol.net.cache.BinaryMemoryCalculator self, Object a, Object b) { print("a "); println( a); println( BTraceUtils.classOf(a)); print("b "); println( b); println( BTraceUtils.classOf(b)); } } |
then your can trace the cacheserver either by startuping btrace.bat pidofthejvm pathoftrace.java, or using btrace plugin for jvisualvm
as the error implys, it do store the object as the native format instead of the binary format
a 98 class java.lang.Integer b POFLib.PurchaseOrder@12fc61a class POFLib.PurchaseOrder a 99 class java.lang.Integer b POFLib.PurchaseOrder@cef65 class POFLib.PurchaseOrder |
if I change the cachem schema back to distributed. No error, and the object is stored as Binary format.
a com.tangosol.util.Binary@153b2cb class com.tangosol.util.Binary b com.tangosol.util.Binary@1ff2e1b class com.tangosol.util.Binary |
C# code
INamedCache cache = CacheFactory.GetCache("repl-customer"); PurchaseOrder o = new PurchaseOrder(); o.ID = i; o.PMName = "PM" + i; o.PoAmount=rand.Next(50000); cache.Add( i , o); |
|
conclusion:
- if you use the replicated cache. the unit-calculator has to be Fixed.
- Objects is stored in different format. Native vs Binary for replicated mode and distributed mode
- if Object is stored in native format, will there be more footprint?
- replicated mode doesn’t support Index, check the blog here.