-
Notifications
You must be signed in to change notification settings - Fork 614
HDDS-3892. Datanode initialization is too slow when there are thousan… #1147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
95836d2
9dda984
5dd9a0f
15ec4d3
20b694a
fa37b9f
71b4571
b4060aa
f86391b
b53da4d
2c9f550
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |
| import java.util.concurrent.locks.Lock; | ||
| import java.util.concurrent.locks.ReentrantLock; | ||
|
|
||
| import com.google.common.util.concurrent.Striped; | ||
| import org.apache.hadoop.hdds.conf.ConfigurationSource; | ||
| import org.apache.hadoop.hdds.utils.MetadataStore; | ||
| import org.apache.hadoop.hdds.utils.MetadataStoreBuilder; | ||
|
|
@@ -43,6 +44,7 @@ public final class ContainerCache extends LRUMap { | |
| private final Lock lock = new ReentrantLock(); | ||
| private static ContainerCache cache; | ||
| private static final float LOAD_FACTOR = 0.75f; | ||
| private final Striped<Lock> rocksDBLock = Striped.lazyWeakLock(1024); | ||
| /** | ||
| * Constructs a cache that holds DBHandle references. | ||
| */ | ||
|
|
@@ -117,30 +119,57 @@ public ReferenceCountedDB getDB(long containerID, String containerDBType, | |
| throws IOException { | ||
| Preconditions.checkState(containerID >= 0, | ||
| "Container ID cannot be negative."); | ||
| lock.lock(); | ||
| ReferenceCountedDB db; | ||
| Lock containerLock = rocksDBLock.get(containerDBPath); | ||
| containerLock.lock(); | ||
| try { | ||
| ReferenceCountedDB db = (ReferenceCountedDB) this.get(containerDBPath); | ||
| lock.lock(); | ||
| try { | ||
| db = (ReferenceCountedDB) this.get(containerDBPath); | ||
| if (db != null) { | ||
| db.incrementReference(); | ||
| return db; | ||
| } | ||
| } finally { | ||
| lock.unlock(); | ||
| } | ||
|
|
||
| if (db == null) { | ||
| try { | ||
| MetadataStore metadataStore = | ||
| MetadataStoreBuilder.newBuilder() | ||
| .setDbFile(new File(containerDBPath)) | ||
| .setCreateIfMissing(false) | ||
| .setConf(conf) | ||
| .setDBType(containerDBType) | ||
| .build(); | ||
| .setDbFile(new File(containerDBPath)) | ||
| .setCreateIfMissing(false) | ||
| .setConf(conf) | ||
| .setDBType(containerDBType) | ||
| .build(); | ||
| db = new ReferenceCountedDB(metadataStore, containerDBPath); | ||
| this.put(containerDBPath, db); | ||
| } catch (Exception e) { | ||
| LOG.error("Error opening DB. Container:{} ContainerPath:{}", | ||
| containerID, containerDBPath, e); | ||
| throw e; | ||
| } | ||
|
|
||
| lock.lock(); | ||
| try { | ||
| ReferenceCountedDB currentDB = | ||
| (ReferenceCountedDB) this.get(containerDBPath); | ||
| if (currentDB != null) { | ||
| // increment the reference before returning the object | ||
| currentDB.incrementReference(); | ||
| // clean the db created in previous step | ||
| db.cleanup(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This cleanup() call may be expensive, and ideally it should be outside the lock. However, I think it will be very rare where you hit this scenario and therefore I think the logic is OK as it is now.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. |
||
| return currentDB; | ||
| } else { | ||
| this.put(containerDBPath, db); | ||
| // increment the reference before returning the object | ||
| db.incrementReference(); | ||
| return db; | ||
| } | ||
| } finally { | ||
| lock.unlock(); | ||
| } | ||
| // increment the reference before returning the object | ||
| db.incrementReference(); | ||
| return db; | ||
| } catch (Exception e) { | ||
| LOG.error("Error opening DB. Container:{} ContainerPath:{}", | ||
| containerID, containerDBPath, e); | ||
| throw e; | ||
| } finally { | ||
| lock.unlock(); | ||
| containerLock.unlock(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.