dtrgqjcd877528 2014-08-10 03:43
浏览 57
已采纳

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

I was reading in directly from a tcp connection after running the redis-benchmark command and as far as I can tell, redis-benchmark is NOT following the redis protocol.

The redis protocol is as stated in its website:

The way RESP is used in Redis as a request-response protocol is the following:

  • Clients send commands to a Redis server as a RESP Array of Bulk Strings.
  • The server replies with one of the RESP types according to the command implementation.

Meaning that a correct client implementation must always send RESP arrays of bulk strings.

If that is true, then, anything that does not start with a * is considered a syntax error (since its not an RESP array).

Thus, if one were to send a ping command to a redis-server, then it must be sent as a resp array of length 1 with 1 bulk string containing the word ping. For example:

"*1 $4 PING "

However, whenever I listen directly to the redis-benchmark command and read its tcp connection I get instead:

"PING "

which does not follow the redis protocol. Is that a bug or is there something implied in the redis protocol that makes pings special? As far as I could tell I couldn't find anything that said that pings were special, nor that length 1 commands were special. Does someone know whats going on?

To see reproduce these results yourself you can copy my code to inspect it directly:

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
", string(b))
    msg := string(b[:n])
    fmt.Printf("+++++> raw input msg: %q
", msg)
}

and run it using go with:

go run main.go

followed on a different terminal (or tmux pane):

redis-benchmark

for all the test or if you only want to run ping with 1 client:

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

you can see the details of how I am running it with the flags at: http://redis.io/topics/benchmarks

  • 写回答

2条回答 默认 最新

  • duan35557593 2014-08-10 04:46
    关注

    That is called an inline command. Check the Inline Commands section of the Redis Protocol article.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向