在对低延迟网络进行了一些基本的googling之后,我列出了程序员和系统设计人员在开始低延迟网络时应该考虑的问题:
硬件、系统和协议的设计必须考虑together
H 111的交换机,使用多个NIC,特别是对于下游和上游数据流,
减少了由其他设备或软件生成的IRQ的数量(简而言之,如果它们不是必需的话就删除它们)
减少互斥和条件的使用。相反,在可能的情况下使用无锁编程技术。利用架构的CAS功能。(与多线程设计相比,没有锁的containers)
Consider单线程-上下文交换机非常expensive.
Understand,并适当地利用了体系结构的缓存系统(L1/L2、RAM等)
更喜欢完全控制内存管理,而不是委托给垃圾Collectors
Use良好质量的电缆,保持电缆尽可能短,减少扭曲和卷曲
的数量。
我的问题是:,我想知道,在进行低延迟网络时,SOers认为其他的事情是重要的。
请批评上述任何一点。
发布于 2011-05-19 22:11:58
电缆的质量通常是一种红鲱鱼。我会更多地考虑连接一个网络分析器,看看你是否有足够的重传来关心。如果你得到了很多,试着隔离它们发生的地方,并更换引起问题的电缆。如果您没有收到导致重传的错误,则电缆(实际上)对延迟没有影响。
NIC和(特别是)交换机上的大型缓冲区本身不会减少延迟。实际上,要真正最小化延迟,通常需要使用最小的缓冲区,而不是更大的缓冲区。存储在缓冲区中而不是被处理的数据会立即增加延迟。老实说,这是很少值得担心的,但仍然。如果您真的想将延迟最小化(并且对带宽关心得更少),那么使用集线器比使用交换机更好(这有点难找到了,但是只要网络拥塞足够低,延迟肯定就会很低)。
多个NIC可以极大地帮助带宽,但是它们对延迟的影响通常是非常小的。
编辑:不过,我的主要建议是获得一种规模感。减少一英尺的网络电缆可以节省大约纳秒的时间--与通过几种汇编语言指令加快数据包处理速度的一般顺序相同。
底线:和任何其他优化一样,要想取得很大的进展,需要在减少延迟之前测量出延迟的位置。在大多数情况下,减少线缆长度(使用一个例子)不会产生足够的差别来引起注意,这仅仅是因为它开始的速度很快。如果某件事情一开始需要10微秒,你所能做的任何事情都不会比10微秒更快,所以除非你拥有如此之快的东西,除非你拥有的东西如此之快,以至于你的时间中有相当大的比例,否则它是不值得攻击的。
发布于 2011-08-02 04:25:48
其他:
1:使用userland网络栈
2:服务中断在与处理代码相同的套接字上(共享缓存)
3:喜欢固定长度的协议,即使它们的字节稍大(解析速度更快)
4:忽略网络字节顺序约定,只使用本机排序。
5:不要在例程和对象池中分配(尤指)。垃圾收集语言)
6:尽量防止字节复制(在TCP发送中很难)
7:使用直通切换模式。
8:攻击网络堆栈以删除TCP慢速启动。
9:为一个巨大的TCP窗口做广告(但不要使用它),这样对方就可以一次拥有大量的信息包。
10:关闭NIC合并,特别是发送(如果需要在应用程序栈中打包)
11:更喜欢铜而不是光学
我可以继续,但这应该会让人们思考
我不同意的是:
1:网络电缆很少是问题,除非是坏了(在电缆类型上有例外)。
发布于 2011-08-02 04:48:33
这可能有点明显,但这是一种我很满意的技术,它适用于UDP和TCP,因此我将介绍它:
1)不要将大量的传出数据排队:具体来说,尽量避免将内存中的数据结构编组到序列化的字节缓冲区中,直到最后可能的时刻。相反,当您的发送套接字选择()s作为写准备时,此时将相关/脏数据结构的当前状态夷为平地,并立即将它们发送出去。这样,数据就永远不会在发送端“积累”。(此外,请确保将套接字的SO_SNDBUF设置为尽可能小,以尽量减少内核内的数据排队)
2)您可以在接收端执行类似的操作,假设您的数据以某种方式进行键控:不需要执行(读取数据消息、处理数据消息、重复)循环,您可以读取所有可用的数据消息,只需将它们放入键控数据结构(例如哈希表),直到套接字没有更多的数据可供读取,然后(然后)迭代数据结构并处理数据。这样做的好处是,如果您的接收客户端必须对接收到的数据执行任何重要的处理,那么将自动/隐式删除过时的传入消息(因为它们的替换将覆盖键控数据结构中的消息),因此传入的数据包不会在内核的传入消息队列中备份。(当然,您可以让内核的队列填充并丢弃数据包,但是程序最终会读取“旧”数据包,并丢弃“更新的”数据包,这通常不是您想要的)。作为进一步的优化,您可以让I/O线程将键控数据结构交给单独的处理线程,这样I/O就不会被处理所阻碍。
https://stackoverflow.com/questions/6065262
复制相似问题