W rzeczy samej! To dlatego, że SCAN działa w ten sposób, cytując dokumentację Redis:
Jednak podczas gdy polecenia blokujące, takie jak SMEMBERS, są w stanie zapewnić wszystkie elementy, które są częścią Zestawu w danym momencie, Rodzina poleceń SCAN oferuje tylko ograniczone gwarancje o zwróconych elementach, ponieważ kolekcja, którą stopniowo iterujemy, może się zmieniać podczas procesu iteracji.
Jednak ponieważ SCAN ma bardzo mało skojarzonych stanów (tylko kursor), ma następujące wady:Dany element może być zwracany wielokrotnie. Od aplikacji zależy obsługa zduplikowanych elementów , na przykład używając tylko zwróconych elementów w celu wykonania operacji, które są bezpieczne po wielokrotnym zastosowaniu.
Więc możesz użyć chcesz użyć array_unique($keys) po foreach
.
Aby zrozumieć, dlaczego iteracja działa w ten sposób, najlepiej jest przeczytać tę część dokumentacji Redis .