Skip to content

Commit

Permalink
cmd/mount: add an option cache-eviction to specify the policy (#3478)
Browse files Browse the repository at this point in the history
  • Loading branch information
SandyXSD authored Apr 18, 2023
1 parent cb335d0 commit ba1d474
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 15 deletions.
5 changes: 5 additions & 0 deletions cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ func clientFlags() []cli.Flag {
Value: "full",
Usage: "checksum level (none, full, shrink, extend)",
},
&cli.StringFlag{
Name: "cache-eviction",
Value: "2-random",
Usage: "cache eviction policy (none or 2-random)",
},
&cli.StringFlag{
Name: "cache-scan-interval",
Value: "3600",
Expand Down
1 change: 1 addition & 0 deletions cmd/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ func getChunkConf(c *cli.Context, format *meta.Format) *chunk.Config {
CacheMode: os.FileMode(cm),
CacheFullBlock: !c.Bool("cache-partial-only"),
CacheChecksum: c.String("verify-cache-checksum"),
CacheEviction: c.String("cache-eviction"),
CacheScanInterval: duration(c.String("cache-scan-interval")),
AutoCreate: true,
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/chunk/cached_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ type Config struct {
CacheMode os.FileMode
CacheSize int64
CacheChecksum string
CacheEviction string
CacheScanInterval time.Duration
FreeSpace float32
AutoCreate bool
Expand Down Expand Up @@ -574,6 +575,12 @@ func (c *Config) SelfCheck(uuid string) {
c.CacheChecksum = CsFull
}
}
if c.CacheEviction == "" {
c.CacheEviction = "2-random"
} else if c.CacheEviction != "2-random" && c.CacheEviction != "none" {
logger.Warnf("cache-eviction should be one of [2-random, none]")
c.CacheEviction = "2-random"
}
}

type cachedStore struct {
Expand Down
39 changes: 24 additions & 15 deletions pkg/chunk/disk_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ type cacheStore struct {
pages map[string]*Page
m *cacheManagerMetrics

used int64
keys map[cacheKey]cacheItem
scanned bool
full bool
checksum string // checksum level
uploader func(key, path string, force bool) bool
used int64
keys map[cacheKey]cacheItem
scanned bool
stageFull bool
rawFull bool
eviction string
checksum string // checksum level
uploader func(key, path string, force bool) bool
}

func newCacheStore(m *cacheManagerMetrics, dir string, cacheSize int64, pendingPages int, config *Config, uploader func(key, path string, force bool) bool) *cacheStore {
Expand All @@ -94,6 +96,7 @@ func newCacheStore(m *cacheManagerMetrics, dir string, cacheSize int64, pendingP
mode: config.CacheMode,
capacity: cacheSize,
freeRatio: config.FreeSpace,
eviction: config.CacheEviction,
checksum: config.CacheChecksum,
hashPrefix: config.HashPrefix,
scanInterval: config.CacheScanInterval,
Expand Down Expand Up @@ -128,17 +131,18 @@ func (cache *cacheStore) stats() (int64, int64) {
func (cache *cacheStore) checkFreeSpace() {
for {
br, fr := cache.curFreeRatio()
cache.full = br < cache.freeRatio/2 || fr < cache.freeRatio/2
if br < cache.freeRatio || fr < cache.freeRatio {
cache.stageFull = br < cache.freeRatio/2 || fr < cache.freeRatio/2
cache.rawFull = br < cache.freeRatio || fr < cache.freeRatio
if cache.rawFull && cache.eviction != "none" {
logger.Tracef("Cleanup cache when check free space (%s): free ratio (%d%%), space usage (%d%%), inodes usage (%d%%)", cache.dir, int(cache.freeRatio*100), int(br*100), int(fr*100))
cache.Lock()
cache.cleanup()
cache.Unlock()

br, fr = cache.curFreeRatio()
if br < cache.freeRatio || fr < cache.freeRatio {
cache.uploadStaging()
}
cache.rawFull = br < cache.freeRatio || fr < cache.freeRatio
}
if cache.rawFull {
cache.uploadStaging()
}
time.Sleep(time.Second)
}
Expand Down Expand Up @@ -173,6 +177,11 @@ func (cache *cacheStore) cache(key string, p *Page, force bool) {
if cache.capacity == 0 {
return
}
if cache.rawFull && cache.eviction == "none" {
logger.Debugf("Caching directory is full (%s), drop %s (%d bytes)", cache.dir, key, len(p.Data))
cache.m.cacheDrops.Add(1)
return
}
cache.Lock()
defer cache.Unlock()
if _, ok := cache.pages[key]; ok {
Expand Down Expand Up @@ -394,16 +403,16 @@ func (cache *cacheStore) add(key string, size int32, atime uint32) {
cache.used += int64(size + 4096)
}

if cache.used > cache.capacity {
if cache.used > cache.capacity && cache.eviction != "none" {
logger.Debugf("Cleanup cache when add new data (%s): %d blocks (%d MB)", cache.dir, len(cache.keys), cache.used>>20)
cache.cleanup()
}
}

func (cache *cacheStore) stage(key string, data []byte, keepCache bool) (string, error) {
stagingPath := cache.stagePath(key)
if cache.full {
return stagingPath, errors.New("Space not enough on device")
if cache.stageFull {
return stagingPath, errors.New("space not enough on device")
}
err := cache.flushPage(stagingPath, data)
if err == nil {
Expand Down
7 changes: 7 additions & 0 deletions pkg/chunk/mem_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type memcache struct {
capacity int64
used int64
pages map[string]memItem
eviction string

metrics *cacheManagerMetrics
}
Expand All @@ -41,6 +42,7 @@ func newMemStore(config *Config, metrics *cacheManagerMetrics) *memcache {
c := &memcache{
capacity: config.CacheSize << 20,
pages: make(map[string]memItem),
eviction: config.CacheEviction,
metrics: metrics,
}
runtime.SetFinalizer(c, func(c *memcache) {
Expand Down Expand Up @@ -74,6 +76,11 @@ func (c *memcache) cache(key string, p *Page, force bool) {
}
c.Lock()
defer c.Unlock()
if c.used > c.capacity && c.eviction == "none" {
logger.Debugf("Caching is full, drop %s (%d bytes)", key, len(p.Data))
c.metrics.cacheDrops.Add(1)
return
}
if _, ok := c.pages[key]; ok {
return
}
Expand Down
2 changes: 2 additions & 0 deletions sdk/java/libjfs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ type javaConf struct {
AutoCreate bool `json:"autoCreate"`
CacheFullBlock bool `json:"cacheFullBlock"`
CacheChecksum string `json:"cacheChecksum"`
CacheEviction string `json:"cacheEviction"`
CacheScanInterval int `json:"cacheScanInterval"`
Writeback bool `json:"writeback"`
MemorySize int `json:"memorySize"`
Expand Down Expand Up @@ -495,6 +496,7 @@ func jfs_init(cname, jsonConf, user, group, superuser, supergroup *C.char) uintp
AutoCreate: jConf.AutoCreate,
CacheFullBlock: jConf.CacheFullBlock,
CacheChecksum: jConf.CacheChecksum,
CacheEviction: jConf.CacheEviction,
CacheScanInterval: time.Second * time.Duration(jConf.CacheScanInterval),
MaxUpload: jConf.MaxUploads,
MaxRetries: jConf.IORetries,
Expand Down
1 change: 1 addition & 0 deletions sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ public void initialize(URI uri, Configuration conf) throws IOException {
obj.put("dirEntryTimeout", Float.valueOf(getConf(conf, "dir-entry-cache", "0.0")));
obj.put("cacheFullBlock", Boolean.valueOf(getConf(conf, "cache-full-block", "true")));
obj.put("cacheChecksum", getConf(conf, "verify-cache-checksum", "full"));
obj.put("cacheEviction", getConf(conf, "cache-eviction", "2-random"));
obj.put("cacheScanInterval", Integer.valueOf(getConf(conf, "cache-scan-interval", "300")));
obj.put("metacache", Boolean.valueOf(getConf(conf, "metacache", "true")));
obj.put("autoCreate", Boolean.valueOf(getConf(conf, "auto-create-cache-dir", "true")));
Expand Down

0 comments on commit ba1d474

Please sign in to comment.