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的需求

上一篇 下一篇

猜你喜欢

热点阅读