最近再用sysbench给DBScale做压力测试的时候发现 DBScale+单个MySQL 的读TPS比单个MySQL要差很多。
跟踪代码后发现DBScale每次执行完一条select语句之后从客户端recv第一个数据包的时间要比第2个数据包的时间多200倍。
查看了TCP的协议发现:
1. TCP会默认开启Nagle's 算法
该算法会将多次send的操作(连续的,数据量小的)缓存到操作系统的发送缓冲中,当执行第一个recv的时候会想将发送缓存中的数据发送出去,然后再接收。
2. 两个recv直接多个连续的send操作会触发Nagle's 算法
例如:
peer.send_n ("GET ", 4);
peer.send_n (pathname, strlen (pathname));
peer.send_n (" HTTP/1.0\r\n\r\n", 13);
DBScale在处理查询结果集包的策略是尽快地将服务端返回的数据包发送给客户端,所以必然会有多次send操作,从而触发Nagle's 算法。
之所以读TPS上不去是因为DBScale将查询结果返回给sysbench客户端的时间被Nagle's 算法delay了。
该问题的解决办法如下:
1. 为socket设置选项 TCP_NODELAY
ACE的socket设置代码如下:
int nodelay = 1;
stream->set_option(ACE_IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof (nodelay);
2. 代码添加代码对多个send操作进行缓存,
转载请注明转自高孝鑫的博客
跟踪代码后发现DBScale每次执行完一条select语句之后从客户端recv第一个数据包的时间要比第2个数据包的时间多200倍。
查看了TCP的协议发现:
1. TCP会默认开启Nagle's
2. 两个recv直接多个连续的send操作会触发Nagle's
DBScale在处理查询结果集包的策略是尽快地将服务端返回的数据包发送给客户端,所以必然会有多次send操作,从而触发Nagle's
之所以读TPS上不去是因为DBScale将查询结果返回给sysbench客户端的时间被Nagle's
该问题的解决办法如下:
1. 为socket设置选项 TCP_NODELAY
ACE的socket设置代码如下:
2. 代码添加代码对多个send操作进行缓存,
转载请注明转自高孝鑫的博客