Redis-基础

你在别的地方也能看到的Redis学习笔记。

Redis

老生常谈

Redis是由C语言编写,支持网络交互,基于内存也可以持久化的Key-Value(非关系型数据库)。

其实我就知道啥叫C语言,其他两个描述我搜了一下。

redis服务器与客户端交互方式

redi处理客户端的流程,通过TCP请求或者Unix socket【①】建立一个socket链接,然后检查最大连接数,再进行内部处理。

  • 先建立链接,再告诉超过最大连接数,再返回错误,断开连接。
  • 服务端处理多个客户端命令的顺序
    1. socket号的大小
    2. kernal报告事件的先后顺序

①:UNIX Domain SOCKET 是在Socket架构上发展起来的用于同一台主机的进程间通讯(IPC)。它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序列号应答等。只是将应用层数据从一个进程拷贝到另一个进程。

最大连接数

输出缓冲区限制

理解为港口运出商品,正常情况风调雨顺,政策可爱。

第一种情况,马上要提升关税了,港口疯狂向外运送商品,一个简单的命令返回的数据太大。

第二种情况是,海上天气不好,来往的船只少或者航速缓慢,但是有很多商品等待运出,在港口堆积,服务器朝客户端发送速率无法及时发送输出缓冲区的数据。

这两种情况都会导致占用内存过高,系统崩溃。redis采取的机制是限制输出缓冲区大小,和打黑除恶。

限制大小,当某一个客户端的缓冲区超过设定的最大值时,直接断开与该客户端的连接,贸易逆差,不和你玩。

打黑除恶,当某一个客户端长时间占用大空间也会断开连接。

实际情况

  1. 对普通客户端来说,限制为0,也就是不限制,因为普通客户端通常采用阻塞式的消息应答模式,如:发送请求,等待返回,再发请求,再等待返回。这种模式通常不会导致输出缓冲区的堆积膨胀。
  2. 对于 Pub/Sub 客户端来说,大小限制是32m,当输出缓冲区超过32m时,会关闭连接。持续性限制是,当客户端缓冲区大小持续60秒超过8m,也会导致连接关闭。
  3. 而对于 Slave 客户端来说,大小限制是256m,持续性限制是当客户端缓冲区大小持续60秒超过64m时,关闭连接。

输入缓冲区限制

比较暴力,当客户端传输的请求大小超过1G时,服务端会直接关闭连接。

这种方式可以有效防止一些客户端或服务端 bug 导致的输入缓冲区过大的问题。

Client超时

对当前的 Redis 版本来说,服务端默认是不会关闭长期空闲的客户端的。但是你可以修改默认配置来设置你希望的超时时间。
比如客户端超过多长时间无交互,就直接关闭。同理,这也可以通过 CONFIG SET 命令或者修改 redis.conf 文件来配置。

值得注意的是,超时时间的设置,只对普通客户端起作用,对 Pub/Sub 客户端来说,长期空闲状态是正常的。

另外,实际的超时时间可能不会像设定的那样精确,这是因为 Redis 并不会采用计时器或者轮训遍历的方法来检测客户端超时,而是通过一种渐近式的方式来完成,
每次检查一部分。所以导致的结果就是,可能你设置的超时时间是10s,但是真实执行的时间是超时12s后客户端才被关闭。

client list

id=2

addr=10.117.146.21:55330

fd=6

name=

age=1759348

idle=0

flags=S

db=0

sub=0

psub=0

multi=-1

qbuf=0

qbuf-free=0

obl=0 oll=0

omem=0

events=r

cmd=replconf

解释为

addr: 客户端的TCP地址,包括IP和端口
fd: 客户端连接 socket 对应的文件描述符句柄号
name: 连接的名字,默认为空,可以通过 CLIENT SETNAME 设置
age: 客户端存活的秒数
idle: 客户端空闲的秒数
flags: 客户端的类型 (N 表示普通客户端,更多类型见 http://redis.io/commands/client-list)
omem: 输出缓冲区的大小
cmd: 最后执行的命令名称

redis的优势

  1. 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
  2. 支持丰富数据类型,支持string,list,set,sorted set,hash
  3. 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
  4. 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

redis的应用场景

缓存

(1) 对于一些要返回给前端数据的缓存,当有大量数据库sql操作时候,为了避免每次接口请求都要去查询数据库,可以把一些数据缓存到redis中,这样是直接从内存中获取数据,速度回增快很多。

(2) web端用户,用于登陆缓存session数据,登陆的一些信息存到session中,缓存到redis中

队列

redis中提供了list接口,这个list提供了lpush和rpop,这两个方法具有原子性,可以插入队列元素和弹出队列元素。

数据存储

redis是非关系型数据库,可以把redis直接用于数据存储,提供了增删改查等操作,因为redis有良好的硬盘持久化机制,redis数据就可以定期持久化到硬盘中,保证了redis数据的完整性和安全性。

redis锁实现防刷机制

redis锁可以处理并发问题,redis数据类型中有一个set类型,set类型在存储数据的时候是无序的,而且每个值是不一样的,不能重复,这样就可以快速的查找元素中某个值是否存在,精确的进行增加删除操作。