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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 你不知道的redis四-redis执行原理

一、Redis运行原理


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


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


20200917110738338.png

二、redis执行协议


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

1、执行抓包命令


20200917113307150.png


2、查看抓包内容

aHR0cHM6Ly9vc2NpbWcub3NjaGluYS5uZXQvb3NjbmV0L3VwLTdkYTgyOTFiMDRiYzdiZDFmNDhjZTQzMmQyNjEwZjA1ZGYxLnBuZw.png


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();
    }
} 


打印输出

20200917113444202.png

发现和抓包内容一致


每个字段标示含义为:


*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个请求,检测服务器性能


20200923200425494.png

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
4月前
|
NoSQL Redis
Redis 执行 Lua保证原子性原理
Redis 执行 Lua 保证原子性原理
375 1
|
4月前
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
141 0
|
3月前
|
缓存 NoSQL Linux
redis的原理(三)
redis的原理(三)
redis的原理(三)
|
2月前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
40 2
|
2月前
|
存储 缓存 NoSQL
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
63 1
|
2月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
281 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
|
3月前
|
存储 缓存 NoSQL
redis的原理(四)
redis的原理(四)
|
3月前
|
存储 缓存 NoSQL
redis的原理(二)
redis的原理(二)
|
3月前
|
缓存 NoSQL 安全
Redis的原理(一)
Redis的原理(一)
|
2月前
|
消息中间件 NoSQL Kafka
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
152 0