summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/memcached-automove-extstore31
1 files changed, 21 insertions, 10 deletions
diff --git a/scripts/memcached-automove-extstore b/scripts/memcached-automove-extstore
index 3419620..fa7a11c 100755
--- a/scripts/memcached-automove-extstore
+++ b/scripts/memcached-automove-extstore
@@ -74,6 +74,7 @@ def determine_move(history, stats, diffs, memfree):
w = history['w'][-1]
oldest = (-1, 0)
youngest = (-1, sys.maxsize)
+ too_free = False
# Most bytes free
decision = (-1, -1)
if int(stats['slab_global_page_pool']) < memfree[0] / 2:
@@ -107,11 +108,17 @@ def determine_move(history, stats, diffs, memfree):
age = window_check(history, sid, 'age') / len(history['w'])
# if > 2.5 pages free, and not dirty, reassign to global page pool
- if slab['free_chunks'] > slab['chunks_per_page'] * MIN_PAGES_FOR_RECLAIM:
- if window_check(history, sid, 'dirty') == 0 and small_slab == True:
+ if slab['free_chunks'] > slab['chunks_per_page'] * MIN_PAGES_FOR_RECLAIM and too_free == False:
+ dirt = window_check(history, sid, 'dirty')
+ excess = window_check(history, sid, 'excess_free')
+ if small_slab == True and dirt == 0:
# If we're a small slab, don't hang on to free memory forever.
decision = (sid, 0)
- break
+ too_free = True
+ elif small_slab == False and dirt == 0 \
+ and excess >= len(history['w']):
+ decision = (sid, 0)
+ too_free = True
# are we the oldest slab class? (and a valid target)
if small_slab == False:
@@ -122,18 +129,18 @@ def determine_move(history, stats, diffs, memfree):
youngest = (sid, age)
- if pool_high and youngest[0] != -1:
+ if w.get('slab_pool_high') and youngest[0] != -1:
# if global pool is too high, feed youngest large class.
# decision = (0, youngest[0])
# No current way to assign directly from global to a class.
# minimize the free chunks limiter and re-check.
decision = (youngest[0], -2)
- elif pool_low and oldest[0] != -1:
+ elif too_free == False and pool_low and oldest[0] != -1:
# if pool is too low, take from oldest large class.
if args.verbose:
print("oldest: [class: {}] [age: {}]".format(int(oldest[0]), oldest[1]))
decision = (oldest[0], 0)
- elif youngest[0] != -1 and oldest[0] != -1 and youngest[0] != oldest[0]:
+ elif too_free == False and youngest[0] != -1 and oldest[0] != -1 and youngest[0] != oldest[0]:
# youngest is outside of the tolerance ratio, move a page around.
if args.verbose:
print("old: [class: {}] [age: {:.2f}]\nyoung: [class: {}] [age: {:.2f}]".format(
@@ -288,16 +295,20 @@ while True:
decision = (-1, -1)
if int(stats['evictions']) > 0:
decision = determine_move(history, stats, diffs, memfree)
- if int(decision[0]) > 0 and decision[1] >= 0:
+ if int(decision[0]) > 0 and int(decision[1]) >= 0:
print("moving page from, to:", decision)
if args.automove:
run_move(s, decision)
elif int(decision[0]) > 0 and decision[1] == -2:
- # we've been told to zero out the memory limit and
- # sleep for a bit.
- last_memfree_check = 0
+ # we've been told to zero out the memory limit.
+ # let the memfree check run "soon".
+ # this (purposefully) can slowly remove limits on
+ # multiple classes if global pool stays too high.
+ last_memfree_check = time() - 58
s.write("extstore free_memchunks {} {}\r\n".format(decision[0], 0))
s.readline()
+ if args.verbose:
+ print("relaxing free:", decision[0])
# Minimize sleeping if we just moved a page to global pool.