> 文档中心 > Redis入门简介

Redis入门简介

文章目录

  • 前言
  • ❤️Redis简介
  • ❤️Redis的数据类型
    • 🤍Redis的数据结构
    • 🤍常用数据类型
    • 🤍其它数据类型
  • ❤️Redis的淘汰策略
    • 🤍过期设置
    • 🤍淘汰策略
  • ❤️Redis的通讯协议
  • ❤️Redis的事件处理
    • 🤍文件事件
    • 🤍时间事件
    • 🤍aeEventLoop
  • ❤️Redis的持久化
    • 🤍RDB
    • 🤍AOF

前言

随着时代的发展,产品的要求不再局限于能不能做到某事,而是更好的实现某事。当技术稳定后,用户对于产品的使用体验也越来越重要,产品速度性能更好、使用起来更简单就越受到用户的喜爱,占有的市场就越多。要想系统的请求速度更快当然离不开缓存,对于后台我们使用做多的缓存就是Redis,今天就为大家系统的讲解一下Redis需要掌握的知识点。

🔔使用的是Redis5版本,windows下载地址为:https://github.com/tporadowski/redis/releases


❤️Redis简介

Redis是由C语言编写的Key-Value类型的数据库,它是免费开源的NOSQL类型数据库,Redis作为最受欢迎的缓存数据库其性能非常高, Redis能读的速度是110000次/s,写的速度是81000次/s ,Redis除了可以作为缓存数据库使用外还可以用做分布式锁、发布订阅使用,当然在其它功能目前都有对应的中间件,所以Redis主要使用来做缓存数据库使用的。

❤️Redis的数据类型

🤍Redis的数据结构

redis中的数据存储的信息除了数据外还包括下面内容组成:

typedef struct redisObject { unsigned type:4;//类型 五种对象类型unsigned encoding:4;//编码 void *ptr;//指向底层实现数据结构的指针int refcount;//引用计数 unsigned lru:LRU_BITS; //LRU_BITS为24bit 记录最后一次被命令程序访问的时间}robj;

type占4位表示对象的类型;encoding占4位表示对象的编码格式;ptr指针(C语言中虐到你放弃的语法);refcount对象的引用次数;lru对象最后一次操作的时间。

🤍常用数据类型

Redis支持五大常用数据类型:
1️⃣ String
Redis中的String类型支持字符串、整数和浮点数,看一下String的常用命令。

命令 描述
set 赋值
get 取值
getset 取值并且赋值
setnx 如果值不存在时赋值,常用作分布式锁
append 尾部追加值
strlen 字符串长度
incr 自增,可以用来作为数据自增ID
incrby 增加固定的数值
decr 自减
decrby 减少固定的数值

🔊 看一下具体的操作:
一般情况下我们都使用表名+key(id等)作为redis的key,这样防止key出现冲突。
Redis入门简介
使用自增,每次自增都会返回自增后的结果
Redis入门简介
使用setnx作为分布式锁,如果数据不存在保存的时候返回1,如果数据存在了返回0。
Redis入门简介
🔊 Redis的String对应int、embstr和raw三种编码格式。
int为数字类型
Redis入门简介
embstr为44个字节以内的短字符串
Redis入门简介
raw为大于44个字节的长字符串
Redis入门简介
2️⃣ list
list就是指的咱平常开发中的集合list,看一下list对应的命令:

命令 描述
lpush 左侧插入
lpop 左侧取出
rpush 右侧插入
rpop 右侧取出
lpushx 左侧头部插入
rpushx 右侧头部插入
blpop 左侧取出,如果为空时阻塞
brpop 右侧取出,如果为空时阻塞
llen 列表中元素的个数
lindex 获得下标为index的元素,从左侧数
lrange 返回列表指定区间的元素,从左侧数
lrem 删除列表中值为value的元素
lset 将列表对应下标的元素修改为value
ltrim 对列表进行截取,只保留start,end区间内的元素
rpoplpush 从列表1右侧弹出元素插入到列表2的左侧
brpoplpush 从列表1右侧弹出元素插入到列表2的左侧,如果为空则阻塞
linsert 将value插入到列表

🔊 看一下对应的使用:
Redis入门简介
使用list要区分哪是左哪是右,是不是对于上面的范围取值顺序感觉别扭,左侧插入的顺序是反着的,rpush才是你认为的顺序。
Redis入门简介
🔊 Redis的list对应的编码格式是quicklist:
Redis入门简介
3️⃣ set
set是无序、唯一的集合,看一下set对应的命令:

命令 描述
sadd 添加元素
srem 删除元素
smembers 查询集合中的所有元素
spop 随机返回一个元素,同时移除该元素
srandmember 随机返回一个元素,但是不删除该元素
scard 获取集合中元素的数量
sismember 判断元素是否在集合内
sinter 求集合的交集
sdiff 求集合的差集
sunion 求集合的并集

🔊 看一下对应的使用:
Redis入门简介
🔊 Redis的set对应的编码格式是intset和hashtable,当集合中的元素是64位以内整数的时候采用的intset作为编码,当存放的是其他类型的时候采用的是hashtable。
Redis入门简介
4️⃣ zset
zset又叫sortedset是有序、不重复的集合,zset中的每一个元素都有一个分值,看一下其命令:

命令 描述
zadd 添加
zrem 删除
zcard 获取集合中元素的数量
zcount 获取集合中score在min,max范围的元素数量
zincrby 在集合成员分数上增加
zscore 获取集合元素的分数
zrank 获取集合从小到大排列
zrevrank 获取集合从大到小排列
zrange 获取指定范围的元素,按照分数递增排列
zrevrange 获取指定范围的元素,按照分数递减排列

🔊 看一下对应的使用:
Redis入门简介
例如水果销量排行使用zset,获取销量前三的数据
Redis入门简介
🔊 Redis的zset对应的编码格式是ziplist和skiplist,如果元素是比较少的整数和短字符串使用的是压缩列表,如果比较多或长字符串等使用的是跳跃表。
Redis入门简介
5️⃣ hash
hash就是我们常说的散列表,看一下其命令:

命令 描述
hset 赋值
hmset 批量赋值
hsetnx 赋值,如果存在则操作不成功
hexists 查看某个field是否存在
hget 取值
hmget 批量取值
hgetall 获取所有的值
hdel 删除
hincrby 指定field自增
hlen 获取field的数量

🔊 看一下对应的使用:
Redis入门简介
🔊 Redis的hash对应的编码格式是hashtable和ziplist,如果元素是比较少的整数和短字符串使用的是ziplist,如果比较多或长字符串等使用的是跳跃表。
Redis入门简介

🤍其它数据类型

除了常用的5中数据类型外,redis又增加了几种数据类型:bitmap位图,设置对应字段的值,值只有0和1两种状态;geo地理位置,就是我们常用的地图中的坐标,还支持坐标查询Xkm内附近的人;stream数据流,常用来作为消息队列使用,但是现在一般消息队列有专用的中间件了,redis用的较少。

❤️Redis的淘汰策略

Redis的读写性能非常的快,但是我们的内存空间是有限的,在有限的空间内要有效的利用,所以需要设置对应的key-value过期。
对应的配置信息在redis.conf中有注释记录。
Redis入门简介

🤍过期设置

🔊maxmemory: 这是redis配置文件中设置使用的最大内存空间,如果设置为0则没有限制的使用内存,一般设置为服务器内存的3/4,留出1/4作为服务器日常使用,当然如果你服务器如果有其他软件部署要考虑清楚。

🔊 expire: 过期时间,上面我们说过redis中的数据记录里面有一个最后操作时间,这里有了一个过期时间,单位是秒,如果最后操作时间到当前时间大于等于过期时间,则数据过期了要被清理掉了。

🤍淘汰策略

Redis中的淘汰机制有定时删除、懒删除和主动删除。其中定时删除是指创建数据的时候创建个定时器,当数据过期时执行定时器删除,比较消耗CPU资源;懒删除指的是数据过期了不删除,当在用数据的时候发现数据过期了才删除;主动删除是我们常说的删除策略了,Redis主动的删除数据。
主动删除分为下面的策略:

  1. LRU指的是最近最少使用的数据删除,注重的最后使用的时间。
  2. LFU指的是最近最少使用的数据删除,注重的最近时间段内使用的次数。
  3. RANDOM指的是过期的数据随机删除。
  4. TTL从设置过期的数据里面随机挑选数据,淘汰TTL值最小的数据。
  5. Noenviction表示不删除数据。

❤️Redis的通讯协议

Redis中客户端和服务器之间交互采用的通讯协议是RESP(Redis的序列化协议)。简单的解释一下就是Redis发送的命令会通过这个协议去解析,将命令解析为Redis可以看懂的语言,看一下解析的语法格式:

  1. 所有的命令或者数据都是以\r\n结尾的,在windows系统下是以\n结尾的。
  2. 对于简单的字符串是以+开头。
  3. 对于错误类型Error是以-开头。
  4. 对于整数类型是以开头。
  5. 对于大字符串类型是以$开头。
  6. 对于数组类型是以 * 开头。

🔊 来简单的解释一下这个通讯协议怎么解析执行命令的。例如执行一个命令:

set  user001 jack

实际上该命令会通过RESP协议解析为下面语句:

*3\r\n$3\r\nSET\r\n$7\r\nuser001\r\n$4\r\njack\r\n

我们把\r\n去掉,格式化看一下解析后的语句的语法,整条命令是字符串格式,但是需要对字符串进行解析解析乘redis能看懂的命令就变成了下面这样,\r\n可以是结束也是开始,一般是从\r\n开始数位数的:
Redis入门简介

❤️Redis的事件处理

Redis中的事件分为文件事件和时间时间。

🤍文件事件

🔊 文件事件是Socket IO事件,主要是客户端的连接、请求、回复、断开等事件。

我们都知道Redis是单线程的,这里的单线程指的是文件事件处理的单线程,并不是Redis就一个线程。通俗的解释一下:正常我们包括数据库连接等都是线程池的,来一个连接建立一个线程,而Redis是单线程处理的,来一个请求链接会交给对应的Request Handler,并不会建立线程。
🔊 Redis的I/O模型
Redis对于文件事件的处理是基于单线程的IO多路复用机制,主要分为四种:

SELECT
SELECT是通过数组实现的,其原理与我们学NIO的时候的那个选择器差不多,当有每次检查时候需要读写的时候,对管理的所有Socket都进行遍历。所以效率比较低,而且有最大数量1024限制。

POLL
POLL的原理与SELECT差不多,同样需要遍历所有连接,效率较低,但是其底层是通过链表实现的,而且没有最大链接数量1024限制。

EPOLL
上面两个每次有事件的时候都需要整体遍历,而且需要在用户空间和内核空间都拷贝一次。EPOLL克服了这些缺点,只需要拷贝一次,将文件描述符Socket事件放到内核的事件表中,实现了用户空间和内核空间的共享,而且EPOLL只管活跃的连接,效率远高于POLL和SELECT,这是Reids默认的实现方式

KQUEUE
KQUEUE是UNIX下的IO多路,这个可以在发生事件之后直接一次性的通知到对应的Socket,效率非常高。

🤍时间事件

时间事件是Redis的另一个事件,分为定时事件和周期事件。
定时事件指的是在程序运行一段时间后执行一次,执行之后该事件就失效了,跟前端常setTimeOut一样效果。
周期事件指的是在一定的时间间隔重复执行某一程序,同前端的setInterval一样效果。

Reids中的时间事件主要用来清理过期的数据、AOF或RDB的持久化操作、清理失效的客户端以及集群同步等功能。

🤍aeEventLoop

aeEventLoop是Redis中事件的核心,管理着整个时间事件和文件事件,一直循环的处理需要执行的事件,看其主函数就是一个While循环:

void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0;  while (!eventLoop->stop) {  if (eventLoop->beforesleep != NULL)  eventLoop->beforesleep(eventLoop);    aeProcessEvents(eventLoop, AE_ALL_EVENTS);     }}

具体的事件细节感兴趣的可以自行学习,这里咱就不多看了,本身就不是学C的,只靠大学快忘干净的那些知识,可能看起来比较困难。

❤️Redis的持久化

Redis的持久化机制分为RDB和AOF机制。Redis的持久化主要是为了Redis服务宕机之后的恢复,我们知道Redis主要是通过内存工作的,如果宕机之后数据消失了,所以需要将持久化到磁盘的数据恢复到内存,这样就不会重启服务后Redis没有数据给数据库造成太大的压力。

🤍RDB

RDB是Redis默认的持久化机制,将内存中的数据按照一定的时间周期通过快照的方式保存到磁盘上。
看一下Redis.conf中对于RDB的配置
Redis入门简介
这是定了三个时间周期,对于要求不断的放松,这样的漏斗式设计性能比较高。
RDB模式使用的二进制压缩文件,空间小,方便主从复制的传输;使用主进程Fork子进程,性能比价高;数据恢复时直接通过二进制镜像文件,适合大规模的数据恢复。
但是RDB模式需要间隔一定的时间存储,我们看到默认的配置里面最小的是1分钟,如果服务挂掉,会丢失最后一个周期内的数据。

🤍AOF

不同于RDB的机制,AOF是将Redis执行的RESP命令持久化到了磁盘中,如果恢复的时候需要按照顺序执行对应的命令即可。可以通过下面配置开启AOF持久化。
Redis入门简介
AOF的持久化有三种保存模式,分别是AOF_FSYNC_NO(不保存)、AOF_FSYNC_EVERYSEC(每秒保存一次)、AOF_FSYNC_ALWAYS(每执行一个命令保存一次),默认每秒保存一次。当然如果说是数据的完整性的话每个命令保存一次效果最好,但是其执行会阻塞Redis主进程,效率较低;而每秒保存一次是通过fork子进程来执行的,不会阻塞主进程效率高,最多也就丢失一两秒的数据,可以被接受。

相较于RDB模式来说,AOF执行保存的频率较高,其性能肯定会受到影响,但是其数据完整性较高,丢失的数据较少。但是从AOF的工作机制来看,其恢复时通过命令恢复的,如果数据较多的话,恢复起来肯定不如RDB直接恢复快。

一般情况下我们不会只选择AOF模式的,性能太差。如果做缓存使用的话可以使用RDB模式,如果作为内存数据库使用的话可以采用RDB+AOF模式。


天天排行榜