百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Redis客户端和服务端如何通信?(redis客户端连接命令)

mhr18 2024-10-23 11:37 25 浏览 0 评论

1.1、客户端与服务端通信

我们知道Redis存在客户端和服务端,那么客户端和服务端是怎么通信的呢?

首先我们要知道Redis是通过Redis协议(RESP)进行通信的,而Redis协议位于TCP协议之上,客户端与服务端保持双工连接。简单来说就是客户端和服务端可以双向通信,客户端收发消息,服务端收发消息。

1.2、什么是双工通信模式?

ping-pong请求响应模式

谈到双工请求之前,需要谈到普通的请求响应模式。客户端发送一个ping请求,服务端回应一个pong响应。客户端收到pong请求后,才会发起第二个ping请求。这个也叫做ping-pong请求响应模式。相当于就是串行的请求,好像加了一把锁似的,让大家排队一个一个进行。

双工请求响应模式

普通的ping-pong需要排队,效率特别低,我们就想同时多发几个请求,并且以最快的速度返回。这时候就使用双工请求,同时发送一批请求,服务端也批量响应

这种模式是将一批命令打包发给服务端,服务端执行完按照顺序打包返回。大大地提升了性能。这个也叫做pipline管道模式。相当于只发了一次请求,却执行了n命令。

使用Jedis发送pipline请求

public static void main(String[] args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    Jedis redis = new Jedis("您的Redis IP地址", 6379);
    // 如果设置了requirepass密码 这里填写密码
//        redis.auth("");
    Pipeline pipe = redis.pipelined();
    for (int i = 0; i < 50000; i++) {
        pipe.set("test:pipeline:" + (i+1), String.valueOf(i+1));
    }
    // 同步发送所有的pipe命令
    pipe.sync();
    stopWatch.stop();
    System.out.println("耗时:" + stopWatch.getTotalTimeSeconds() + "s");
}

运行程序

可以看到redis的pipeline效率是非常高的,如果每个请求一个连接,量级越大,速度会严重下降的。

查看redis

1.3、客户端请求

redis客户端和服务端请求和响应数据是建立在TCP上的,所以报文格式一定会有所约定。

  • 客户端和服务端发送的命令或数据一律以\r\n(CRLF)结尾。
  • 客户端发送给服务端的参数都是二进制安全(binary safe)的。

我们直接使用telnet连接一下redis-server。

如果windows没有telnet命令

C:\Users\Administrator>telnet
'telnet' 不是内部或外部命令,也不是可运行的程序或批处理文件。

开启telnet命令

1.开始——控制面板——程序和功能
2.启用或关闭Windows功能——勾选“Telnet客户端”或是“Telnet Client”,点击确定
3.点击确定后等待系统做更改,提示Windows已经完成请求的更改表示已经启用成功。
4.启用成功后,重新尝试cmd——telnet IP 端口号命令即可。

使用telnet连接redis

# 连接redis 执行后会进入交互操作页
telnet 162.14.74.11 6379

可以看到 我们输入一个ping,就会返回一个pong。并且pong前 面有一个加号是怎么回事呢?

这就是Reids的格式规范约束之一。以下会列出redis的格式规范。

1.3.1、Redis请求响应格式规范

  1. 间隔符号,在Linux下是\r\n,在Windows下是\n
  2. 简单字符串 Simple Strings, 以 "+"加号 开头
  3. 错误 Errors, 以"-"减号 开头
  4. 整数型 Integer, 以 ":" 冒号开头
  5. 大字符串类型 Bulk Strings, 以 "#34;美元符号开头,长度限制512M
  6. 数组类型 Arrays,以 "*"星号开头

来看一下使用SET命令,Redis的格式是怎样的。首先我们开启设置redis的AOF模式,才能看到对应的命令。

############### APPEND ONLY 持久化方式 ###############
#默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失>,#根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性。Redis会把每次写入的数据在接>收后都写入 appendonly.aof 文件,#每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
appendonly yes

#aof文件名
appendfilename "appendonly.aof"

#aof持久化策略的配置
#no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快。
#always表示每次写入都执行fsync,以保证数据同步到磁盘。
#everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。
appendfsync everysec

