java低延迟可能的手段【yetdone】
-java
堆内对象池 启用nocleaner堆外内存,增大新生代 精确控制gc次数
把程序写简单,编译期能干的事情就不在运行时干;避免用不必要的virutal function
关注java c的同一段逻辑的cpu cycle 和切换,jvm背地里会干的一些事情
contiguous 相邻内存块,尽量让可能被同时使用的数据挨在一起(CPU缓存空间局限性)
数据要分两种,一种从交易所发过来的市场数据,流量很大,另一种是系统向交易所发出的交易指令,相比前者流量很小,这两种数据需要在不同的TCP/IP连接里传输。
避免阻塞,优先轮训,甚至避免超线程(同一个核心上两个线程对缓存行的访问是串行化的)甚至多线程(避免上下文切换);
数据无需编码解码,可以直接顺序从内存读取,直接可以在网络上收发(避免堆内内存反序列化,直接读写直接内存甚至内核内存,减少拷贝)
修改jvm
-内存
用memory pool,用lock free data structure (Intel TBB),避免kernel call. 善用cache。
限制动态分配内存,当堆空间不足时会调用sbrk(),当分配内存很大时会调用mmap(),这些都是系统调用,而且新分配的内存被first touch时也要过很久才能准备好(缓存里没有);一次随机内存访问花费的时间和顺序访问对于CPU(CPU缓存空间局限性)来说花费的时间相差两个数量级
能在cache里面存下data和instructions,就不用access main memory,能在registers里面存下,就不要access cache。
-网络协议
tcp协议栈优化,去除复杂网络可靠性冗余
select ack / syn捎带报文
udp报单 tcp确认回报
禁用nagle,或禁用/修改delay ack时间
增加滑动窗口大小,根据实际流量调优
tcp慢启动优化
频繁小包ack导致高频系统调用和上下文切换
udp包控制在mtu 1472字节-局域网,548字节-互联网,不要ip层分片
tls 1.3椭圆曲线代替rsa
quic ,kcp等可靠udp协议,kcp用带宽空间换时间
走专线,缩短数据链路层,定制mtu
用户态tcp协议栈,减少拷贝
-内核
其实就是在数据,比如市场信息,进入cpu之前(当然那种fpga进,fpga出的特殊解决方案除外),尽量减少数据拷贝以及context switches。
上下文切换是非常耗时的,其中固定的消耗包括(cpu流水线被冲掉、各种寄存器需要被保存和恢复、内核中的调度算法要被执行),此外,缓存很有可能出现大量miss
指定cpu affinity时考虑LLC缓存(同核的两个超线程是共享L1,同cpu的两个核是共享L3,不同NUMA核是通过QPI总线);会被多个核同时读写的数据按照缓存行对齐(避免false sharing)。
使用带有内核bypass功能的网卡。每个进程或者线程都独占一个cpu核(!=CPU亲和,有点像CPU隔离,某个CPU就干这个事不响应中断,防止缓存被刷)【isolcpus和irqbalance的细节见注释3】,并且不停地轮询,用以保证快速响应。尽量避免任何可能导致阻塞的事件(如mutex),某些注定很慢的活动(比如把log写到磁盘上)应该被独立出来放到别的cpu上,不能影响主线程(不要切换,不要系统调用)。
要做到低延时首先确保最少的线程切换一般通过设置CPU亲和性实现,尽量减少中断一般采用内核旁路UIO实现,为避免数据拷贝一般使用用户态协议栈,kernel bypass
cpu isolation
https://www.zhihu.com/question/23185359?share_code=rvLR1N3eBoB3&utm_campaign=Sharon&utm_content=group2_supplementQuestions&utm_psn=1949103301565068316
-其他
                    
                
                
            
        
浙公网安备 33010602011771号