金融系统性能优化之道

简介: 系统设计得再好,如不能及时完成业务处理也不行。为什么不同业务有不同优化需求,以及常见的优化方式和问题有哪些。

系统设计得再好,如不能及时完成业务处理也不行。为什么不同业务有不同优化需求,以及常见的优化方式和问题有哪些。


1 分析

“快”在不同的环境下有不同的定义:


对互联网业务,快一般意味着吞吐量大

对金融业务,快意味着延时低

为什么有这两种定义的区别?互联网业务在经济学上有个特点:边际成本(Marginal Cost)基本为零。


边际成本决定业务扩张的成本,既然扩张成本低,互联网业务倾向于扩张,且大规模扩张。扩张结果就是互联网业务会有大量用户,这也决定互联网业务需解决大流量问题。


流量大为何和速度快扯上关系?

秒杀发现网页卡,半天显示不了内容。这时候你肯定抱怨网站速度慢,这是因为在解决秒杀这种大流量问题,互联网通常采用延时换吞吐量,即降低你的网页加载速度来支持更多人秒杀。虽吞吐量上去,但延时增加。虽然所有人体验都因此变更差,但至少大家还能买到东西,没有出现网站宕机。所以互联网的“快”,指服务器集群的处理能力快,能同时处理很多东西。


**金融业务的边际成本一般都很高。**金融机构在和机构用户进行对接前,双方都要做详细的客户身份识别(KYC,Know Your Customer)。对接后就是业务、财务、合规、风控等一系列的流程。因为这些流程都有一定的时间和人力物力成本,所以机构类的金融业务很难像互联网大规模扩张。


既然机构类的金融业务无法大规模扩张,金融机构就无法靠规模优势来彼此竞争,只能靠质量优势吸引客户。在金融行业,时间就是金钱,所以金融机构就会想办法把速度提高,才能帮客户省钱。这决定金融行业的“快”指的就是延时低。


互联网业务和金融业务有一个重合点,那就是普惠金融,如第三方支付、小额信贷等。普惠金融的业务特点更接近互联网业务,对快的要求也和互联网业务一样。


尽管金融业务多种多样,但我们把握住相应背景中“快”的本质定义,就能更合理地选择优化方向了。那么接下来,我们就从吞吐量和延时这两个方面,分别来看看金融系统的优化要点。


2 吞吐量优化

两种常见方法:


2.1 分库分表

吞吐量最常见的解决方式。


单个数据库表易受单机硬件处理速度限制,但拆成为多部分后,每部分都可放在不同机器处理,使用更多硬件资源。所以分库分表之后,可用大量硬件应对大流量。


切分时注意一个原则,切分完的子表需要互相独立,但也要完全穷尽(MECE,Mutually Exclusive Collectively Exhaustive)。互相独立指的是子表之间不要有任何内容的重复。完全穷尽:把原始的表切割完后,不要有任何数据丢失。即切分表时,要保证切分后的结果不多不少。


2.1.1 按hash值和主键切分

最常见的水平切分。按数据库主键切分:


按主键的哈希(Hash)值来分

按主键的范围(Range)来分

按哈希值来分,注意哈希函数的值域大小。一般把每个哈希值对应的数据都放在一台机器。机器数量有限,所以哈希函数的值域一般不大,如10或100。


**按哈希值切分有一个很大的优点是有一定随机性。**用户访问并不一定很随机,有可能出现某些主键范围的访问量特别集中。由于哈希值会将原值打散,所以可能将流量分散在不同机器,避免单台机器过载。


不过哈希值的随机性也带来缺点,连续访问性能差,不过互联网应用很少看到需要主键连续访问。


但金融行业有市场数据,如股票和期货的实时交易价格信息。使用时,一般会访问一个时间段内所有数据,因此在时间上需连续访问。按时间的哈希值来切分就不太适合。


2.1.2 按范围切分

优点:主键的范围连续,对于市场数据的访问很友好。


但范围连续的优点也成为缺点。范围连续可能导致访问过集中,造成单机过载。如量化分析时,可能会大量访问最近min的市场数据,按照范围划分会导致存有最近数据的服务器被大量访问。


2.1.3 分库分表的问题

