diff options
author | Tim Burke <tim.burke@gmail.com> | 2020-06-18 11:48:14 -0700 |
---|---|---|
committer | Alistair Coles <alistairncoles@gmail.com> | 2022-01-26 18:15:09 +0000 |
commit | 8c6ccb5fd41864155a043856ff9240e84999e4bf (patch) | |
tree | b8e4e6f89f727f6655629ff798e2cf3b7a66150d /swift/proxy | |
parent | 8ef530d795df7f0300e761933c916546427a79fe (diff) | |
download | swift-8c6ccb5fd41864155a043856ff9240e84999e4bf.tar.gz |
proxy: Add a chance to skip memcache when looking for shard ranges
By having some small portion of calls skip cache and go straight to
disk, we can ensure the cache is always kept fresh and never expires (at
least, for active containers). Previously, when shard ranges fell out of
cache there would frequently be a thundering herd that could overwhelm
the container server, leading to 503s served to clients or an increase
in async pendings.
Include metrics for hit/miss/skip rates.
Change-Id: I6d74719fb41665f787375a08184c1969c86ce2cf
Related-Bug: #1883324
Diffstat (limited to 'swift/proxy')
-rw-r--r-- | swift/proxy/controllers/base.py | 12 | ||||
-rw-r--r-- | swift/proxy/controllers/container.py | 11 | ||||
-rw-r--r-- | swift/proxy/server.py | 8 |
3 files changed, 26 insertions, 5 deletions
diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index 278a8b832..d08392601 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -33,6 +33,7 @@ import functools import inspect import itertools import operator +import random from copy import deepcopy from sys import exc_info @@ -2384,9 +2385,14 @@ class Controller(object): cached_ranges = infocache.get(cache_key) if cached_ranges is None and memcache: - cached_ranges = memcache.get(cache_key) - self.app.logger.increment('shard_updating.cache.%s' - % ('hit' if cached_ranges else 'miss')) + skip_chance = \ + self.app.container_updating_shard_ranges_skip_cache + if skip_chance and random.random() < skip_chance: + self.app.logger.increment('shard_updating.cache.skip') + else: + cached_ranges = memcache.get(cache_key) + self.app.logger.increment('shard_updating.cache.%s' % ( + 'hit' if cached_ranges else 'miss')) if cached_ranges: shard_ranges = [ diff --git a/swift/proxy/controllers/container.py b/swift/proxy/controllers/container.py index 6a54454a3..36cc53b3a 100644 --- a/swift/proxy/controllers/container.py +++ b/swift/proxy/controllers/container.py @@ -15,6 +15,7 @@ import json import math +import random import six from six.moves.urllib.parse import unquote @@ -150,7 +151,15 @@ class ContainerController(Controller): shard='listing') cached_ranges = infocache.get(cache_key) if cached_ranges is None and memcache: - cached_ranges = memcache.get(cache_key) + skip_chance = \ + self.app.container_listing_shard_ranges_skip_cache + if skip_chance and random.random() < skip_chance: + self.app.logger.increment('shard_listing.cache.skip') + else: + cached_ranges = memcache.get(cache_key) + self.app.logger.increment('shard_listing.cache.%s' % ( + 'hit' if cached_ranges else 'miss')) + if cached_ranges is not None: infocache[cache_key] = tuple(cached_ranges) # shard ranges can be returned from cache diff --git a/swift/proxy/server.py b/swift/proxy/server.py index e63d20d56..1e1388c41 100644 --- a/swift/proxy/server.py +++ b/swift/proxy/server.py @@ -35,7 +35,7 @@ from swift.common.utils import Watchdog, get_logger, \ get_remote_client, split_path, config_true_value, generate_trans_id, \ affinity_key_function, affinity_locality_predicate, list_from_csv, \ register_swift_info, parse_prefixed_conf, config_auto_int_value, \ - config_request_node_count_value + config_request_node_count_value, config_percent_value from swift.common.constraints import check_utf8, valid_api_version from swift.proxy.controllers import AccountController, ContainerController, \ ObjectControllerRouter, InfoController @@ -227,6 +227,12 @@ class Application(object): self.recheck_account_existence = \ int(conf.get('recheck_account_existence', DEFAULT_RECHECK_ACCOUNT_EXISTENCE)) + self.container_updating_shard_ranges_skip_cache = \ + config_percent_value(conf.get( + 'container_updating_shard_ranges_skip_cache_pct', 0)) + self.container_listing_shard_ranges_skip_cache = \ + config_percent_value(conf.get( + 'container_listing_shard_ranges_skip_cache_pct', 0)) self.allow_account_management = \ config_true_value(conf.get('allow_account_management', 'no')) self.container_ring = container_ring or Ring(swift_dir, |