目录

Redis定义        

分布式系统

单机架构

分布式

Redis特性

内存中存储数据

可编程性

可扩展性

持久性

集群

高可用性

速度快

Redis客户端

客户端的形态

通用命令

set  

get

keys

exists

del

expire

过期策略

ttl

type


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)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