diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 60f94456e9a..d9ea5210060 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -428,6 +428,9 @@ Release 2.2.1 - UNRELEASED HADOOP-10046. Print a log message when SSL is enabled. (David S. Wang via wang) + HADOOP-10079. log a warning message if group resolution takes too long. + (cmccabe) + OPTIMIZATIONS BUG FIXES diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java index 5bedadd7973..5a75cbdf15b 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java @@ -240,6 +240,14 @@ public class CommonConfigurationKeysPublic { public static final String HADOOP_SECURITY_GROUPS_CACHE_SECS = "hadoop.security.groups.cache.secs"; /** See core-default.xml */ + public static final long HADOOP_SECURITY_GROUPS_CACHE_SECS_DEFAULT = + 300; + /** See core-default.xml */ + public static final String HADOOP_SECURITY_GROUPS_CACHE_WARN_AFTER_MS = + "hadoop.security.groups.cache.warn.after.ms"; + public static final long HADOOP_SECURITY_GROUPS_CACHE_WARN_AFTER_MS_DEFAULT = + 5000; + /** See core-default.xml */ public static final String HADOOP_SECURITY_AUTHENTICATION = "hadoop.security.authentication"; /** See core-default.xml */ diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Groups.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Groups.java index 51cdce6cce2..d9d8781245d 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Groups.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/Groups.java @@ -50,6 +50,7 @@ public class Groups { private final Map userToGroupsMap = new ConcurrentHashMap(); private final long cacheTimeout; + private final long warningDeltaMs; public Groups(Configuration conf) { impl = @@ -60,11 +61,16 @@ public Groups(Configuration conf) { conf); cacheTimeout = - conf.getLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_CACHE_SECS, 5*60) * 1000; + conf.getLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_CACHE_SECS, + CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_CACHE_SECS_DEFAULT) * 1000; + warningDeltaMs = + conf.getLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_CACHE_WARN_AFTER_MS, + CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_CACHE_WARN_AFTER_MS_DEFAULT); if(LOG.isDebugEnabled()) LOG.debug("Group mapping impl=" + impl.getClass().getName() + - "; cacheTimeout=" + cacheTimeout); + "; cacheTimeout=" + cacheTimeout + "; warningDeltaMs=" + + warningDeltaMs); } /** @@ -76,17 +82,24 @@ public Groups(Configuration conf) { public List getGroups(String user) throws IOException { // Return cached value if available CachedGroups groups = userToGroupsMap.get(user); - long now = Time.now(); + long startMs = Time.monotonicNow(); // if cache has a value and it hasn't expired - if (groups != null && (groups.getTimestamp() + cacheTimeout > now)) { + if (groups != null && (groups.getTimestamp() + cacheTimeout > startMs)) { if(LOG.isDebugEnabled()) { LOG.debug("Returning cached groups for '" + user + "'"); } return groups.getGroups(); } - + // Create and cache user's groups - groups = new CachedGroups(impl.getGroups(user)); + List groupList = impl.getGroups(user); + long endMs = Time.monotonicNow(); + long deltaMs = endMs - startMs ; + if (deltaMs > warningDeltaMs) { + LOG.warn("Potential performance problem: getGroups(user=" + user +") " + + "took " + deltaMs + " milliseconds."); + } + groups = new CachedGroups(groupList, endMs); if (groups.getGroups().isEmpty()) { throw new IOException("No groups found for user " + user); } @@ -133,9 +146,9 @@ private static class CachedGroups { /** * Create and initialize group cache */ - CachedGroups(List groups) { + CachedGroups(List groups, long timestamp) { this.groups = groups; - this.timestamp = Time.now(); + this.timestamp = timestamp; } /** diff --git a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml index ab453ae1aaf..746d209715a 100644 --- a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml +++ b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml @@ -105,6 +105,15 @@ + + hadoop.security.groups.cache.warn.after.ms + 5000 + + If looking up a single user to group takes longer than this amount of + milliseconds, we will log a warning message. + + + hadoop.security.group.mapping.ldap.url