原文地址:http://www.infoq.com/cn/presentations/optimization-of-asynchronous-processing-in-distributed-systems

视频地址:http://v.qq.com/boke/page/l/0/6/l0196plsvp6.html

主讲人:赵海平 Facebook hiphop HHVM 阿里巴巴技术保障部

问题1.进入大数据时代,

用户增多,数据增多带来挑战,上亿的用户,不能一台机器存所以数据,一个计算机更强大,针对一个用户要做的事情也比以前更多,造成数据量的膨胀。

多到再不可能访问一个数据库就可以展示网页,需要访问多个库。

不好的做法,访问数据库1的结果是访问2需要的依赖,只能先访问1再拿1的结果去访问2,最后汇总结果显示出来。

问题:同步等待。

发现有时候1和2其实没有依赖性,这样就无意义的等待。

并行的发送2个数据库去查询比较好,facebook早年就是有这样的代码,几个mysql同时查询,专门的查询函数查询多个查询,只要这些查询之间没有依赖。

这样让代码复杂性,不过不要紧。问题在于人脑思维有局限性,在真实场景有小组,每个小组负责自己的业务,负责查询自己所在的数据库,所有每个组在函数上是一个同步的写法,同步的等待过程,从数据库抓数据,只要调用其函数就需要同步等待,让并行处理变难。

第三方需要调用多个函数都各自做各自的事情,都同步的抓数据,只能先后调用。让并行处理很复杂。facebook就遇到这样的现实问题。

如何把并行在代码层面写的很直观,又在机器层面执行的非常好就是一个艺术。

新的写法-异步写法

我知道需要访问数据库,先不马上访问,把访问数据库的所有条件记录先下来,记录下来的目的是稍微等待看有没有其他地方也需要访问这个或者其他数据库,如果有可以两个一起处理。所有异步写法就不是一个同步的等待。

异步返回的是Future这样一个object而不是结果result。Future可能不同语言叫法不一样,但是目的都是一样就是将所有将来需要访问数据库的信息记录下来,先不去访问它,有不同的Future的object就可以汇总在一起,再执行。

要判断什么样的Future的object可以并行处理,什么样的不能并行处理。可以做调整。

异步写法不再担心函数把异步写法合并,有函数也没事,getresult到最后把Future的object返回给调用者,这个函数可以暂时认为已经结束执行,下一次就无需访问我了,因为我已经告诉你怎么去访问数据库,然后调用者可以去调用其他函数,再调用函数的过程中没有任何的等待过程。调用的人有一个总的调度过程。不同的团队可以写自己的函数,这些函数可以合作。

要求同一个公司都这样写,不然其他调用者对于一个是Future,而另一个是同步进行,调用者就会不知所措,因为返回不同。调用者希望所有的函数给他的都是Future的object。

但是这样阻碍很多的代码转变,fb就经历过这样痛苦的转变,不过异步确实让代码更有效的执行,就开始渐渐在代码中加入异步的调用函数,发现所有调用都要改为Future。

代码第一天开始就用正确的写法以后就不会有这样的问题,facebook局部的把代码变为异步的方法。一旦异步遇到同步就马上去执行异步的数据,把结果再和同步汇总,最后facebook还是把整个网站改为异步写法。每一个函数只要有一个调用远程服务的网络IO的过程就要将其改为异步的。到一个数据库查询先发一个seng请求然后yield,还有另一个操作就是接受Response,把一个同步的等待分为一半一半,一个seng请求和接受Response。

最后发现一个网页形成一棵树,右边最下面2个叶子可以没有任何依赖性都可以到远端调用数据,调用数据都回来了后执行其共同的父节点。然后左边2个叶子没有任何依赖性的执行,每一个节点都是一个Future的object,每个节点2个状态:一个是正在等待执行,还有一个是已经执行了。只有所有的叶子节点执行后才可以开始自己的执行,逐级往上依赖的执行。

一个网页不是马上从后端服务器调用数据,而是组成一个distributed(分布式的)查询,每一个分布式查询可以组成一个依赖性树。

第一个face阶段:总调用者拿到一颗很大的树,这颗树描述数据调用的依赖性。树的每一个node都记录下来怎么调用数据。

