热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

滴滴出行高并发高性能的分布式架构设计之道

(点击上方的蓝色文字,可快速关注我们)如今,我们去任何一个地方都要先问问有没有Wi-Fi,网络已经明显影响到我

(点击上方的蓝色文字,可快速关注我们)

如今,我们去任何一个地方都要先问问有没有Wi-Fi,网络已经明显影响到我们的生活。

互联网生下来就是为了服务海量用户,在这个时代,几乎没有哪个应用再为单机而生。每个公司的每个产品将要面临的都是不可预知的用户海量请求。显然这个靠分布式程序来解决,比靠单机靠谱得多。然而不幸的是,如果一开始你的架构设计不可扩展,有再多的机器,有再多的云解决方案,对你来说至多是将单机程序跑在了一个虚拟的单机上。下面就让我们回到WOT2016 互联网运维与开发者大会现场,跟随滴滴出行首席架构师一起了解,分布时代架构设计和程序开发面临着哪些新挑战,以及滴滴出行的应对思路。

0?wx_fmt=jpeg

李令辉,滴滴出行首席架构师,于2014年中加入滴滴,经历了滴滴高速成长的阶段,见证了滴滴从一个打车软件变成一个出行平台。移动互联网资深从业者,对移动互联网技术发展趋势以及技术团队的组建有独道见解。他具有多年互联网架构的设计经验,擅长高性能高并发高可用的架构设计工作,主导了滴滴打车技术迭代中的核心服务架构升级。

分布式时代的困境

为单机而生的应用将不复存在

很少有一个应用能准确预测自己的用户量有多大,因此,一开始就为上亿用户去设计一个极为复杂的分布式架构,几乎是不可能的。因为这不仅会带来极高的成本,还会牺牲整个系统的灵活度。并不是每个公司都像谷歌一样,在创业初期就有面对世界上所有数据的雄心壮志,来开发一个分布式文件系统。大多数公司一定是从几台服务器起家,在用户不断增长,并发请求增加,业务越来越复杂的过程中,百临不得已将程序从单机搬到多台机器。把单个进程拆成多个服务的问题。

分布式开发工具的缺乏

每个人的工作量平白无故一个互联网的多个节点组成的,通过网络耦合的一个分布式环境。平白无故的被这种分布式带来的必然复杂性提高了。但是,真正的分布式开发工具还远未成熟。 程序员可以使用的工具还是古老的VI,四十年前的Emacs和十几年前的Eclipse等单机开发工具,服务之间的依赖关系完全无法管理,日志格式和日志内容无法保证一致和可追溯。上线,扩容,降级等运维工作和规范没有被很好的设计。 任何一次问题或者开发,都需要多人协作,效率极为低下。

重造车轮的解决方案

我们希望有更好的解决方案。看起来,业界解决方案百花争鸣。但实际上,大部分都是基于开源的RPC方案,比较成型的几个方案包括Erlang OTP, Scala Akka等。公司内通过各种定制的方案去耦合,去互相管理关系,互相依赖,把一个事工作起来。大一点的公司会强制的推行运维规范。而每个公司或者社区都对这种分布式环境用自己的理解。 这带来的后果是,大家都在开源社区的基础上重复造同样的东西,这个是成本很高的事情。

再者,很多解决方案都依赖于特定的业务场景来制定。比如通讯软件,对实时性要求很高,对可用性要求非常高,然而电商并不那么关心一个请求能不能快速返回,而是强调数据的一致性。所以每个业务特点决定了有不同的解决方案,而且很少有为分布式而生的方案,都是从单机方案演化或者渐变来的,这些问题都会让每一个在从中开发的人不得不知道全貌,对研发效率来讲是个巨大的伤害。分布式也确实个足够复杂的领域,很难有一揽子通用解决方案。

那么,在设计分布式系统架构时,应该考虑哪些方面?

分布式架构设计基本要素

容错

