Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit 4fc7c14

Browse files
authored
Merge pull request #1061 from ethereum/fix/slow-import
Fix slow import
2 parents d83e8be + 7145c86 commit 4fc7c14

File tree

8 files changed

+83
-19
lines changed

8 files changed

+83
-19
lines changed

ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,14 @@ public AbstractCachedSource<byte[], byte[]> blockchainDbCache() {
154154
return ret;
155155
}
156156

157+
public DbSource<byte[]> keyValueDataSource(String name) {
158+
return keyValueDataSource(name, DbSettings.DEFAULT);
159+
}
160+
157161
@Bean
158162
@Scope("prototype")
159163
@Primary
160-
public DbSource<byte[]> keyValueDataSource(String name) {
164+
public DbSource<byte[]> keyValueDataSource(String name, DbSettings settings) {
161165
String dataSource = systemProperties().getKeyValueDataSource();
162166
try {
163167
DbSource<byte[]> dbSource;
@@ -170,7 +174,7 @@ public DbSource<byte[]> keyValueDataSource(String name) {
170174
dbSource = rocksDbDataSource();
171175
}
172176
dbSource.setName(name);
173-
dbSource.init();
177+
dbSource.init(settings);
174178
dbSources.add(dbSource);
175179
return dbSource;
176180
} finally {
@@ -267,7 +271,11 @@ public ProgramPrecompile deserialize(byte[] stream) {
267271

268272
@Bean
269273
public DbSource<byte[]> blockchainDB() {
270-
return keyValueDataSource("blockchain");
274+
DbSettings settings = DbSettings.newInstance()
275+
.withMaxOpenFiles(systemProperties().getConfig().getInt("database.maxOpenFiles"))
276+
.withMaxThreads(Math.max(1, Runtime.getRuntime().availableProcessors() / 2));
277+
278+
return keyValueDataSource("blockchain", settings);
271279
}
272280

273281
@Bean
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.ethereum.datasource;
2+
3+
/**
4+
* Defines configurable database settings
5+
*
6+
* @author Mikhail Kalinin
7+
* @since 26.04.2018
8+
*/
9+
public class DbSettings {
10+
11+
public static final DbSettings DEFAULT = new DbSettings()
12+
.withMaxThreads(1)
13+
.withMaxOpenFiles(32);
14+
15+
int maxOpenFiles;
16+
int maxThreads;
17+
18+
private DbSettings() {
19+
}
20+
21+
public static DbSettings newInstance() {
22+
DbSettings settings = new DbSettings();
23+
settings.maxOpenFiles = DEFAULT.maxOpenFiles;
24+
settings.maxThreads = DEFAULT.maxThreads;
25+
return settings;
26+
}
27+
28+
public int getMaxOpenFiles() {
29+
return maxOpenFiles;
30+
}
31+
32+
public DbSettings withMaxOpenFiles(int maxOpenFiles) {
33+
this.maxOpenFiles = maxOpenFiles;
34+
return this;
35+
}
36+
37+
public int getMaxThreads() {
38+
return maxThreads;
39+
}
40+
41+
public DbSettings withMaxThreads(int maxThreads) {
42+
this.maxThreads = maxThreads;
43+
return this;
44+
}
45+
}

ethereumj-core/src/main/java/org/ethereum/datasource/DbSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public interface DbSource<V> extends BatchSource<byte[], V> {
3838
/**
3939
* Initializes DB (open table, connection, etc)
4040
*/
41-
void init();
41+
void init(DbSettings settings);
4242

4343
/**
4444
* @return true if DB connection is alive

ethereumj-core/src/main/java/org/ethereum/datasource/inmem/HashMapDB.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
*/
1818
package org.ethereum.datasource.inmem;
1919

20+
import org.ethereum.datasource.DbSettings;
2021
import org.ethereum.datasource.DbSource;
2122
import org.ethereum.util.ALock;
2223
import org.ethereum.util.ByteArrayMap;
2324
import org.ethereum.util.FastByteComparisons;
2425

2526
import java.util.Map;
2627
import java.util.Set;
27-
import java.util.concurrent.locks.Lock;
2828
import java.util.concurrent.locks.ReadWriteLock;
2929
import java.util.concurrent.locks.ReentrantReadWriteLock;
3030

@@ -86,7 +86,7 @@ public String getName() {
8686
}
8787

8888
@Override
89-
public void init() {}
89+
public void init(DbSettings settings) {}
9090

9191
@Override
9292
public boolean isAlive() {

ethereumj-core/src/main/java/org/ethereum/datasource/inmem/HashMapDBSimple.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,13 @@
1717
*/
1818
package org.ethereum.datasource.inmem;
1919

20+
import org.ethereum.datasource.DbSettings;
2021
import org.ethereum.datasource.DbSource;
21-
import org.ethereum.util.ALock;
2222
import org.ethereum.util.ByteArrayMap;
2323
import org.ethereum.util.FastByteComparisons;
2424

2525
import java.util.Map;
2626
import java.util.Set;
27-
import java.util.concurrent.locks.ReadWriteLock;
28-
import java.util.concurrent.locks.ReentrantReadWriteLock;
2927

3028
/**
3129
* Created by Anton Nashatyrev on 12.10.2016.
@@ -75,7 +73,7 @@ public String getName() {
7573
}
7674

7775
@Override
78-
public void init() {}
76+
public void init(DbSettings settings) {}
7977

8078
@Override
8179
public boolean isAlive() {

ethereumj-core/src/main/java/org/ethereum/datasource/leveldb/LevelDbDataSource.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.ethereum.datasource.leveldb;
1919

2020
import org.ethereum.config.SystemProperties;
21+
import org.ethereum.datasource.DbSettings;
2122
import org.ethereum.datasource.DbSource;
2223
import org.ethereum.util.FileUtil;
2324
import org.iq80.leveldb.*;
@@ -54,6 +55,8 @@ public class LevelDbDataSource implements DbSource<byte[]> {
5455
DB db;
5556
boolean alive;
5657

58+
DbSettings settings = DbSettings.DEFAULT;
59+
5760
// The native LevelDB insert/update/delete are normally thread-safe
5861
// However close operation is not thread-safe and may lead to a native crash when
5962
// accessing a closed DB.
@@ -71,7 +74,8 @@ public LevelDbDataSource(String name) {
7174
}
7275

7376
@Override
74-
public void init() {
77+
public void init(DbSettings settings) {
78+
this.settings = settings;
7579
resetDbLock.writeLock().lock();
7680
try {
7781
logger.debug("~> LevelDbDataSource.init(): " + name);
@@ -88,7 +92,7 @@ public void init() {
8892
options.cacheSize(0);
8993
options.paranoidChecks(true);
9094
options.verifyChecksums(true);
91-
options.maxOpenFiles(32);
95+
options.maxOpenFiles(settings.getMaxOpenFiles());
9296

9397
try {
9498
logger.debug("Opening database");
@@ -135,7 +139,7 @@ private Path getPath() {
135139
public void reset() {
136140
close();
137141
FileUtil.recursiveDelete(getPath().toString());
138-
init();
142+
init(settings);
139143
}
140144

141145
@Override

ethereumj-core/src/main/java/org/ethereum/datasource/rocksdb/RocksDbDataSource.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.ethereum.datasource.rocksdb;
1919

2020
import org.ethereum.config.SystemProperties;
21+
import org.ethereum.datasource.DbSettings;
2122
import org.ethereum.datasource.DbSource;
2223
import org.ethereum.datasource.NodeKeyCompositor;
2324
import org.ethereum.util.FileUtil;
@@ -56,6 +57,8 @@ public class RocksDbDataSource implements DbSource<byte[]> {
5657
ReadOptions readOpts;
5758
boolean alive;
5859

60+
DbSettings settings = DbSettings.DEFAULT;
61+
5962
// The native RocksDB insert/update/delete are normally thread-safe
6063
// However close operation is not thread-safe.
6164
// This ReadWriteLock still permits concurrent execution of insert/delete/update operations
@@ -85,7 +88,8 @@ public String getName() {
8588
}
8689

8790
@Override
88-
public void init() {
91+
public void init(DbSettings settings) {
92+
this.settings = settings;
8993
resetDbLock.writeLock().lock();
9094
try {
9195
logger.debug("~> RocksDbDataSource.init(): " + name);
@@ -103,9 +107,8 @@ public void init() {
103107
options.setCompressionType(CompressionType.LZ4_COMPRESSION);
104108
options.setBottommostCompressionType(CompressionType.ZSTD_COMPRESSION);
105109
options.setLevelCompactionDynamicLevelBytes(true);
106-
options.setMaxBackgroundCompactions(4);
107-
options.setMaxBackgroundFlushes(2);
108-
options.setMaxOpenFiles(32);
110+
options.setMaxOpenFiles(settings.getMaxOpenFiles());
111+
options.setIncreaseParallelism(settings.getMaxThreads());
109112

110113
// key prefix for state node lookups
111114
options.useFixedLengthPrefixExtractor(NodeKeyCompositor.PREFIX_BYTES);
@@ -237,7 +240,7 @@ public Set<byte[]> keys() throws RuntimeException {
237240
public void reset() {
238241
close();
239242
FileUtil.recursiveDelete(getPath().toString());
240-
init();
243+
init(settings);
241244
}
242245

243246
private Path getPath() {

ethereumj-core/src/main/resources/ethereumj.conf

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@ database {
218218
# 1_000_000: 5658 Mb
219219
maxDepth = 192
220220
}
221+
222+
# defines a number of opened files by db instance
223+
# this number has significant impact on read amplification
224+
# on the other hand it can force exceeding of user's limit,
225+
# OS usually set it to 1024 for all applications
226+
maxOpenFiles = 512
221227
}
222228

223229
# Cache settings
@@ -239,7 +245,7 @@ cache {
239245
}
240246

241247
# total size in Mbytes of the state DB read cache
242-
stateCacheSize = 256
248+
stateCacheSize = 384
243249

244250
# the size of block queue cache to be imported in MBytes
245251
blockQueueSize = 32

0 commit comments

Comments
 (0)