第二个face:执行整个树,执行的过程就是所有的底层的叶子可以并行执行,再上面一层,要看执行的速度,有时候某些点快就可以上去的更早,有的点上的稍微晚点执行。无论怎么样,最后的目的是一直往上,顶点也被执行完,这个顶点就是网页的html就被完全准备好了。

发现把PHP变为这样一种语言,不像原来那样一上来就执行,而是一上来先Lazy一下,组成一个query,然后等看清楚完整的query之后再开始执行第二个face。

实例:找出所有朋友中在淘宝买过东西的人。

不能马上得到friends列表会得到一个Future的object,这个Future的object将来会告诉我有哪些朋友。

再yield return getTaoBaoBuyers(friends);需要执行第二个数据调用,是对friends有依赖性的,要知道有哪些friends,然后查这个friend有没有在淘宝购物。

如果是另一个不恰当的例子,在淘宝买保时捷的人可能不会很多就2个人。

第一个例子在淘宝上买过东西的人实际上是狠多的。

在淘宝上买保时捷少的情况下这个查询就出现这样一种问题,是找朋友还是倒过来先查那2个人在淘宝上买过保时捷,再看看这2个人那个是我的朋友?

同一个问题2个方向去解决:可以先查我的朋友,也可以先查这2个人。这2个方向是怎么决定的?

如果第二个问题沿用第一行代码就错了。

应该先查买过保时捷的人!因为第二件事情做得人比较少。

这种情况在传统数据库早就存在,因为存在表连接。在数据库优化上在join的时候会自动做这种优化,看那个表返回的少。innno join从小表这边走。表join方向的问题,传统数据库这样的问题已经被优化,但是写程序就没有做到这一点。

但是fb把网页改为异步,但是fb还没有能够在2个face之间去分析优化查询。

这个问题不仅仅是php中有。任何语言都会遇到要访问多个库的情形,是并行串行?同步异步?的问题。

用同步处理CPU的利用率上不去,用线程去处理并行方案不是最佳方案。线程设的最高300以上以及到了环境的极限。

这个时候需要用很多小小的协程等一些方案做一些小的task.

写代码必须一行行写,但是其实机器可以并行执行代码,这是人脑思维和机器执行的差异。

其实这些并行的优化就是以前数据库做的内部优化的放大。

写第一行代码就已经把表join的方向给静态固化,把哪一个class放memcached里给固化下来。这些都不是一个真正的优化过程。

要的是不要告诉我们表join从哪个方向,也不要告诉我把哪一个class放memcached里给固化,因为写这个的研发人员不知道从系统资源的角度上来说哪个class更值得放入缓存。或者以后业务有整体大的变化,有哪些新的class应该放入缓存,老的class应该从缓存搬走。

所有的这些优化应该是中间的face介于这两者之间组成查询,然后看这个查询在哪儿可以执行,最后经过这样一个优化过程当中再去执行,所有的这些是中间的调度过程中去执行优化过程。

Java和php都没有给我们这样的便利。在fb加了yield return这样的语法实际上非常类似于python的yield return,虽然有yield,但是只是把程序变成2个face。

我们没有办法把这个查询优化为一个更值得优化的一棵树再去执行。

.

只要是分布式系统就要思考怎么用异步来优化。

希望大家把计算机当成科学来看待,以后语言层面已经把异步优化给处理好。