修改之后重启redis

# 我使用docker启动的,直接重启容器
docker restart redis

# 如果使用redis命令重启,那就使用redis-server命令

发送命令和响应结果

root@62ddf68b878d:/data# redis-cli    
127.0.0.1:6379> set test_command hello
OK

appendonly.aof中的命令记录

*3
$3
set
$12
test_command
$5
hello

实际收到的响应数据

+OK\r\n

Redis服务端是如何接受请求,处理之后返回给客户端的呢?来看一下Reids的命令处理流程吧!

1.3.2、Redis命令处理流程

Redis命令处理流程-整体

  1. Redis服务端启动并监听Socket
  2. Redis客户端主动建立连接并发送命令
  3. Redis服务端为客户端创建一个Client对象,监听事件等
  4. Redis服务端读取Socket数据到缓存区
  5. Redis服务端将缓冲区内容解析为命令(判断单条/多条调用响应的处理器)
  6. Redis服务端解析成功后调用processCommand方法执行命令
  7. Redis服务端将结果写入输出缓冲区
  8. Redis客户端从输出缓冲区读取到Socket
  9. 最后客户端主动关闭连接

Redis执行命令详情流程

大致分三个部分

1、调用 lookupCommand 方法获得对应的 redisCommand

2、检测当前 Redis 是否可以执行该命令

3、调用 call 方法真正执行命令并返回结果

1.4、服务端响应

1.4.1、协议响应格式

状态回复

对于状态,回复的第一个字节是“+”

错误回复

对于错误,回复的第一个字节是“ - ”

1. -ERR unknown command 'foobar' 
2. -WRONGTYPE Operation against a key holding the wrong kind of value

整数回复

对于整数,回复的第一个字节是“:”

单条批量回复

对于批量字符串,回复的第一个字节是“$”

"$6 foobar"

多条批量回复

对于多条批量回复(数组),回复的第一个字节是“*”

"*3"

1.4.2、协议解析处理

包括协议解析、调用命令、返回结果

协议解析

Redis客户端输入命令后,redis-cli会把命令转换为RESP协议格式发送给服务端,服务端需要解析该协议。

1、解析命令请求参数的数量

命令请求参数数量遵循协议格式"*N\r\n",N表示命令的参数个数。

set name:1 zhangsan

这个命令就是就是有三个,所以aof文件第一行就是*3\r\n, 来吧看一下

*3
$3
set
$6
name:1
$8
zhangsan

可以看到确实是这样,第一行就是*3\r\n, 只是因为编辑器把\r\n直接显示成为了换行符。

2、循环解析参数

第二行到最后一行就是循环打印了每个参数的长度和对应的值。

循环解析,直到没有$符号,则表示解析完毕了,然后准备去执行命令了。

协议执行

协议执行,其实就是根据参数和对应的参数值,拿到命令,去调用命令,然会返回执行结果。执行过成如上面的命令处理流程图。

1、判断是否是quit命令,如果是,直接返回并关闭客户端

2、校验命令语法,执行lookupCommand查找命令,如果不存在则返回"unknown command",表示不知道该命令。

3、参数数目校验,参数数目和解析出来的个数要一致,如果不,则返回"wrong number of arguments"

4、校验权限,最大内存,集群,持久化等校验。

5、调用call函数执行命令,并记录命令执行时间和调用次数等,时间太长需要记录慢查询日志。

6、根据协议响应的格式将执行结果回复给客户端

1.5、Redis请求响应小结

其实Redis的请求响应流程还是比较简单的,简单来说就概括为以下四点。

1、Redis客户端发送命令并转换为RESP协议,然后发送给服务端

2、Redis服务端收到请求,解析RESP协议为正常的命令和参数

3、通过一系列的校验,命令,权限,集群等

4、调用call函数执行命令,遵循响应协议将结果返回给客户端。

2、相关文章

本人还写了Redis的其他相关文章,有兴趣的可以点击查看!

相关推荐

Docker安装详细步骤及相关环境安装配置

