前言
Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式,
一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行的,keys是以遍历的方式实现的复杂度是 O(n),Redis库中的key越多,查找实现代价越大,产生的阻塞时间越长。
二是scan命令,以非阻塞的方式实现key值的查找,绝大多数情况下是可以替代keys命令的,可选性更强
以下写入100000条key***:value***格式的测试数据(ps:用pipline的话,1w一笔,每一笔在秒级完成)
# -*- coding: utf-8 -*- # !/usr/bin/env python3 import redis import sys import datetime def create_testdata(): r = redis.StrictRedis(host='***.***.***.***', port=****, db=0, password='root') counter = 0 with r.pipeline(transaction=False) as p: for i in range(0, 100000): p.set('key' + str(i), "value" + str(i)) counter = counter + 1 if (counter == 10000): p.execute() counter = 0 print("set by pipline loop") if __name__ == "__main__": create_testdata()
比如这里查询key111开头的key有哪些?
若使用keys命令,则执行keys key1111*,一次性全部查出来。
同样,如果使用scan命令,则用scan 0 match key1111* count 20
scan的语法为:SCAN cursor [MATCH pattern] [COUNT count]The default COUNT value is 10
.
SCAN命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程。
这里使用scan 0 match key1111* count 20
命令来完成这个查询,稍显意外的是,使用一开始都没有查询到结果,这个要从scan命令的原理来看。
scan在遍历key的时候,0就代表第一次,key1111*代表按照key1111开头的模式匹配,count 20中的20并不是代表输出符合条件的key,而是限定服务器单次遍历的字典槽位数量(约等于)。
那么,什么又叫做槽的数据?这个槽是不是Redis集群中的slot?答案是否定的。其实上图已经给出了答案了。
如果上面说的“字典槽”的数量是集群中的slot,又知道集群中的slot数量是16384,那么遍历16384个槽之后,必然能遍历出来所有的key信息,上面清楚地看到,当遍历的字典槽的数量20000的时候,游标依旧没有走完遍历结果,因此这个字典槽并不等于集群中的slot的概念。
经过测试,在scan的时候,究竟遍历多大的COUNT值能完全match到符合条件的key,跟具体对象的key的个数有关,
如果以超过key个数的count来scan,必定会一次性就查找到所有符合条件的key,比如在key个数为10W个的情况下,一次遍历20w个字典槽,肯定能完全遍历出来结果。
scan 指令是一系列指令,除了可以遍历所有的 key 之外,还可以对指定的容器集合进行遍历。
zscan 遍历 zset 集合元素,
hscan 遍历 hash 字典的元素、
sscan 遍历 set 集合的元素。
SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一个参数总是一个数据库键(某个指定的key)。
另外,使用redis desktop manager
的时候,当刷新某个库的时候,控制台自动不断刷新scan命令,也就知道它在干嘛了
参考:http://jinguoxing.github.io/redis/2018/09/04/redis-scan/
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。