summaryrefslogtreecommitdiff
path: root/swift/proxy
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2020-06-18 11:48:14 -0700
committerAlistair Coles <alistairncoles@gmail.com>2022-01-26 18:15:09 +0000
commit8c6ccb5fd41864155a043856ff9240e84999e4bf (patch)
treeb8e4e6f89f727f6655629ff798e2cf3b7a66150d /swift/proxy
parent8ef530d795df7f0300e761933c916546427a79fe (diff)
downloadswift-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.py12
-rw-r--r--swift/proxy/controllers/container.py11
-rw-r--r--swift/proxy/server.py8
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,