2121import static org .apache .hadoop .ozone .om .OMConfigKeys .OZONE_OM_CONTAINER_LOCATION_CACHE_SIZE_DEFAULT ;
2222import static org .apache .hadoop .ozone .om .OMConfigKeys .OZONE_OM_CONTAINER_LOCATION_CACHE_TTL ;
2323import static org .apache .hadoop .ozone .om .OMConfigKeys .OZONE_OM_CONTAINER_LOCATION_CACHE_TTL_DEFAULT ;
24+ import static org .apache .hadoop .ozone .om .OMConfigKeys .OZONE_OM_CONTAINER_LOCATION_DATANODE_CACHE_SIZE ;
25+ import static org .apache .hadoop .ozone .om .OMConfigKeys .OZONE_OM_CONTAINER_LOCATION_DATANODE_CACHE_SIZE_DEFAULT ;
2426
27+ import com .google .common .cache .Cache ;
2528import com .google .common .cache .CacheBuilder ;
2629import com .google .common .cache .CacheLoader ;
2730import com .google .common .cache .CacheLoader .InvalidCacheLoadException ;
2831import com .google .common .cache .LoadingCache ;
2932import jakarta .annotation .Nonnull ;
3033import java .io .IOException ;
34+ import java .util .ArrayList ;
3135import java .util .HashMap ;
3236import java .util .List ;
3337import java .util .Map ;
3741import org .apache .hadoop .hdds .client .ECReplicationConfig ;
3842import org .apache .hadoop .hdds .client .ReplicationConfig ;
3943import org .apache .hadoop .hdds .conf .OzoneConfiguration ;
40- import org .apache .hadoop .hdds .scm .container .common .helpers .ContainerWithPipeline ;
44+ import org .apache .hadoop .hdds .protocol .DatanodeDetails ;
45+ import org .apache .hadoop .hdds .protocol .DatanodeID ;
4146import org .apache .hadoop .hdds .scm .pipeline .Pipeline ;
4247import org .apache .hadoop .hdds .scm .protocol .ScmBlockLocationProtocol ;
4348import org .apache .hadoop .hdds .scm .protocol .StorageContainerLocationProtocol ;
@@ -52,21 +57,28 @@ public class ScmClient {
5257 private final StorageContainerLocationProtocol containerClient ;
5358 private final LoadingCache <Long , Pipeline > containerLocationCache ;
5459 private final CacheMetrics containerCacheMetrics ;
60+ private final CacheMetrics datanodeDetailsCacheMetrics ;
5561
5662 ScmClient (ScmBlockLocationProtocol blockClient ,
5763 StorageContainerLocationProtocol containerClient ,
5864 OzoneConfiguration configuration ) {
5965 this .containerClient = containerClient ;
6066 this .blockClient = blockClient ;
67+ Cache <DatanodeID , DatanodeDetails > datanodeDetailsCache =
68+ createDatanodeDetailsCache (configuration );
6169 this .containerLocationCache =
62- createContainerLocationCache (configuration , containerClient );
70+ createContainerLocationCache (configuration , containerClient ,
71+ datanodeDetailsCache );
6372 this .containerCacheMetrics = CacheMetrics .create (containerLocationCache ,
6473 "ContainerInfo" );
74+ this .datanodeDetailsCacheMetrics = CacheMetrics .create (
75+ datanodeDetailsCache , "DatanodeDetails" );
6576 }
6677
6778 static LoadingCache <Long , Pipeline > createContainerLocationCache (
6879 OzoneConfiguration configuration ,
69- StorageContainerLocationProtocol containerClient ) {
80+ StorageContainerLocationProtocol containerClient ,
81+ Cache <DatanodeID , DatanodeDetails > datanodeDetailsCache ) {
7082 int maxSize = configuration .getInt (OZONE_OM_CONTAINER_LOCATION_CACHE_SIZE ,
7183 OZONE_OM_CONTAINER_LOCATION_CACHE_SIZE_DEFAULT );
7284 TimeUnit unit = OZONE_OM_CONTAINER_LOCATION_CACHE_TTL_DEFAULT .getUnit ();
@@ -81,7 +93,9 @@ static LoadingCache<Long, Pipeline> createContainerLocationCache(
8193 @ Nonnull
8294 @ Override
8395 public Pipeline load (@ Nonnull Long key ) throws Exception {
84- return containerClient .getContainerWithPipeline (key ).getPipeline ();
96+ Pipeline pipeline =
97+ containerClient .getContainerWithPipeline (key ).getPipeline ();
98+ return newPipelineWithDNCache (pipeline , datanodeDetailsCache );
8599 }
86100
87101 @ Nonnull
@@ -92,12 +106,44 @@ public Map<Long, Pipeline> loadAll(
92106 .stream ()
93107 .collect (Collectors .toMap (
94108 x -> x .getContainerInfo ().getContainerID (),
95- ContainerWithPipeline ::getPipeline
109+ x -> newPipelineWithDNCache (x .getPipeline (),
110+ datanodeDetailsCache )
96111 ));
97112 }
98113 });
99114 }
100115
116+ static Cache <DatanodeID , DatanodeDetails > createDatanodeDetailsCache (
117+ OzoneConfiguration configuration ) {
118+ int datanodeCacheMaxSize = configuration .getInt (
119+ OZONE_OM_CONTAINER_LOCATION_DATANODE_CACHE_SIZE ,
120+ OZONE_OM_CONTAINER_LOCATION_DATANODE_CACHE_SIZE_DEFAULT );
121+
122+ return CacheBuilder .newBuilder ()
123+ .maximumSize (datanodeCacheMaxSize )
124+ .recordStats ()
125+ .build ();
126+ }
127+
128+ static Pipeline newPipelineWithDNCache (Pipeline pipeline ,
129+ Cache <DatanodeID , DatanodeDetails > datanodeDetailsCache ) {
130+ Pipeline .Builder builder = pipeline .toBuilder ();
131+ List <DatanodeDetails > nodes = new ArrayList <>();
132+ for (DatanodeDetails node : pipeline .getNodes ()) {
133+ DatanodeDetails datanodeDetails =
134+ datanodeDetailsCache .getIfPresent (node .getID ());
135+ // Call compareNodeValues to handle IP / hostname changes
136+ if (datanodeDetails != null && node .compareNodeValues (datanodeDetails )) {
137+ nodes .add (datanodeDetails );
138+ } else {
139+ datanodeDetailsCache .put (node .getID (), node );
140+ nodes .add (node );
141+ }
142+ }
143+ builder .setNodes (nodes );
144+ return builder .build ();
145+ }
146+
101147 public ScmBlockLocationProtocol getBlockClient () {
102148 return this .blockClient ;
103149 }
@@ -166,6 +212,7 @@ private <T> T handleCacheExecutionException(ExecutionException e)
166212
167213 public void close () {
168214 containerCacheMetrics .unregister ();
215+ datanodeDetailsCacheMetrics .unregister ();
169216 }
170217
171218}
0 commit comments