De fato! Isso porque o SCAN funciona dessa maneira, citando a documentação do Redis:
No entanto, enquanto comandos de bloqueio como SMEMBERS são capazes de fornecer todos os elementos que fazem parte de um conjunto em um determinado momento, A família de comandos SCAN oferece apenas garantias limitadas sobre os elementos retornados, pois a coleção que iteramos incrementalmente pode mudar durante o processo de iteração.
No entanto, como SCAN tem muito pouco estado associado (apenas o cursor), ele tem as seguintes desvantagens:Um determinado elemento pode ser retornado várias vezes. Cabe ao aplicativo lidar com o caso de elementos duplicados , por exemplo, usando apenas os elementos retornados para realizar operações que são seguras quando reaplicadas várias vezes.
Então você pode querer usar array_unique($keys) após o
foreach
. Para entender por que a iteração funciona dessa maneira, o melhor é ler esta parte da documentação do Redis .