Gitlab Community Edition Instance
Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
cdstar
cdstar
Commits
f1f5d2cd
Commit
f1f5d2cd
authored
Dec 02, 2019
by
mhellka
Browse files
Make NioPool cache size configurable; Fixed some metrics
parent
808f5d98
Changes
2
Hide whitespace changes
Inline
Side-by-side
cdstar-backend-nio/src/main/java/de/gwdg/cdstar/pool/nio/NioPool.java
View file @
f1f5d2cd
...
...
@@ -53,6 +53,8 @@ import de.gwdg.cdstar.ta.UserTransaction;
@Plugin
public
class
NioPool
implements
StoragePool
{
private
static
final
String
PROP_CACHE_SIZE
=
"cacheSize"
;
private
static
final
String
PROP_PATH
=
"path"
;
static
final
String
EXT_BLOB
=
".bin"
;
static
final
String
EXT_REVISION
=
".json"
;
static
final
String
FILENAME_NEXT
=
"HEAD_NEXT"
;
...
...
@@ -62,21 +64,21 @@ public class NioPool implements StoragePool {
public
static
final
int
SHARD_DEPTH
=
2
;
private
static
JsonFormat
objectLoader
=
new
JsonFormat
();
private
int
cacheSize
=
1024
;
// Running transactions
ConcurrentHashMap
<
String
,
NioSession
>
scopes
=
new
ConcurrentHashMap
<>();
final
Path
basePath
;
private
final
FileSharder
pathSharder
;
NioRecoveryHandler
recoveryHandler
;
LoadingCache
<
Path
,
JsonIndex
>
indexCache
;
private
final
PoolStats
stats
;
final
NioRecoveryHandler
recoveryHandler
;
private
LoadingCache
<
Path
,
JsonIndex
>
indexCache
;
public
NioPool
(
Config
cfg
)
throws
IOException
,
ConfigException
{
// TODO: Make more than just the path configurable
this
(
Paths
.
get
(
cfg
.
get
(
"path"
)));
this
(
Paths
.
get
(
cfg
.
get
(
PROP_PATH
)));
cfg
.
setDefault
(
PROP_CACHE_SIZE
,
Integer
.
toString
(
cacheSize
));
setCacheSize
(
cfg
.
getInt
(
PROP_CACHE_SIZE
));
}
public
NioPool
(
Path
base
)
throws
IOException
{
...
...
@@ -85,15 +87,21 @@ public class NioPool implements StoragePool {
recoveryHandler
=
new
NioRecoveryHandler
(
this
);
if
(!
Files
.
isDirectory
(
base
))
Files
.
createDirectories
(
basePath
);
rebuildCache
();
}
indexCache
=
Caffeine
.
newBuilder
()
// TODO: Make this configurable
.
maximumSize
(
1024
)
// Allow GC to shrink the heap during idle hours.
.
expireAfterAccess
(
60
,
TimeUnit
.
SECONDS
)
.
build
(
this
::
loadFromDisk
);
public
void
setCacheSize
(
int
cacheSize
)
{
this
.
cacheSize
=
cacheSize
;
rebuildCache
();
}
stats
=
new
PoolStats
();
private
void
rebuildCache
()
{
indexCache
=
Caffeine
.
newBuilder
()
// TODO: Make this configurable
.
maximumSize
(
cacheSize
)
// Allow GC to shrink the heap during idle hours.
.
expireAfterAccess
(
60
,
TimeUnit
.
SECONDS
)
.
build
(
this
::
loadFromDisk
);
}
@Override
...
...
@@ -157,7 +165,7 @@ public class NioPool implements StoragePool {
void
write
(
JsonIndex
obj
)
throws
IOException
{
try
(
final
OutputStream
stream
=
Files
.
newOutputStream
(
getObjectFile
(
obj
.
id
,
obj
.
rev
),
StandardOpenOption
.
CREATE_NEW
);
OutputStream
buffered
=
new
BufferedOutputStream
(
stream
))
{
OutputStream
buffered
=
new
BufferedOutputStream
(
stream
))
{
objectLoader
.
write
(
buffered
,
obj
);
}
}
...
...
@@ -295,6 +303,7 @@ public class NioPool implements StoragePool {
/**
* Create the object directory, if it does not exist already.
*
* @param id Object ID
* @return true on success, false otherwise
*/
...
...
@@ -316,11 +325,9 @@ public class NioPool implements StoragePool {
/**
* Lock an object globally for writing (reading allowed).
*
* @param id
* The object ID
* @param nextRevision
* The target revision, or null if the lock is not actually
* creating a new revision.
* @param id The object ID
* @param nextRevision The target revision, or null if the lock is not actually
* creating a new revision.
*/
SymlinkLock
lockObject
(
String
id
,
String
nextRevision
)
throws
IOException
{
return
new
SymlinkLock
(
getHEAD
(
id
),
getObjectFile
(
id
,
nextRevision
),
...
...
@@ -342,48 +349,52 @@ public class NioPool implements StoragePool {
return
false
;
}
/**
* Return a snapshot of the current pool statistics
*/
public
PoolStats
getStats
()
{
return
s
tats
;
return
new
PoolS
tats
()
;
}
public
class
PoolStats
{
public
CacheStats
getCacheStats
()
{
return
indexCache
.
stats
();
}
FileStore
getFileStore
()
throws
IOException
{
Path
target
=
basePath
;
while
(
Files
.
isSymbolicLink
(
target
))
target
=
Files
.
readSymbolicLink
(
target
);
return
Files
.
getFileStore
(
target
);
}
public
long
getDiskTotal
()
{
private
final
CacheStats
cacheStats
;
private
long
fsFree
=
-
1
;
private
long
fsTotal
=
-
1
;
private
final
long
cacheSize
;
public
PoolStats
()
{
cacheStats
=
indexCache
.
stats
();
cacheSize
=
indexCache
.
estimatedSize
();
try
{
return
getFileStore
().
getTotalSpace
();
Path
target
=
basePath
;
while
(
Files
.
isSymbolicLink
(
target
))
target
=
Files
.
readSymbolicLink
(
target
);
final
FileStore
fileStore
=
Files
.
getFileStore
(
target
);
fsFree
=
fileStore
.
getUsableSpace
();
fsTotal
=
fileStore
.
getTotalSpace
();
}
catch
(
final
IOException
e
)
{
return
-
1
;
log
.
warn
(
"Unable to read file system statistics"
,
e
)
;
}
}
public
long
getDiskFree
()
{
try
{
return
getFileStore
().
getUsableSpace
();
}
catch
(
final
IOException
e
)
{
return
-
1
;
}
public
long
diskTotal
()
{
return
fsTotal
;
}
public
long
diskFree
()
{
return
fsFree
;
}
public
long
cacheSize
()
{
return
indexCache
.
estimated
Size
()
;
return
cache
Size
;
}
public
long
cacheHitCount
()
{
return
indexC
ache
.
s
tats
()
.
hitCount
();
return
c
ache
S
tats
.
hitCount
();
}
public
long
cacheMissCount
()
{
return
indexC
ache
.
s
tats
()
.
missCount
();
return
c
ache
S
tats
.
missCount
();
}
}
...
...
cdstar-runtime/src/main/java/de/gwdg/cdstar/runtime/services/VaultRegistry.java
View file @
f1f5d2cd
...
...
@@ -27,7 +27,6 @@ import de.gwdg.cdstar.config.MapConfig;
import
de.gwdg.cdstar.pool.PoolError
;
import
de.gwdg.cdstar.pool.StoragePool
;
import
de.gwdg.cdstar.pool.nio.NioPool
;
import
de.gwdg.cdstar.pool.nio.NioPool.PoolStats
;
import
de.gwdg.cdstar.runtime.Config
;
import
de.gwdg.cdstar.runtime.ConfigException
;
import
de.gwdg.cdstar.runtime.RuntimeContext
;
...
...
@@ -116,7 +115,7 @@ public class VaultRegistry implements RuntimeListener {
vaultConfigs
.
forEach
((
name
,
vc
)
->
{
try
{
vc
.
close
();
}
catch
(
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
log
.
warn
(
"Failed to properly close vault: {}"
,
vc
.
getName
(),
e
);
}
});
...
...
@@ -130,15 +129,15 @@ public class VaultRegistry implements RuntimeListener {
if
(
vaultConfigs
.
containsKey
(
vaultName
))
throw
new
IllegalStateException
(
"Vault loaded twice: "
+
vaultName
);
Config
properties
=
ConfigLoader
.
fromFile
(
getConfigPathFor
(
vaultName
).
toFile
());
VaultConfigImpl
vci
=
new
VaultConfigImpl
(
vaultName
,
properties
);
final
Config
properties
=
ConfigLoader
.
fromFile
(
getConfigPathFor
(
vaultName
).
toFile
());
final
VaultConfigImpl
vci
=
new
VaultConfigImpl
(
vaultName
,
properties
);
vaultConfigs
.
put
(
vci
.
getName
(),
vci
);
return
vci
;
}
private
synchronized
void
saveVault
(
String
vaultName
,
Config
properties
,
boolean
reload
)
throws
IOException
{
Path
confFile
=
getConfigPathFor
(
vaultName
);
VaultConfigImpl
old
=
vaultConfigs
.
remove
(
vaultName
);
final
Path
confFile
=
getConfigPathFor
(
vaultName
);
final
VaultConfigImpl
old
=
vaultConfigs
.
remove
(
vaultName
);
if
(!
reload
&&
(
old
!=
null
||
Files
.
exists
(
confFile
)))
throw
new
IllegalStateException
(
"Vault exists: "
+
vaultName
);
...
...
@@ -156,7 +155,7 @@ public class VaultRegistry implements RuntimeListener {
if
(
old
!=
null
)
old
.
close
();
VaultConfigImpl
vci
=
new
VaultConfigImpl
(
vaultName
,
properties
);
final
VaultConfigImpl
vci
=
new
VaultConfigImpl
(
vaultName
,
properties
);
vaultConfigs
.
put
(
vaultName
,
vci
);
runtime
.
lookupAll
(
VaultConfigListener
.
class
).
forEach
(
l
->
l
.
vaultConfigChanged
(
vaultConfigs
.
get
(
vaultName
)));
...
...
@@ -181,8 +180,8 @@ public class VaultRegistry implements RuntimeListener {
}
public
StoragePool
getPoolFor
(
VaultConfig
vault
)
{
VaultConfigImpl
vci
=
(
VaultConfigImpl
)
vault
;
StoragePool
pool
=
vci
.
pool
;
final
VaultConfigImpl
vci
=
(
VaultConfigImpl
)
vault
;
final
StoragePool
pool
=
vci
.
pool
;
if
(
pool
==
null
)
return
initPool
(
vci
);
return
pool
;
...
...
@@ -194,8 +193,8 @@ public class VaultRegistry implements RuntimeListener {
return
vci
.
pool
;
try
{
Config
scoped
=
vci
.
config
.
with
(
"pool"
);
String
poolClassName
=
scoped
.
get
(
"class"
,
NioPool
.
class
.
getName
());
final
Config
scoped
=
vci
.
config
.
with
(
"pool"
);
final
String
poolClassName
=
scoped
.
get
(
"class"
,
NioPool
.
class
.
getName
());
// Resolve relative or missing pool data paths
scoped
.
set
(
"path"
,
dataPath
.
resolve
(
scoped
.
get
(
"path"
,
vci
.
getName
())).
toAbsolutePath
().
toString
());
...
...
@@ -217,21 +216,16 @@ public class VaultRegistry implements RuntimeListener {
private
void
addMetrics
(
VaultConfigImpl
vci
)
{
if
(
vci
.
pool
instanceof
NioPool
)
{
runtime
.
lookup
(
MetricRegistry
.
class
).
ifPresent
(
mr
->
{
String
name
=
"pool."
+
vci
.
getName
();
NioPool
pool
=
(
NioPool
)
vci
.
pool
;
PoolStats
poolStats
=
pool
.
getStats
();
mr
.
gauge
(
name
+
".cache.hit"
,
()
->
()
->
poolStats
.
cacheHitCount
());
mr
.
gauge
(
name
+
".cache.miss"
,
()
->
()
->
poolStats
.
cacheMissCount
());
mr
.
gauge
(
name
+
".cache.size"
,
()
->
()
->
poolStats
.
cacheSize
());
mr
.
gauge
(
name
+
".disk.total"
,
()
->
()
->
poolStats
.
getDiskTotal
());
mr
.
gauge
(
name
+
".disk.free"
,
()
->
()
->
poolStats
.
getDiskFree
());
final
String
name
=
"pool."
+
vci
.
getName
();
final
NioPool
pool
=
(
NioPool
)
vci
.
pool
;
mr
.
gauge
(
name
+
".cache.hit"
,
()
->
()
->
pool
.
getStats
().
cacheHitCount
());
mr
.
gauge
(
name
+
".cache.miss"
,
()
->
()
->
pool
.
getStats
().
cacheMissCount
());
mr
.
gauge
(
name
+
".cache.size"
,
()
->
()
->
pool
.
getStats
().
cacheSize
());
mr
.
gauge
(
name
+
".disk.total"
,
()
->
()
->
pool
.
getStats
().
diskTotal
());
mr
.
gauge
(
name
+
".disk.free"
,
()
->
()
->
pool
.
getStats
().
diskFree
());
});
}
}
private
boolean
isValidVaultName
(
String
name
)
{
...
...
@@ -249,7 +243,7 @@ public class VaultRegistry implements RuntimeListener {
public
class
VaultConfigImpl
implements
VaultConfig
,
Closeable
{
private
StoragePool
pool
;
private
boolean
isPublic
;
private
final
boolean
isPublic
;
private
final
String
name
;
private
final
Config
config
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment