redis针对string的命令及应用场景

文章目录

  • [一. redis中的string命令](#一. redis中的string命令)
  • [二. string类型的应用场景](#二. string类型的应用场景)
    • [1. 缓存](#1. 缓存)
    • [2. 计数功能](#2. 计数功能)
    • [3. 共享会话](#3. 共享会话)
    • [4. 手机验证码](#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. 手机验证码

  1. 生成验证码
    通常有限制, 例如一分钟内不能再次获取验证码
  2. 检查验证码

伪代码:

String 发送验证码(phoneNumber) {
	 key = "shortMsg:limit:" + phoneNumber;
	 // 设置过期时间为 1 分钟(60 秒)
	 // 使⽤ NX,只在不存在 key 时才能设置成功
	 bool r = Redis 执⾏命令:set key 1 ex 60 nx
	 if (r == false) {
		 // 说明之前设置过该⼿机的验证码了
		 long c = Redis 执⾏命令:incr key
		 if (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;
	 }
}
相关推荐
萌小丹Fighting13 分钟前
【Postgres_Python】使用python脚本批量创建和导入多个PG数据库
数据库
青灯文案118 分钟前
Oracle 数据库常见字段类型大全及详细解析
数据库·oracle
羊小猪~~41 分钟前
MYSQL学习笔记(四):多表关系、多表查询(交叉连接、内连接、外连接、自连接)、七种JSONS、集合
数据库·笔记·后端·sql·学习·mysql·考研
Wx120不知道取啥名2 小时前
缓存为什么比主存快?
缓存·缓存为什么比主存快?·sram的原理·dram的原理
村口蹲点的阿三3 小时前
Spark SQL 中对 Map 类型的操作函数
javascript·数据库·hive·sql·spark
暮湫5 小时前
MySQL(1)概述
数据库·mysql
fajianchen5 小时前
记一次线上SQL死锁事故:如何避免死锁?
数据库·sql
chengpei1475 小时前
实现一个自己的spring-boot-starter,基于SQL生成HTTP接口
java·数据库·spring boot·sql·http
等一场春雨5 小时前
CentOS 安装Redis
linux·redis·centos
中东大鹅6 小时前
MongoDB的索引与聚合
数据库·hadoop·分布式·mongodb