1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-14 20:31:56 +00:00

set send socket buf. mw/mr sleep default to 350.

This commit is contained in:
winlin 2014-12-05 11:24:05 +08:00
parent 4d1c162ebd
commit fad6074a25
10 changed files with 101 additions and 36 deletions

View file

@ -726,6 +726,7 @@ The play benchmark by [st-load](https://github.com/winlinvip/st-load):
* 2014-11-12, SRS 2.0.14, 3.5k(3500)clients, 95%CPU, 78MB. [commit](https://github.com/winlinvip/simple-rtmp-server/commit/8acd143a7a152885b815999162660fd4e7a3f247)
* 2014-11-13, SRS 2.0.15, 6.0k(6000)clients, 82%CPU, 203MB. [commit](https://github.com/winlinvip/simple-rtmp-server/commit/cc6aca9ad55342a06440ce7f3b38453776b2b2d1)
* 2014-11-22, SRS 2.0.30, 7.5k(7500)clients, 87%CPU, 320MB. [commit](https://github.com/winlinvip/simple-rtmp-server/commit/58136ec178e3d47db6c90a59875d7e40946936e5)
* 2014-12-05, SRS 2.0.55, 8.0k(8000)clients, 89%CPU, 360MB. (mw_sleep=1800)[commit](https://github.com/winlinvip/simple-rtmp-server/commit/58136ec178e3d47db6c90a59875d7e40946936e5)
### Publish benchmark
@ -739,7 +740,7 @@ The publish benchmark by [st-load](https://github.com/winlinvip/st-load):
* 2014-12-04, SRS 2.0.49, 1.4k(1400) publishers, 68%CPU, 144MB.
* 2014-12-04, SRS 2.0.49, 2.5k(2500) publishers, 95%CPU, 404MB. [commit](https://github.com/winlinvip/simple-rtmp-server/commit/29324fab469e0f7cef9ad04ffdbce832ac7dd9ff)
* 2014-12-04, SRS 2.0.51, 2.5k(2500) publishers, 91%CPU, 259MB. [commit](https://github.com/winlinvip/simple-rtmp-server/commit/f57801eb46c16755b173984b915a4166922df6a6)
* 2014-12-04, SRS 2.0.52, 4.0k(4000) publishers, 80%CPU, 331MB. (mr_sleep=2000) [commit](https://github.com/winlinvip/simple-rtmp-server/commit/5589b13d2e216b91f97afb78ee0c011b2fccf7da)
* 2014-12-04, SRS 2.0.52, 4.0k(4000) publishers, 80%CPU, 331MB. (mr_sleep=2000)[commit](https://github.com/winlinvip/simple-rtmp-server/commit/5589b13d2e216b91f97afb78ee0c011b2fccf7da)
## Architecture

View file

@ -158,14 +158,15 @@ vhost mrw.srs.com {
# when there are 2500 publisher, the total memory of SRS atleast:
# 183KB * 2500 = 446MB
# the value recomment is [300, 2000]
# default: 500
latency 500;
# default: 350
latency 350;
}
# set the MW(merged-write) latency in ms.
# SRS always set mw on, so we just set the latency value.
# the latency of stream >= mw_latency + mr_latency
# default: 500
mw_latency 500;
# the value recomment is [300, 1800]
# default: 350
mw_latency 350;
}
# vhost for edge, edge and origin is the same vhost

View file

@ -421,13 +421,14 @@ int SrsPublishRecvThread::on_reload_vhost_mr(string vhost)
void SrsPublishRecvThread::set_socket_buffer(int sleep_ms)
{
// the underlayer api will set to SRS_MR_SOCKET_BUFFER bytes.
// the bytes:
// 4KB=4096, 8KB=8192, 16KB=16384, 32KB=32768, 64KB=65536,
// 128KB=131072, 256KB=262144, 512KB=524288
// the buffer should set to SRS_MR_MAX_SLEEP_MS*kbps/8,
// the buffer should set to sleep*kbps/8,
// for example, your system delivery stream in 1000kbps,
// sleep 800ms for small bytes, the buffer should set to:
// 800*1000/8=100000B(about 128KB).
// other examples:
// 2000*3000/8=750000B(about 732KB).
// 2000*5000/8=1250000B(about 1220KB).
int kbps = 5000;

View file

@ -83,7 +83,9 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd)
duration = 0;
kbps = new SrsKbps();
kbps->set_io(skt, skt);
mw_sleep = SRS_PERF_MW_SLEEP;
mw_enabled = false;
_srs_config->subscribe(this);
}
@ -212,7 +214,10 @@ int SrsRtmpConn::on_reload_vhost_removed(string vhost)
int SrsRtmpConn::on_reload_vhost_mw(string /*vhost*/)
{
mw_sleep = _srs_config->get_mw_sleep_ms(req->vhost);
int sleep_ms = _srs_config->get_mw_sleep_ms(req->vhost);
// when mw_sleep changed, resize the socket send buffer.
change_mw_sleep(sleep_ms);
return ERROR_SUCCESS;
}
@ -513,8 +518,7 @@ int SrsRtmpConn::playing(SrsSource* source)
// use isolate thread to recv,
// @see: https://github.com/winlinvip/simple-rtmp-server/issues/217
SrsQueueRecvThread trd(rtmp,
SRS_CONSTS_RTMP_PULSE_TIMEOUT_US / 1000);
SrsQueueRecvThread trd(rtmp, SRS_PERF_MW_SLEEP);
// start isolate recv thread.
if ((ret = trd.start()) != ERROR_SUCCESS) {
@ -558,10 +562,15 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd)
// initialize other components
SrsPithyPrint pithy_print(SRS_CONSTS_STAGE_PLAY_USER);
SrsMessageArray msgs(SYS_CONSTS_MAX_PLAY_SEND_MSGS);
SrsMessageArray msgs(SRS_PERF_MW_MSGS);
bool user_specified_duration_to_stop = (req->duration > 0);
int64_t starttime = -1;
// setup the mw config.
// when mw_sleep changed, resize the socket send buffer.
mw_enabled = true;
change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost));
while (true) {
// to use isolate thread to recv, can improve about 33% performance.
// @see: https://github.com/winlinvip/simple-rtmp-server/issues/196
@ -602,6 +611,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd)
srs_verbose("sleep for no messages to send");
st_usleep(mw_sleep * 1000);
}
srs_info("got %d msgs, mw=%d", count, mw_sleep);
// reportable
if (pithy_print.can_print()) {
@ -980,6 +990,46 @@ int SrsRtmpConn::process_play_control_msg(SrsConsumer* consumer, SrsMessage* msg
return ret;
}
void SrsRtmpConn::change_mw_sleep(int sleep_ms)
{
if (!mw_enabled) {
return;
}
// the bytes:
// 4KB=4096, 8KB=8192, 16KB=16384, 32KB=32768, 64KB=65536,
// 128KB=131072, 256KB=262144, 512KB=524288
// the buffer should set to sleep*kbps/8,
// for example, your system delivery stream in 1000kbps,
// sleep 800ms for small bytes, the buffer should set to:
// 800*1000/8=100000B(about 128KB).
// other examples:
// 2000*3000/8=750000B(about 732KB).
// 2000*5000/8=1250000B(about 1220KB).
int kbps = 5000;
int socket_buffer_size = sleep_ms * kbps / 8;
int fd = st_netfd_fileno(stfd);
int onb_sbuf = 0;
socklen_t sock_buf_size = sizeof(int);
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &onb_sbuf, &sock_buf_size);
// socket send buffer, system will double it.
int nb_sbuf = socket_buffer_size / 2;
// set the socket send buffer when required larger buffer
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, sock_buf_size) < 0) {
srs_warn("set sock SO_SENDBUF=%d failed.", nb_sbuf);
}
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, &sock_buf_size);
srs_trace("mw changed %d=>%d, max_msgs=%d, esbuf=%d, sbuf %d=>%d",
mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, socket_buffer_size,
onb_sbuf, nb_sbuf);
mw_sleep = sleep_ms;
}
int SrsRtmpConn::check_edge_token_traverse_auth()
{
int ret = ERROR_SUCCESS;

View file

@ -73,6 +73,8 @@ private:
SrsKbps* kbps;
// the MR(merged-write) sleep time in ms.
int mw_sleep;
// the MR(merged-write) only enabled for play.
int mw_enabled;
public:
SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd);
virtual ~SrsRtmpConn();
@ -102,6 +104,7 @@ private:
virtual int handle_publish_message(SrsSource* source, SrsMessage* msg, bool is_fmle, bool vhost_is_edge);
virtual int process_publish_message(SrsSource* source, SrsMessage* msg, bool vhost_is_edge);
virtual int process_play_control_msg(SrsConsumer* consumer, SrsMessage* msg);
virtual void change_mw_sleep(int sleep_ms);
private:
virtual int check_edge_token_traverse_auth();
virtual int connect_server(int origin_index, st_netfd_t* pstsock);

View file

@ -216,7 +216,7 @@ int SrsMessageQueue::dump_packets(int max_count, SrsMessage** pmsgs, int& count)
} else {
// erase some vector elements may cause memory copy,
// maybe can use more efficient vector.swap to avoid copy.
// @remark for the pmsgs is big enough, for instance, SYS_CONSTS_MAX_PLAY_SEND_MSGS 128,
// @remark for the pmsgs is big enough, for instance, SRS_PERF_MW_MSGS 128,
// the rtmp play client will get 128msgs once, so this branch rarely execute.
msgs.erase(msgs.begin(), msgs.begin() + count);
}

View file

@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 53
#define VERSION_REVISION 55
// server info.
#define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_ROLE "origin/edge server"

View file

@ -60,7 +60,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRS_PERF_MERGED_READ
// the default config of mr.
#define SRS_PERF_MR_ENABLED false
#define SRS_PERF_MR_SLEEP 500
#define SRS_PERF_MR_SLEEP 350
/**
* the MW(merged-write) send cache time in ms.
@ -73,9 +73,26 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* @remark the socket send buffer default to 185KB, it large enough.
* @see https://github.com/winlinvip/simple-rtmp-server/issues/194
* @see SrsConfig::get_mw_sleep_ms()
* @remark the mw sleep and msgs to send, maybe:
* mw_sleep msgs iovs
* 350 24/48 48/84
* 500 24/48 48/84
* 800 42/64 84/128
* 1000 64/85 128/170
* 1200 65/86 130/172
* 1500 87/110 174/220
* 1800 106/128 212/256
* 2000 134/142 268/284
*/
// the default config of mw.
#define SRS_PERF_MW_SLEEP 500
#define SRS_PERF_MW_SLEEP 350
/**
* how many msgs can be send entirely.
* for play clients to get msgs then totally send out.
* for the mw sleep set to 1800, the msgs is about 128.
* @remark, recomment to 156.
*/
#define SRS_PERF_MW_MSGS 156
/**
* how many chunk stream to cache, [0, N].

View file

@ -98,42 +98,28 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// always use fmt0 as cache.
//#define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5
/**
* how many msgs can be send entirely.
* for play clients to get msgs then totally send out.
* for example, 25fps video, 40ms per video packet,
* while audio is 20ms per audio packet where 2/3 is audios,
* when SYS_CONSTS_MAX_PLAY_SEND_MSGS is 128, then
* we will send all 128*40ms/3=1706ms packets in a time,
* which should greater than the SRS_CONSTS_RTMP_PULSE_TIMEOUT_US
* (for example, 500ms), that is, we should:
* SYS_CONSTS_MAX_PLAY_SEND_MSGS * 40 / 3 >= SRS_CONSTS_RTMP_PULSE_TIMEOUT_US
* @remark, recomment to 128.
*/
#define SYS_CONSTS_MAX_PLAY_SEND_MSGS 128
/**
* for performance issue,
* the iovs cache, @see https://github.com/winlinvip/simple-rtmp-server/issues/194
* iovs cache for multiple messages for each connections.
* each iovc is 16bytes, sizeof(iovec)=16, suppose the chunk size is 64k,
* each message send in a chunk which needs only 2 iovec,
* so the iovs max should be (SYS_CONSTS_MAX_PLAY_SEND_MSGS * 16 * 2)
* suppose the chunk size is 64k, each message send in a chunk which needs only 2 iovec,
* so the iovs max should be (SRS_PERF_MW_MSGS * 2)
*
* @remark, SRS will realloc when the iovs not enough.
*/
#define SRS_CONSTS_IOVS_MAX (SYS_CONSTS_MAX_PLAY_SEND_MSGS * 32)
#define SRS_CONSTS_IOVS_MAX (SRS_PERF_MW_MSGS * 2)
/**
* for performance issue,
* the c0c3 cache, @see https://github.com/winlinvip/simple-rtmp-server/issues/194
* c0c3 cache for multiple messages for each connections.
* each c0 <= 16byes, suppose the chunk size is 64k,
* each message send in a chunk which needs only a c0 header,
* so the c0c3 cache should be (SYS_CONSTS_MAX_PLAY_SEND_MSGS * 16)
* so the c0c3 cache should be (SRS_PERF_MW_MSGS * 16)
*
* @remark, SRS will try another loop when c0c3 cache dry, for we cannot realloc it.
* so we use larger c0c3 cache, that is (SYS_CONSTS_MAX_PLAY_SEND_MSGS * 32)
* so we use larger c0c3 cache, that is (SRS_PERF_MW_MSGS * 32)
*/
#define SRS_CONSTS_C0C3_HEADERS_MAX (SYS_CONSTS_MAX_PLAY_SEND_MSGS * 32)
#define SRS_CONSTS_C0C3_HEADERS_MAX (SRS_PERF_MW_MSGS * 32)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

View file

@ -645,7 +645,7 @@ int SrsProtocol::do_send_messages(SrsMessage** msgs, int nb_msgs)
// we donot use the complex basic header,
// ensure the basic header is 1bytes.
if (msg->header.perfer_cid < 2) {
srs_warn("change the chunk_id=%d to default=%d",
srs_info("change the chunk_id=%d to default=%d",
msg->header.perfer_cid, RTMP_CID_ProtocolControl);
msg->header.perfer_cid = RTMP_CID_ProtocolControl;
}
@ -682,6 +682,10 @@ int SrsProtocol::do_send_messages(SrsMessage** msgs, int nb_msgs)
// for we donot know how many messges maybe to send entirely,
// we just alloc the iovs, it's ok.
if (iov_index >= nb_out_iovs - 2) {
srs_warn("resize iovs %d => %d, max_msgs=%d",
nb_out_iovs, nb_out_iovs + SRS_CONSTS_IOVS_MAX,
SRS_PERF_MW_MSGS);
nb_out_iovs += SRS_CONSTS_IOVS_MAX;
int realloc_size = sizeof(iovec) * nb_out_iovs;
out_iovs = (iovec*)realloc(out_iovs, realloc_size);
@ -732,6 +736,8 @@ int SrsProtocol::do_send_messages(SrsMessage** msgs, int nb_msgs)
if (iov_index <= 0) {
return ret;
}
srs_info("mw %d msgs in %d iovs, max_msgs=%d, nb_out_iovs=%d",
nb_msgs, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs);
// send by writev
// sendout header and payload by writev.