文章目录
- 一、scan命令
- 二、数据库管理命令
- 三、RESP协议
- 四、string类型
- 五、list类型
- 六、set类型
- 七、hash类型
- 八、zset类型
一、scan命令
keys是一次性把整个redis中所有的key都获取道,这个操作比较危险,可能会一下子得到大量的key,阻塞redis服务器
通过渐进式遍历,即不是一个命令,把所有的key都拿到,而是每执行一次命令,只获取到其中的一部分,这样就可以做到:既能获取到所有的key,同时又不会卡死服务器,代表命令scan
如下图,cursor是光标,光标就指向了当前遍历的位置,光标设置为0,意味着这次遍历是从头开始获取,下面的"2",表示下次继续遍历,光标从哪里开始,后面的则是真正遍历到的key的内容
注意:不能把cursor理解成下标,它不是一个连续递增的整数,仅仅是一个字符串,客户端是不认识cursor的,redis服务器知道这个光标对应的元素位置
pattern则和keys对应的pattern用法一样,不再赘述
count,是给redis服务器一个"提示/建议",最终返回的key个数和count不一定是相同的,但是不会差很多
如下图,返回0,就表明遍历完了!
如下图,可以看出返回的光标位置,是随机变化的,并没有如同下标一样单调递增
渐进式遍历,在遍历过程中,不会在服务器这边存储任何的状态信息,此处的遍历是随时可以终止的,不会对服务器产生任何的副作用。例如:你去超市买东西,结账时,结到一半,你不想要部分东西了,就可以给收银员说不要了,收银员也就会叫工作人员来收走
渐进式遍历scan虽然解决了阻塞的问题,但如果在遍历期间键有所变化(增加、删除、修改),可能导致遍历时键的重复遍历或遗漏
渐进式命令还有一些其它命令,这里不再述说,读者可前往官网翻阅!!!
二、数据库管理命令
如同MySQL,redis中也是有database的,只不过不是自己创建的,而是现有的,用户既不能创建新的数据库,也不能删除已有的数据库
默认redis给用户提供了16个数据库0-15,这16个数据库中的数据是隔离的(相互之间不会有影响),默认使用 0 号数据库
选择数据库
清空数据库中的key,分为异步和同步两种
清空所有数据库中的key,也分为异步和同步两种
获取当前数据库中key的个数
三、RESP协议
为什么我们能编写出redis的自定义客户端,而王者荣耀等其它的不行?
因为redis没有用https等其它现有的应用层协议,同时,redis的自定义协议是公开的!!!
如下图,是RESP协议的缩写
resp协议的优点:
1、简单好实现;
2、快速进行解析;
3、肉眼可读。
resp协议虽然使用了TCP协议,但没有和TCP强耦合
客户端给服务器发送的redis命令,是以bulk string数组的形式发送的
不同的命令,返回结果不一样,有的命令,直接返回ok,有的命令,可能返回个整数,有的命令,可能返回个数组
如下图,针对不同的类型,redis服务器就将以不同的格式回复,即将下面的字符串,写入到tcp socket中即可
simple string 只能用来传输文本
bulk string可以传输二进制数据
redis客户端要按照上述格式,构造出字符串,往socket中写入;同时从socket中读取字符串,也要按照上述格式解析。不过这不需要我们自己来做,因为已经有大佬实现了这套协议的解析/构造,只要使用他们提供的库,就可以比较简单方便地完成和redis服务器通信的操作!
这里采用redis-plus-plus的库来操作redis,虽然库很多,但都大同小异!
安装redis-plus-plus的路径如下:
Github地址: https://github.com/sewenew/redis-plus-plus
因为redis-plus-plus依赖了hiredis,所以需要先下载hiredis
Centos安装:
yum install hiredis-devel.x86_64
Ubuntu安装:
apt install libhiredis-dev
下载redis-plus-plus源码
Centos编译安装:
Centos自带的cmake版本过低,需要先安装cmake3
yum install cmake3
然后安装以下步骤操作,最后一部需要sudo或切换至root执行:
Ubuntu编译安装:
连接redis服务器
如下图,通过find命令先找到redis++的头文件和库文件目录
这里用<>包含头文件,<>:在系统目录下搜索头文件,“”:在项目目录中搜索头文件
如下图, 用url来构建对象,指明传输层协议,服务器地址,以及端口号,值得注意的是,url并不专属于http!
进行ping操作,检查是否连通,成功返回字符串pong
由于这里引用了hiredis和redis库,所以需要在编译时指定库的路径,以及线程库
运行结果如下图所示
四、string类型
set和get命令
如下图可知,函数的参数和命令行输入差不多,StringView是字符串类型,只是不能被修改
OptionalString可以表示"非法值"或"无效值",redis中的非法值是用nil表示的,直接用std::string表示nil不是很方便,std:string*表示,又涉及到内存管理的问题,所以redis的作者封装了OptionalString这个类型!
如下图,获取key1和key2的value,是正常的,但获取不存在的key3的value,就发生了抛异常,所以这里可以用两种方式解决,一种是捕捉异常,另一种则是 if 语句判断一下是不是为空即可!
exists命令
如下图,参数是一个初始化列表,可用来判断多个key是否存在,返回值为存在的key的个数
为什么把清理数据放在开头?
1、如果放在结束,一旦执行的程序中间出现了异常,就可能导致清理数据没有被执行;
2、放在开头,当执行完一个操作之后,redis里面仍然是有数据的,也方便程序员手工检查数据的内容!!!
del命令
如下图,删除key,也和exsits一样,支持删除多个
expire和ttl命令
如下图,expire给key设置过期时间,ttl获取key剩余的时间
keys命令
如下图,是查找所有的key,参数pattern是匹配规则,back_insert_iterator是插入迭代器,本质是输出迭代器
这里为什么不直接使用容器作为参数,key内部直接操作容器,进行插入?
因为这里可以解耦合,当是其它容器时,而不需要去改变迭代器!!!
STL中的五种迭代器的类型
输入迭代器
输出迭代器:back_insert_iterator,区间的任意位置,在该位置之前插入;font_insert_iterator,区间的开头,往前面插入;back_insert_iterator,区间的末尾,往后面插入,对于这些插入迭代器,*,++都是啥也不干!!!核心操作:如it = it2,it是back_insert_iterator,就是把it2指向的元素插入到it指向的容器末尾,相当于调用push_back()
前向迭代器
双向迭代器
随机访问迭代器
mset和mget命令
如下图, 当获取不存在的key4的value时,就抛出异常了
setrange和getrange命令
如下图,这两个命令也与在命令行输入时,用法一致
incr和decr命令
五、list类型
lpush和lrange命令
lpop命令
blpop命令
如下图,开始时没有数据,当有数据插入时,就会立即返回,如果时间超过100s也会返回
llen命令
六、set类型
sadd命令
sismember命令
scard命令
spop命令
sinter命令
七、hash类型
hset和hget命令
hexists命令
hdel和hlen命令
hkeys和hvals命令
hmset和hmget命令
八、zset类型
zadd和zrange命令
zcard命令
zrem命令
zscore命令
zrank命令