Skip to content

SCAN | Redis

特点

  • 如果有一个元素, 它从遍历开始直到遍历结束期间都存在于被遍历的数据集当中, 那么 SCAN命令总会在某次迭代中将这个元素返回给用户。
  • 如果有一个元素, 它从遍历开始就已经被删除,且直到遍历结束也没有被添加回来, 那么 SCAN命令确保不会返回这个元素。

缺点

  • 同一个元素可能会被返回多次。 处理重复元素的工作交由应用程序负责, 比如说, 可以考虑将迭代返回的元素仅仅用于可以安全地重复执行多次的操作上。
  • 如果一个元素是在迭代过程中被添加到数据集的, 又或者是在迭代过程中从数据集中被删除的, 那么这个元素可能会被返回, 也可能不会, 这是未定义的(undefined)。

注意事项

  • 返回的结果可能会有重复,需要客户端去重复,这点非常重要;
  • 遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的;
  • 单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零;

源码

https://github.com/redis/redis/blob/1571907ea02020a829fca63806780c6f3ecf65a0/src/dict.c#L892

实际上是直接获取 hash 表的槽,一个槽一个槽的返回。游标可以找到槽的位置。

用了一个很巧妙的算法来计算游标

  • 在扩容时不会重复且不会漏掉数据
  • 在缩容是不会漏掉数据