在分布式环境里,错误无处不在,并且无时无刻不在发生。而且,错误不只是机器故障,当几百人投入研发工作的时候,一定会有人犯错,而且每个人都会犯错,会常态的犯错。因此,研发团队不应该只想着如何避免错误的发生,而是如何在小错误下,不影响业务,保持服务健康运营。而一但不加考虑的对架构每个模块进行降级,势必带来一场巨大的灾难。

数据格式

数据格式实际面临的困境和依赖管理是一样的,因为每个人只负责单独的模块,而不会去关心整个业务用什么样的数据格式通信。究竟代码中到底多少是用来Verify Data的?又有多少是用来Pack/Unpack Data的?如果不统一就会陷入泥潭,工作效率低到无法接受,日志收集和监控也几乎没法实现。

路由层

关于路由层的解决方案没有高下之分,只要能解业务中的问题,降低运维成本和开发成本,就是好的方案。

但是,一定要尽量避免同时存在多种解决方案。函数调用是路由,反射是路由,URL是路由,RPC的IP+Port+Function也是路由。虽然说,并不是所有业务都能用统一的方法来路由的。路由的灵活性和规范性决定了运维难度,盲目追求灵活度平白无故的又把运维提的工作高一个量级。架构本质是控制复杂度,主要方法就是分而治之,解耦,耦合从本质上来说就是路由。

服务

为了满足用户新的要求,追上市场新的步伐,每个互联网公司的研发团队都不曾停下脚步,保证服务不断进化和升级。这同时也带来了许多问题:

  • 如何稳定高效的迭代?

  • 依赖刚迭代的服务的旧服务怎么办?

  • 我想给某个服务/模块做AB Test怎么办?

  • 多个模块可以同时做AB Test么?

  • 如果不能,研发变成串行上线真的好么?

看待这些问题一定要从全局出发,而最重要的是接口的统一,形成一致的标准,让大家在一条共同的准绳上。

监控

现在大家所做的监控,基本都是在监控机器的状态。其实在几百台机器这样的较小规模下,这样做的意义并不大。真正应该监控的,应该是程序。而严控程序的状态,只能依赖日志。

因此,每个架构师都要考虑,如何设计可以监控服务的日志系统,要提供可监控的接口。是每个架构师要考虑你的服务是怎么被监控的,你要提供可监控的接口。至于采集间隔。一般来说规模越大,采集粒度越低,规模越小,采集粒度越高。

另外,监控的信息是Pull or Push?监控的结果全部需要人来处理么?日志是否可以用来作为系统之间交互的数据?这些问题都需要大家根据自己的业务场景不断探索。

你的运维方案完美吗?

每个公司的运维团队都在考虑这个问题。你的目的是为了降低你的成本,提高你的效率。请合理的计算你的成本和效率,就是你要把人算进去,而不是就算机器。大家可以通过以下几个维度来评估:

  • 资源利用率如何?对大部分团队来说,研发的人力成本要远远高于机器成本,你要首先考虑的是你的人都并发起来了,而不是你的CPU都被吃掉了

  • 解决方案是否简单?这对应着人才招聘的门槛。对于新人来说,总要让他快速的上手做一个项目,验证自己的能力,所以解决方案一定要相对简单。怎么扩容,怎么缩容,都应该有成型的一整套方案

  • 开发测试上线流程是否需要人工介入?

  • 小流量测试的支持如何?

  • 回滚、限流、断流方案是否统一提供等等问题 ?

滴滴出行的分布式设构设计思路

Linux之所以强大,是因为每一个模块都只负责最简单的事情,面对输入和输出,而输入和输出的格式是确定的。分布式架构设计的思路也应如此,同样的规则,同样的用法组合在一起是可以发挥巨大作用的。

0?wx_fmt=jpeg

