为什么redis-benchmark命令不遵循redis协议?

时间:2014-08-10 03:43:31

标签: tcp go redis

我在运行redis-benchmark命令后直接从tcp连接读取,据我所知,redis-benchmark不遵循redis协议。

redis protocol如其网站所述:

  

在Redis中使用RESP作为请求 - 响应协议的方式是   以下内容:

     
      
  • 客户端将命令作为批量字符串的RESP数组发送到Redis服务器。
  •   
  • 服务器根据命令实现回复一种RESP类型。
  •   

意味着正确的客户端实现必须始终发送批量字符串的RESP数组。

如果这是真的,那么任何不以*开头的东西都被认为是语法错误(因为它不是RESP数组)。

因此,如果要将一个ping命令发送到redis-server,那么它必须作为长度为1的resp数组发送,其中包含1个包含单词ping的大量字符串。例如:

  

" * 1 \ r \ n $的4 \ r \ nPING \ r \ n"

然而,每当我直接听redis-benchmark命令并读取它的tcp连接时,我得到了:

  

" PING \ r \ n"

遵循redis协议。这是一个错误还是redis协议中隐含的东西会使ping变得特别?据我所知,我无法找到任何说ping特别的东西,也不知道长度1命令是特殊的。有人知道最近发生了什么吗?

要查看自己重现这些结果,您可以复制my code直接检查它:

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    RedisBenchmark()
}

func RedisBenchmark() {
    url := "127.0.0.1:6379"
    fmt.Println("listen: ", url)
    ln, err := net.Listen("tcp", url) //announces on local network
    if err != nil {
        log.Fatal(err)
    }
    for {
        conn, err := ln.Accept() //waits and returns the next connection to the listener
        if err != nil {
            log.Fatal(err)
        }

        tcpConn := conn.(*net.TCPConn)
        go HandleConnection(tcpConn)
    }
}

func HandleConnection(tcpConn *net.TCPConn) {
    b := make([]byte, 256) //TODO how much should I read at a time?
    n, err := tcpConn.Read(b)
    if err != nil {
        fmt.Println("n: ", n)
        log.Fatal(err)
    }
    fmt.Printf("+++++> raw input string(b): %q\n", string(b))
    msg := string(b[:n])
    fmt.Printf("+++++> raw input msg: %q\n", msg)
}

并使用go with:

运行它

go run main.go

跟随另一个终端(或tmux窗格):

redis-benchmark

用于所有测试,或者如果您只想用1个客户端运行ping:

redis-benchmark -c 1 -t ping -n 1

您可以使用http://redis.io/topics/benchmarks

上的标记查看我如何运行它的详细信息

2 个答案:

答案 0 :(得分:4)

这称为内联命令。查看Redis协议文章的Inline Commands部分。

答案 1 :(得分:0)

您可以参考源代码,找出内联命令与 RESP 之间的差异。

readQueryFromClient
|-->  if command begins with * --> processInlineBuffer()process it as RESP
|
|-->  if command not begins with * --> processMultibulkBuffer():process it as inline command 

RESP 是一种更有效的解析Redis服务器命令的方法