zoukankan      html  css  js  c++  java
  • 整理:[保留] [算法] 超高性能网络编程, Asynchronous network I/O

    http://bbs.chinaunix.net/viewthread.php?tid=1214570&extra=&page=1

    [保留]  [算法] 超高性能网络编程, Asynchronous network I/O
    为什么是超高性能?
    因为常见资料太过普通, 没有讨论到核心问题.


    本贴目的:
    讨论Linux下的高性能网络编程.
    热烈欢迎参加讨论, 或提供关键的技术参考资料. 最新的资料确实不好找.


    项目背景:
    流媒体交换服务器, 单台服务器配置4个1Gbps 网口.
    要求客户连接超过1024, (单客户约512kbps),  网络满负载运行, 实时性好.

    参考产品:
    华为与3COM合作的 杭洲H3C公司的 MS8000媒体交换服务器, 最高并发量只达到1024路.  使用双核CPU,4个 1Gbps网口.
    MS8000媒体交换服务器

    H3C还开发了面向电信高端的 媒体交换机.  基本框架应该是嵌入式, 在协议栈中实现流媒体交换. 在网络性能上应该是马马虎虎.
    H3C UMS9005 通用媒体交换机

    网络并发能力理论上应该达到物理极限.
    所以发此贴, 还望国内的网络高手不吝赐教!    H3C MS8000的网络性能也不见得就最优化.


    重要资料:

    [1]、 Dan Kegel - "The C10K problem"
            http://www.kegel.com/c10k.html
            主题:   Web servers 同时处理10000个客户端的技术问题,包括不同OS.

    [2]、 Improving (network) I/O performance ...
    http://www.xmailserver.org/linux-patches/nio-improve.html

            epoll模型原理及性能测量结论.

    [3]、 Drepper's New Network Interface (proposal for Linux 2.6+)
    At OLS 2006, Ulrich Drepper proposed a new high-speed asynchronous networking API. See:
    his paper, "The Need for Asynchronous, Zero-Copy Network I/O"
    his slides :http://people.redhat.com/drepper/newni-slides.pdf
    LWN article from July 22 : http://lwn.net/Articles/192410/


    [4]、Benchmarking BSD and Linux
    http://bulk.fefe.de/scalability/

    在BSD 和Linux系统下,一系列网络性能的测量对比。


    注释:

    AIO:  Asynchronous I/O;

    以上的资料只到2006年底, 没找到最新的.

    epoll 只是事件通知模型.  没有异步IO. 使用epoll 仍然需要用户处理缓存.
    Linux 下目前的AIO实现不支持socket, 可以支持文件AIO.


    关于windows IOCP:   对用户来讲是异步模型. 但是, 其实现并不是真正的异步.
    真正的AIO是由kernel完成, 不需要线程切换, 应当能实现Zero-Copy.

    以下是在跟贴中提供的资料,整理一下方便使用:


    [1]、High-Performance Server Architecture
    http://pl.atyp.us/content/tech/servers.html


    [2]、 高性能网络编程,第 1 部分: 最大程度地利用您的网络资源
    http://www.ibm.com/developerwork ... perform1/index.html

    高性能网络编程,第 2 部分: 加快客户机和服务器的处理速度
    http://www.ibm.com/developerwork ... perform2/index.html

    3楼 发表于 2008-7-17 11:09
    我觉得性能的提升应该是多方面的。下面有一个资料:
    http://www.ibm.com/developerwork ... perform2/index.html

    4楼 发表于 2008-7-17 11:12


    QUOTE:
    原帖由 scutan 于 2008-7-17 11:09 发表
    我觉得性能的提升应该是多方面的。下面有一个资料:
    http://www.ibm.com/developerwork ... perform2/index.html

    谢谢。
    是有很多方而, 比如自己的缓存问题,mbuf /sk_buff。
    但核心的还是通信模型的问题。如果是真正的异步模型就最理想。

    9楼 发表于 2008-7-17 11:27


    QUOTE:
    原帖由 yunhappy 于 2008-7-17 11:24 发表
    这么看来 linux 2.6 的 epoll 效率很稳定嘛

    是.
    linux 2.6 几乎在所有网络操作的时候,效率都是 O(1), 不会因数客户数量上升而降低效率。

    11楼 发表于 2008-7-17 12:42
    其实在linux平台下异步模型实际都是半同步和半异步这种模式.
    epoll还是由单线程来操作的.

    16楼 发表于 2008-7-17 15:10
    LZ发的那些BSD和Linux的比较已经很老了

    现在FreeBSD7.0出来了,多线程以及userland的jemalloc性能已经相当强了。

    还有请问LZ,是想写个高并发的呢?还是高相应的呢?

    高并发的话,只拿着epoll和kqueue是不够了,需要一个非常合理完善的框架。建议看看<POSA2>

    其实所谓高性能是在整个框架的性能,而绝对不仅仅是两个系统调用的事。

    17楼 发表于 2008-7-17 16:03


    QUOTE:
    原帖由 zsniper 于 2008-7-17 15:10 发表
    LZ发的那些BSD和Linux的比较已经很老了

    现在FreeBSD7.0出来了,多线程以及userland的jemalloc性能已经相当强了。

    还有请问LZ,是想写个高并发的呢?还是高相应的呢?

    高并发的话,只拿着epoll和kqueue ...

    现在最重要的是网络I/O的并发吞吐量问题.  古老的socket API 有性能限制, 像send()和recv()至少需要拷贝一次缓存. 所以才有那么多人讨论AIO和Zero-Copy. 当然还有其它并发性能问题.

    这个BSD和Linux的测试是2003年左右.  可以说明当时linux在网络上的领先.  测试还证明OpenBSD根本不适合网络服务器. 当然BSD会有改进.

    18楼 发表于 2008-7-17 16:08
    难道现在有什么可以脱离write()和read()的方法吗??

    至少要从mbuf拷贝到用户空间。。如何zero-copy????

    AIO只是一种事件通知方法,内核告诉应用程序有数据可读或者有数据可写,之后再read()和write(),难道你能zero-copy??

    现在能做的只是在write()和read()的基础上,搭建出高性能的框架~

    19楼 发表于 2008-7-17 16:20
    回复 #18 zsniper 的帖子

    这就是为什么这么多人讨论研究socket的并发问题和改进方案.
    Ulrich Drepper 在论文里提议的方案是直接访问DMA, read()/receive()只需要返回一个DMA内存指针.
    这些是研究性内容, 实现思路可以参考.

    20楼 发表于 2008-7-17 16:53
    其实,我觉得高并发的瓶颈在于你上层的实现,而不在于底层的read().

    就我看来,花大精力放在上层实现,才有意义。

    还有就是,上层实现的时候,出现内存拷贝的情况很多,并不一定要不在乎系统底层的一点性能损失。

    当然这是我的愚见,LZ的想法很好,希望能研究出成果来。。。


    PS:支持键盘老农 , 因为kqueue性能真的很好,并且能支持普通文件(我不了解epoll)   。
    21楼 发表于 2008-7-17 17:09
    很是想知道 怎么控制epoll的超时.          

    有连接进来后, 这个 连接什么也不干, 怎么控制这个连接的超时呢?

    22楼 发表于 2008-7-17 17:09
    回复 #21 yunhappy 的帖子

    libevent可以解决超时问题,自己写的话,效率没有那么高,


    当然我也写过一个用红黑树实现的超时,效率不高。。。。


    我用的libevent-1.3的版本,他是用堆排序作的。可以参考一下。。

    23楼 发表于 2008-7-17 17:39
    我用epoll 测试过2W路的并发
    找4台设备, 每台5000路, 每秒发一个数据包(5000并发), 每个数据包1400Bytes.
    服务端CPU使用率40~50%

    服务器配置: Intel(R) Pentium(R) 4 CPU 3.00GHz 双核

    25楼 发表于 2008-7-17 17:49
    kqueue可以管网络,文件,事件用的很爽,没iocp那么累还要考虑同步,iocp下对多个连接在做广播时真的很难受。但俩者在功能和性能差不多,iocp也可以管文件读取。epoll据传说只管socket其他好像不行,没有深入研究。一般情况下,程序运行的好坏跟写程序的人有关系,就系统kqueue和iocp俩者的差别一般很难比较的出来。

    对数据在传递时用拷贝还传指针,指针会快很多,但一般我还会去拷贝,因为传指针在多线程下不确定性太大,安全第一。在我做的项目中3000-4000个客户端占用资源最厉害的是数据库,其他现在的占用资源很少。

    26楼 发表于 2008-7-17 17:50


    QUOTE:
    原帖由 cookis 于 2008-7-17 17:39 发表
    我用epoll 测试过2W路的并发
    找4台设备, 每台5000路, 每秒发一个数据包(5000并发), 每个数据包1400Bytes.
    服务端CPU使用率40~50%

    服务器配置: Intel(R) Pentium(R) 4 CPU 3.00GHz 双核

    你做的反射还是广播。
    27楼 发表于 2008-7-17 17:51
    回复 #24 cookis 的帖子

    高深 是指通过硬件控制么?
    29楼 发表于 2008-7-17 17:55


    QUOTE:
    原帖由 yunhappy 于 2008-7-17 17:51 发表
    高深 是指通过硬件控制么?

    你的客户端跟服务器之间没有心跳机制吗..我就是说的这个..

    30楼 发表于 2008-7-17 17:56


    QUOTE:
    原帖由 键盘老农 于 2008-7-17 17:50 发表

    你做的反射还是广播。

    服务器只收, 因为当时主要是测试仪epoll的接收能力. TCP模式.
    31楼 发表于 2008-7-17 20:28
    回复 #24 cookis 的帖子

    服务器上不需要用心跳来控制超时,只需要记录每个socket最后一次通信的时间戳,只需要用红黑树记录这些点,设定的时间到了,就进行超时处理,在我的思路中,心跳只是超时处理函数的一种。
    32楼 发表于 2008-7-17 22:02
    回复 #23 cookis 的帖子

    10w并发也测试过,嘿嘿,客户端不够用,没继续加了,epoll支持楼主1024并发完全绰绰有余.

    就像楼上有位大哥说的,瓶颈肯定在应用层,保证好应用层代码的性能就行,没必要在i/o模型上钻太多牛角尖.

    33楼 发表于 2008-7-17 23:55
    特定平台上最优的IO模型几乎是周知的,我觉得讨论一下高性能服务器的进程/线程模型更实在。
    34楼 发表于 2008-7-18 09:10
    3.0GHz的CPU, 配上4个1Gbps网卡,理论上有4Gbps的网络I/O. 瓶颈会在哪?
    缓存拷贝的开销的很大的. 线程切换代价也大. 多线程比较适合需要阻塞的场合.

    通信模型是只能依赖于OS, 剩下的是应用层.
    我现在的思路,只有选择epoll, 然后应用层协议栈参考TCP/IP, sk_buff/mmap.

    据我查的资料, UNIX-like操作系统的网络I/O还没有实现内核级的异步. 如果把epoll封装一下,看起来也会像kqueue或iocp.
    35楼 发表于 2008-7-18 09:28


    QUOTE:
    原帖由 zsniper 于 2008-7-17 17:09 发表
    libevent可以解决超时问题,自己写的话,效率没有那么高,


    当然我也写过一个用红黑树实现的超时,效率不高。。。。


    我用的libevent-1.3的版本,他是用堆排序作的。可以参考一下。。

    谢谢各位!
    用开源库首先会增加函数堆栈. 像ACE虽然适跨合平台,但也会有代价.   libevent应该是个不错的选择.
    36楼 发表于 2008-7-18 09:32


    QUOTE:
    原帖由 fm971 于 2008-7-18 09:10 发表
    3.0GHz的CPU, 配上4个1Gbps网卡,理论上有4Gbps的网络I/O. 瓶颈会在哪?
    缓存拷贝的开销的很大的. 线程切换代价也大. 多线程比较适合需要阻塞的场合.

    通信模型是只能依赖于OS, 剩下的是应用层.
    我现在的思路 ...

    多线程适合阻塞的场合???谬论!!!!

    看过HAHS,LF这些框架吗?再次建议你多看看POSA2

    还需要说明的是,epoll本身就是以kqueue为蓝板开发的,所以在原理上kqueue和epoll一样,但不等同于IOCP,

    其实IOCP已经是一种框架了,而kqueue和epoll只是一种内核通知应用程序事件的API。

    想要封装epoll,其实就是做个框架,跟你本身做底层的想法又冲突了,请问LZ,你到底想做什么???
    37楼 发表于 2008-7-18 10:02


    QUOTE:
    原帖由 cookis 于 2008-7-17 17:41 发表
    这个得通过你应用层的心跳来控制吧..

    心跳不能处理那些恶意客户端,连上来什么事情也不做的,只回复你的心跳数据包~,占着你的socket

    所以说,心跳只是一个理论的方法,实际上需要一些其他技术。
    38楼 发表于 2008-7-18 10:35
    回复 #31 zsniper 的帖子

    就像QQ msn 都有心跳, 让服务器知道它们还活着.. 而不是网络中断, 或主机已经断电, 或程序崩溃, 这样才好管理这些client,
    而不是一直持有它们所占的资源.

    我昨晚看了一下livevent 的 active timeout 机制, 它类似ACE的Heap_Timer的实现, 用堆排序, 将距离超时最近的放在顶端.
    你为什么用红黑树呢, 红黑树只是查找快一些, 但timeout这种机制只是需要得到最大或最小的元素, 堆结构正适合,


    我没有细看. 我猜libevet只是检测 是否在限定时间内收到第一个数据包. 是吧..

    但如果有大量的无效的连接上来. 也发了一些程序不认识的数据, 那应用程序也是没有办法的.

    我觉得这最好还是由应用层来控制, 为每一次会话作一个状态机, 当收到连接时, 生成一个会话对象, 由定时器来定时检测每个状态是否超时.
    这些通信库提供的功能越简单越高效, 越稳定, 况且又不是所有人都有那样的需求.
    39楼 发表于 2008-7-18 10:38


    QUOTE:
    原帖由 zsniper 于 2008-7-18 10:02 发表

    心跳不能处理那些恶意客户端,连上来什么事情也不做的,只回复你的心跳数据包~,占着你的socket

    所以说,心跳只是一个理论的方法,实际上需要一些其他技术。

    你的心跳应该定制一个消息格式吧..恶意连接怎么会知道这个格式呢.
    40楼 发表于 2008-7-18 10:38


    QUOTE:
    原帖由 zsniper 于 2008-7-18 09:32 发表

    多线程适合阻塞的场合???谬论!!!!

    看过HAHS,LF这些框架吗?再次建议你多看看POSA2

    还需要说明的是,epoll本身就是以kqueue为蓝板开发的,所以在原理上kqueue和epoll一样,但不等同于IOCP,
    ...

    多谢指正. 我的目标当然是要实现最大的网络I/O吞吐能力.

    HAHS/LF/POSA2有它的适应场合. 但不是用在这种纯粹的网络I/O.
    做以前的项目没看过mbuf,HAHS, 但我的实现思路是一样的.
    有些人把事件通知模型封装成类似的异步模型. 我也不了解kqueue原来是事件. 不过像IOCP的效率也已经不错了.
    41楼 发表于 2008-7-18 10:45


    QUOTE:
    原帖由 cookis 于 2008-7-18 10:35 发表
    就像QQ msn 都有心跳, 让服务器知道它们还活着.. 而不是网络中断, 或主机已经断电, 或程序崩溃, 这样才好管理这些client,
    而不是一直持有它们所占的资源.

    我昨晚看了一下livevent 的 active timeout 机制,
    ...........
    我觉得这最好还是由应用层来控制, 为每一次会话作一个状态机, 当收到连接时, 生成一个会话对象, 由定时器来定时检测每个状态是否超时.
    这些通信库提供的功能越简单越高效, 越稳定, 况且又不是所有人都有那样的需求. ...

    想法不错.  在少量的线程里面, 甚至单线程, 要处理上万个socket, 你说这个定时器还能怎么实现?
    我的理解也只有排序和查找.
    42楼 发表于 2008-7-18 10:51
    回复 #40 fm971 的帖子

    能否讲一下 sk_buff 在什么环境下使用, 有什么效果?

    43楼 发表于 2008-7-18 10:52


    QUOTE:
    原帖由 cookis 于 2008-7-18 10:35 发表
    就像QQ msn 都有心跳, 让服务器知道它们还活着.. 而不是网络中断, 或主机已经断电, 或程序崩溃, 这样才好管理这些client,
    而不是一直持有它们所占的资源.

    我昨晚看了一下livevent 的 active timeout 机制,  ...

    红黑树难道不能知道最小值和最大值吗??

    还有我也说了,这是我的效率很低的实现方法。

    我想这应该比心跳来的更灵活吧~

    我现在的实现方法,就是基于libevent的超时机制,超时 后再调用自己设定的函数,发出确认数据包,没有收到时,就close();

    44楼 发表于 2008-7-18 10:56
    回复 #41 fm971 的帖子

    如果要单线程的话. 定时器的驱动就得是epoll 或select了.
    只排序就行了. 不用查找. 我们只需要得到与当前时间相差最大的定时器对象就可以了.
    45楼 发表于 2008-7-18 11:00
    回复 #43 zsniper 的帖子

    我没有说红黑树得不到最大值和最小值. 我只是想说堆结构更适合这种只需要最大值和最小值的需求

    其实仔细想想. 如果为每个连接做一个超时机制. 还不如单独做一个定时器来定时检查所有的连接是否超时.
    这样唤醒epoll 或kqueue的机会要少得多. 也就是epoll 或 kqeueu的处理非socket事件的压力要少得多.
    46楼 发表于 2008-7-18 11:04
    回复 #45 cookis 的帖子

    我觉得自己写效率不是很高,因为技术还达不到,

    所以我就建议用libevent.

    还有在我的程序里面,只要接受到封包格式错误的数据包,我就认为这是非法数据包,直接close(),所以不用担心客户端不断发送恶意数据包的情况。
    47楼 发表于 2008-7-18 11:07
    回复 #46 zsniper 的帖子

    我觉得没什么神秘的..只要你用对了算法. 效率跟他一样.

    我想请教一个问题. 我在libevent中没有看到互斥.  那么它是怎么运转event_loop 的. 如果我有新的socket要注册进去怎么办
    而且我整个服务也不可能只有一个线程啊.
    48楼 发表于 2008-7-18 11:26
    回复 #47 cookis 的帖子

    event_loop就是单线程的阿~

    localsocket就是等待accept事件,新的socket进来后,再通过回调函数设置读写事件,加入eventbase
    49楼 发表于 2008-7-18 11:33
    回复 #48 zsniper 的帖子

    OK

    event_loop run with thread1 

    业务逻辑肯定运行在另外一个线程thread2. 如果thread2 想注册或先移除一个socket.
    不能直接操作event_list吧.
    50楼 发表于 2008-7-18 11:41
    回复 #49 cookis 的帖子

    业务逻辑在上层完成,完成后让IO_MAIN_THREAD处理注册或先移除一个socket

    之间用队列联系起来,

    这就是所谓的HAHS模式。

    51楼 发表于 2008-7-18 12:19
    回复 #50 zsniper 的帖子

    no..no.

    我还是无法理解. 在没有互斥的情况下. 其他线程怎么通知所谓的 IO_MAIN_THREAD 注册或移除 socket
    53楼 发表于 2008-7-18 15:12
    linux最新的内核有实现真正的AIO吗?
    54楼 发表于 2008-7-18 15:59


    QUOTE:
    原帖由 cookis 于 2008-7-18 10:51 发表
    能否讲一下 sk_buff 在什么环境下使用, 有什么效果?

    Linux 的 TCP/IP协议栈是用sk_buff, 主要满足协议栈对缓存的要求, 比如各层之间的透明.
    另一种被讨论的方法, 大概叫"分散/聚合缓存",  通过一次内存操作可以处理不同位置的内存分片.  会有优势的地方.
    55楼 发表于 2008-7-18 16:08


    QUOTE:
    原帖由 cookis 于 2008-7-18 11:33 发表
    OK

    event_loop run with thread1 

    业务逻辑肯定运行在另外一个线程thread2. 如果thread2 想注册或先移除一个socket.
    不能直接操作event_list吧.

    一般来说应该有锁操作.  libevent怎么实现我也不知道.
    做自己的协议栈一般不会用开源库, 比如说在嵌入式机的 IP/TCP/ 上再实现一层. 目前我也不用libevent.
    56楼 发表于 2008-7-18 16:17
    中小量链接用select

    大量用epoll等(操作系统依赖)
    58楼 发表于 2008-7-18 17:12
    呵呵,我现在做的东西跟楼主做的几乎一样,也是交换数据的,说说自己的一些看法。

    (1) I/O 模型的选择,

    epoll就一定好吗?  epoll最有用的就是ET模式,适合于那种有大量连接,但是有数据连接有限的情况,
    如果你有10000个连接,但是很不幸,这10000个连接全部都有数据,你还是得遍历一把进行处理,( 这里对ET模式下怎么处理数据就不讨论了)。

    这个和select, poll有什么区别。

    epoll还有比select, poll先进得地方, 就在于将fd得列表维护在内核中, 而select, poll是调用一次,传递一次, 这点epoll领先是没得说得。

    但是如果我是每个线程处理100个连接, 分10个线程来处理1000个连接, 那么上面得优点几乎可以不考虑。

    模型得选择要符合自己得程序架构,不见得最先进的东西就适合你

    (2) 使用非堵塞

    做为网络服务器, 堵塞I/O一般情况下不予考虑

    (3) 减少I/O操作和无谓的系统调用

    比如利用writev一次性写入多个数据, 减少write调用的次数.

    (4) tcp是双工的

    这点不要忽略掉, 数据转发程序就在于数据的转发速度, 这里我采用读和写分开线程的处理方式

    (5) 进程还是线程

    这个无关紧要,一个粒度和数据访问, 稳定性的问题。减少之间的相互影响,尽量没有关联, 比如减少对相关互斥数据的访问等等。

    (6) 尽量在设计上做到不需要同步

    比如使用环形?
    61楼 发表于 2008-7-18 17:26


    QUOTE:
    原帖由 unixpm 于 2008-7-18 17:12 发表

    这10000个连接全部都有数据,你还是得遍历一把进行处理,

    为什么要遍历一把.. epoll已经将活动的句柄全部返回了..剩下的是你自己定位的算法问题了..是遍历还是用fd索引
    65楼 发表于 2008-7-20 16:01
    实际的说,基于Generic OS(Linux/*nix/Windows)的Network I/O都存在理论速度上限的瓶颈,因为OS自身的开销(任务切换,虚拟内存转换等),总线的时延,较低的总线带宽等等都会大幅降低I/O性能,而这是软件本身无法解决的硬伤。

    如果你的方案确实需要处理非常大的流量,比如LZ前面提到的H3C的产品,建议还是采用硬件方案(NP、FPGA etc)

    个人认为,纯软件的方式,要想让实际处理能力接近理论值,是非常困难的,即使达到了,过低的收益比也会大幅度降低其价值。

    LZ提及的 "H3C UMS9005"从其官方资料推测来看,应该是基于H3C or HW某款较高端的数通产品开发而成的,通常这样的产品都是基于NP架构的(网络流量由快速的数据面处理,各个线路板之间采用高速交换网进行数据交换),和你提到的AIO没有啥关系,放在一起比没有任何意义。

    另外基于Linux/*nix的纯软件方案,在高可靠性(HA)上有其致命的硬伤,不可能用在关键业务上。
    66楼 发表于 2008-7-21 09:26


    QUOTE:
    原帖由 unixpm 于 2008-7-18 17:13 发表
    呵呵,我现在做的东西跟楼主做的几乎一样,也是交换数据的,说说自己的一些看法。

    (1) I/O 模型的选择,

    epoll就一定好吗?  epoll最有用的就是ET模式,适合于那种有大量连接,但是有数据连接有限的情况, ...

    不错.  有两个点很值得关注,  contect-switches, IP 分片.
    67楼 发表于 2008-7-21 09:53


    QUOTE:
    原帖由 Kendiv 于 2008-7-20 16:01 发表
    实际的说,基于Generic OS(Linux/*nix/Windows)的Network I/O都存在理论速度上限的瓶颈,因为OS自身的开销(任务切换,虚拟内存转换等),总线的时延,较低的总线带宽等等都会大幅降低I/O性能,而这是软件本身 ...

    多谢指点. 研究网络的也包括国外一些内核相关的专家。假设能实现 AIO/Zero-Copy当然就很理想。

    因为纯软件方案开发成本低、硬件成本低, 可以适合很多场合.

    UMS9005虽说是硬件方案,有它的可靠性等特性。但只能带4块业务板,每块板最大8Gbps。如果软件方案也接近8Gbps,就有得比了。
    软件方案相对来说是有它的可靠性等劣势。但是像OS里的TCP/IP协议栈也属于软件,可靠性是能经受考验的。
    68楼 发表于 2008-7-21 10:00


    QUOTE:
    原帖由 Kendiv 于 2008-7-20 16:01 发表
    实际的说,基于Generic OS(Linux/*nix/Windows)的Network I/O都存在理论速度上限的瓶颈,因为OS自身的开销(任务切换,虚拟内存转换等),总线的时延,较低的总线带宽等等都会大幅降低I/O性能,而这是软件本身 ...

    确实.. 软件费半天劲优化, 有时还不如多花点儿钱升级一下设备.
    69楼 发表于 2008-7-21 10:27


    QUOTE:
    原帖由 fm971 于 2008-7-21 09:53 发表
    ... 每块板最大8Gbps。如果软件方案也接近8Gbps,就有得比了。
    软件方案相对来说是有它的可靠性等劣势。但是像OS里的TCP/IP协议栈也属于软件,可靠性是能经受考验的。

    嗯,软件达到8Gbps?? 你用8块1G的网卡? 还是10块? 使用普通的小型机吗?(1U/2U)??? 那种分时复用的总线机制能达到8*1G=8Gbit?

    还有,我所指的可靠性并不是指协议栈是否可靠,比如当设备在线时,如果某个网口突然down掉,你如何处理?系统关键组件死掉后,是否能及时自动启动/恢复?

    还有就是是否能保证业务中断时间始终位于一个下限范围里?等等。
    70楼 发表于 2008-7-21 11:07


    QUOTE:
    原帖由 Kendiv 于 2008-7-21 10:27 发表


    嗯,软件达到8Gbps?? 你用8块1G的网卡? 还是10块? 使用普通的小型机吗?(1U/2U)??? 那种分时复用的总线机制能达到8*1G=8Gbit?

    还有,我所指的可靠性并不是指协议栈是否可靠,比如当设备在线时,如 ...

    你说的没错. 硬件版是有很多优势.  但是要用NP/ASIC架构我不知道要多少成本!

    他们的8Gbps也只是理论值.  如果用PC架构的高端服务器, IO能力还是不同的.
    71楼 发表于 2008-7-21 11:51
    嗯,性能和成本本来就是相互矛盾的东西,呵呵。

    72楼 发表于 2008-7-21 14:47
    这种硬件系统是怎么解决速度问题的。。
    76楼 发表于 2008-7-31 17:26
    可以肯定的说这不叫超高性能。单机50w~100w的连接同时在线,还勉强能称.按楼主描述的, 视频这样的东西,用select监视描述符,足够了。
    同样的系统调用,和逻辑结构,不同的程序员实现起来差别n大。。。
    77楼 发表于 2008-7-31 18:46


    QUOTE:
    原帖由 wyezl 于 2008-7-31 17:26 发表
    可以肯定的说这不叫超高性能。单机50w~100w的连接同时在线,还勉强能称.按楼主描述的, 视频这样的东西,用select监视描述符,足够了。
    同样的系统调用,和逻辑结构,不同的程序员实现起来差别n大。。。

    愿闻其详!
    80楼 发表于 2008-8-7 16:51
    sports.sinajs.cn  单机每秒可以处理15w+ http请求,支撑50w+  connections同时在线.在2cpu  4核机器上测试。
    hq.sinajs.cn  每天上百亿http请求。

    系统资源都比较空闲,负载比较低。。。

    sports.sinajs.cn单机每秒可以处理15w+ http请求,支撑50w+  connections同时在线.在2cpu  4核机器上测试。hq.sinajs.cn  每天上百亿http请求。系统资源都比较空闲,负载比较低。。。

    81楼 发表于 2008-8-9 02:26
    回复 #80 wyezl 的帖子

    你这个是网站是吧,跟H3C的东西完全是两码事,别人那是视频。
    83楼 发表于 2008-8-9 22:24
    回复 #81 idsel 的帖子

    看标题   超高性能网络编程, Asynchronous network I/O
    底层技术换汤不换药。
    84楼 发表于 2008-8-10 01:02
    回复 #83 wyezl 的帖子

    你的意思是一个服务器支持几万到几十万路视频?????呵呵~~

    85楼 发表于 2008-8-10 10:17
    似乎还没有很好的AIO实现吧
    glibc记得使用线程模拟的

    86楼 发表于 2008-8-10 20:59


    QUOTE:
    原帖由 idsel 于 2008-8-10 01:02 发表
    你的意思是一个服务器支持几万到几十万路视频?????呵呵~~

    哥们,这话我可没说。
    视频种东西,占用大量带宽,可能10k用户不到,1G带宽就跑满了。
    10k以下的服务,算不上 “高性能网络编程”,更不要说“超高了”。
    用epoll就相当于杀鸡用牛刀。
    要根据服务的特点去决定你要用什么网络i/o模型。
    视频服务的瓶颈并不在监视大量的闲散connections上。
    个人觉得,select 足够了。
    就更下象棋一样,卒子用好了,一样能将军。
    88楼 发表于 2008-8-28 08:56


    QUOTE:
    原帖由 wyezl 于 2008-8-7 16:51 发表
    sports.sinajs.cn  单机每秒可以处理15w+ http请求,支撑50w+  connections同时在线.在2cpu  4核机器上测试。
    hq.sinajs.cn  每天上百亿http请求。

    系统资源都比较空闲,负载比较低。。。

    "单机每秒可以处理15w+ http请求",取决于每个请求要做多少事情,如果每个请求的工作量都很小,那么只要用合适的方式做好accept就可以了。每秒要做14w次socket accept,这种应用比较罕见。
    “支撑50w+  connections同时在线”,这个在线是什么意思,http有在线的吗?逻辑上的login,有500w也没关系吧?

    “每天上百亿http请求”,按照24小时算是平均每秒11w,峰值估计是平均值的3-5倍,那么就是每秒30w到50w。数字比上面的例子大一点,不过关键点类似。


    我猜,sports.sinajs.cn和hq.sinajs.cn应该都是一个类似路由的东西吧,应该是负责分发请求的。一台机器来搞定所有事情,是不符合可扩展性的要求的。
    89楼 发表于 2008-8-28 09:06
    http://www.xmailserver.org/linux-patches/nio-improve.html

    测试说明dual PIII 1GHz, 256 Mb RAM的机器,每秒可以处理约27500个128字节的http请求。

    “2cpu  4核机器” 比 “dual PIII 1GHz”的性能高五倍,也算一个reasonable的数值吧。
    90楼 发表于 2008-9-9 17:52


    QUOTE:
    原帖由 wwwsq 于 2008-8-28 08:56 发表

    "单机每秒可以处理15w+ http请求",取决于每个请求要做多少事情,如果每个请求的工作量都很小,那么只要用合适的方式做好accept就可以了。每秒要做14w次socket accept,这种应用比较罕见。
    “支撑50w+   ...

    不是类似路由的东西,而是一个类似apache的东西。
    当然,如果我愿意,我可以稍微修改就能成为高效的类似路由的东西或者一个高效的代理服务器。
    低层技术都不变,作为什么服务,只是一种表现。


    50w+  connections , 就是说,有50w人都连接了这个服务器,而且每几秒可能都有一个请求,建立的连接会一直保持着。有走的有来的,50w是活着的连接。

    我们扩展性非常好,可以线性扩展。
    你的猜测都只有部分正确。
    肯定是没有自己动手写过这种东西。
    91楼 发表于 2008-9-9 18:00


    QUOTE:
    原帖由 wwwsq 于 2008-8-28 09:06 发表
    http://www.xmailserver.org/linux-patches/nio-improve.html

    测试说明dual PIII 1GHz, 256 Mb RAM的机器,每秒可以处理约27500个128字节的http请求。

    “2cpu  4核机器” 比 “dual PIII 1GHz”的性能高五 ...

    不reasonable,我怎么能实现呢。


    不过,这个效率我还能提高不少,以前取数据耽误不少时间,我要是愿意可以把取数据的效率提高50倍。
    等有人超过我了,我再做改进,现在懒得动。
    92楼 发表于 2008-9-9 18:07
    QQ服务器是怎样的架构?
    93楼 发表于 2008-9-9 19:17


    QUOTE:
    原帖由 wyezl 于 2008-9-9 17:52 发表

    不是类似路由的东西,而是一个类似apache的东西。
    当然,如果我愿意,我可以稍微修改就能成为高效的类似路由的东西或者一个高效的代理服务器。
    低层技术都不变,作为什么服务,只是一种表现。

    50w ...

    如果每秒15w的http请求是通过长连接实现的,那就比较好理解,我见过一个服务器每秒钟处理100w+的request,每个request大概十几个字节。

    据我所知accept的时候socket底层是要做很多分配buffer之类的体力活的,对于长连接,那么请求只是数据流。
    94楼 发表于 2008-9-9 19:19


    QUOTE:
    原帖由 wyezl 于 2008-9-9 18:00 发表

    不reasonable,我怎么能实现呢。

    不过,这个效率我还能提高不少,以前取数据耽误不少时间,我要是愿意可以把取数据的效率提高50倍。
    等有人超过我了,我再做改进,现在懒得动。

    取数据的效率提高50倍,是把accept和recv合并为一次内核操作吗?或者是把自己的程序变成一个kernel module ?
    95楼 发表于 2008-9-9 21:06


    QUOTE:
    原帖由 Kendiv 于 2008-7-20 16:01 发表
    实际的说,基于Generic OS(Linux/*nix/Windows)的Network I/O都存在理论速度上限的瓶颈,因为OS自身的开销(任务切换,虚拟内存转换等),总线的时延,较低的总线带宽等等都会大幅降低I/O性能,而这是软件本身 ...

    采用NP方案一般适合路由器这种IP层的处理。如果用NP来实现基于TCP的应用层(如web), 应该怎么架构呢?
    96楼 发表于 2008-9-10 15:06


    QUOTE:
    原帖由 cookis 于 2008-7-18 10:35 发表
    你为什么用红黑树呢, 红黑树只是查找快一些, 但timeout这种机制只是需要得到最大或最小的元素, 堆结构正适合

    使用复杂数据结构的话都有维护的成本, 多线程情况下, 还需要加锁处理
    不如设定一个超时轮询线程, 将所有现有的连接按时间戳排序, 然后依次排除
    97楼 发表于 2008-9-10 15:19


    QUOTE:
    原帖由 wwwsq 于 2008-9-9 19:17 发表

    我见过一个服务器每秒钟处理100w+的request,每个request大概十几个字节。

    ...

    哥们这服务器什么配置。网络I/O能达到这个数?
    98楼 发表于 2008-9-11 17:55


    QUOTE:
    原帖由 wyezl 于 2008-9-10 15:19 发表


    哥们这服务器什么配置。网络I/O能达到这个数?

    千兆网。

    100w乘以15字节=15M字节。
    99楼 发表于 2008-9-12 11:51


    QUOTE:
    原帖由 wyezl 于 2008-8-7 16:51 发表
    sports.sinajs.cn  单机每秒可以处理15w+ http请求,支撑50w+  connections同时在线.在2cpu  4核机器上测试。
    hq.sinajs.cn  每天上百亿http请求。

    系统资源都比较空闲,负载比较低。。。

    刚刚看到有人说, 受限于 non-paged Kernel memory, 4G 内存的 windows 系统, 同一时间 15w 左右的 socket 是极限
    不知道 linux/unix 的情况怎么样?
    100楼 发表于 2008-9-12 12:35


    QUOTE:
    原帖由 wwwsq 于 2008-9-11 17:55 发表

    千兆网。

    100w乘以15字节=15M字节。

    只知其一不知其二。

    先不算要维持一个http只连接,http头至少要70多字节,只发个hello world加起来也要80字节。

    就算只发15个字节,千兆网又能如何,普通网卡一秒也就只能发20w个包。
    按你的说法,我如果每个包一个字节,那么一秒发500w个包也很轻松了。。。

    就算我用最好的网卡,按我说的这样的普通服务器,每秒50w http处理量,绝对世上罕见,不过对我来说不是很难实现。
    101楼 发表于 2008-9-12 14:59


    QUOTE:
    原帖由 wyezl 于 2008-9-12 12:35 发表


    只知其一不知其二。

    先不算要维持一个http只连接,http头至少要70多字节,只发个hello world加起来也要80字节。

    就算只发15个字节,千兆网又能如何,普通网卡一秒也就只能发20w个包。
    按你的说法 ...

    并不是每个request都是一个单独的tcp packet,在一个数据包里面可以有很多个request。
    102楼 发表于 2008-9-13 12:04


    QUOTE:
    原帖由 fm971 于 2008-7-17 11:03 发表

    为什么是超高性能?
    因为常见资料太过普通, 没有讨论到核心问题.


    本贴目的:
    讨论Linux下的高性能网络编程.
    热烈欢迎参加讨论, 或提供关键的技术参考资料. 最新的资料确实不好找.


    项目背景:
    流媒 ...

    我谨慎怀疑这个AIO的效率问题, 估计只是用了一个独立线程循环发送罢了...
    104楼 发表于 2008-10-6 11:08


    QUOTE:
    原帖由 fm971 于 2008-7-21 11:07 发表

    你说的没错. 硬件版是有很多优势.  但是要用NP/ASIC架构我不知道要多少成本!

    他们的8Gbps也只是理论值.  如果用PC架构的高端服务器, IO能力还是不同的.

    真正的服务器和PC架构的还是不同,性能要好多

  • 相关阅读:
    凤凰架构-读书笔记
    《团队协作的五大障碍》笔记
    MongoDB基本操作命令一
    NBI可视化集成clickhouse,实现百亿级数据分析能力
    AI文本与图像数据集荟萃
    gitLab内网部署
    git管理子模块
    git基础使用
    linux内核数据结构之链表-再实现
    win10下安装linux子系统
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/1430200.html
Copyright © 2011-2022 走看看