[#776] writecache: Limit size of used disk space

There is a need to limit disk space used by write-cache. It is almost
impossible to calculate the value exactly. It is proposed to estimate the
size of the cache by the number of objects stored in it.

Track amounts of objects saved in DB and FSTree separately. To do this,
`ObjectCounters` interface is defined. It is generalized to a store of
numbers that can be made persistent (new option `WithObjectCounters`). By
default DB number is calculated as key number in default bucket, and FS
number is set same to DB since it is currently hard to read the actual value
from `FSTree` instance. Each PUT/DELETE operation to DB or FS
increases/decreases corresponding counter. Before each PUT op an overflow
check is performed with the following formula for evaluating the occupied
space: `NumDB * MaxDBSize + NumFS * MaxFSSize`. If next PUT can cause
write-cache overflow, object is written to the main storage.

By default maximum write-cache size is set to 1GB.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-09-08 12:32:20 +03:00 committed by Alex Vanin
parent 0a130177d6
commit a1696a81b6
6 changed files with 203 additions and 10 deletions

View file

@ -60,6 +60,7 @@ const (
maxInMemorySizeBytes = 1024 * 1024 * 1024 // 1 GiB
maxObjectSize = 64 * 1024 * 1024 // 64 MiB
smallObjectSize = 32 * 1024 // 32 KiB
maxCacheSizeBytes = 1 << 30 // 1 GiB
)
var (
@ -81,6 +82,7 @@ func New(opts ...Option) Cache {
maxObjectSize: maxObjectSize,
smallObjectSize: smallObjectSize,
workersCount: flushWorkersCount,
maxCacheSize: maxCacheSizeBytes,
},
}
@ -91,9 +93,21 @@ func New(opts ...Option) Cache {
return c
}
// Open opens and initializes database.
// Open opens and initializes database. Reads object counters from the ObjectCounters instance.
func (c *cache) Open() error {
return c.openStore()
err := c.openStore()
if err != nil {
return err
}
if c.objCounters == nil {
c.objCounters = &counters{
db: c.db,
fs: c.fsTree,
}
}
return c.objCounters.Read()
}
// Init runs necessary services.
@ -103,8 +117,9 @@ func (c *cache) Init() error {
return nil
}
// Close closes db connection and stops services.
// Close closes db connection and stops services. Executes ObjectCounters.FlushAndClose op.
func (c *cache) Close() error {
close(c.closeCh)
c.objCounters.FlushAndClose()
return c.db.Close()
}