将原来在一台机器上处理的事情,变成在多台机器处理。无论按哪种切分方法,都会带来多机环境的问题。


正确性

分库分表后,大家可同时更改多个表的内容。由于这些表在不同机器,网络通讯需一定时间,你很难确定别的机器上的内容是正确的。就算你验证正确,在网络消息传回来的那段时间,也可能发生变化。因此分库分表后,你需要一定分布式正确性保障,即分布式事务。


延时

分布式事务需要至少两次网络沟通,这也决定分库分表方案的最低延时。对个人用户,网络延时带来问题不大,但对高频交易相关机构,会延时过高。


容灾

机器不可能一直在线,一定会出问题,只是时间早晚问题。如果你学过概率论就会更理解这点,机器数目越多,出问题概率越高,所以分库分表一定要考虑集群容灾。


容量限制

分库分表过程一旦完成就很难再调整分库数量。因此有经验的架构师在最开始会做一些看起来“超前”准备。比如说如分10个库就够,可能你分20或50个。但互联网应用的增长速度谁都说不准,很可能爆发增长,这时候依然会出现集群整体容量不足。


2.2 MQ

核心思想:将流量先写入MQ,然后服务器按固定速度处理MQ内的消息。这样就算是峰值流量进来了,也不会服务器过载。


消息系统是很常见的一种处理峰值流量的架构。秒杀一般分为三个阶段。第一个阶段准备期,支付系统流量和平常一样,无需特殊准备。


第二阶段秒杀开始之后的几min。这时从系统监控上可以看到一个很高的流量峰值。这峰值是电商系统丢给支付系统的流量,代表理论上最高的并发量。


支付系统的流量并不会直接处理,而是会写入MQ。消息队列也有个消息写入速度的上限,但这上限很高,通常不会成为瓶颈。


支付系统尽最大能力从消息系统拉取要处理的消息。这处理速度有上限,一般是分库分表后所有机器的处理能力。和消息系统不同,支付系统处理速度低于电商系统丢过来的峰值流量。所以电商系统丢过来的流量很高,但时间很短。支付系统处理速度慢,时间也长。


第三阶段秒杀结束后。这时候系统流量会慢慢恢复到秒杀开始之前的情况,一切回归正常。


中间第二阶段比喻成削峰填谷:


15.jpeg


除削峰填谷,还可继续优化吗?要结合业务。虽然你在零点秒杀,但货品需过一段时间才能送到你手。等你确认收货后,商家才能收到你的钱。所以从你付钱到商家收钱中间有很长一段时间,这就给我们进一步优化空间。


在秒杀时,钱不是从买家账号直接打到卖家账号,而是先打到中间账号,即担保账号。所以我们在处理秒杀时,只需处理买家账号到中间账号的流量问题。


买家账号到中间账号还可进一步切分。支付系统角度,只要买家账号能正确扣款,中间账号稍微延迟点打款没问题。中间账号的打款就算丢了也问题不大。支付系统在每天晚上日切时进行所有账户对账。如果中间账号的打款丢了,会通过补账方式把钱再补回来。即中间账号可异步处理。


首先,在秒杀开始时,即秒杀第二阶段,支付系统只处理买家账号,将对中间账号的处理暂时搁置,减少一半的账号操作。到第三阶段,再慢慢恢复对中间账号的处理。


这时候系统多第四阶段,即快递送货之后打款给卖家的阶段:

14.jpeg



3 延时优化

吞吐量优化是系统能力横向扩展,宏观资源调配。而延时是系统能力纵向扩展,微观资源调配,因此需不同解决方案。


3.1 单机优化

提高单机性能有一个反直觉的解决方案:单线程处理。为什么单线程可以有这样高的处理速度呢?


谈到多线程优势,常提到可用到计算机的多个CPU或者多个核,因此有更多的计算资源,因此可以处理更多的事情。听起来有道理,但假设计算之间不抢占资源。多线程处理时,计算机操作系统会进行线程调度。线程调度需更新操作系统内的核心数据结构及更新CPU上的各种缓存,这过程需消耗时间。所以虽然多线程能用到更多资源,但准备资源本身就消耗资源。


这就是为什么单线程可比多线程更快。这只是一种可能性,为能真正超过多线程,还是要做些处理。


