diff --git a/cmd/registry/config.yml b/cmd/registry/config.yml index a8d469b6..5dd39cb3 100644 --- a/cmd/registry/config.yml +++ b/cmd/registry/config.yml @@ -5,6 +5,8 @@ log: service: registry environment: development storage: + cache: + layerinfo: inmemory filesystem: rootdirectory: /tmp/registry-dev http: diff --git a/configuration/configuration.go b/configuration/configuration.go index c38cf7c6..b43b9aba 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -187,7 +187,12 @@ type Storage map[string]Parameters func (storage Storage) Type() string { // Return only key in this map for k := range storage { - return k + switch k { + case "cache": + // allow configuration of caching + default: + return k + } } return "" } @@ -211,9 +216,17 @@ func (storage *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error { if len(storageMap) > 1 { types := make([]string, 0, len(storageMap)) for k := range storageMap { - types = append(types, k) + switch k { + case "cache": + // allow configuration of caching + default: + types = append(types, k) + } + } + + if len(types) > 1 { + return fmt.Errorf("Must provide exactly one storage type. Provided: %v", types) } - return fmt.Errorf("Must provide exactly one storage type. Provided: %v", types) } *storage = storageMap return nil diff --git a/doc/configuration.md b/doc/configuration.md index 6071efe6..eba81772 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -28,6 +28,8 @@ storage: v4auth: true chunksize: 5242880 rootdirectory: /s3/object/name/prefix + cache: + layerinfo: inmemory auth: silly: realm: silly-realm @@ -162,10 +164,20 @@ storage: v4auth: true chunksize: 5242880 rootdirectory: /s3/object/name/prefix + cache: + layerinfo: inmemory ``` The storage option is **required** and defines which storage backend is in use. At the moment only one backend may be configured, an error is returned when the registry is started with more than one storage backend configured. +A `cache` subsection can be used to enable caching of data accessed in the +storage backend. Currently, the only available cache provides fast access to +layer metadata. This if configured using the `layerinfo` field. The following +cache implementations are available: + +- redis: using the redis pool to cache layer meta data. +- inmemory: use an in memory map to cache layer meta data. + The following backends may be configured, **all options for a given storage backend are required**: ### filesystem diff --git a/registry/handlers/app.go b/registry/handlers/app.go index e333d6d9..0863732c 100644 --- a/registry/handlers/app.go +++ b/registry/handlers/app.go @@ -103,11 +103,28 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App app.configureEvents(&configuration) app.configureRedis(&configuration) - if app.redis != nil { - app.registry = storage.NewRegistryWithDriver(app.driver, cache.NewRedisLayerInfoCache(app.redis)) - } else { - // always fall back to inmemory storage - app.registry = storage.NewRegistryWithDriver(app.driver, cache.NewInMemoryLayerInfoCache()) + // configure storage caches + if cc, ok := configuration.Storage["cache"]; ok { + switch cc["layerinfo"] { + case "redis": + if app.redis == nil { + panic("redis configuration required to use for layerinfo cache") + } + app.registry = storage.NewRegistryWithDriver(app.driver, cache.NewRedisLayerInfoCache(app.redis)) + ctxu.GetLogger(app).Infof("using redis layerinfo cache") + case "inmemory": + app.registry = storage.NewRegistryWithDriver(app.driver, cache.NewInMemoryLayerInfoCache()) + ctxu.GetLogger(app).Infof("using inmemory layerinfo cache") + default: + if cc["layerinfo"] != "" { + ctxu.GetLogger(app).Warnf("unkown cache type %q, caching disabled", configuration.Storage["cache"]) + } + } + } + + if app.registry == nil { + // configure the registry if no cache section is available. + app.registry = storage.NewRegistryWithDriver(app.driver, nil) } app.registry, err = applyRegistryMiddleware(app.registry, configuration.Middleware["registry"])