Skip to content

Commit

Permalink
Produce a warning when dbms.pagecache.memory.size is not configured
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvest committed Nov 10, 2016
1 parent aad0689 commit a41b29a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 46 deletions.
Expand Up @@ -37,7 +37,6 @@
import org.neo4j.kernel.configuration.Settings; import org.neo4j.kernel.configuration.Settings;
import org.neo4j.kernel.configuration.Title; import org.neo4j.kernel.configuration.Title;
import org.neo4j.kernel.impl.cache.MonitorGc; import org.neo4j.kernel.impl.cache.MonitorGc;
import org.neo4j.kernel.impl.util.OsBeanUtil;
import org.neo4j.logging.Level; import org.neo4j.logging.Level;


import static org.neo4j.graphdb.factory.GraphDatabaseSettings.BoltConnector.EncryptionLevel.OPTIONAL; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.BoltConnector.EncryptionLevel.OPTIONAL;
Expand Down Expand Up @@ -375,47 +374,7 @@ public abstract class GraphDatabaseSettings
"the page cache. The default page cache memory assumes the machine is dedicated to running " + "the page cache. The default page cache memory assumes the machine is dedicated to running " +
"Neo4j, and is heuristically set to 50% of RAM minus the max Java heap size." ) "Neo4j, and is heuristically set to 50% of RAM minus the max Java heap size." )
public static final Setting<Long> pagecache_memory = public static final Setting<Long> pagecache_memory =
setting( "dbms.memory.pagecache.size", BYTES, defaultPageCacheMemory(), min( 8192 * 30L ) ); setting( "dbms.memory.pagecache.size", BYTES, null, min( 8192 * 30L ) );

private static String defaultPageCacheMemory()
{
// First check if we have a default override...
String defaultMemoryOverride = System.getProperty( "dbms.pagecache.memory.default.override" );
if ( defaultMemoryOverride != null )
{
return defaultMemoryOverride;
}

double ratioOfFreeMem = 0.50;
String defaultMemoryRatioOverride = System.getProperty( "dbms.pagecache.memory.ratio.default.override" );
if ( defaultMemoryRatioOverride != null )
{
ratioOfFreeMem = Double.parseDouble( defaultMemoryRatioOverride );
}

// Try to compute (RAM - maxheap) * 0.50 if we can get reliable numbers...
long maxHeapMemory = Runtime.getRuntime().maxMemory();
if ( 0 < maxHeapMemory && maxHeapMemory < Long.MAX_VALUE )
{
try
{
long physicalMemory = OsBeanUtil.getTotalPhysicalMemory();
if ( 0 < physicalMemory && physicalMemory < Long.MAX_VALUE && maxHeapMemory < physicalMemory )
{
long heuristic = (long) ((physicalMemory - maxHeapMemory) * ratioOfFreeMem);
long min = ByteUnit.mebiBytes( 32 ); // We'd like at least 32 MiBs.
long max = ByteUnit.tebiBytes( 1 ); // Don't heuristically take more than 1 TiB.
long memory = Math.min( max, Math.max( min, heuristic ) );
return String.valueOf( memory );
}
}
catch ( Exception ignore )
{
}
}
// ... otherwise we just go with 2 GiBs.
return "2g";
}


@Description( "Specify which page swapper to use for doing paged IO. " + @Description( "Specify which page swapper to use for doing paged IO. " +
"This is only used when integrating with proprietary storage technology." ) "This is only used when integrating with proprietary storage technology." )
Expand Down
Expand Up @@ -34,6 +34,7 @@
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.mapped_memory_page_size; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.mapped_memory_page_size;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.pagecache_memory; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.pagecache_memory;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.pagecache_swapper; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.pagecache_swapper;
import static org.neo4j.kernel.configuration.Settings.BYTES;


