浅浅谈一谈Redis的客户端
Redis客户端
Redis也是一个客户端/服务端结构的程序。
MySQL也是一个客户端/服务端结构的程序。
Redis的客户端也有多种形态
1.自带命令行客户端
redis-cli
2.图形化界面的客户端(桌面程序,web程序)
像这样的图形化程序,依赖 windows 系统.而未来在实际工作中,你用来办公的 windows 系统,连接到服务器可能会有诸多限制,你的 windows 上的图形化界面客户端能不能连上你们的服务器里的 redis, 是个未知数!!!(和 mysql 同理)
中间可能会经历很多的跳板机,堡垒机,权限校验。
3.基于redis的api自行开发客户端(工作中最主要的形态)
非常类似于MySQL的C语言API和JDBC
同样是存储键值对数据,用Redis和 hash map的优劣
使用hash map是可以直接操作内存的。
使用Redis是先通过网络然后操作内存的
Redis中最核心的两个命令:
Redis是按照键值对的方式存储数据。
get根据key来取value
set把key和value存储进去。
必须要先进入redis-cli 客户端程序,才能输入redis指令
这里的key和value都是字符串。
对于上述这里的key 和 value ,不要加上引号,就是字符串的类型。
当然加上引号也是可以的,单引号与双引号都行。
Redis的命令是不区分大小写的,也就和MySQL类似。
当输入get命令的时候,如果当前的key不存在,会返回一个nil,和null/NULL同理。
Redis全局命令
全局命令,就是能够搭配任意一个数据结构来使用的命令
Redis支持很多种数据结构,整体上来说,Redis是键值对结构,key固定是字符串,value实际上会有多种类型。(字符串,哈希表,列表,集合,有序集合)
操作不同的数据结构就会有不同的命令。
keys 用来查询当前服务器上匹配的key
通过一些特殊符号(通配符)来描述key的模样,匹配上述模样的key就能被查询出来。
语法: keys pattern
此中,pattern是包含特殊符号字符串。
规则大致如下
当然,keys命令的时间复杂度为O(N)
所以在生产环境上,一般都会禁止使用keys命令,尤其是keys *
原因是生产环境上的key可能会特别的多,而redis是一个单线程的服务器。执行keys * 的时间非常的长,就是redis服务器被阻塞了,无法给其他的客户端提供服务。
redis经常会用于做缓存,挡在MySQL前面,替MySQL负重前行的家伙,万一redis被一个keys * 阻塞住了,此时其他的查询redis操作就会超时,此时这些请求就会直接查询数据库,然后突然一大波请求过来了,MySQL就会措手不及,就挂掉了。
导致整个系统瘫痪了。
exists 判定key是否存在
语法:exists key / [key ...]
返回值:key存在的个数
键值对存储的体系中(类似哈希表)
key得是唯一的
所以这个返回值返回一个非0/1数是对于多个key来说的。时间复杂度为O(1),也可以说是O(N),如果是N,就是指key的个数。
redis组织这些key就是按照哈希表的方式来组织的。
redis的value可以是多种数据结构,本身又是一个通过哈希表的方式来组织的。
如果我们有两个名分别为hello和hallo的key,我们执行以下两组命令。
exists hello hallo
exists hello
exists hallo
这里虽然能让我们知道的结果是一样的,但是其实区别还是很大的。
原因:
redis 是一个客户端/服务器结构的程序,客户端和服务端之间通过网络来进行通信。
分开的写法会产生更多的网络通信,效率会比较低,且成本比较高。
当然这里的效率和成本是与内存进行相比。
封装和分用
进行网络通信的时候,发送方发送一个数据,这个数据就要从应用层到物理层,层层封装。
(每一层协议都要加上报头和报尾)
接收方收到一个数据,这个数据就要从物理层到应用层,层层分用。
(把每一层协议中的报头或者报尾给拆掉)
跟发快递和收快递相似。
网卡是IO设备,速度上是和内存没法相提并论的。
更何况,客户端和服务器不一定在同一台主机上,中间可能还相隔十分远。
redis也很清楚上述的问题,所以redis的很多命令都是支持一次就能操作多个key /多种操作。
del
删除指定的key(可以一次删除一个或多个)
语法:del key [key...]
时间复杂度为O(1)
返回值:删除掉的key的个数
这里还是提个问题,这个del命令是否具有像MySQL一样的危险程度?
一般来说,危险程度还是比较小的,由于redis的一个主要场景是作为缓存,此时的redis存放的是热点数据,全量数据存放在MySQL当中,此时,如果把redis中的key删除了几个,一般来说问题是不大的。
相比之下,如果是MySQL这样的数据被删除,可能影响是巨大的。但是如果redis作为数据库,此时误删的影响就很大了。
如果是把redis作为消息队列(mq) 这种需要具体问题具体分析。
expire
给指定的key 设置过期时间 --- key存活时间超过这个指定的值,就会被自动删除。
语法: expire key seconds(秒)
很多业务场景,是有时间限制的。 经典的是---手机验证码。
eg:点外卖---优惠券 在指定的时间内有效 这个场景也是可以使用expire来实现
基于redis 实现分布式锁 --- 为了避免出现不能正确解锁的情况,通常都会在加锁的时候设置一个过期时间。
在使用expire的时候,还是有个小问题,这个单位也是一个小问题,对于计算机来说,秒这个单位是非常长的。
那么就可以使用底下类似命令。
pexpire key 毫秒
时间复杂度为O(1)
返回值:1 表示设置成功,0 表示设置失败。
生产环境(线上环境)
未来工作中会涉及到的几个环境
1.办公环境,可能是一台笔记本电脑
2.开发环境,有的时候,开发环境和办公环境是同一个,有的时候,开发环境是一个单独的服务器。
PS:做前端/客户端,一般来说,开发环境就是办公环境
做后端,很可能是一个单独的服务器。
有的后端程序比较复杂1.编译一次时间特别长(C++) -> C++ 23 才会引入module(#include接锅)
所以会使用一些高性能的服务器进行编译。
2.有的程序一启动,就要消耗很多的CPU和内存资源
3.有的程序比较依赖Linux,在windows环境搭建不起来
3.测试环境(测试工程师使用)
以上统称为线下环境,外界用户无法访问到。
4.线上环境/生产环境
线上环境,外界用户是可以访问到的。
一旦生产环境出现问题,一定会对用户的使用产生影响。