|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectcom.bigdata.LRUNexus
public class LRUNexus
Static singleton factory.
There are two quick fixes: (1) Disable the Global LRU; and (2)
discard the cache if there is an abort on a store. The latter is
pretty easy since we only have one store with abort semantics, which
is the AbstractJournal, so that is how this is being handled
right now by AbstractJournal.abort().
An optimization would essentially isolate the writes on the cache per BTree or between commits. At the commit point, the written records would be migrated into the "committed" cache for the store. The caller would read on the uncommitted cache, which would read through to the "committed" cache. This would prevent incorrect reads without requiring us to throw away valid records in the cache. This could be a significant performance gain if aborts are common on a machine with a lot of RAM.
LRUNexus.Options-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC
G1 appears faster for query, but somewhat slower for load. This is probably related to the increased memory demand during load (more of the data winds up buffered). G1 might work for both use cases with a smaller portion of the heap given over to buffers.
G1 can also trip a crash, at least during load. There is a Sun incident
ID# 1609804 for this., Look into the memory pool threshold notification mechanism. See
ManagementFactory.getMemoryPoolMXBeans() and
MemoryPoolMXBean. TonyP suggests that tracking the old
generation occupancy may be a better metric (more stable). The tricky
part is to identify which pool(s?) correspond(s) to the old generation.
Once that is done, the idea is to set a notification threshold using
MemoryPoolMXBean.setUsageThreshold(long) and to only clear
references from the tail of the global LRU when we have exceeded that
threshold. Reading the javadoc, it seems that threshold notification
would probably come after a (full) GC. The goal would have to be
something like reducing the bytesInMemory to some percentage of its
value at threshold notification (e.g., 80%). Since we can't directly
control that and the feedback from the JVM is only at full GC
intervals, we need to simply discard some percentage of the references
from the tail of the global LRU. We could actually adjust the desired
#of references on the LRU if that metric appears to be relatively
stable. However, note that the average #of bytes per reference and the
average #of instances of a reference on the LRU are not necessarily
stable values. We could also examine the recordCount (total cache size
across all caches). If weak references are cleared on an ongoing basis
rather than during the full GC mark phase, then that will be very close
to the real hard reference count., Does it make sense to both buffer the index segment nodes region and
buffer the nodes and leaves? [buffering the nodes region is an option.], Note that a r/w store will require an approach in which addresses are
PURGED from the store's cache during the commit protocol. That might be
handled at the tx layer., Better ergonomics! Perhaps keep some minimum amount for the JVM and
then set a trigger on the GC time and if it crosses 5-10% of the CPU
time for the application, then reduce the maximum bytes allowed for the
global LRU buffer., Settings be made public (or package private) and used as the
input to a designated constructor method signature for all of the
implementations. This would make it possible to plug in a new
implementation without hard wiring things in the code.
| Nested Class Summary | |
|---|---|
static interface |
LRUNexus.Options
These options are MUST BE specified as ENVIRONMENT variables on the command line when you start the JVM. |
| Field Summary | |
|---|---|
static IGlobalLRU<Long,Object> |
INSTANCE
Global instance. |
protected static org.apache.log4j.Logger |
log
|
| Constructor Summary | |
|---|---|
LRUNexus()
|
|
| Method Summary | |
|---|---|
static IGlobalLRU.ILRUCache<Long,Object> |
getCache(IRawStore store)
Factory returns the IGlobalLRU.ILRUCache for the store iff the
LRUNexus is enabled. |
static boolean |
getIndexSegmentBuildPopulatesCache()
Return true if the IndexSegmentBuilder will populate
the IGlobalLRU with records for the new IndexSegment
during the build. |
static void |
main(String[] args)
Command line utility may be used to confirm the environment settings. |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
protected static final transient org.apache.log4j.Logger log
public static final IGlobalLRU<Long,Object> INSTANCE
Note: A Sun G1 bug in JDK 1.6.0_16 provides a false estimate of the available memory.
LRUNexus.Options| Constructor Detail |
|---|
public LRUNexus()
| Method Detail |
|---|
public static final boolean getIndexSegmentBuildPopulatesCache()
true if the IndexSegmentBuilder will populate
the IGlobalLRU with records for the new IndexSegment
during the build.
LRUNexus.Options.INDEX_SEGMENT_BUILD_POPULATES_CACHEpublic static IGlobalLRU.ILRUCache<Long,Object> getCache(IRawStore store)
IGlobalLRU.ILRUCache for the store iff the
LRUNexus is enabled.
store - The store.
LRUNexus is enabled and
otherwise null.
IllegalArgumentException - if the store is null.
public static void main(String[] args)
throws ClassNotFoundException
args - Ignored. All parameters are specified either in the
environment or using JVM
-Dcom.bigdata.LRUNexus.foo=bar arguments on the
command line.
ClassNotFoundException
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||