《异步处理在分布式系统中的优化作用》学习笔记相关推荐

  1. 第二行代码学习笔记——第六章:数据储存全方案——详解持久化技术

    本章要点 任何一个应用程序,总是不停的和数据打交道. 瞬时数据:指储存在内存当中,有可能因为程序关闭或其他原因导致内存被回收而丢失的数据. 数据持久化技术,为了解决关键性数据的丢失. 6.1 持久化技 ...

  2. 第一行代码学习笔记第二章——探究活动

    知识点目录 2.1 活动是什么 2.2 活动的基本用法 2.2.1 手动创建活动 2.2.2 创建和加载布局 2.2.3 在AndroidManifest文件中注册 2.2.4 在活动中使用Toast ...

  3. 第一行代码学习笔记第八章——运用手机多媒体

    知识点目录 8.1 将程序运行到手机上 8.2 使用通知 * 8.2.1 通知的基本使用 * 8.2.2 通知的进阶技巧 * 8.2.3 通知的高级功能 8.3 调用摄像头和相册 * 8.3.1 调用 ...

  4. 第一行代码学习笔记第六章——详解持久化技术

    知识点目录 6.1 持久化技术简介 6.2 文件存储 * 6.2.1 将数据存储到文件中 * 6.2.2 从文件中读取数据 6.3 SharedPreferences存储 * 6.3.1 将数据存储到 ...

  5. 第一行代码学习笔记第三章——UI开发的点点滴滴

    知识点目录 3.1 如何编写程序界面 3.2 常用控件的使用方法 * 3.2.1 TextView * 3.2.2 Button * 3.2.3 EditText * 3.2.4 ImageView ...

  6. 第一行代码学习笔记第十章——探究服务

    知识点目录 10.1 服务是什么 10.2 Android多线程编程 * 10.2.1 线程的基本用法 * 10.2.2 在子线程中更新UI * 10.2.3 解析异步消息处理机制 * 10.2.4 ...

  7. 第一行代码学习笔记第七章——探究内容提供器

    知识点目录 7.1 内容提供器简介 7.2 运行权限 * 7.2.1 Android权限机制详解 * 7.2.2 在程序运行时申请权限 7.3 访问其他程序中的数据 * 7.3.1 ContentRe ...

  8. 第一行代码学习笔记第五章——详解广播机制

    知识点目录 5.1 广播机制 5.2 接收系统广播 * 5.2.1 动态注册监听网络变化 * 5.2.2 静态注册实现开机广播 5.3 发送自定义广播 * 5.3.1 发送标准广播 * 5.3.2 发 ...

  9. 第一行代码学习笔记第九章——使用网络技术

    知识点目录 9.1 WebView的用法 9.2 使用HTTP协议访问网络 * 9.2.1 使用HttpURLConnection * 9.2.2 使用OkHttp 9.3 解析XML格式数据 * 9 ...

  10. 安卓教程----第一行代码学习笔记

    安卓概述 系统架构 Linux内核层,还包括各种底层驱动,如相机驱动.电源驱动等 系统运行库层,包含一些c/c++的库,如浏览器内核webkit.SQLlite.3D绘图openGL.用于java运行 ...

最新文章

  1. 一:HDFS 用户指导
  2. 数据库面试知识点汇总
  3. django-中间件0911-2
  4. 面试经历-19-03-14
  5. MIT自适应律MRAC的理解和MATLAB实现
  6. Atitit 信用卡与会员卡(包括银行卡)的发展之路
  7. ARINC 429总线学习资料?
  8. html词云图生成,图悦在线词云图制作工具
  9. 小觅相机运行VINS-Fusion(二)——Camera-IMU参数标定
  10. 用python 控制台打印图片示例
  11. CSDN 技术问答升级规则
  12. 华为云RDS全量备份恢复到自建数据库(数据库qp文件恢复)
  13. Python语言在人工智能(AI)中的优势
  14. 浏览器实现pdf下载、ms http下载、IE不兼容
  15. 聊下git merge --squash
  16. 2021年塔式起重机司机考试及塔式起重机司机复审考试
  17. 【Java】1、Java 基础入门
  18. LaTeX--简易教程--论文写作神器
  19. 利用js实现抽奖小游戏
  20. 烤仔说 | 全员戒备,保护学费!

热门文章

  1. html5的在线播放页面,整理5款html5网页播放器,总有一款适合你吧
  2. Python,OpenCV中的K近邻(knn K-Nearest Neighbor)及改进版的K近邻
  3. C语言:随笔9--链表
  4. C++:while(getline())函数
  5. Python Qt GUI设计:QLabel标签类(基础篇—11)
  6. 液体测量技术:从水到血液
  7. 力扣(LeetCode)刷题,简单题(第21期)
  8. 三、如何搞自定义数据集?
  9. url获取网站信息不包含网页源文件内的标签_前嗅ForeSpider链接抽取应用场景及链接在源码的html标签里写脚本...
  10. 一个精简的开源点云库