你不知道的redis四-redis执行原理

目录

一、Redis运行原理

 二、redis执行协议 

RESP协议

模拟resp协议进行redis写入

三、redis性能测试

Redis慢查询分析

Redis慢查询极值设置

慢查询原理

慢查询命令


一、Redis运行原理

redis服务器对命令的处理都是单线程的,但是I/O层面却面向多个客户端并发地提供服务,并发到内部单线程的转化通过多路复用框架来实现。redis命令从发送到执行经理以下四个过程

  1. 发送命令
  2. 命令排队
  3. 命令执行
  4. 结果返回

 二、redis执行协议 

对redis请求进行抓包,查看抓包内容

1、执行抓包命令

2、查看抓包内容 

redis协议位于TCP层之上,即客户端和redis实例保持双工的连接,交互的都是序列化后的协议数据

RESP协议

Redis 服务器与客户端通过RESP(REdis Serialization Protocol)协议通信。

RESP 底层采用的是TCP 的连接方式,通过tcp 进行数据传输,然后根据解析规则解析相应信息,完成交互。

我们可以测试下,首先运行一个serverSocket 监听6379,来接收redis 客户端的请求信息。实现如下

1、建立socket连接监听6379端口,用于接收请求并输出

/**
 * /**
 * <p>模拟redis</p>
 *
 * @author DK
 * @version V1.0
 */
public class SimulatedRedis {

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(6379);
        Socket rec = server.accept();
        byte[] result = new byte[2048];
        rec.getInputStream().read(result);
        System.out.println(new String(result));
    }
}

2、使用jedis客户度端请求本地6379端口

/**
 * /**
 * <p>模拟redis</p>
 *
 * @author DK 
 * @version V1.0
 */
public class SimulatedRedisClient {

    public static void main(String[] args) throws IOException {
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.set("user:2", "9999");
        jedis.close();
    }
} 

 打印输出

发现和抓包内容一致

每个字段标示含义为:

*3    表示有几组数据 

$ 3   表示set长度为3

Set   命令

$6    表示key长度为6

User:2   key

$1    表示value长度为1

 2       value

主要以下特点:从上述实例中发现,redis使用resp协议的好处为容易实现,解析快,人类可读,并且传输在TCP层,可以减少不必要的信息传输

模拟resp协议进行redis写入

/**
 * /**
 * <p>模拟redis</p>
 *
 * @author DK 
 * @version V1.0
 */
public class RespRedis {

    public static void main(String[] args) {
        SocketAddress addr = new InetSocketAddress("10.1.253.188", 6379);
        Socket sk = new Socket();
        try {
            sk.connect(addr);
            OutputStream out = sk.getOutputStream();
            StringBuffer sb = new StringBuffer();
            sb.append("*3\r\n");
            sb.append("$3\r\n");
            sb.append("SET\r\n");
            sb.append("$6\r\n");
            sb.append("user:0\r\n");
            sb.append("$5\r\n");
            sb.append("11111\r\n");
            System.out.println(sb.toString());
            byte[] b = sb.toString().getBytes();
            out.write(b);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三、redis性能测试

Redis慢查询分析

mysql一样:当执行时间超过极大值时,会将发生时间 耗时 命令记录

redis命令生命周期:发送 排队 执行 返回,慢查询只统计3执行步骤的时间

Redis慢查询极值设置

一般有两种方式,默认时间为10ms

1、命令方式

config set slowlog-log-slower-than 10000  //10毫秒

使用config set完后,若想将配置持久化保存到redis.conf,要执行config rewrite

2、配置文件修改

redis.conf修改:找到slowlog-log-slower-than 10000 ,修改保存即可

注意:slowlog-log-slower-than =0记录所有命令 -1命令都不记录

慢查询原理

慢查询记录也是存在队列里的,slow-max-len 存放的记录最大条数,

比如设置的slow-max-len=10,当有第11条慢查询命令插入时,队列的第一条命令

就会出列,第11条入列到慢查询队列中, 可以config set动态设置,

也可以修改redis.conf完成配置

慢查询命令

获取队列里慢查询的命令:slowlog get

获取慢查询列表当前的长度:slowlog len    //以上只有1条慢查询,返回1;

1)对慢查询列表清理(重置):slowlog reset //再查slowlog len 此时返回0 清空;

2)对于线上slow-max-len配置的建议:线上可加大slow-max-len的值,记录慢查询存长命令时redis会做截断,不会占用大量内存,线上可设置1000以上

3)对于线上slowlog-log-slower-than配置的建议:默认为10毫秒,根据redis并发量来调整,对于高并发比建议为1毫秒

4)慢查询是先进先出的队列,访问日志记录出列丢失,需定期执行slowlog get,将结果存储到其它设备中(如mysql)

1、redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 10000

     100个并发连接,10000个请求,检测服务器性能

 

猜你喜欢

转载自blog.csdn.net/b379685397/article/details/108637784