public class ConfiguringPageCacheFactory public class ConfiguringPageCacheFactory
{ {
Expand Down Expand Up @@ -102,7 +103,8 @@ protected PageCache createPageCache()


public int calculateMaxPages( Config config, int cachePageSize ) public int calculateMaxPages( Config config, int cachePageSize )
{ {
long pageCacheMemory = config.get( pagecache_memory ); Long pageCacheMemorySetting = config.get( pagecache_memory );
long pageCacheMemory = interpretMemorySetting( pageCacheMemorySetting );
long maxHeap = Runtime.getRuntime().maxMemory(); long maxHeap = Runtime.getRuntime().maxMemory();
if ( pageCacheMemory / maxHeap > 100 ) if ( pageCacheMemory / maxHeap > 100 )
{ {
Expand All @@ -114,6 +116,63 @@ public int calculateMaxPages( Config config, int cachePageSize )
return (int) Math.min( Integer.MAX_VALUE - 2000, pageCount ); return (int) Math.min( Integer.MAX_VALUE - 2000, pageCount );
} }


private long interpretMemorySetting( Long pageCacheMemorySetting )
{
if ( pageCacheMemorySetting != null )
{
return pageCacheMemorySetting;
}
String heuristic = defaultHeuristicPageCacheMemory();
log.warn( "The " + pagecache_memory.name() + " setting has not been configured. It is recommended that this " +
"setting is always explicitly configured, to ensure the system has a balanced configuration. " +
"Until then, a computed heuristic value of '" + heuristic + "' will be used " +
"instead. " );
return BYTES.apply( heuristic );
}

public static String defaultHeuristicPageCacheMemory()
{
// First check if we have a default override...
String defaultMemoryOverride = System.getProperty( "dbms.pagecache.memory.default.override" );
if ( defaultMemoryOverride != null )
{
return defaultMemoryOverride;
}

double ratioOfFreeMem = 0.50;
String defaultMemoryRatioOverride = System.getProperty( "dbms.pagecache.memory.ratio.default.override" );
if ( defaultMemoryRatioOverride != null )
{
ratioOfFreeMem = Double.parseDouble( defaultMemoryRatioOverride );
}

// Try to compute (RAM - maxheap) * 0.50 if we can get reliable numbers...
long maxHeapMemory = Runtime.getRuntime().maxMemory();
if ( 0 < maxHeapMemory && maxHeapMemory < Long.MAX_VALUE )
{
try
{
long physicalMemory = OsBeanUtil.getTotalPhysicalMemory();
if ( 0 < physicalMemory && physicalMemory < Long.MAX_VALUE && maxHeapMemory < physicalMemory )
{
long heuristic = (long) ((physicalMemory - maxHeapMemory) * ratioOfFreeMem);
long min = ByteUnit.mebiBytes( 32 ); // We'd like at least 32 MiBs.
long max = ByteUnit.gibiBytes( 20 ); // Don't heuristically take more than 20 GiBs.
// 20 GiBs of page cache memory is ~2.6 million 8 KiB pages. If each page has an overhead of
// 72 bytes, then this will take up ~175 MiBs of heap memory. We should be able to tolerate that
// in most environments.
long memory = Math.min( max, Math.max( min, heuristic ) );
return String.valueOf( memory );
}
}
catch ( Exception ignore )
{
}
}
// ... otherwise we just go with 2 GiBs.
return "2g";
}

public int calculatePageSize( Config config, PageSwapperFactory swapperFactory ) public int calculatePageSize( Config config, PageSwapperFactory swapperFactory )
{ {
int pageSwappersPageSizeHint = swapperFactory.getCachePageSizeHint(); int pageSwappersPageSizeHint = swapperFactory.getCachePageSizeHint();
Expand Down
Expand Up @@ -20,12 +20,13 @@
package org.neo4j.unsafe.impl.batchimport; package org.neo4j.unsafe.impl.batchimport;


import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory;


import static java.lang.Math.min; import static java.lang.Math.min;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.pagecache_memory;
import static org.neo4j.io.ByteUnit.kibiBytes; import static org.neo4j.io.ByteUnit.kibiBytes;
import static org.neo4j.io.ByteUnit.mebiBytes; import static org.neo4j.io.ByteUnit.mebiBytes;
import static org.neo4j.kernel.configuration.Settings.BYTES;


/** /**
* User controlled configuration for a {@link BatchImporter}. * User controlled configuration for a {@link BatchImporter}.
Expand Down Expand Up @@ -64,7 +65,8 @@ public long pageCacheMemory()
{ {
// Get the upper bound of what we can get from the default config calculation // Get the upper bound of what we can get from the default config calculation
// We even want to limit amount of memory a bit more since we don't need very much during import // We even want to limit amount of memory a bit more since we don't need very much during import
return min( MAX_PAGE_CACHE_MEMORY, Config.defaults().get( pagecache_memory ) ); String defaultPageCacheMemory = ConfiguringPageCacheFactory.defaultHeuristicPageCacheMemory();
return min( MAX_PAGE_CACHE_MEMORY, BYTES.apply( defaultPageCacheMemory ) );
} }


@Override @Override
Expand Down Expand Up @@ -124,7 +126,8 @@ public Overridden( Config config )
@Override @Override
public long pageCacheMemory() public long pageCacheMemory()
{ {
return min( MAX_PAGE_CACHE_MEMORY, config.get( pagecache_memory ) ); String defaultPageCacheMemory = ConfiguringPageCacheFactory.defaultHeuristicPageCacheMemory();
return min( MAX_PAGE_CACHE_MEMORY, BYTES.apply( defaultPageCacheMemory ) );
} }


@Override @Override
Expand Down

0 comments on commit a41b29a

Please sign in to comment.