这样的架构设计带来的一个巨大好处是,信息流在进来的时候进入信息分发,信息分发把它分到合适的管道,那个管道处理完再放给下一个管道。每个管道都只做输入和输出的事情,实现高可用、高吞吐。这种方案很多云服务商都会提供。这样做的好处时是,我们只需要管理消息队列,可以在任意一个节点把流量复制走。在任何一个环节中可以拿到它所有的数据,不再依赖日志,只依赖输入、输出。而输入、输出是存在硬盘上的,数据不会丢失。

另一个优点是进程是异步传输的。同步模型一个很明显的缺点是在所有的层次中,一个进程在执行某个请求的时候如果需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去。在流量很大的时候,做一个重试可能某一个环节就会面临崩溃了,某个环节的连接数被打满。

而在这个方案中,连接就只有两三处,不需要等待数据回报,只需要确认收据接收,而且不需要逐条验证。成本很低,性能很高。

但这个架构设计显然不能解决所有的问题。比如用MySql作为存储等必须同步的服务时,需要给有状态的服务提供一个抽象层Seivice。上面的服务可以请求它。可以理解为在Linux中敲一个命令要读一个文件,那个文件是有状态的,是存在那里的,而这些模块是没有状态的。

这个设计要解决的问题不是简简单单的机器运维问题,而是人在研发过程中,如何避免我面临复杂环境中的险,解决由于粗糙的架构设计带来的效率低下,不可控,不稳定,手足无措的状态。

0?wx_fmt=jpeg

滴滴选择了Docker+Kubernetes作为分布集群管理解决方案,它的好处是可以直接提供资源管理,资源隔离,部署,升级,路由等等需求。但是,只有Kubernetes是不够的,Kubernetes只能管理那些无状态的事务。并不是所有的事情都可以完全抽象成无状态的,有状态的部分应该如何实现扩容,都要依据具体的业务场景,这是很难的设计。

最后要说的是,没有完美的方案,如果你自己要开发这个事情,建议大家最好用一种方案,不要每一个用一种。但是没办法,你就是不同的好几波人开发的,并且场景不一样,很有可能还是那个样子,如何解决有状态事务的快速扩容和运维管理,现在还没有最终的结论。希望和业务同仁共同探讨。


欢迎关注“互联网架构师”,我们分享最有价值的互联网技术干货文章,助力您成为有思想的全栈架构师,只聊架构,不聊其他!打造最有价值的架构师圈子和社区。

长按下方的二维码可以快速关注我们


640?wx_fmt=jpeg

如想加群讨论学习,请点击右下角的“加群学习”菜单入群






推荐阅读
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 初探PLC 的ST 语言转换成C++ 的方法
    自动控制软件绕不开ST(StructureText)语言。它是IEC61131-3标准中唯一的一个高级语言。目前,大多数PLC产品支持ST ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • SQL Server 内存中OLTP内部机制概述(一)
    内存中OLTP(项目名为“Hekaton”)是一个新的完全集成到SQLServer中的数据库引擎组件。它专为访问内存常驻数据的OLTP工作负荷而进行优化。内存中OLTP有助于OLT ... [详细]
  • Emacs在minibuffer里的操作
    为什么80%的码农都做不了架构师?|Key|Description||--------------------------------------------- ... [详细]
  • 近期看见一篇来自Intel的很有意思的分析文章,作者提到在他向45名与会的各公司程序员开发经理战略师提问“什么是实施并行编程的最大障碍”时,下面五个因素 ... [详细]
  • 用友深耕烟草行业25年,提出数字化转型建议
    本文介绍了用友在烟草行业深耕25年的经验,提出了数字化转型的建议,包括总体要求、主要任务、发展阶段和六位一体推进举措。通过数字化转型,烟草行业将注入新动能,实现高质量发展。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 与.Net大师Jeffrey Richter面对面交流——TUP对话大师系列活动回顾(多图配详细文字)...
    与.Net大师JeffreyRichter面对面交流——TUP对话大师系列活动回顾(多图配文字)上周末很有幸参加了CSDN举行的TUP活动, ... [详细]
author-avatar
我是80初
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有