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的个数
为什么我们能编写出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执行:
如下图,通过find命令先找到redis++的头文件和库文件目录
这里用<>包含头文件,<>:在系统目录下搜索头文件,“”:在项目目录中搜索头文件
如下图, 用url来构建对象,指明传输层协议,服务器地址,以及端口号,值得注意的是,url并不专属于http!
由于这里引用了hiredis和redis库,所以需要在编译时指定库的路径,以及线程库
set和get命令
如下图可知,函数的参数和命令行输入差不多,StringView是字符串类型,只是不能被修改
OptionalString可以表示"非法值"或"无效值",redis中的非法值是用nil表示的,直接用std::string表示nil不是很方便,std:string*表示,又涉及到内存管理的问题,所以redis的作者封装了OptionalString这个类型!
如下图,获取key1和key2的value,是正常的,但获取不存在的key3的value,就发生了抛异常,所以这里可以用两种方式解决,一种是捕捉异常,另一种则是 if 语句判断一下是不是为空即可!
如下图,参数是一个初始化列表,可用来判断多个key是否存在,返回值为存在的key的个数
1、如果放在结束,一旦执行的程序中间出现了异常,就可能导致清理数据没有被执行;
2、放在开头,当执行完一个操作之后,redis里面仍然是有数据的,也方便程序员手工检查数据的内容!!!
del命令
如下图,删除key,也和exsits一样,支持删除多个
如下图,expire给key设置过期时间,ttl获取key剩余的时间
如下图,是查找所有的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时,就抛出异常了
如下图,这两个命令也与在命令行输入时,用法一致
lpush和lrange命令
如下图,开始时没有数据,当有数据插入时,就会立即返回,如果时间超过100s也会返回
sadd命令
hset和hget命令
zadd和zrange命令