From aee7c55fbbd1b9db06efcc16521a8e7441fc1f65 Mon Sep 17 00:00:00 2001 From: Chunlin Yang Date: Tue, 3 Aug 2021 16:49:31 +0800 Subject: [PATCH 1/4] reduce the length of scenario name (#4516) Signed-off-by: clyang82 --- test/e2e/tools_bucket_web_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/tools_bucket_web_test.go b/test/e2e/tools_bucket_web_test.go index 6ee8140bbff..97d6c0db009 100644 --- a/test/e2e/tools_bucket_web_test.go +++ b/test/e2e/tools_bucket_web_test.go @@ -112,7 +112,7 @@ func TestToolsBucketWebExternalPrefix(t *testing.T) { func TestToolsBucketWebExternalPrefixAndRoutePrefix(t *testing.T) { t.Parallel() - s, err := e2e.NewScenario("e2e_test_tools_bucket_web_external_prefix_and_route_prefix") + s, err := e2e.NewScenario("e2e_test_tools_bucket_web_and_route_prefix") testutil.Ok(t, err) t.Cleanup(e2ethanos.CleanScenario(t, s)) From baea4ce9ef52846f258d4251589173e4ad759fc8 Mon Sep 17 00:00:00 2001 From: Roy C Date: Tue, 3 Aug 2021 12:25:24 -0700 Subject: [PATCH 2/4] query: add memcached autodiscovery support (#4487) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add memcached autodiscovery support Signed-off-by: Roy Chiang * pass logger to provider struct Signed-off-by: Roy Chiang * fix linter issues Signed-off-by: Roy Chiang * remove copypasted comment Signed-off-by: Roy Chiang * address comments Signed-off-by: Roy Chiang * Update docs/components/store.md Co-authored-by: Giedrius Statkevičius Signed-off-by: Roy Chiang * add lock/unlock for autodiscovery provider Signed-off-by: Roy Chiang Co-authored-by: Giedrius Statkevičius --- CHANGELOG.md | 1 + docs/components/query-frontend.md | 1 + docs/components/store.md | 4 +- pkg/cacheutil/memcached_client.go | 57 ++++++++---- pkg/discovery/memcache/provider.go | 114 ++++++++++++++++++++++++ pkg/discovery/memcache/provider_test.go | 81 +++++++++++++++++ pkg/discovery/memcache/resolver.go | 111 +++++++++++++++++++++++ pkg/discovery/memcache/resolver_test.go | 83 +++++++++++++++++ 8 files changed, 435 insertions(+), 17 deletions(-) create mode 100644 pkg/discovery/memcache/provider.go create mode 100644 pkg/discovery/memcache/provider_test.go create mode 100644 pkg/discovery/memcache/resolver.go create mode 100644 pkg/discovery/memcache/resolver_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index e6b49139e4d..d3669f90365 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re - [#3970](https://github.com/thanos-io/thanos/pull/3970) Azure: Adds more configuration options for Azure blob storage. This allows for pipeline and reader specific configuration. Implements HTTP transport configuration options. These options allows for more fine-grained control on timeouts and retries. Implements MSI authentication as second method of authentication via a service principal token. - [#4406](https://github.com/thanos-io/thanos/pull/4406) Tools: Add retention command for applying retention policy on the bucket. - [#4430](https://github.com/thanos-io/thanos/pull/4430) Compact: Add flag `downsample.concurrency` to specify the concurrency of downsampling blocks. +- [#4487](https://github.com/thanos-io/thanos/pull/4487) Query: Add memcached auto discovery support. ### Fixed diff --git a/docs/components/query-frontend.md b/docs/components/query-frontend.md index e16228b6700..6e1a6a7f74e 100644 --- a/docs/components/query-frontend.md +++ b/docs/components/query-frontend.md @@ -74,6 +74,7 @@ config: max_item_size: 0 max_get_multi_batch_size: 0 dns_provider_update_interval: 0s + auto_discovery: false expiration: 0s ``` diff --git a/docs/components/store.md b/docs/components/store.md index 888a8469917..0b955a4b3d9 100644 --- a/docs/components/store.md +++ b/docs/components/store.md @@ -290,11 +290,12 @@ config: max_item_size: 0 max_get_multi_batch_size: 0 dns_provider_update_interval: 0s + auto_discovery: false ``` The **required** settings are: -- `addresses`: list of memcached addresses, that will get resolved with the [DNS service discovery](../service-discovery.md/#dns-service-discovery) provider. +- `addresses`: list of memcached addresses, that will get resolved with the [DNS service discovery](../service-discovery.md/#dns-service-discovery) provider. If your cluster supports auto-discovery, you should use the flag `auto_discovery` instead and only point to *one of* the memcached servers. This typically means that there should be only one address specified that resolves to any of the alive memcached servers. Use this for Amazon ElastiCache and other similar services. While the remaining settings are **optional**: @@ -306,6 +307,7 @@ While the remaining settings are **optional**: - `max_get_multi_batch_size`: maximum number of keys a single underlying operation should fetch. If more keys are specified, internally keys are splitted into multiple batches and fetched concurrently, honoring `max_get_multi_concurrency`. If set to `0`, the batch size is unlimited. - `max_item_size`: maximum size of an item to be stored in memcached. This option should be set to the same value of memcached `-I` flag (defaults to 1MB) in order to avoid wasting network round trips to store items larger than the max item size allowed in memcached. If set to `0`, the item size is unlimited. - `dns_provider_update_interval`: the DNS discovery update interval. +- `auto_discovery`: whether to use the auto-discovery mechanism for memcached. ## Caching Bucket diff --git a/pkg/cacheutil/memcached_client.go b/pkg/cacheutil/memcached_client.go index cb5adcb0d03..445138b3e6d 100644 --- a/pkg/cacheutil/memcached_client.go +++ b/pkg/cacheutil/memcached_client.go @@ -21,6 +21,7 @@ import ( "gopkg.in/yaml.v2" "github.com/thanos-io/thanos/pkg/discovery/dns" + memcacheDiscovery "github.com/thanos-io/thanos/pkg/discovery/memcache" "github.com/thanos-io/thanos/pkg/extprom" "github.com/thanos-io/thanos/pkg/gate" "github.com/thanos-io/thanos/pkg/model" @@ -53,6 +54,7 @@ var ( MaxGetMultiConcurrency: 100, MaxGetMultiBatchSize: 0, DNSProviderUpdateInterval: 10 * time.Second, + AutoDiscovery: false, } ) @@ -114,6 +116,9 @@ type MemcachedClientConfig struct { // DNSProviderUpdateInterval specifies the DNS discovery update interval. DNSProviderUpdateInterval time.Duration `yaml:"dns_provider_update_interval"` + + // AutoDiscovery configures memached client to perform auto-discovery instead of DNS resolution + AutoDiscovery bool `yaml:"auto_discovery"` } func (c *MemcachedClientConfig) validate() error { @@ -153,8 +158,8 @@ type memcachedClient struct { // Name provides an identifier for the instantiated Client name string - // DNS provider used to keep the memcached servers list updated. - dnsProvider *dns.Provider + // Address provider used to keep the memcached servers list updated. + addressProvider AddressProvider // Channel used to notify internal goroutines when they should quit. stop chan struct{} @@ -177,6 +182,15 @@ type memcachedClient struct { dataSize *prometheus.HistogramVec } +// AddressProvider performs node address resolution given a list of clusters. +type AddressProvider interface { + // Resolves the provided list of memcached cluster to the actual nodes + Resolve(context.Context, []string) error + + // Returns the nodes + Addresses() []string +} + type memcachedGetMultiResult struct { items map[string]*memcache.Item err error @@ -220,20 +234,31 @@ func newMemcachedClient( reg prometheus.Registerer, name string, ) (*memcachedClient, error) { - dnsProvider := dns.NewProvider( - logger, - extprom.WrapRegistererWithPrefix("thanos_memcached_", reg), - dns.GolangResolverType, - ) + promRegisterer := extprom.WrapRegistererWithPrefix("thanos_memcached_", reg) + + var addressProvider AddressProvider + if config.AutoDiscovery { + addressProvider = memcacheDiscovery.NewProvider( + logger, + promRegisterer, + config.Timeout, + ) + } else { + addressProvider = dns.NewProvider( + logger, + extprom.WrapRegistererWithPrefix("thanos_memcached_", reg), + dns.GolangResolverType, + ) + } c := &memcachedClient{ - logger: log.With(logger, "name", name), - config: config, - client: client, - selector: selector, - dnsProvider: dnsProvider, - asyncQueue: make(chan func(), config.MaxAsyncBufferSize), - stop: make(chan struct{}, 1), + logger: log.With(logger, "name", name), + config: config, + client: client, + selector: selector, + addressProvider: addressProvider, + asyncQueue: make(chan func(), config.MaxAsyncBufferSize), + stop: make(chan struct{}, 1), getMultiGate: gate.New( extprom.WrapRegistererWithPrefix("thanos_memcached_getmulti_", reg), config.MaxGetMultiConcurrency, @@ -561,11 +586,11 @@ func (c *memcachedClient) resolveAddrs() error { defer cancel() // If some of the dns resolution fails, log the error. - if err := c.dnsProvider.Resolve(ctx, c.config.Addresses); err != nil { + if err := c.addressProvider.Resolve(ctx, c.config.Addresses); err != nil { level.Error(c.logger).Log("msg", "failed to resolve addresses for memcached", "addresses", strings.Join(c.config.Addresses, ","), "err", err) } // Fail in case no server address is resolved. - servers := c.dnsProvider.Addresses() + servers := c.addressProvider.Addresses() if len(servers) == 0 { return fmt.Errorf("no server address resolved for %s", c.name) } diff --git a/pkg/discovery/memcache/provider.go b/pkg/discovery/memcache/provider.go new file mode 100644 index 00000000000..9bb13178240 --- /dev/null +++ b/pkg/discovery/memcache/provider.go @@ -0,0 +1,114 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package memcache + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/thanos-io/thanos/pkg/errutil" + "github.com/thanos-io/thanos/pkg/extprom" +) + +// Provider is a stateful cache for asynchronous memcached auto-discovery resolution. It provides a way to resolve +// addresses and obtain them. +type Provider struct { + sync.RWMutex + resolver Resolver + clusterConfigs map[string]*clusterConfig + logger log.Logger + + configVersion *extprom.TxGaugeVec + resolvedAddresses *extprom.TxGaugeVec + resolverFailuresCount prometheus.Counter + resolverLookupsCount prometheus.Counter +} + +func NewProvider(logger log.Logger, reg prometheus.Registerer, dialTimeout time.Duration) *Provider { + p := &Provider{ + resolver: &memcachedAutoDiscovery{dialTimeout: dialTimeout}, + clusterConfigs: map[string]*clusterConfig{}, + configVersion: extprom.NewTxGaugeVec(reg, prometheus.GaugeOpts{ + Name: "auto_discovery_config_version", + Help: "The current auto discovery config version", + }, []string{"addr"}), + resolvedAddresses: extprom.NewTxGaugeVec(reg, prometheus.GaugeOpts{ + Name: "auto_discovery_resolved_addresses", + Help: "The number of memcached nodes found via auto discovery", + }, []string{"addr"}), + resolverLookupsCount: promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "auto_discovery_total", + Help: "The number of memcache auto discovery attempts", + }), + resolverFailuresCount: promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "auto_discovery_failures_total", + Help: "The number of memcache auto discovery failures", + }), + logger: logger, + } + return p +} + +// Resolve stores a list of nodes auto-discovered from the provided addresses. +func (p *Provider) Resolve(ctx context.Context, addresses []string) error { + clusterConfigs := map[string]*clusterConfig{} + errs := errutil.MultiError{} + + for _, address := range addresses { + clusterConfig, err := p.resolver.Resolve(ctx, address) + p.resolverLookupsCount.Inc() + + if err != nil { + level.Warn(p.logger).Log( + "msg", "failed to perform auto-discovery for memcached", + "address", address, + ) + errs.Add(err) + p.resolverFailuresCount.Inc() + + // Use cached values. + p.RLock() + clusterConfigs[address] = p.clusterConfigs[address] + p.RUnlock() + } else { + clusterConfigs[address] = clusterConfig + } + } + + p.Lock() + defer p.Unlock() + + p.resolvedAddresses.ResetTx() + p.configVersion.ResetTx() + for address, config := range clusterConfigs { + p.resolvedAddresses.WithLabelValues(address).Set(float64(len(config.nodes))) + p.configVersion.WithLabelValues(address).Set(float64(config.version)) + } + p.resolvedAddresses.Submit() + p.configVersion.Submit() + + p.clusterConfigs = clusterConfigs + + return errs.Err() +} + +// Addresses returns the latest addresses present in the Provider. +func (p *Provider) Addresses() []string { + p.RLock() + defer p.RUnlock() + + var result []string + for _, config := range p.clusterConfigs { + for _, node := range config.nodes { + result = append(result, fmt.Sprintf("%s:%d", node.dns, node.port)) + } + } + return result +} diff --git a/pkg/discovery/memcache/provider_test.go b/pkg/discovery/memcache/provider_test.go new file mode 100644 index 00000000000..6ebbc16657f --- /dev/null +++ b/pkg/discovery/memcache/provider_test.go @@ -0,0 +1,81 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package memcache + +import ( + "context" + "sort" + "testing" + "time" + + "github.com/pkg/errors" + + "github.com/go-kit/kit/log" + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestProviderUpdatesAddresses(t *testing.T) { + ctx := context.TODO() + clusters := []string{"memcached-cluster-1", "memcached-cluster-2"} + provider := NewProvider(log.NewNopLogger(), nil, 5*time.Second) + resolver := mockResolver{ + configs: map[string]*clusterConfig{ + "memcached-cluster-1": {nodes: []node{{dns: "dns-1", ip: "ip-1", port: 11211}}}, + "memcached-cluster-2": {nodes: []node{{dns: "dns-2", ip: "ip-2", port: 8080}}}, + }, + } + provider.resolver = &resolver + + testutil.Ok(t, provider.Resolve(ctx, clusters)) + addresses := provider.Addresses() + testutil.Equals(t, []string{"dns-1:11211", "dns-2:8080"}, addresses) + + resolver.configs = map[string]*clusterConfig{ + "memcached-cluster-1": {nodes: []node{{dns: "dns-1", ip: "ip-1", port: 11211}, {dns: "dns-3", ip: "ip-3", port: 11211}}}, + "memcached-cluster-2": {nodes: []node{{dns: "dns-2", ip: "ip-2", port: 8080}}}, + } + + testutil.Ok(t, provider.Resolve(ctx, clusters)) + addresses = provider.Addresses() + sort.Strings(addresses) + testutil.Equals(t, []string{"dns-1:11211", "dns-2:8080", "dns-3:11211"}, addresses) +} + +func TestProviderDoesNotUpdateAddressIfFailed(t *testing.T) { + ctx := context.TODO() + clusters := []string{"memcached-cluster-1", "memcached-cluster-2"} + provider := NewProvider(log.NewNopLogger(), nil, 5*time.Second) + resolver := mockResolver{ + configs: map[string]*clusterConfig{ + "memcached-cluster-1": {nodes: []node{{dns: "dns-1", ip: "ip-1", port: 11211}}}, + "memcached-cluster-2": {nodes: []node{{dns: "dns-2", ip: "ip-2", port: 8080}}}, + }, + } + provider.resolver = &resolver + + testutil.Ok(t, provider.Resolve(ctx, clusters)) + addresses := provider.Addresses() + sort.Strings(addresses) + testutil.Equals(t, []string{"dns-1:11211", "dns-2:8080"}, addresses) + + resolver.configs = nil + resolver.err = errors.New("oops") + + testutil.NotOk(t, provider.Resolve(ctx, clusters)) + addresses = provider.Addresses() + sort.Strings(addresses) + testutil.Equals(t, []string{"dns-1:11211", "dns-2:8080"}, addresses) +} + +type mockResolver struct { + configs map[string]*clusterConfig + err error +} + +func (r *mockResolver) Resolve(_ context.Context, address string) (*clusterConfig, error) { + if r.err != nil { + return nil, r.err + } + return r.configs[address], nil +} diff --git a/pkg/discovery/memcache/resolver.go b/pkg/discovery/memcache/resolver.go new file mode 100644 index 00000000000..4e7406cfba7 --- /dev/null +++ b/pkg/discovery/memcache/resolver.go @@ -0,0 +1,111 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package memcache + +import ( + "bufio" + "context" + "fmt" + "net" + "strconv" + "strings" + "time" + + "github.com/thanos-io/thanos/pkg/runutil" +) + +type clusterConfig struct { + version int + nodes []node +} + +type node struct { + dns string + ip string + port int +} + +type Resolver interface { + Resolve(ctx context.Context, address string) (*clusterConfig, error) +} + +type memcachedAutoDiscovery struct { + dialTimeout time.Duration +} + +func (s *memcachedAutoDiscovery) Resolve(ctx context.Context, address string) (config *clusterConfig, err error) { + conn, err := net.DialTimeout("tcp", address, s.dialTimeout) + if err != nil { + return nil, err + } + defer runutil.CloseWithErrCapture(&err, conn, "closing connection") + + rw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)) + if _, err := fmt.Fprintf(rw, "config get cluster\n"); err != nil { + return nil, err + } + if err := rw.Flush(); err != nil { + return nil, err + } + + config, err = s.parseConfig(rw.Reader) + if err != nil { + return nil, err + } + + return config, err +} + +func (s *memcachedAutoDiscovery) parseConfig(reader *bufio.Reader) (*clusterConfig, error) { + clusterConfig := new(clusterConfig) + + configMeta, err := reader.ReadString('\n') + if err != nil { + return nil, fmt.Errorf("failed to read config metadata: %s", err) + } + configMeta = strings.TrimSpace(configMeta) + + // First line should be "CONFIG cluster 0 [length-of-payload-] + configMetaComponents := strings.Split(configMeta, " ") + if len(configMetaComponents) != 4 { + return nil, fmt.Errorf("expected 4 components in config metadata, and received %d, meta: %s", len(configMetaComponents), configMeta) + } + + configSize, err := strconv.Atoi(configMetaComponents[3]) + if err != nil { + return nil, fmt.Errorf("failed to parse config size from metadata: %s, error: %s", configMeta, err) + } + + configVersion, err := reader.ReadString('\n') + if err != nil { + return nil, fmt.Errorf("failed to find config version: %s", err) + } + clusterConfig.version, err = strconv.Atoi(strings.TrimSpace(configVersion)) + if err != nil { + return nil, fmt.Errorf("failed to parser config version: %s", err) + } + + nodes, err := reader.ReadString('\n') + if err != nil { + return nil, fmt.Errorf("failed to read nodes: %s", err) + } + + if len(configVersion)+len(nodes) != configSize { + return nil, fmt.Errorf("expected %d in config payload, but got %d instead.", configSize, len(configVersion)+len(nodes)) + } + + for _, host := range strings.Split(strings.TrimSpace(nodes), " ") { + dnsIpPort := strings.Split(host, "|") + if len(dnsIpPort) != 3 { + return nil, fmt.Errorf("node not in expected format: %s", dnsIpPort) + } + port, err := strconv.Atoi(dnsIpPort[2]) + if err != nil { + return nil, fmt.Errorf("failed to parse port: %s, err: %s", dnsIpPort, err) + } + clusterConfig.nodes = append(clusterConfig.nodes, node{dns: dnsIpPort[0], ip: dnsIpPort[1], port: port}) + } + + return clusterConfig, nil +} diff --git a/pkg/discovery/memcache/resolver_test.go b/pkg/discovery/memcache/resolver_test.go new file mode 100644 index 00000000000..a1dad82e74f --- /dev/null +++ b/pkg/discovery/memcache/resolver_test.go @@ -0,0 +1,83 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package memcache + +import ( + "bufio" + "strings" + "testing" + + "github.com/pkg/errors" + + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestGoodClusterConfigs(t *testing.T) { + resolver := memcachedAutoDiscovery{} + testCases := []struct { + content string + config clusterConfig + }{ + {"CONFIG cluster 0 23\r\n100\r\ndns-1|ip-1|11211\r\nEND\r\n", + clusterConfig{nodes: []node{{dns: "dns-1", ip: "ip-1", port: 11211}}, version: 100}, + }, + {"CONFIG cluster 0 37\r\n0\r\ndns-1|ip-1|11211 dns-2|ip-2|8080\r\nEND\r\n", + clusterConfig{nodes: []node{{dns: "dns-1", ip: "ip-1", port: 11211}, {dns: "dns-2", ip: "ip-2", port: 8080}}, version: 0}, + }, + } + + for _, testCase := range testCases { + reader := bufio.NewReader(strings.NewReader(testCase.content)) + + config, err := resolver.parseConfig(reader) + + testutil.Ok(t, err) + testutil.Equals(t, testCase.config, *config) + } +} + +func TestBadClusterConfigs(t *testing.T) { + resolver := memcachedAutoDiscovery{} + testCases := []struct { + content string + expectedErr error + }{ + {"", + errors.New("failed to read config metadata: EOF"), + }, + {"CONFIG cluster\r\n", + errors.New("expected 4 components in config metadata, and received 2, meta: CONFIG cluster"), + }, + {"CONFIG cluster 0 configSize\r\n", + errors.New("failed to parse config size from metadata: CONFIG cluster 0 configSize, error: strconv.Atoi: parsing \"configSize\": invalid syntax"), + }, + {"CONFIG cluster 0 100\r\n", + errors.New("failed to find config version: EOF"), + }, + {"CONFIG cluster 0 100\r\nconfigVersion\r\n", + errors.New("failed to parser config version: strconv.Atoi: parsing \"configVersion\": invalid syntax"), + }, + {"CONFIG cluster 0 100\r\n0\r\n", + errors.New("failed to read nodes: EOF"), + }, + {"CONFIG cluster 0 0\r\n100\r\ndns-1|ip-1|11211\r\nEND\r\n", + errors.New("expected 0 in config payload, but got 23 instead."), + }, + {"CONFIG cluster 0 17\r\n100\r\ndns-1|ip-1\r\nEND\r\n", + errors.New("node not in expected format: [dns-1 ip-1]"), + }, + {"CONFIG cluster 0 22\r\n100\r\ndns-1|ip-1|port\r\nEND\r\n", + errors.New("failed to parse port: [dns-1 ip-1 port], err: strconv.Atoi: parsing \"port\": invalid syntax"), + }, + } + + for _, testCase := range testCases { + reader := bufio.NewReader(strings.NewReader(testCase.content)) + + _, err := resolver.parseConfig(reader) + + testutil.Assert(t, testCase.expectedErr.Error() == err.Error(), "expected error '%v', but got '%v'", testCase.expectedErr.Error(), err.Error()) + } + +} From 26791c4c890e7296abe718400b26043961f6f703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Wed, 4 Aug 2021 00:38:29 +0300 Subject: [PATCH 3/4] CHANGELOG: fix changelog item (#4517) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has just been added so it needs to be under the unreleased section. Signed-off-by: Giedrius Statkevičius --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3669f90365..b88a66a1f87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re ### Added - [#4453](https://github.com/thanos-io/thanos/pull/4453) Tools: Add flag `--selector.relabel-config-file` / `--selector.relabel-config` / `--max-time` / `--min-time` to filter served blocks. - [#4482](https://github.com/thanos-io/thanos/pull/4482) COS: Add http_config for cos object store client. +- [#4487](https://github.com/thanos-io/thanos/pull/4487) Query: Add memcached auto discovery support. ### Fixed @@ -35,7 +36,6 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re - [#3970](https://github.com/thanos-io/thanos/pull/3970) Azure: Adds more configuration options for Azure blob storage. This allows for pipeline and reader specific configuration. Implements HTTP transport configuration options. These options allows for more fine-grained control on timeouts and retries. Implements MSI authentication as second method of authentication via a service principal token. - [#4406](https://github.com/thanos-io/thanos/pull/4406) Tools: Add retention command for applying retention policy on the bucket. - [#4430](https://github.com/thanos-io/thanos/pull/4430) Compact: Add flag `downsample.concurrency` to specify the concurrency of downsampling blocks. -- [#4487](https://github.com/thanos-io/thanos/pull/4487) Query: Add memcached auto discovery support. ### Fixed From cd18b61551692ed9e28794f0fa6346ecfb6708d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Wed, 4 Aug 2021 03:34:02 +0300 Subject: [PATCH 4/4] MAINTAINERS: fix my workplace (#4518) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed my workplace recently so update MAINTAINERS.md accordingly. Signed-off-by: Giedrius Statkevičius --- MAINTAINERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 369af06708c..60e32598364 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -4,7 +4,7 @@ |-----------------------|------------------------|--------------------------|----------------------------------------------|---------------| | Bartłomiej Płotka | bwplotka@gmail.com | `@bwplotka` | [@bwplotka](https://github.com/bwplotka) | Red Hat | | Frederic Branczyk | fbranczyk@gmail.com | `@brancz` | [@brancz](https://github.com/brancz) | Polar Signals | -| Giedrius Statkevičius | giedriuswork@gmail.com | `@Giedrius Statkevičius` | [@GiedriusS](https://github.com/GiedriusS) | AdForm | +| Giedrius Statkevičius | giedriuswork@gmail.com | `@Giedrius Statkevičius` | [@GiedriusS](https://github.com/GiedriusS) | Vinted | | Kemal Akkoyun | kakkoyun@gmail.com | `@kakkoyun` | [@kakkoyun](https://github.com/kakkoyun) | Polar Signals | | Lucas Servén Marín | lserven@gmail.com | `@squat` | [@squat](https://github.com/squat) | Red Hat | | Prem Saraswat | prmsrswt@gmail.com | `@Prem Saraswat` | [@onprem](https://github.com/onprem) | Red Hat |