redis协议-yii2源码理解

本文深入解析Redis协议,包括客户端如何构造命令并发送数据,以及服务器如何处理和响应。重点介绍了命令封包、发送、接收及解包的流程,同时提到了批处理(pipeline)的实现原理。此外,还提供了Redis协议的回复格式和相关链接,为理解Redis通信机制提供了详细指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. redis 协议 图示

 

1. client一端的收发数据处理

(有时间研究下 redis server 一端的 收发数据处理)

   client发送数据给 redis server

*参数数量\r\n    $参数字节数\r\n参数数据\r\n

2. 封包encode

/**
 * Executes a redis command.
 * For a list of available commands and their parameters see http://redis.io/commands.
 *
 * The params array should contain the params separated by white space, e.g. to execute
 * `SET mykey somevalue NX` call the following:
 *
 * ```php
 * $redis->executeCommand('SET', ['mykey', 'somevalue', 'NX']);
 * ```
 */
public function executeCommand($name, $params = [])
{
    $this->open();

    $params = array_merge(explode(' ', $name), $params);
    $command = '';
    $paramsCount = 0;
    foreach ($params as $arg) {
        if ($arg === null) {
            continue;
        }

        $paramsCount++;
        $command .= '$' . mb_strlen($arg, '8bit') . "\r\n" . $arg . "\r\n";
    }
    $command = '*' . $paramsCount . "\r\n" . $command;

3. 发送数据,发送到连接socket的缓冲区

private function sendCommandInternal($command, $params)
{
    $written = @fwrite($this->_socket, $command);

4. 返回包的 格式

+  简单字符串回复   ;  + 状态描述字符串 \r\n

-   错误回复 ;  -  错误类型字符串 空格  错误描述字符串  \r\n

:   整数回复;  :  整数字符串 \r\n

$    二进制安全字符串回复( bulk strings reply) ;   $  回复数据字节数  \r\n   回复数据  \r\n

  *  批量回复(arrays reply) ;   * 回复数量  \r\n  [后边都是其他回复类型的格式]  … [后边都是其他回复类型的格式]

5.  从连接socket 读取数据 & 从应用程序缓冲区 获取一个包 & 解包decode 

($line = fgets($this->_socket)) === false)

//从连接socket的接收缓冲区读取数据
if (($line = fgets($this->_socket)) === false) {
     ...
}


$type = $line[0];
$line = mb_substr($line, 1, -2, '8bit');   //去掉后边的\r\n
switch ($type) {
    case '+': // Status reply
        ...
    case '-': // Error reply
    ...


第一个字节来区分 包的类型

+   状态描述字符 ,   OK,    PONG
- 

$   
	如果是 $-1\r\n   

	数据的长度:$length = (int)$line + 2;   //包括后边的\r\n
	采取 循环的读, 直到读不出数据 / 
while ($length > 0) {
    if (($block = fread($this->_socket, $length)) === false) {
        ......
    }
    $data .= $block;
    $length -= mb_strlen($block, '8bit');
}

    //把读取到的数据,去掉最后的两个字节(\r\n)
    mb_substr($data, 0, -2, '8bit');


 *   
     *数量\r\n   [后边都是其他回复类型的格式] … [后边都是其他回复类型的格式]  
     循环地处理 [后边都是其他回复类型的格式];
	循环地 decode

6. pipeline 有些客户端会实现 pipeline 怎么实现的,原理是?

注意 pipeline 不对应特殊的协议规则,只是客户端把几个命令一起发送给服务端,而不必等收到redis server的回复后再发送下一个命令

9. 相关链接

官网协议文档:http://www.redis.cn/topics/protocol.html

10. redis server 收发数据处理

todo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值