HDFS-9724. Degraded performance in WebHDFS listing as it does not reuse ObjectMapper. Contributed by Akira Ajisaka.

This commit is contained in:
Haohui Mai 2016-02-04 11:28:45 -08:00
parent 496f33de0c
commit 1bcfab8e7f
3 changed files with 19 additions and 13 deletions

View File

@ -87,6 +87,7 @@
import org.apache.hadoop.util.Progressable; import org.apache.hadoop.util.Progressable;
import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.util.StringUtils;
import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectReader;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -128,6 +129,8 @@ public class WebHdfsFileSystem extends FileSystem
private InetSocketAddress nnAddrs[]; private InetSocketAddress nnAddrs[];
private int currentNNAddrIndex; private int currentNNAddrIndex;
private boolean disallowFallbackToInsecureCluster; private boolean disallowFallbackToInsecureCluster;
private static final ObjectReader READER =
new ObjectMapper().reader(Map.class);
/** /**
* Return the protocol scheme for the FileSystem. * Return the protocol scheme for the FileSystem.
@ -361,8 +364,7 @@ private Path makeAbsolute(Path f) {
+ "\" (parsed=\"" + parsed + "\")"); + "\" (parsed=\"" + parsed + "\")");
} }
} }
ObjectMapper mapper = new ObjectMapper(); return READER.readValue(in);
return mapper.reader(Map.class).readValue(in);
} finally { } finally {
in.close(); in.close();
} }

View File

@ -2775,6 +2775,9 @@ Release 2.7.3 - UNRELEASED
HDFS-9730. Storage ID update does not happen when there is a layout change HDFS-9730. Storage ID update does not happen when there is a layout change
(Tsz Wo Nicholas Sze via kihwal) (Tsz Wo Nicholas Sze via kihwal)
HDFS-9724. Degraded performance in WebHDFS listing as it does not reuse
ObjectMapper. (Akira AJISAKA via wheat9)
Release 2.7.2 - 2016-01-25 Release 2.7.2 - 2016-01-25
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -38,6 +38,12 @@
public class JsonUtil { public class JsonUtil {
private static final Object[] EMPTY_OBJECT_ARRAY = {}; private static final Object[] EMPTY_OBJECT_ARRAY = {};
// Reuse ObjectMapper instance for improving performance.
// ObjectMapper is thread safe as long as we always configure instance
// before use. We don't have a re-entrant call pattern in WebHDFS,
// so we just need to worry about thread-safety.
private static final ObjectMapper MAPPER = new ObjectMapper();
/** Convert a token object to a Json string. */ /** Convert a token object to a Json string. */
public static String toJsonString(final Token<? extends TokenIdentifier> token public static String toJsonString(final Token<? extends TokenIdentifier> token
) throws IOException { ) throws IOException {
@ -72,9 +78,8 @@ private static String toJsonString(final Class<?> clazz, final Object value) {
public static String toJsonString(final String key, final Object value) { public static String toJsonString(final String key, final Object value) {
final Map<String, Object> m = new TreeMap<String, Object>(); final Map<String, Object> m = new TreeMap<String, Object>();
m.put(key, value); m.put(key, value);
ObjectMapper mapper = new ObjectMapper();
try { try {
return mapper.writeValueAsString(m); return MAPPER.writeValueAsString(m);
} catch (IOException ignored) { } catch (IOException ignored) {
} }
return null; return null;
@ -116,10 +121,9 @@ public static String toJsonString(final HdfsFileStatus status,
m.put("fileId", status.getFileId()); m.put("fileId", status.getFileId());
m.put("childrenNum", status.getChildrenNum()); m.put("childrenNum", status.getChildrenNum());
m.put("storagePolicy", status.getStoragePolicy()); m.put("storagePolicy", status.getStoragePolicy());
ObjectMapper mapper = new ObjectMapper();
try { try {
return includeType ? return includeType ?
toJsonString(FileStatus.class, m) : mapper.writeValueAsString(m); toJsonString(FileStatus.class, m) : MAPPER.writeValueAsString(m);
} catch (IOException ignored) { } catch (IOException ignored) {
} }
return null; return null;
@ -331,9 +335,8 @@ public static String toJsonString(final AclStatus status) {
new TreeMap<String, Map<String, Object>>(); new TreeMap<String, Map<String, Object>>();
finalMap.put(AclStatus.class.getSimpleName(), m); finalMap.put(AclStatus.class.getSimpleName(), m);
ObjectMapper mapper = new ObjectMapper();
try { try {
return mapper.writeValueAsString(finalMap); return MAPPER.writeValueAsString(finalMap);
} catch (IOException ignored) { } catch (IOException ignored) {
} }
return null; return null;
@ -371,8 +374,7 @@ public static String toJsonString(final List<XAttr> xAttrs,
final XAttrCodec encoding) throws IOException { final XAttrCodec encoding) throws IOException {
final Map<String, Object> finalMap = new TreeMap<String, Object>(); final Map<String, Object> finalMap = new TreeMap<String, Object>();
finalMap.put("XAttrs", toJsonArray(xAttrs, encoding)); finalMap.put("XAttrs", toJsonArray(xAttrs, encoding));
ObjectMapper mapper = new ObjectMapper(); return MAPPER.writeValueAsString(finalMap);
return mapper.writeValueAsString(finalMap);
} }
public static String toJsonString(final List<XAttr> xAttrs) public static String toJsonString(final List<XAttr> xAttrs)
@ -381,11 +383,10 @@ public static String toJsonString(final List<XAttr> xAttrs)
for (XAttr xAttr : xAttrs) { for (XAttr xAttr : xAttrs) {
names.add(XAttrHelper.getPrefixedName(xAttr)); names.add(XAttrHelper.getPrefixedName(xAttr));
} }
ObjectMapper mapper = new ObjectMapper(); String ret = MAPPER.writeValueAsString(names);
String ret = mapper.writeValueAsString(names);
final Map<String, Object> finalMap = new TreeMap<String, Object>(); final Map<String, Object> finalMap = new TreeMap<String, Object>();
finalMap.put("XAttrNames", ret); finalMap.put("XAttrNames", ret);
return mapper.writeValueAsString(finalMap); return MAPPER.writeValueAsString(finalMap);
} }
} }