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號