Я бы сказал, что это связано с истечением срока действия ключа.
Хранилища ключей / значений, такие как Redis или memcached, не могут позволить определить физический таймер для каждого объекта, срок действия которого истекает.Их будет слишком много.Вместо этого они определяют структуру данных для простого отслеживания элементов, срок действия которых истекает, и мультиплексируют все события истечения в один физический таймер.Они также склонны реализовывать ленивую стратегию для обработки этих событий.
С Redis, когда срок действия элемента истекает, ничего не происходит.Однако перед каждым доступом к элементу систематически выполняется проверка, чтобы избежать возврата просроченных элементов и потенциального удаления элемента.Вдобавок к этой ленивой стратегии каждые 100 мс запускается алгоритм мусорщика, чтобы физически истечь количество элементов (т.е. удалить их из основного словаря).Количество рассмотренных ключей на каждой итерации зависит от рабочей нагрузки по истечении срока действия (алгоритм является адаптивным).
Следствием этого является то, что Redis может иметь отставание элементов, срок действия которых истекает в данный момент времени, когда у вас есть устойчивыйпоток событий истечения.
Теперь, возвращаясь к вопросу, команда DBSIZE просто возвращает размер основного словаря, поэтому она включает элементы с истекшим сроком, которые еще не были удалены.Команда KEYS просматривает весь словарь, получая доступ к отдельным ключам, поэтому исключает все просроченные элементы.Поэтому количество предметов может не совпадать.