@RequestMapping("{cacheName}/{key}/details") @ResponseBody public Object keyDetail( @PathVariable("cacheName") String cacheName, @PathVariable("key") String key, Model model) { Element element = cacheManager.getCache(cacheName).get(key); String dataPattern = "yyyy-MM-dd hh:mm:ss"; Map<String, Object> data = Maps.newHashMap(); data.put("objectValue", element.getObjectValue().toString()); data.put("size", PrettyMemoryUtils.prettyByteSize(element.getSerializedSize())); data.put("hitCount", element.getHitCount()); Date latestOfCreationAndUpdateTime = new Date(element.getLatestOfCreationAndUpdateTime()); data.put( "latestOfCreationAndUpdateTime", DateFormatUtils.format(latestOfCreationAndUpdateTime, dataPattern)); Date lastAccessTime = new Date(element.getLastAccessTime()); data.put("lastAccessTime", DateFormatUtils.format(lastAccessTime, dataPattern)); if (element.getExpirationTime() == Long.MAX_VALUE) { data.put("expirationTime", "不过期"); } else { Date expirationTime = new Date(element.getExpirationTime()); data.put("expirationTime", DateFormatUtils.format(expirationTime, dataPattern)); } data.put("timeToIdle", element.getTimeToIdle()); data.put("timeToLive", element.getTimeToLive()); data.put("version", element.getVersion()); return data; }
/** * Measures the size of the memory store by measuring the serialized size of all elements. If the * objects are not Serializable they count as 0. * * <p>Warning: This method can be very expensive to run. Allow approximately 1 second per 1MB of * entries. Running this method could create liveness problems because the object lock is held for * a long period * * @return the size, in bytes */ public final long getSizeInBytes() throws CacheException { long sizeInBytes = 0; for (Object o : map.values()) { Element element = (Element) o; if (element != null) { sizeInBytes += element.getSerializedSize(); } } return sizeInBytes; }
/** * Bootstraps the cache from a random CachePeer. Requests are done in chunks estimated at 5MB * Serializable size. This balances memory use on each end and network performance. * * <p>Bootstrapping requires the establishment of a cluster. This can be instantaneous for * manually configued clusters or may take a number of seconds for multicast ones. This method * waits up to 11 seconds for a cluster to form. * * @throws RemoteCacheException if anything goes wrong with the remote call */ public void doLoad(Ehcache cache) throws RemoteCacheException { List cachePeers = acquireCachePeers(cache); if (cachePeers == null || cachePeers.size() == 0) { LOG.debug( "Empty list of cache peers for cache " + cache.getName() + ". No cache peer to bootstrap from."); return; } Random random = new Random(); int randomPeerNumber = random.nextInt(cachePeers.size()); CachePeer cachePeer = (CachePeer) cachePeers.get(randomPeerNumber); LOG.debug("Bootstrapping " + cache.getName() + " from " + cachePeer); try { // Estimate element size Element sampleElement = null; List keys = cachePeer.getKeys(); for (int i = 0; i < keys.size(); i++) { Serializable key = (Serializable) keys.get(i); sampleElement = cachePeer.getQuiet(key); if (sampleElement != null && sampleElement.getSerializedSize() != 0) { break; } } if (sampleElement == null) { LOG.debug( "All cache peer elements were either null or empty. Nothing to bootstrap from. Cache was " + cache.getName() + ". Cache peer was " + cachePeer); return; } long size = sampleElement.getSerializedSize(); int chunkSize = (int) (maximumChunkSizeBytes / size); List requestChunk = new ArrayList(); for (int i = 0; i < keys.size(); i++) { Serializable serializable = (Serializable) keys.get(i); requestChunk.add(serializable); if (requestChunk.size() == chunkSize) { fetchAndPutElements(cache, requestChunk, cachePeer); requestChunk.clear(); } } // get leftovers fetchAndPutElements(cache, requestChunk, cachePeer); LOG.debug( "Bootstrap of " + cache.getName() + " from " + cachePeer + " finished. " + keys.size() + " keys requested."); } catch (Throwable t) { throw new RemoteCacheException( "Error bootstrapping from remote peer. Message was: " + t.getMessage(), t); } }
/** * Performance and capacity tests. * * <p> */ @Test public void testBootstrap() throws CacheException, InterruptedException, RemoteException { // load up some data StopWatch stopWatch = new StopWatch(); Integer index = null; for (int i = 0; i < 2; i++) { for (int j = 0; j < 1000; j++) { index = Integer.valueOf(((1000 * i) + j)); cache1.put( new Element( index, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")); } } long elapsed = stopWatch.getElapsedTime(); long putTime = ((elapsed / 1000)); LOG.info("Put Elapsed time: " + putTime); assertEquals(2000, cache1.getSize()); Thread.sleep(7000); assertEquals(2000, manager2.getCache("sampleCache1").getSize()); assertEquals(2000, manager3.getCache("sampleCache1").getSize()); assertEquals(2000, manager4.getCache("sampleCache1").getSize()); assertEquals(2000, manager5.getCache("sampleCache1").getSize()); // now test bootstrap manager1.addCache("bootStrapResults"); Cache cache = manager1.getCache("bootStrapResults"); List cachePeers = manager1.getCacheManagerPeerProvider("RMI").listRemoteCachePeers(cache1); CachePeer cachePeer = (CachePeer) cachePeers.get(0); List keys = cachePeer.getKeys(); assertEquals(2000, keys.size()); Element firstElement = cachePeer.getQuiet((Serializable) keys.get(0)); long size = firstElement.getSerializedSize(); assertEquals(504, size); int chunkSize = (int) (5000000 / size); List requestChunk = new ArrayList(); for (int i = 0; i < keys.size(); i++) { Serializable serializable = (Serializable) keys.get(i); requestChunk.add(serializable); if (requestChunk.size() == chunkSize) { fetchAndPutElements(cache, requestChunk, cachePeer); requestChunk.clear(); } } // get leftovers fetchAndPutElements(cache, requestChunk, cachePeer); assertEquals(keys.size(), cache.getSize()); }