为什么redis-benchmark命令不遵循redis协议?(How come the redis-benchmark command is not following the redis protocol?)
在运行
redis-benchmark
命令之后,我直接从tcp连接读取,据我所知,redis-benchmark
不遵循redis协议。redis协议如其网站所述:
RESP在Redis中用作请求 - 响应协议的方式如下:
- 客户端将命令作为Bulk Strings的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命令是特别的。 有人知道发生了什么事吗?
要查看自己重现这些结果,您可以复制我的代码以直接检查它:
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运行它:
go run main.go
跟随在不同的终端(或tmux窗格):
redis-benchmark
对于所有测试或者如果您只想与1个客户端运行ping:
redis-benchmark -c 1 -t ping -n 1
你可以在http://redis.io/topics/benchmarks看到有关我如何运行它的详细信息
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\r\n$4\r\nPING\r\n"
However, whenever I listen directly to the redis-benchmark command and read its tcp connection I get instead:
"PING\r\n"
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\n", string(b)) msg := string(b[:n]) fmt.Printf("+++++> raw input msg: %q\n", 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
原文:https://stackoverflow.com/questions/25225333
最满意答案
如果您已正确设置约束并且应用程序的部署目标是> = iOS 8,则可以使用自动行高计算。 因此,您必须在
viewDidLoad
执行以下操作:tableView.estimatedRowHeight = 44 tableView.rowHeight = UITableViewAutomaticDimension
其中44应该是某种平均行高。 那么你根本不必实现
estimatedRowHeight
和heightForRow
方法......你也可以实现
heightForRow
并执行以下操作:// if cell is of kind textview cell return UITableViewAutomaticDimension // else return some static value
if you have setup your constraints correctly and your app's deployment target is >= iOS 8 you can use the automatic row height calculation. therefore you have to do the following in
viewDidLoad
:tableView.estimatedRowHeight = 44 tableView.rowHeight = UITableViewAutomaticDimension
where 44 should be some kind of average rowheight. then you do not have to implement the methods
estimatedRowHeight
andheightForRow
at all...you can also implement
heightForRow
and do something like the following:// if cell is of kind textview cell return UITableViewAutomaticDimension // else return some static value
相关问答
更多-
单元格高度等于图像宽度(Cell height equal to image width)[2022-03-10]
你不能在heightForRowAtIndexPath调用单元格对象,因为它会在cellForRowAtIndexPath调用heightForRowAtIndexPath时创建无限循环。 其次,使用约束调整width因为函数名称清楚地表明它是高度。 如果您确定控件的高度,请使用此选项 return 90.0 //its optional if height is fixed 其他 为top , bottom , left , right , width和height约束添加约束,并使用> = cond ... -
使UItableview单元格高度等于其子UItableview(Make UItableview cell height equal to it's child UItableview)[2023-05-08]
首先看看我的ViewController,它有一个tableview(tblview)和UITableViewCell(CustomTableViewCell), class ViewController: UIViewController { @IBOutlet var tblview:UITableView! override func viewDidLoad() { super.viewDidLoad() self.tblview.delegate = ... -
第一个问题:是的,确实如此。 您需要使用不同的水平压缩阻力优先级。 您可能还需要较低优先级的不等式来设置限制。 第二个问题:问题是你没有完全确定身高。 您必须从单元格的顶部到单元格的底部一直有约束,以便单元格的高度由其内部的内容严格确定。 First question: Yes, it is. You'll need to use different horizontal compression resistance priorities. You might also need a lower prior ...
-
UItableview每个单元格标签都要隐藏,高度应该更改(UItableview each cell label want to hide and height should be change)[2023-03-12]
是的,这是可能的。您必须根据方法cellForRowAtIndexPath的国家/地区名称应用条件。 喜欢这个 if(countryName isEqualToString @"Canada"){ countryInfoLabel.numberofLines=0; countryInfoLabel.text=[NSString stringWithFormat:@"Population:%@",populationFromService]]; } 根据国家/地区名称在countryIn ... -
如果你已经做了一切正确的事情仍然无法获得所需的输出意味着问题将受到限制。 我做了一个简单的约束布局,使用这个骨架作为参考并重新约束你的单元格。 将(W:20,H:20)添加到[img]。 确保将行数设置为0,以及所有其他自动尺寸的东西。 IB约束截图。 输出: If u have done everything correct and still u r unable the get desired output means the issue will be with constraints. I hav ...
-
对于这个问题,我创建了扩展: extension String { func widthWithConstrainedHeight(_ height: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: CGFloat.greatestFiniteMagnitude, height: height) let boundingBox = self.boundingRect( ...
-
如果您已正确设置约束并且应用程序的部署目标是> = iOS 8,则可以使用自动行高计算。 因此,您必须在viewDidLoad执行以下操作: tableView.estimatedRowHeight = 44 tableView.rowHeight = UITableViewAutomaticDimension 其中44应该是某种平均行高。 那么你根本不必实现estimatedRowHeight和heightForRow方法...... 你也可以实现heightForRow并执行以下操作: // if c ...
-
这样做的方法是使用自动布局。 您需要从单元格的顶部到底部设置垂直约束: 单元格的上边缘与第一个标签的上边缘之间的距离。 从第一个标签的下边缘到图像视图的上边缘的距离。 从图像视图的下边缘到第二个标签的上边缘的距离。 等等 ... 自动布局将根据您在标签和图像视图中放置的内容的大小来确定单元格的大小。 您还应该记住将表视图上的estimatedRowHeight属性设置为一些有意义的值。 这将有助于表格视图将内容大小的某些计算推迟到用户开始滚动时。 另外,将表视图上的rowHeight属性设置为UITable ...
-
Masonry提供了以编程方式添加约束的更简单方法。 LEt说你有一个UIView并且想要为它添加约束: UIView *superview = self; UIView *view1 = [[UIView alloc] init]; view1.translatesAutoresizingMaskIntoConstraints = NO; view1.backgroundColor = [UIColor greenColor]; [superview addSubview:view1]; UIE ...
-
有一种方便的方法来使用约束并在代码中更改它。 首先,声明一个约束属性: @IBOutlet weak var labelHeight: NSLayoutConstraint! 其次,将它绑定在XIB或Stroyboard中: 最后,您可以通过编程方式更改它: self.labelHeight.constant = 130 There is a convenience way to use constraint and change it in code. First, declare a constra ...