Go在证券行情系统中的应用

以⾏情云和交易云为核⼼,⼴发证券构建了OpenTrading交易平台、GF Quant量化分析平台、各类交易终端、开发者社区等FinTech⽣态系统,从理念到技术⽔平均⾛在业内前沿。 ⾼频⾏情信息包括实时报价、逐笔成交、分时成交、周期K线、资⾦流向等信息数据,券商通过专线线路从交易所获取原始数据后通过计算⽣成。 海量并发和海量数据处理的系统,GC的内存对象扫描标记不仅消耗⼤量CPU 资源,还会因为GC过程Stop The World造成毫秒级延时,拖慢⾏情推送速 度。 Go 1.8 Release Notes: 相⽐1.7版本GC Pause⼤幅减⼩,通常低于100微妙甚⾄10微秒 Go 使⽤CMS(Concurrent Mark Sweep) GC算法,优点是不中断业务的情况下并⾏执⾏,将STW时间降低到最⼩,缺点是并⾏执⾏需要更多的同步开销降低了吞吐量,以及堆空间的增⻓难以预测。
展开查看详情

1.Go在证券⾏行行情系统中的应⽤用 ⼴广发证券 刘楠

2. Agenda • 证券⾏行行情系统背景介绍 • 证券⾏行行情业务特点 • ⾏行行情系统开发遇到的挑战

3. 证券⾏行行情系统背景介绍 以⾏行行情云和交易易云为核⼼心,⼴广发证券构建 了了OpenTrading交易易平台、GF Quant量量化分析 平台、各类交易易终端、开发者社区等FinTech ⽣生态系统,从理理念到技术⽔水平均⾛走在业内前沿。 ⾼高频⾏行行情信息包括实时报价、逐笔成交、 分时成交、周期K线、资⾦金金流向等信息数据, 券商通过专线线路路从交易易所获取原始数据后通 过计算⽣生成。

4.证券⾏行行情系统的特点 * 超低延迟: 延迟过⼤大会误导投资决策,导致客户流失 * 超⾼高并发: ⽜牛市时全⺠民炒股刷⾏行行情数据 * 超⾼高可靠性:数据出错可导致真⾦金金⽩白银的损失 * 超严格监管:全⾯面监管从严监管的时代受到各种合规约束 2015年年5⽉月29⽇日,招商证券、东兴证券、⻬齐鲁证券、国泰君安等证券公司信息系统发⽣生中断或缓慢,引起各 ⽅方⼴广泛关注。——证券⽇日报《证监部⻔门处罚部分信息系统瘫痪券商》

5.⾏行行情开发遇到的挑战 1 开发语⾔言的选择 2 GC问题的困扰 3 ⾯面向并发的数据结构 4 融合替代⽅方案 5 ⽹网络底层优化

6.1 开发语⾔言的选择问题 C/C++:  历史悠久的⾼性能系统级语⾔,类似于AE86,1970s的设计理念,车重不⾜1吨,适合爱改 装和造轮⼦的⽼司机 Java: ⾦融机构⼴泛使⽤的安全可靠系统级语⾔,类似于T99主战坦克,诞⽣于1990s,车重50吨, ⽕⼒猛装甲厚⾏动迟缓安全性⾼ Golang: 为并发⽽⽣集成现代设计理念的系统级语⾔,类似于Tesla Model S,诞⽣于近⼏年,有 AutoPilot等ADAS功能,代表业界发展⽅向 我们团队有着互联⽹技术基因,⽤前沿开源技术打造创新型 FinTech Startup

7.2 GC问题的困扰 海海量量并发和海海量量数据处理理的系统,GC的内存对象扫描标记不不仅消耗⼤大量量CPU 资源,还会因为GC过程Stop The World造成毫秒级延时,拖慢⾏行行情推送速 度。 ⾏行行情与交易易都是与时间赛跑的实时应⽤用领域 例例如,为了了把芝加哥期货市场和纽交所的通讯时间缩短3毫秒⽽而花费数亿美元 专⻔门埋⼀一条遇⼭山开⼭山遇河挖隧道只为了了⾛走直线的光纤,再如频繁花巨资更更新通 讯设备只为了了⼏几微秒的提速,乃⾄至co-location到把机器器并排放在证交所的服务 器器旁边。

