如何通过链路优化压榨单机性能https://ai.taobao.com/?pid=mm_99396806_34958614_123420078

215 阅读8分钟

本人目前从事的是针对分布式im后端服务器的架构优化,本篇文章主要介绍的也是本人这几个月使用go做 项目的优化心得,本篇文章中不做太多解释,对一些看不懂的原理请大家自行去查找一下资料.

说到分布式系统,业务服务器,一般都离不开一个名词,io密集。有些时候一个高并发的服务需要的io有 上十次,比如说在im系统的中群聊系统,不管是写扩散也好读扩散也罢,任何操作都是线性上升的io。那 如何保证io效率,降低链路上的io次数的同时还要保证可靠性就是一个系统最重要的环节。本文就链路中 的三大细节优化谈论:一 缓存优化(也是高并发优化);二 通信优化(也是一致性优化);三 重发优化(也叫高可靠优化)。

一 缓存优化

说到缓存优化,很多人就要想,什么是缓存优化呢?比如说在群聊的时候,一个群聊会话中人们最在乎的消息是哪些消息呢?最近的消息,若一个群每天产生1000条消息,那会有人想看7天前的消息吗?若一个群每个人的都是陌生人,会有人想要看一小时之前的聊天记录吗?人们最在乎的都是最近的数据,那么这时候如果将数据存储在mysql等持久化数据库中,查询数据库的延迟会让一台业务服务器永远达不到自己的cpu峰值。所以本人思考发现,一个会话中,人们最频繁需要收到的信息只是那前100条,而这如果放在缓存中那么就不需要进行io,将大大减少io的次数,比如说一条数据发到100人的群,那么就减少了线性长度的查询io。(在这里可能有通信层的通信io,这里需要放在下面再去优化。)从这我们可以看出热点消息热点资讯等等频繁访问的或者频繁使用的接口我们可以通过缓存去减少业务层和数据层的io访问。

说完了缓存的优点,这里需要提一下缓存的缺点(容灾)。容灾是一个可以用一门大学课程去讲解的课程,每个大型的网络公司都遭受过宕机带来的金钱损失。那么一个高可靠性的容灾如何去做,如何在减少数据层访问的状态下去保证容灾呢?现本人认为,缓存可以分为两种缓存,可以丢失的和不可以丢失的缓存。那么什么是可以丢失的缓存呢?比方说群体的高写操作缓存,若一个数据由多个客户读取和书写,那么每个人的数据都不会是一个即时的数据。那么缓存存在的额外信息是可以丢失,比如说红点信息,红点只是提醒他人的信号,它是用户友好的且用户不怎么在意的信息,一个用户不会在乎他的未读消息是10条还是11条,那么这个信号就可以丢失。而不可丢失的缓存非常难,我们必须保证其可靠性达到5个9或者6个9,那么冗余保存就是一个策略,这个策略也同时是重发优化的好策略。不过是否有其他的策略呢?增量日志保存,通过比如保存一段时间的日志去使用日志服务器保证业务服务器可靠性,但是还有其他的策略,在业务服务器宕机的时候,其针对一段时间的消息是丢失了的,那么用户容易了解到消息已丢失吗?容易,只要有用户在这台业务服务器上使用会话,那么这个用户就可以传递重连信号,这时候重连的节点可以通过用户的信息增量去重新保存数据。当然可能保存的数据不会那么多,可能有些数据这个用户不知道,但这是群聊,其实大多数用户不需要知道所有的消息。一个用户保存的信息就是足够的信息。这利用了每个人的共通性,虽然相比其他策略没有那么高的可靠性,但是其能够减少服务器的缓存容灾成本。

二 通信优化

谈到通信优化不得不提的就是网关,负载均衡,通信算法等等名词。最近微服务中有一种架构叫service mesh架构,本人了解不深,但从其名称上我们可以了解其使用的是一种网格的架构,每一个业务服务器可以执行所有的业务服务,而不是通过一些如gRPC等策略将业务细分(ps:虽然现有的gRPC服务可以达到上千万的吞吐量,但其通过io通信依旧是其瓶颈所在)。这就使得业务操作只需要使用单机操作,而通信操作就是通过专门和业务服务器连接的通信服务器进行,至于上面提到的缓存状态也是通过通信服务器作为保存,然后给通信服务器配套主从机或者不配套主从机只通过io操作与附件的通信服务器做冗余操作。本人也认同service mesh架构的一些思想,一个io密集的操作的中心应该是降低io的次数而不是通过rpc减少单台业务服务器的链路长度。

说完通信架构说一些通信算法。本人目前没有过多涉猎负载均衡策略,所以本文不去探讨如何负载均衡。通信算法上有着一致性的要求,有些服务如支付更需要强一致性,但本人目前接触的都是最终一致性的服务。因为很多时候人们不需要了解细枝末节的东西,人们急的时候有更多工具可以保证一致性状态。所以本人目前使用gossip算法,gossip算法就像名字一样是一个八卦算法,其增量认同,最终一致性的特点降低了通信服务器的通信往来,gossip算法通过定时发送增量信息,与其他服务器交换数据,且用单点通信和集群通信等等优化了转发的效率。比如跨省通信和跨通信服务商的通信架构,很有可能发送节点和接收节点不在一个集群上,这导致有时候发送节点会将信息先通过高级节点同步再通过低级节点同步来传输数据,该策略的好处就是节点通信不是一个线性增加的链路连接而是线性增加的宽带连接。

三 重发优化

重发优化是在私聊业务中最费脑细胞的东西,若一条消息只有到达对方才能确认发送成功那么再怎么好的架构都会被发送方和接收方的网络打败。链路的不可确定性从判断一个人的网络情况变成判断两个人的网络情况那么架构优化就需要有4倍的工作要做,重发机制的触发也会非常频繁,但从业务本身的角度来看,一个人发送私聊到服务器,服务器暂时存储了,那么发送端的任务和业务服务器的任务就结束了,剩下的就是转发到接收端的通信层去了,私聊消息如微信一般是没有服务器保存的,本人目前从事的私聊业务也是如此。所以在转发到通信层之后,通信层的缓存将会暂时存储这条消息并发送给接收端,等接收端返回ack之后才会删除。按照用户良好优化,重发机制由tcp协议自动控制亦或者自己通过udp协议在应用层实现。

这是本人关于这六个月以来针对一个Im系统的优化心得,里面有部分心得是im系统独有的,并且其概念没有多少新意,希望大家仅供思考,实际使用中注意需求和实现的平衡,这样才能达到系统最高的优化。并且本人认为链路优化仅仅只是分布式系统优化的一部分,在很多时候如何选用语言实现和使用网络io库也是一个大的学问课。