最近自己在虚拟机上搭建一个docker,将项目运行在虚拟机中。需要提前准备的工具,FinallShell(远程链接工具),VM(虚拟机-配置网络)、CentOS7(Linux操作系统-在虚拟机上安装)...

Linux下安装常用软件都有哪些?做了一个汇总列表,你看还缺啥?

1.安装列表MySQL5.7.11Java1.8ApacheMaven3.6+tomcat8.5gitRedisNginxpythondocker2.安装mysql1.拷贝mysql安装文件到...

Nginx安装和使用指南详细讲解(nginx1.20安装)

Nginx安装和使用指南安装1.检查并安装所需的依赖软件1).gcc:nginx编译依赖gcc环境安装命令:yuminstallgcc-c++2).pcre:(PerlCompatibleRe...

docker之安装部署Harbor(docker安装hacs)

在现代软件开发和部署环境中,Harbor作为一个企业级的容器镜像仓库,提供了高效、安全的镜像管理解决方案。通过Docker部署Harbor,可以轻松构建私有镜像仓库,满足企业对镜像存储、管理和安全性...

成功安装 Magento2.4.3最新版教程「技术干货」

外贸独立站设计公司xingbell.com经过多次的反复实验,最新版的magento2.4.3在oneinstack的环境下的详细安装教程如下:一.vps系统:LinuxCentOS7.7.19...

【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu

学习Linux并掌握Java环境配置及SpringBoot项目部署是一个系统化的过程,以下是从零开始的详细指南,帮助你逐步掌握这些技能。一、Linux基础入门1.安装Linux系统选择发行版:推荐...

cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务

cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务(yum选择的,时间不同,版本不同)如果对运维课程感兴趣,可以在b站上搜索我的账号:运维实战课程,可以关注我,学习更多免费的运...

时隔三月,参加2020秋招散招,终拿字节跳动后端开发意向书.

3个月前头条正式批笔试4道编程题只AC了2道,然后被刷了做了200多道还是太菜了,本来对字节不抱太大希望,毕竟后台竞争太大,而且字节招客户端开发比较多。后来看到有散招免笔试,抱着试一试的心态投了,然而...

Redisson:Java程序员手中的“魔法锁”

Redisson:Java程序员手中的“魔法锁”在这个万物互联的时代,分布式系统已经成为主流。然而,随着系统的扩展,共享资源的争夺成为了一个棘手的问题。就比如你想在淘宝“秒杀”一款商品,却发现抢的人太...

【线上故障复盘】RPC 线程池被打满,1024个线程居然不够用?

1.故障背景昨天晚上,我刚到家里打开公司群,就看见群里有人讨论:线上环境出现大量RPC请求报错,异常原因:被线程池拒绝。虽然异常量很大,但是异常服务非核心服务,属于系统旁路,服务于数据核对任务,即使...

小红书取消大小周,有人不高兴了!

小红书宣布五一节假日之后,取消大小周,恢复为正常的双休,乍一看工作时长变少,按道理来说大家应该都会很开心,毕竟上班时间缩短了,但是还是有一些小红书的朋友高兴不起来,心情很复杂。因为没有了大小周,以前...

延迟任务的多种实现方案(延迟机制)

场景订单超时自动取消:延迟任务典型的使用场景是订单超时自动取消。功能精确的时间控制:延时任务的时间控制要尽量准确。可靠性:延时任务的处理要是可靠的,确保所有任务最终都能被执行。这通常要求延时任务的方案...

百度java面试真题(java面试题下载)

1、SpingBoot也有定时任务?是什么注解?在SpringBoot中使用定时任务主要有两种不同的方式,一个就是使用Spring中的@Scheduled注解,另一个则是使用第三方框架Q...

回归基础:访问 Kubernetes Pod(concurrent.futures访问数据库)

Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多概念。在这里,学习几种访问集群外pod的方法。Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多不同的...

Spring 缓存神器 @Cacheable:3 分钟学会优化高频数据访问

在互联网应用中,高频数据查询(如商品详情、用户信息)往往成为性能瓶颈。每次请求都触发数据库查询,不仅增加服务器压力,还会导致响应延迟。Spring框架提供的@Cacheable注解,就像给方法加了一...

取消回复欢迎 发表评论: