Redis入门简介


前言

随着时代的发展,产品的要求不再局限于能不能做到某事,而是更好的实现某事。当技术稳定后,用户对于产品的使用体验也越来越重要,产品速度性能更好、使用起来更简单就越受到用户的喜爱,占有的市场就越多。要想系统的请求速度更快当然离不开缓存,对于后台我们使用做多的缓存就是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出现冲突。
在这里插入图片描述
使用自增,每次自增都会返回自增后的结果
在这里插入图片描述
使用setnx作为分布式锁,如果数据不存在保存的时候返回1,如果数据存在了返回0。
在这里插入图片描述
🔊 Redis的String对应int、embstr和raw三种编码格式。
int为数字类型
在这里插入图片描述
embstr为44个字节以内的短字符串
在这里插入图片描述
raw为大于44个字节的长字符串
在这里插入图片描述
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插入到列表

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

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

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

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

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

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

🔊 看一下对应的使用:
在这里插入图片描述
🔊 Redis的hash对应的编码格式是hashtable和ziplist,如果元素是比较少的整数和短字符串使用的是ziplist,如果比较多或长字符串等使用的是跳跃表。
在这里插入图片描述

🤍其它数据类型

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

❤️Redis的淘汰策略

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

🤍过期设置

🔊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中的事件分为文件事件和时间时间。

🤍文件事件

🔊 文件事件是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的配置
在这里插入图片描述
这是定了三个时间周期,对于要求不断的放松,这样的漏斗式设计性能比较高。
RDB模式使用的二进制压缩文件,空间小,方便主从复制的传输;使用主进程Fork子进程,性能比价高;数据恢复时直接通过二进制镜像文件,适合大规模的数据恢复。
但是RDB模式需要间隔一定的时间存储,我们看到默认的配置里面最小的是1分钟,如果服务挂掉,会丢失最后一个周期内的数据。

🤍AOF

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

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

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


  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值