Мы сталкиваемся с ситуацией, когда в определенных слэбах происходят вытеснения, даже если для memcached выделено достаточно памяти, но memcached не освобождает/не перебалансирует неиспользуемые страницы из других слэбов.
версия memcached: 1.4.15
Вот вывод memcached-tool-ng (стороннего инструмента с немного более подробной информацией о memstats).
# Item_Size Max_age Pages Count Used Mem To Store Efficiency Evicted Evict_Time OOM
10 6.9K 1583s 1 2 1.00 MB 12.99 KB 1.27 % 0 0 0
11 11.1K 480s 83 1890 83.00 MB 17.38 MB 20.94 % 282249 480 0
12 17.8K 479s 57 1156 57.00 MB 19.67 MB 34.51 % 6959481 479 0
13 28.4K 480s 1052 7277 1.03 GB 136.18 MB 12.94 % 941078 480 0
14 45.5K 27s 562 17 562.00 MB 536.25 KB 0.09 % 114861 22 0
15 72.7K 21s 574 2 574.00 MB 125.03 KB 0.02 % 2615 18 0
16 116.4K 30055s 790 300 790.00 MB 25.96 MB 3.29 % 34786 22 0
17 186.2K 30230s 1823 1433 1.78 GB 187.89 MB 10.31 % 21823 22 0
18 297.9K 30201s 2604 26 2.54 GB 4.91 MB 0.19 % 1373 25 0
19 476.7K 35234s 1322 2 1.29 GB 615.39 KB 0.05 % 0 0 0
20 1024.0K 0s 2 0 2.00 MB 0 b 0.00 % 0 0 0
Total used memory: 8.66 GB (for 393.24 MB of data)
Global efficiency: 4.43 %
Total used memory: 8.66 GB (for 393.24 MB of data)
Global efficiency: 4.43 %
Глядя на количество страниц и количество объектов, очевидно, что много памяти тратится впустую в более высоких слэбах. Рассмотрим слэб 18 или 19, в слэбе 18 всего 26 объектов, предположим, что нам может понадобиться максимум 13 страниц для размещения этих объектов, общее количество выделенных страниц составляет 2604.
Наше приложение обычно устанавливает TTL не более 480 секунд для любого объекта, однако максимальный возраст в более высоких слэбах слишком высок, а в более плотных (нижних) слэбах наблюдаются выселения партий.
Может ли кто-нибудь объяснить, почему Memcached не извлекает неиспользуемые страницы из более высоких блоков и не распределяет их по блокам, где требуется больше страниц?