把你的线程绑定到某块CPU。如Linux操作系统有个C函数 sched_setaffinity,把你的程序绑定到指定的CPU。


默认情况下绑定到CPU指的是你的程序只会在这块CPU上运行,不会跑到其他的CPU。尽管其他程序还是可能会过来抢你的这块CPU,但是你的程序绑定到CPU之后,还是会运行得更快。


绑定CPU还有一些优化空间。Linux内核启动时有个 isolcpus 的启动选项。这个选项可以将一块CPU独立出来,这样任何程序都不可以使用这块CPU了。唯一可以使用这块CPU的方式是你将进程绑定到这块CPU,这样你就能真正独占这块CPU了。


访问内存时,注意CPU并非直接访问内存,而是通过CPU缓存来访问。机器加载缓存时会一次性加载一小段内存,这也决定**内存的顺序访问会比乱序访问速度更快。**进行金融风险计算时,会用到多维数组,这时需根据算法访问顺序合理组织数组的位置。


内存另一个需要注意的是C语言分配内存需要一定时间,而且这时间长度还随机。所以如你的程序需频繁分配内存或对延时敏感,最好自己实现内存池。


文件系统。事件溯源由于顺序写文件,可达非常高的写速度,所以如你的程序也能顺序写文件,尽量按顺序写。


如一定要随机写,mmap 会将文件映射到进程的内存页表。这样在C程序里就能像访问内存一样访问文件。这就减少用户进程和操作系统之间来回拷贝数据的开销,节省时间。


3.2 网络优化

一台机器的各个组成部分相对来说还是比较稳定的,所以单机优化都有一些可以复用的优化手段。而网络则是非常不确定的一个环境,优化的手段需要结合实际情况来看。在这里我们重点看看Linux上比较有用的几个函数,它们可以解决网络消息处理的问题。


C10K:有没有可能让一台机器支撑一万并发。用进程或线程的方法达不到,所以就要 epoll 。Linux独有函数,可同时监听大量网络链接。当网络链接变得可读写,会通知你的程序。你就不需要同时等待所有网络链接,只需等待这个函数的通知。epoll还做内核数据结构优化,就算网络链接特别多,也能高效工作。但 epoll 只告诉你网络是否可读写,你还是要自己写代码读写网络。由于每次读写网络都会调用内核函数,这样会造成大量用户态和内核态切换,浪费很多计算资源。


咋解决这问题?2018年Linux内核新增 io_uring,解决用户态切换过多问题。在写程序时准备个队列,记录所有你想要做的读写操作,同时也包含你预先分配的读写内存。


接着你将这个队列一股脑交给内核。内核会先做 epoll ,检查哪些网络链接可开始读写。然后内核多做一步,帮你处理网络数据。


如果你的操作是写网络,会把你内存的数据写出去。如你的操作是读操作的话,会把数据读到你预先分配的内存。内核操作完之后会把这些操作的状态记录在另一个列表里,返回给你的用户态进程。

13.jpeg


架构上来说,io_uring 替你把 epoll 和之后的读写操作在内核态批量处理,同时用户进程和内核共享数据页表,这样既节省了状态切换开销,也节省了数据拷贝开销。


目前有一些网络操作频繁的应用正在实验这种新技术。不过相对于已经存在近10年的 epoll 来说,io_uring 从文档和工具上来说都还不太成熟,所以你要做好挑战的准备。


总结

如何优化金融系统。首先我们分析了为什么金融系统会有吞吐量和延时这两个优化的方向。普惠金融和互联网业务类似,面向大众,对系统吞吐量要求非常高。机构金融专业性特别强,对延时要求非常高。


吞吐量优化:分库分表和使用消息队列。分库分表有按哈希值和范围这两种不同的划分方式。这两种划分方式都有各自的优缺点,但是它们都有正确性、延时、容灾和容量限制这四个问题。我会在第三个模块讲解应该如何解决这些问题。


消息队列的作用是对流量做削峰填谷。我们用秒杀场景下的支付系统为例,讲解了在碰到问题时应该如何分析业务规律,应该如何利用业务规律的特点来优化系统架构。