8.2.1 Go在GC性能上的改进 • Go 1.8 Release Notes: 相⽐比1.7版本GC Pause ⼤大幅减⼩小,通常低于100微妙甚⾄至10微秒 • Go 使⽤用CMS(Concurrent Mark Sweep) GC算 法,优点是不不中断业务的情况下并⾏行行执⾏行行,将 STW时间降低到最⼩小,缺点是并⾏行行执⾏行行需要更更 多的同步开销降低了了吞吐量量,以及堆空间的增 ⻓长难以预测。

9.2.2 GC算法考量量的因素 1 并发:回收器器利利⽤用多核机器器并⾏行行执⾏行行 2 停顿时间:回收器器会造成多⻓长时间的停顿 3 停顿频率:回收器器造成的停顿频率分布 4 压缩:移动内存对象,整理理内存碎⽚片 5 堆内存开销:回收器器最少需要多少额外的内存开销 6 GC吞吐量量:在给定的CPU时间内,回收器器可回收垃圾数量量

10. 堆空间的暴暴涨 ⽆无压缩?吞吐量量不不⾜足?⽆无停顿处理理不不及时?并发执⾏行行不不可预测?

11.2.3 避免Goroutine的频繁创建销毁 • 并发量量⼩小于1000时:每个请求分配⼀一个Goroutine,并发模型简单易易 于开发,类似于Apache并发模型 • 并发量量⼤大于1000时:频繁创建的Goroutine在销毁时产⽣生⼤大量量内存垃 圾,GC过程拖慢系统响应速度,宜采⽤用Nginx并发模型

12.2.4 对象缓存池的使⽤用 • 不不创建新对象才能避免GC • 对象的创建速度和销毁速度近似平衡 • sync.Pool⽆无法控制缓存对象数量量和销毁时机 • 造⾃自⼰己的轮⼦子

13.对象缓存池的简单实现

14.2.5 栈对象和堆对象 • 栈对象在函数返回时释放,堆对象由GC释放 • Go编译器器的做法:不不逃逸的对象放栈上,可能逃逸的放堆上 • 尽量量使⽤用栈对象,特别是在快速调⽤用和返回的函数中,栈对象的分配速 度⽐比堆对象快⼀一倍 • ⻓长时间不不返回的函数中,过多的栈对象可能增加Goroutine调度开销 • go tool compile -m 辅助分析对象的分配情况

15.3 ⾯面向并发的数据结构 • 多线程时代并发访问临界区资源时往 往要加锁,锁的存在使得并⾏行行任务互 相⼲干扰影响性能 • 多处理理器器多核时代并发问题更更加严重, 同⼀一内存单元读写也会互相⼲干扰影响 性能

16.3.1内部存储器器层次结构 Cache Miss的代价: 内存的延迟往往是很⾼高的,从10到100纳秒不不等。 ⼀一个3.0GHz的CPU在100ns可以处理理多达1200条指 令。⼀一次缓存失效约等于失去执⾏行行500 CPU指令机会。 Cache ⼀一致性协议: 缓存段处于独占或已修改状态时才可修改,否则通 过总线请求独占权,通知其他处理理器器失效同⼀一缓存段的 拷⻉贝。

17.3.2 Per-CPU storage • 统计变量量之间的⼲干扰 • 并⾏行行读锁之间的⼲干扰

18.3.3 ⽀支持并发访问的Map • 多级Hash Map是⼀一种容量量固定的数据结构,将并发访问锁的粒度细化到每个Map存储元组 Hash 1 Hash 2 Hash 3 Hash 3 … Hash k Level 1 Level 2 Level 3 Level 4 Level 5 Level 6 … Level N

19.4 融合替代⽅方案 • 第三⽅方库产⽣生⼤大量量垃圾对象 • Goroutine难以管理理10万级以上连接 • Cgo调度性能不不⾼高 • …… 以上问题的解决⽅方案:Cgo线程常驻内存,通过内存与Go通信

20.5 ⽹网络底层优化 • Docker等虚拟⽹网络可以调⼤大MTU使⽤用巨型帧传输数据,应⽤用层⼀一次系统调⽤用可以传输更更多数据

21.• 跨主机通信可以利利⽤用⽹网卡硬件的分⽚片offload和校验offload功能 开启前 开启后

22.⼤大包⽆无法正常接收的问题 • 数据⻓长度为1493的UDP数据包校验错误 • Docker容器器⽹网卡信息和Docker host⽹网卡信息

23.• 同类问题报告 https://github.com/docker/docker/issues/18776

24.drivers/net/veth.c

25. Thank you! nandyliu@outlook.com