赞
踩
scan命令和keys命令的时间复杂度都是O(N),这里是一致的。
虽然时间复杂度都是O(N),但scan是分次进行的,不会阻塞线程。
SCAN cursor [MATCH pattern] [COUNT count]
redis 127.0.0.1:6379> scan 0 # 使用 0 作为游标,新开始一次迭代 1) "17" # 本次迭代返回的游标 2) 1) "key-12" 2) "key-8" 3) "key-4" 4) "key-14" 5) "key-16" 6) "key-17" 7) "key-15" 8) "key-10" 9) "key-3" 10) "key-7" 11) "key-1" redis 127.0.0.1:6379> scan 17 # 使用的是第一次迭代时返回的游标 17 可以接着上一次迭代,继续迭代 1) "0" # 这次迭代返回0,表示数据集已经被完整遍历过了 2) 1) "key-5" 2) "key-18" 3) "key-0" 4) "key-2" 5) "key-19" 6) "key-13" 7) "key-6" 8) "key-9" 9) "key-11"
从完整遍历开始直到完整遍历结束期间, 一直存在于数据集内的所有元素都会被完整遍历返回; 这意味着, 如果有一个元素, 它从遍历开始直到遍历结束期间都存在于被遍历的数据集当中, 那么 SCAN 命令总会在某次迭代中将这个元素返回给用户。
由于使用游标来记录迭代状态,因此scan命令是有一些缺陷的
scan命令是使用游标来遍历的,游标返回0说明整个数据集都遍历完成。
上图是高位进位的图示,如果我们此时遍历到10时发生扩容,我们接下来会继续遍历
010->110->001->101->011->111
也就是说扩容后也不会重复遍历到之前遍历过的元素。
这张图是正常的低位进位,如果遍历到01发生扩容,接下来继续遍历:
001->010->011->100->101->110->111
可以发现100这个元素被重复遍历了,因此使用高位进位是更好的选择。
随着操作的不断执行, 哈希表保存的键值对会逐渐地增多或者减少, 为了让哈希表的负载因子(load factor)维持在一个合理的范围之内, 当哈希表保存的键值对数量太多或者太少时, 程序需要对哈希表的大小进行相应的扩展或者收缩。
为了避免 rehash 对服务器性能造成影响, 服务器不是一次性将 ht[0] 里面的所有键值对全部 rehash 到 ht[1],而是分多次、渐进式地将 ht[0] 里面的键值对慢慢地 rehash 到 ht[1]。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。