延时优化的一些常见方法。延时优化要从单机优化开始,优化对CPU、内存和文件这些资源使用。网络优化主要是通过 epoll 来减少在高并发情况下的线程开销,同时用io_uring来进一步减少网络操作的用户态和内核态的切换开销。


普惠金融的架构是从宏观层面解决架构的横向扩张问题,是互联网云计算的标准使用场景。机构金融是从微观层面解决架构的纵向扩张问题,需要对用户进程、操作系统和硬件做特别的优化和控制,因此非常不适合云计算的解决方案。知道这些区别之后,你还要根据具体业务进行相应的优化和选择。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
25天前
|
缓存 前端开发 JavaScript
优化前端性能的十大最佳实践
在现代网页开发中,前端性能优化不仅仅是为了提升用户体验,还能显著提高网站的加载速度和响应时间。本文探讨了十大最佳实践,从优化资源加载到减少网络请求,再到提高页面渲染效率,每个实践都旨在解决常见的性能瓶颈。通过实现这些策略,开发者可以显著提升前端性能,提升用户满意度,并确保网站在各种设备上的流畅运行。
|
11天前
|
缓存 Android开发 UED
安卓应用开发中的性能优化实践
【8月更文挑战第31天】在安卓的世界里,性能是王道。本文将带你深入理解如何通过代码优化和工具使用来提升你的安卓应用性能。我们将一起探索内存管理、布局优化、多线程处理等关键领域,并配以实用的代码示例,让你的应用飞一般地运行起来!
|
22天前
|
监控 算法 Java
企业应用面临高并发等挑战,优化Java后台系统性能至关重要
随着互联网技术的发展,企业应用面临高并发等挑战,优化Java后台系统性能至关重要。本文提供三大技巧:1)优化JVM,如选用合适版本(如OpenJDK 11)、调整参数(如使用G1垃圾收集器)及监控性能;2)优化代码与算法,减少对象创建、合理使用集合及采用高效算法(如快速排序);3)数据库优化,包括索引、查询及分页策略改进,全面提升系统效能。
30 0
|
10月前
|
存储 消息中间件 数据库
Milvus性能优化提速之道:揭秘优化技巧,避开十大误区,确保数据一致性无忧,轻松实现高性能
Milvus性能优化提速之道:揭秘优化技巧,避开十大误区,确保数据一致性无忧,轻松实现高性能
Milvus性能优化提速之道:揭秘优化技巧,避开十大误区,确保数据一致性无忧,轻松实现高性能
带你读《阿里云卓越架构白皮书_导读版》——4、性能优化(2)
带你读《阿里云卓越架构白皮书_导读版》——4、性能优化(2)
196 0
带你读《阿里云卓越架构白皮书》——4、性能优化(1)
带你读《阿里云卓越架构白皮书》——4、性能优化(1)
195 0
|
运维 监控 Cloud Native
干货|后互联网时代,运维工程师的必备性能优化指北
在竞争激烈的后互联网时代,深度挖掘每份流量背后的商业价值成为每个企业的必修课,而网站性能与体验的优化是这一过程中重要环节。 因此,《网站性能与体验优化指北》成为后互联网时代的网站运维的必备电子书。
|
测试技术 监控 弹性计算
阿里巴巴在应用性能测试场景设计和实现上的实践
提升性能前,先测试摸个底,找到性能瓶颈。 测试前,先设计好应用性能的测试场景,并实现它。 本文是《Performance Test Together》(简称PTT)系列专题分享的第5期,该专题将从性能压测的设计、实现、执行、监控、问题定位和分析、应用场景等多个纬度对性能压测的全过程进行拆解,以帮助大家构建完整的性能压测的理论体系,并提供有例可依的实战。
9167 8
|
SQL 存储 网络协议
深入浅出!阿里运维专家三种方法教你如何应对高并发“海啸”场景
高并发高压力下我们是如何保障数据库的稳定性和可用性的。
1619 0
深入浅出!阿里运维专家三种方法教你如何应对高并发“海啸”场景
|
SQL 算法 Java
一线架构师带你玩性能优化
系统优化一个方面是系统化的对IT系统或交易链上的每个环节进行分析并优化,另一个是对单一系统进行瓶颈点分析和调优。优化的目标无非是:提高系统的响应速度、吞吐量、降低各层耦合,以应对灵活对边的市场。
9560 0