Redis数据类型-String
set 、get、 setnx(常用于分布式锁中,存在这个键就不能覆盖)返回(nil)是空的意思
单次set (n) time:n次网络+n次命令时间(Redis)
批量mset(n) time:1次网络+n次命令时间(Redis) 网络开销
操作命令
set 设置值
set key value
set命令有几个选项:
ex seconds: 为键设置秒级过期时间。
px milliseconds: 为键设置毫秒级过期时间。
nx: 键必须不存在,才可以设置成功,用于添加(分布式锁常用)。
xx: 与nx相反,键必须存在,才可以设置成功,用于更新。
从执行效果上看,ex参数和expire命令基本一样。还有一个需要特别注意的地方是如果一个字符串已经设置了过期时间,然后你调用了set 方法修改了它,它的过期时间会消失。
而nx和xx执行效果如下
除了set选项,Redis 还提供了setex和 setnx两个命令:
setex key
seconds value
setnx key value
setex和 setnx的作用和ex和nx选项是一样的。也就是,setex为键设置秒级过期时间,setnx设置时键必须不存在,才可以设置成功。
因为键foo-ex已存在,所以setnx失败,返回结果为0,键foo-ex2不存在,所以setnx成功,返回结果为1。
有什么应用场景吗?以setnx命令为例子,由于Redis的单线程命令处理机制,如果有多个客户端同时执行setnx key value,根据setnx的特性只有一个客户端能设置成功,setnx可以作为分布式锁的一种实现方案。当然分布式锁没有不是只有一个命令就OK了,其中还有很多的东西要注意,我们后面会用单独的章节来讲述基于Redis的分布式锁。
get 获取值
如果要获取的键不存在,则返回nil(空):
mset 批量设置值
通过mset命令一次性设置4个键值对
mget 批量获取值
批量获取了键a、b、c、d的值:
如果有些键不存在,那么它的值为nil(空),结果是按照传入键的顺序返回。
批量操作命令可以有效提高效率,假如没有mget这样的命令,要执行n次get命令具体耗时如下:
n次 get时间=n次网络时间+n次命令时间
使用mget命令后,要执行n次get命令操作具体耗时如下:
n次get时间=1次网络时间+n次命令时间
Redis可以支撑每秒数万的读写操作,但是这指的是Redis服务端的处理能力,对于客户端来说,一次命令除了命令时间还是有网络时间,假设网络时间为1毫秒,命令时间为0.1毫秒(按照每秒处理1万条命令算),那么执行1000次 get命令需要1.1秒(10001+10000.1=1100ms),1次mget命令的需要0.101秒(11+10000.1=101ms)。
Incr 数字运算
incr命令用于对值做自增操作,返回结果分为三种情况:
值不是整数,返回错误。
值是整数,返回自增后的结果。
键不存在,按照值为0自增,返回结果为1。
除了incr命令,Redis提供了decr(自减)、 incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数),具体效果请同学们自行尝试。
append追加指令
append可以向字符串尾部追加值
strlen 字符串长度
返回字符串长度
注意:每个中文占3个字节
getset 设置并返回原值
getset和set一样会设置值,但是不同的是,它同时会返回键原来的值
setrange 设置指定位置的字符
下标从0开始计算。设置的字符串会把原来位置同等长度的字符串替换掉,如果设置的下标超过了原有的字符串下标,则会有几个空串填充
getrange 截取字符串
getrange 截取字符串中的一部分,形成一个子串,需要指明开始和结束的偏移量,截取的范围是个闭区间。
命令的时间复杂度
字符串这些命令中,除了del 、mset、 mget支持多个键的批量操作,时间复杂度和键的个数相关,为O(n),getrange和字符串长度相关,也是O(n),其余的命令基本上都是O(1)的时间复杂度,在速度上还是非常快的。
使用场景
字符串类型的使用场景很广泛:
缓存功能
Redis 作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。
计数
使用Redis 作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。
共享Session
一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自服务器中,这样会造成一个问题,出于负载均衡的考虑,分布式服务会将用户的访问均衡到不同服务器上,用户刷新一次访问可能会发现需要重新登录,这个问题是用户无法容忍的。
为了解决这个问题,可以使用Redis将用户的Session进行集中管理,,在这种模式下只要保证Redis是高可用和扩展性的,每次用户更新或者查询登录信息都直接从Redis中集中获取。
限速
比如,很多应用出于安全的考虑,会在每次进行登录时,让用户输入手机验证码,从而确定是否是用户本人。但是为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次。一些网站限制一个IP地址不能在一秒钟之内方问超过n次也可以采用类似的思路。
做计数器 incr incr-key 、get incr-key、decr incr-key、incrby incr_key2 3 (每次加3)、incrbyfloat incr-key 0.5
getset 命令 一边返回原来的老值一边改成新值。如果没这个键更改失败返回nil
Redis字符串命令:大部分命令的时间复杂度都是O(1),分布式session确保不同用户登录不同负载服务,使用String