stream mode如何实现单server千万qps
2024-05-14 本文已影响0人
谭英智
一般来说server单机,实现30w qps算很高了,
但是受摩尔定律的限制,单核的性能已经发挥到了极致,市场上,也出现了大量多核的服务器
那么对于单线程epoll的服务器架构变得不再适用
因为它没办法发挥出多核机器的极限性能
code
server:
while(true) {
wait_fd_event(fds);
for(auto& fd: fds) {
buf = read(fd);
handle(buf);
}
}
client:
while(true) {
write(fd, buf);
}
read/write system call latency
读写fd,一般耗时3us
那么1秒内,最多发生30w次的读或者写
这也导致了单线程,读或者写fd的次数,上限只有30w/s
引入多线程
server:
//thread 1: 30w/s
while(true) {
wait_fd_event(fds1);
for(auto& fd: fds) {
buf = read(fd);
enqueue(buf); // lock free queue
}
}
//thread 2: 30w/s
while(true) {
wait_fd_event(fds2);
for(auto& fd: fds) {
buf = read(fd);
enqueue(buf); // lock free queue
}
}
//thread 3: 30w/s
while(true) {
wait_fd_event(fds3);
for(auto& fd: fds) {
buf = read(fd);
enqueue(buf); // lock free queue
}
}
//main thread:
while(true) {
dequeue(buf); // lock free queue
set_order(buf);
handle(); //handle first order message
}
client:
// main thread
while(true) {
buf->seq = seq;
seq++;
enqueue(buf); //lock free queue
}
// thread 1
while(true) {
dequeue(buf) //lock free queue
write(fd1, buf);
}
// thread 1
while(true) {
dequeue(buf) //lock free queue
write(fd2, buf);
}
// thread 1
while(true) {
dequeue(buf) //lock free queue
write(fd3, buf);
}
启动四个线程
每个client与server建立3个fd
client在消息体中包含seq,用来定序
client主线程通过无锁队列发送消息给三个网络线程
网络线程从无锁队列中获取消息,并发送到server
每个线程的qps是30w/s
那么三个网络处理线程,就是90w/s
总结
因此通过上面的分析
如果需要实现1kw qps
需要启用30个网络线程
client与server需要建立30个socket
最终实现千万qps server的需求