diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/memcached-automove-extstore | 31 |
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. |