Redis的命令以及一些使用场景
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
- EXISTS key:检查给定 key 是否存在。
EXPIRE key seconds:为给定 key 设置过期时间,以秒计;EXPIREAT key timestamp:EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
结合起来可以设置一个限制,在某段时间(例如:一天内)内,通过判断这个锁来对用户的操作进行限制。例如:限制用户是否本日已经投票,助力,登录限制等。 - KEYS pattern:查找所有符合给定模式( pattern)的 key 。
SCAN cursor [MATCH pattern] [COUNT count]:迭代数据库中的数据库键
这两个命令都可以查询对应库的key。根据数据量区分,使用场景和方法不同;
①、keys,一次性全部返回符合条件的key,返回数据不会重复,如果数据量很大将会等待很久,是用于查询出的数据量小时使用,比如几千几百,或者是精确查询用。
keys *
keys user_*
②、SCAN cursor [MATCH pattern] [COUNT count],模糊分页查询。cursor:查询游标,第一次0,后面就是使用返回数组中第一个值,当返回的值为0时则表示遍历完毕。[MATCH pattern]:匹配一个表达式。[COUNT count]:指定从数据集里返回多少元素,默认值为 10,但并不是每次都会返回设置的count条数据,返回数据条数<=设置的count。
特点:
- 随机性较高,没有规律,可能会有重复,;
- 返回的游标不固定,没有规律,唯一能判断遍历结束的标志就是返回结果集的第一个元素为0;
- 返回的列表存在重复的情况,需要应用程序自己处理。
- 由于全部遍历完需要一点时间,如果过程中键被操作了,那么影响未知。
- 返回的数量没有确定的数量
> scan 9 match access_* count 10
51
access_to_refresh:344bd4b3-4b3e-472a-b759-854eb67449d0
access_to_refresh:f2664c19-4b11-4cb1-a635-8583a6394156
access_to_refresh:ddb08b5e-e13b-4368-b66c-a0baa2c8b690
access_to_refresh:9b05eaa2-13c5-40db-b920-3c5eebb41443
> scan 51 match access_* count 10
0
access_to_refresh:25700512-42bb-42f0-bb97-20606cbe187a
access_to_refresh:8bf74b08-8101-499a-aa23-43b2de7ac72b
access_to_refresh:36a737e9-10cd-4f7a-8bae-ef14df8ed339
- SETBIT key offset value:对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
GETBIT key offset: 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
BITCOUNT key [start] [end]: 统计字符串中每位为1的总数
BITOP operation destkey key [key]:对一个或多个保存二进制位的字符串key进行位元操作,并将结果保存到destkey上。operation可以是AND、OR、NOT、XOR这四种操作中的任意一种。
可以用于大量用户上线次数/签到记录,签到为1,不签到为0,下面例如用户第一天签到和第6天签到,第2到第5天均没签到。
key为sign:userId:date
每位用户每年占用365 比特位(bit)=》45.6b(字节,byte),很省空间。
127.0.0.1:6379> setbit sign:110:202011 0 1
(integer) 0
127.0.0.1:6379> setbit sign:110:202011 5 1 # sign:110:202011 => 10001
(integer) 0
127.0.0.1:6379> getbit sign:110:202011 5
(integer) 1
127.0.0.1:6379> getbit sign:110:202011 0
(integer) 1
127.0.0.1:6379> getbit sign:110:202011 2
(integer) 0
127.0.0.1:6379> bitcount sign:110:202011 0 -1
#统计sig:110:202011的value即10001中有多少个1
(integer) 2
4.ZADD key score1 member1 [score2 member2]:向有序集合添加一个或多个成员,或者更新已存在成员的分数。
用来记录用户积分/学分排名。
5.Redis HyperLogLog
redis 127.0.0.1:6379> PFADD runoobkey "redis"
(integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mongodb"
(integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mysql"
(integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mysql"
(integer) 0 #已经有相同数据,写入失败
redis 127.0.0.1:6379> PFCOUNT runoobkey
(integer) 3
只有计数功能,可以大概过滤相同参数,以及固定很小(12k)的空间,所以很适合统计数量,但不能获取各个元素。
所以可以用作统计每个页面的UV数量,PV可以用String 的 incr key统计,UV需要过滤相同IP。如果存储每个访问的IP,需要的空间大,意义不大;同时UV也不需要很精确,所以大致过滤一下即可。如果是要记录实时数据让统计分析(包括记录访客标识以及访问的页面)就不适合了。
也可以用来记录用户浏览历史,当有推荐内容时过滤已经看过的内容,虽然有一定概率数据有重复,但是在可以接受的范围内。
这里顺带引出布隆过滤器和bigmap相关知识点。
布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k,以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置为0。对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。(这段话与图片引用于 布隆过滤器(Bloom Filter)的原理和实现 中的描述,还有一些细节实现 感兴趣可阅读 )
bigmap:超大位数组,类似很长的****0000011100000***********,用位来标识数据,可以节省大量空间。
6.Redis 事务
按照上面所说,redis事务无法像数据库事务一样要么全部成功则成功,要么失败,只是批量操作,各命令之间互不影响。那么如果是批量查询的话,直接用redis管道命令,强调数据一致性则用Lua命令保证。
7.Redis 脚本
redis 脚本也就是执行lua脚本,需要注意的是,为了不多次加载lua脚本,可以先用
SCRIPT LOAD script:将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。这个命令返回给定脚本的 SHA1 校验和,用这个返回值来判断是否已经加载到缓存中,避免多次加载脚本。
** SCRIPT EXISTS sha1 [sha1 …]**:用于校验指定的脚本是否已经被保存在缓存当中
redis 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'" # 载入一个脚本
"232fd51614574cf0867b83d384a5e898cfd24e5a"
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
(integer) 1
redis 127.0.0.1:6379> SCRIPT FLUSH # 清空缓存
OK
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
(integer) 0
8.恢复数据
如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。
命令:save, bgsave
或者在配置文件中设置条件触发: