初识Redis
目录
Redis定义
根据官方文档所述,我们可以知道Redis是一个开源的,内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理(不是Linux环境下的消息队列)。
这时我们会产生疑问,内存中存储数据,直接定义一个变量不就行了吗?所以这里我们要明确,Redis是在分布式系统中,才能发挥它的能力的。如果知识单机程序,直接通过变量存储数据的方式是比使用Redis更优的选择。如果是多台主机进行通信,Redis就是基于网络,可以把自己内存中的变量给别的主机的进程使用。
分布式系统
单机架构
单机架构就是只有一台服务器,这个服务器负责所有的工作。
对于简单的业务来说,单机架构确实也能满足需求,但是随着业务进一步增长,用户量和数据量都进一步增加,这时一台主机往往难以应付,由于一台主机的硬件资源是有上限的,所以就需要引入更多的主机,即引入更多的硬件资源。
分布式
系统中的多个模块被部署于不同服务器之上,即可以将该系统称为分布式系统。如Web服务器与 数据库分别⼯作在不同的服务器上,或者多台Web服务器被分别部署在不同服务器上。
常见的分布式架构有应用数据分离架构、应用服务集群架构、读写分离/主从分离架构、冷热分离架构、业务拆分架构(微服务)。
Redis特性
内存中存储数据
向MySQL主要通过“表”的方式存储组织数据,这种数据库称为“关系型数据库”;而Redis主要通过“键值对”的方式存储组织数据,称为“非关系型数据库”。
Redis中的键值对,key都是string,value则可以是string,hashes,lists,sets,sorted sets,streams……的任意一种。
可编程性
针对Redis的操作,可以直接通过简单的交互式命令进行操作,也可以通过一些脚本的方式,批量执行一些操作。
可扩展性
可以在Redis原有的功能基础上再进行扩展,Redis提供一一组API,通过C,C++和Rust这几种语言编写Redis扩展(本质上就是动态链接库)。
持久性
Redis会将数据备份一份到硬盘上,避免因为存储在内存上的数据,因为进程退出/系统重启而丢失。当Redis重启时,就会在重启时加载硬盘中备份的数据到内存上,使Redis的内存恢复到重启前的状态。
集群
一个Redis能存储的数据是有限的(内存空间有限),引入多个主机,部署多个Redis节点,每个Redis存储数据的一部分。
高可用性
Redis自身是支持“主从”结构的,从节点就是主节点的备份。如果主节点挂了,从节点就能变成主节点,代替它进行工作。
速度快
Redis数据存储在内存中,比访问硬盘的数据库,速度快得多。
Redis核心功能都是比较简单的逻辑--=-------都是比较简单的操作内存的数据结构。
从网络角度,Redis使用了I/O多路复用技术(epoll)。
Redis使用的是单线程模型。Redis的核心任务是操作内存的数据结构,所以不会过多的占用CPU,所以如果引入多线程不仅不会提高效率,还会增加线程之间的竞争开销。
这里说的单线程,是指只使用一个线程,处理所有的命令请求,不是说一个redis服务器进程内部只有一个线程。只是其他的线程是在处理网络IO。
这种模型,保证了服务器收到的着多个请求是串行执行的,不会存在线程安全问题。
Redis客户端
Redis采用客户端-服务端架构,通过TCP协议通信,默认端口号为6379。
客户端的形态
1.自带的命令行客户端
#启动
redis-cli
#关闭
ctrl+d
2.图形化界面的客户端
3.基于redis的api自行开发客户端[工作中的最主要形态](类似于MySQL的C语言API和JDBC)
通用命令
上面说到Redis是按照键值对的方式存储数据的。所以下面引出两个最核心的命令set和get。
Redis中的命令不区分大小写。
set
将key和value存储进去。
set key value
上面的key和value都必须是字符串,但是不需要添加""或者''
get
根据key获取value的值,如果key不存在,则返回nil和C++中的NULL是差不多的意思。
get key
keys
用来查询当前服务器上匹配的key。通过一些特殊符号(通配符)来描述key的模样,匹配上述模样的key就能被查询出来。
keys pattern
返回所有满足样式(pattern)的key。支持如下通配样式:
h?llo: ?表示匹配一个任意字符,如hallo、hbllo……
h*llo: *表示匹配任意个(包括0个)任意字符,如hllo、hello、heeello……
h[ae]llo: []里面的字符表示满足条件的字符,如hallo、hello
h[^ae]llo: ^表示除了^后面的字符其他的都匹配,只有hallo和hello不匹配
h[a-e]llo: 表示匹配的字符范围,如hallo、hbllo……hello
keys命令的时间复杂度O(N),所以在工作中的生产环境(线上环境)上,一般都会禁止使用keys *
keys *:表示查询redis中的所有的key!!!
原因:生产环境上的key可能会非常多!!!而redis是一个单线程的服务器,执行keys *的时间非常长,就使redis服务器被阻塞了,无法给其他客户端提供服务!!!
exists
判断一个或多个key是否存在。
exists key [key ...]
时间复杂度O(1)。返回key存在的个数。
那么exists hello和exists hallo两条命令合并成一条exists hallo hello有什么区别吗?
redis是一个客户端-服务器结构的程序,客户端和服务器之间通过网络来进行通信!每次输入的命令都会由redis客户端包装成请求,发送给服务器,再由服务器返回响应。所以对于拆开来的写法就会产生更多轮次的网络通信,就会降低效率,提高成本。
del
删除一个或多个key。
del key [key ...]
时间复杂度O(1)。返回删除掉的key的个数。
expire
给指定的key设置过期时间(秒)。key存活时间超出这个指定的值,就会被自动删除。
expire key seconds
时间复杂度O(1)。返回1表示设置成功,0表示设置失败。
pexpire命令设置的时间单位是毫秒。
过期策略
redis是通过什么方式知道哪些key已经过期要被删除,哪些key还没过期。
如果key的数量很多,如果直接遍历所有的key,显示是行不通的,效率低下。
Redis的整体策略:
1.定期删除:隔一段时间,抽取一部分key,进行验证过期时间。保证这个抽查的过程足够高效。
2.惰性删除:当一个key已经到过期时间了,但是暂时还不删它key还存在。紧跟着后面又有一次访问,正好用到这个key,于是这次访问就会让redis服务器触发删除key的操作,同时返回一个nil。
上述两种策略的结合,还是有可能会有很多的key被残留,没有及时删除。所以Redis还提供了一系列的内存淘汰策略。
ttl
查看指定key的过期时间还剩多少。
ttl key
时间复杂度O(1)。返回剩余过期的时间,-1表示没有关联过期时间,-2表示key不存在。
type
返回key对应的value的数据类型。(none、string、list、set、zset、hash、stream……)
type key
时间复杂度O(1)。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)