文章目录
- 一. redis中的string命令
- 1. 常见命令
- SET
- GET
- MGET
- MSET
- SETNX
- SETEX
- PSETEX
- 2. 计数命令
- incr
- incrby
- decr
- decrby
- incrbyfloat
- 3. 其他命令
- append
- getrange
- setrange
- strlen
- 小结
- 二. string类型的应用场景
- 1. 缓存
- 2. 计数功能
- 3. 共享会话
- 4. 手机验证码
一. redis中的string命令
redis中的字符串, 直接就是按照二进制的方式存储的, 不会做任何编码转换
不仅可以存储数据, 还可以整数, 普通文本字符串, JSON, xml, 二进制数据…
不过⼀个字符的最大值不能超过 512 MB。
由于 Redis 内部存储字符串完全是按照⼆进制流的形式保存的,所以 Redis 是不处理字符集
编码问题的,客户端传入的命令中使用的是什么字符集编码,就存储什么字符集编码
1. 常见命令
SET
如果key不存在, 创建新的键值对
如果key不存在, 则让新的value覆盖旧的value, 可能回盖面原来的数据类型, 原来的key的生存时间也会失效
flushall 清除所有的键值对
GET
注意: 获取 key 对应的 value。如果 key 不存在,返回 nil。如果 value 的数据类型不是 string,会报错
MGET
⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil。
MSET
⼀次性设置多个 key 的值
使用 mget / mset 由于可以有效地减少了⽹络时间,所以性能相较更高。
SETNX
设置key-value, 不存在才能设置, 存在设置失败
SETEX
设置key-value和过期时间
语法:
setex key seconds value
PSETEX
设置key-value和过期时间(毫秒)
语法:
psetex key ms value
2. 计数命令
incr
针对value + 1
如果 key 不存在,则视为 key 对应的 value 是 0, 自增后返回1。
如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
incrby
针对value + n
如果 key 不存在,则视为 key 对应的 value 是 0。
如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
decr
针对value - 1
如果 key 不存在,则视为 key 对应的 value 是 0, 自增后返回1。
如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
decrby
针对value - n
如果 key 不存在,则视为 key 对应的 value 是 0
如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错
incrbyfloat
将 key 对应的 string 表示的浮点数加上对应的值。
如果对应的值是负数,则视为减去对应的值。如果key 不存在,则视为 key 对应的 value 是 0。
如果 key 对应的不是 string,或者不是⼀个浮点数,则报错。允许采用科学计数法表示浮点数。
3. 其他命令
append
如果 key 已经存在并且是⼀个 string,命令会将 value 追加到原有 string 的后边。
如果 key 不存在,则效果等同于 SET 命令。
xshell终端, 默认的字符编码是utf8, 一个汉字通常是3个字节的~
对应16进制utf8编码
在启动redis客户端时, 加上–raw, 能够使redis能够自动把二进制数据进行翻译
getrange
返回 key 对应的 string 的子串,由 start 和 end 确定(左闭右闭)
可以使用负数表示倒数。-1 代表倒数第一个字符,-2 代表倒数第⼆个,其他的与此类似。
超过范围的偏移量会根据 string 的长度调整成正确的值。
setrange
覆盖字符串的⼀部分,从指定的偏移开始。
setrange针对不存在的key, 会把offset之前的内容填充成0x00:
strlen
获取 key 对应的 string 的长度。当 key 存放的类型不是 string 时,报错。
单位是字节
小结
二. string类型的应用场景
1. 缓存
整体的思路:
应用服务器访问数据时, 先查询redis
如果redis上数据存在, 就直接从redis取数据交给应用服务器, 不需要访问数据库
如果redis上数据不存在, 再读取mysql, 把读到的数据返回给应用服务器, 并把这个数据写到redis中
那么这个过程, 就是把最近使用到的数据当做热点数据存到redis中
防止redis中的数据越来越多, 有以下两个策略:
1.在把数据写入redis中的同时, 设置过期时间
2.在redis内存不足时, 提供了"淘汰策略"
与 MySQL 等关系型数据库不同的是,Redis 没有表、字段这种命名空间,⽽且也没有对键名有强制要求(除了不能使⽤⼀些特殊字符)。但设计合理的键名,有利于防⽌键冲突和项⽬的可维护性,⽐较推荐的⽅式是使⽤ “业务名:对象名:唯⼀标识:属性” 作为键名。例如MySQL 的数据库名为 vs,⽤⼾表名为 user_info,那么对应的键可以使⽤"vs:user_info:6379"、“vs:user_info:6379:name” 来表⽰,如果当前 Redis 只会被⼀个业务使⽤,可以省略业务名 “vs:”。如果键名过程,则可以使⽤团队内部都认同的缩写替代,例如"user:6379:friends:messages:5217" 可以被 “u:6379🇫🇷m:5217” 代替。毕竟键名过⻓,还是会导致 Redis 的性能明显下降的。
2. 计数功能
redis并不擅长数据统计
统计数据仓库, 可能是mysql, 可能是hdfs…
采用异步的方式, 不是来一个请求, 就必须立即马上写一个数据, 只需保证最终结果是相同的即可
3. 共享会话
如果每个应用服务器, 维护自己的会话记录, 此时彼此之间不共享, 访问到不痛的服务器上, 就可能出现一些不能正确处理的情况了
4. 手机验证码
- 生成验证码
通常有限制, 例如一分钟内不能再次获取验证码 - 检查验证码
伪代码:
String 发送验证码(phoneNumber) {key = "shortMsg:limit:" + phoneNumber;// 设置过期时间为 1 分钟(60 秒)// 使⽤ NX,只在不存在 key 时才能设置成功bool r = Redis 执⾏命令:set key 1 ex 60 nxif (r == false) {// 说明之前设置过该⼿机的验证码了long c = Redis 执⾏命令:incr keyif (c > 5) {// 说明超过了⼀分钟 5 次的限制了// 限制发送return null;}}// 说明要么之前没有设置过⼿机的验证码;要么次数没有超过 5 次String validationCode = ⽣成随机的 6 位数的验证码();validationKey = "validation:" + phoneNumber;// 验证码 5 分钟(300 秒)内有效Redis 执⾏命令:set validationKey validationCode ex 300;// 返回验证码,随后通过⼿机短信发送给⽤⼾return validationCode ;
}
// 验证⽤⼾输⼊的验证码是否正确
bool 验证验证码(phoneNumber, validationCode) {validationKey = "validation:" + phoneNumber;String value = Redis 执⾏命令:get validationKey;if (value == null) {// 说明没有这个⼿机的验证码记录,验证失败return false;}if (value == validationCode) {return true;} else {return false;}
}