低延迟网络技术和“子弹”

| 在对低延迟网络进行了一些基本的搜索之后,我提出了以下清单,程序员和系统设计人员在着手进行低延迟网络时应考虑的事项: 硬件,系统和协议的设计必须一起考虑 使用UDP而不是TCP开发协议并实现简单的确认,在应用程序级别重新发送逻辑 减少消耗或打包数据的进程或线程的上下文切换的数量(最好为零) 对操作系统使用最佳选择器(选择,队列,epoll等) 使用具有大量板载缓冲区(fifo)的高质量NIC和交换机 使用多个NIC,专门用于下游和上游数据流 减少其他设备或软件生成的IRQ的数量(如果不需要,则将其删除) 减少互斥量和条件的使用。而是尽可能使用无锁编程技术。利用该架构的CAS功能。 (无锁容器) 考虑单线程而不是多线程设计-上下文切换非常昂贵。 了解并正确利用架构的缓存系统(L1 / L2,RAM等) 建议完全控制内存管理,而不是委派给垃圾收集器 使用高质量的电缆,使电缆尽可能短,减少扭曲和卷曲的次数 我的问题:我想知道SO伙伴在开始低延迟网络时还有哪些其他重要的事情。 随时批评以上几点     
已邀请:
电缆质量通常是一种红色鲱鱼。我会想更多有关连接网络分析仪的信息,以查看您是否获得足够的重传数据来关心。如果数量很多,请尝试隔离发生故障的地方,并更换引起问题的电缆。如果没有出现导致重新传输的错误,则电缆对延迟几乎没有影响。 NIC和(尤其是)交换机上的大缓冲区本身不会减少延迟。实际上,为了真正减少延迟,通常需要使用最小的缓冲区,而不是较大的缓冲区。位于缓冲区而不是被处理的数据会立即增加延迟。说实话,它很少值得担心,但仍然值得。如果您真的想最小化延迟(并且不关心带宽),那么最好使用集线器而不是使用交换机(已经很难找到了,但是只要网络拥塞足够低,绝对可以降低延迟) 。 多个NIC可以极大地帮助带宽,但是它们对延迟的影响通常很小。 编辑:不过,我的主要建议是获得一定的规模感。减少一英尺的网络电缆可以节省大约一纳秒的时间,这与通过一些汇编语言指令来加速数据包处理的一般顺序相同。 底线:与其他任何优化一样,要想走得更远,您需要测量延迟在什么地方,然后您可以做很多事情来减少延迟。在大多数情况下,减少电线的长度(仅举一个例子)并不会引起太大的变化,这仅仅是因为它起步很快。如果开始花费10微秒的时间,那么您将无法加快速度超过10微秒,因此除非您的处理速度如此之快,以至于10 us是您的大部分时间,否则就不值得攻击。     
其他: 1:使用用户态网络堆栈 2:服务中断与处理代码在同一套接字上(共享缓存) 3:首选固定长度的协议,即使它们的字节稍大一些(快速解析) 4:忽略网络字节顺序约定,仅使用本机顺序 5:从不在例程和对象池中分配(尤其是垃圾收集的语言) 6:尝试防止字节复制尽可能多(在TCP发送中很难) 7:使用直通切换模式 8:破解网络堆栈以消除TCP缓慢启动 9:宣告一个巨大的TCP窗口(但不要使用它),以便另一侧一次可以有很多机上数据包 10:关闭NIC合并,尤其是对于发送(如果需要,在应用程序堆栈中打包) 11:更喜欢铜而不是光学 我可以继续前进,但是那应该使人们思考 我不同意的一个: 1:网络电缆很少会出现问题,除非损坏了(电缆类型例外)     
这可能有点明显,但这是我很满意的一种技术,并且可以同时用于UDP和TCP,因此我将在此进行介绍: 1)切勿将大量传出数据排队:具体地说,请尽量避免将内存中的数据结构编组到序列化字节缓冲区中,直到最后一刻。相反,当您的发送套接字select()设置为可写时,则在那时将相关/脏数据结构的当前状态展平,并立即将它们发送出去。这样,数据就永远不会在发送方“积累”。 (另外,请确保将套接字的SO_SNDBUF设置为尽可能小,以最大程度地减少内核内部的数据排队) 2)您可以在接收端执行类似的操作,假设您的数据是以某种方式加密的:您可以读取所有可用的数据消息并将其放入(而不是(读取数据消息,处理数据消息,重复)循环)一个键控数据结构(例如哈希表),直到套接字没有更多数据可读取,然后(然后才)遍历该数据结构并处理该数据。这样做的好处是,如果您的接收客户端必须对接收到的数据进行任何非平凡的处理,则过时的传入消息将被自动/隐式丢弃(因为它们的替换将覆盖密钥数据结构中的消息),因此赢得了传入数据包不会备份到内核的传入消息队列中。 (当然,您可以让内核的队列填充和丢弃数据包,但是程序最终会读取\'old \'数据包并丢弃\'new \'数据包,这通常不是你想要什么)。作为进一步的优化,您可以让I / O线程将键控数据结构移交给一个单独的处理线程,以使I / O不会被处理拖延。     

要回复问题请先登录注册