https://mp.weixin.qq.com/s/NMIIa0W722zo_AxCqASc0g

TiDB 与 gRPC 的那点事儿

黄东旭 PingCAP 2017-08-10
 

gRPC 背景介绍

其实做分布式系统那么久,几乎也是天天和 RPC 打交道,要说 各个模块是系统的筋肉,那 RPC 就是整个系统的血管,数据的流通,信令的传递,都离不开 RPC。

RPC 并不是一个固定的东西,可重可轻,重的如同 MS 的 DCOM,JAVA 的 EJB,轻的 HTTP 也可以说是 RPC,甚至自己写个 TCP 的文本通信协议也算。

大家也都知道 Google 内部其实没怎么用 gRPC,大量使用的是 Stubby,它作为 gRPC 的前身,也是一个 Protobuf RPC 的实现,因为大量依赖了 Google 的其他基础服务所以不太方便开放出来给社区使用。

随着 SPDY / QUIC,乃至 HTTP/2  的成熟,Google 决定用这些更加标准的组件来构建一个新的 RPC 框架,也就是 gRPC。不过这个项目过于庞大,而且 Google 内部 Stubby 已经用了超过 10 年,很难直接替换,毕竟程序员最烦的事情之一就是去改跑着好好的老代码。。。

不过 anyway,尽管 gRPC 没有在 Google 内部广泛使用,也是给社区带来了一个非常好的基础组件,现在为止包括 ETCD / Kubernetes / TiDB 在内的大量社区顶级开源分布式项目都在使用它。

为何选择 gRPC?

有人说,RPC 多简单啊,不就是一个长连接,Sender 和 Reciver 来回发包嘛,顶多再搞个服务发现做 Failover,搞得那么复杂为啥。另外要强大不是已经有 EJB 什么的嘛,gRPC 的意义何在?我想从官方的 gRPC 的设计动机和原则说起:

1、Google 应该是践行服务化的先驱之一,在业界没那么推崇微服务的时代,Google 就已经大规模的微服务化。

微服务的精髓之一就是服务之间传递的是可序列化消息,而不是对象和引用,这个思想是和 DCOM 及 EJB 完全相反的。只有数据,不包含逻辑;这个设计的好处不用我多说也很好理解,参考 CSP 。

2、Protobuf 作为一个良好的序列化方案,注意,只是 序列化(尽管 pb 也有定义 rpc service 的能力,Protobuf 默认生成的代码并不包含 RPC 的实现),它并不像 Thrift 天生就带一个 RPC Framework,相对的来说比较轻。

在 gRPC 的设计中,一个很重要的原则就是 Payload agnostic,RPC 框架不应该规定用的是什么 payload 格式,可以是 Protobuf,JSON,XML,这也让 gRPC 的设计和层次更加清晰。

3、比传统的 Request / Response 更丰富的 API Interface,这个是我们使用 gRPC 的重要理由,gRPC 不仅支持传统的一应一答的模式,更是支持三种 Streaming 的调用方式,现代的业务经常会需要传输大的数据流,Streaming API 的设计让这些业务写起来轻松很多。

4、有了 Streaming 就不可避免地需要引入 Flow-control ,这点 gRPC 的处理很聪明,直接依赖了 HTTP/2,在流控这边不怎么用操心,顺带还可以用 HTTP 反向代理做负载均衡。

但是另一方面也会带来更多的调优复杂度,毕竟和 Web 的使用场景不太一样,比如默认的 INITIAL_WINDOW_SIZE 在 gRPC 里是 64k,太小,吞吐上不去,需要人工改大。

5、另一方面由于直接使用了 HTTP/2,TLS 的支持就几乎是天然的,对于 TiDB 这样的商业数据库而言,传输层加密是一个很重要的功能,在 gRPC 中直接就可以支持。本着不重新造轮子的原则,直接用 gRPC 就好了。

https://mp.weixin.qq.com/s/nH4WG1lY56LvXATh_cvPVw

深度解析gRPC以及京东分布式服务框架跨语言实战

闫家宝 亿级流量网站架构 2017-02-22

gRPC设计动机和原则

最初由Louis Ryan在谷歌其他同事帮助下写成,如下文:

设计动机

十多年来,谷歌一直使用一个叫做Stubby的通用RPC基础框架,用它来连接在其数据中心内和跨数据中心运行的大量微服务。其内部系统早就接受了如今越来越流行的微服务架构。拥有一个统一的、跨平台的RPC的基础框架,使得服务的首次发行在效率、安全性、可靠性和行为分析上得到全面提升,这是支撑这一时期谷歌快速增长的关键。

Stubby有许多非常棒的特性,然而,它没有基于任何标准,而且与其内部的基础框架耦合得太紧密以至于被认为不适合公开发布。随着SPDY、HTTP/2和QUIC的到来,许多类似特性在公共标准中出现,并提供了Stubby不支持的其它功能。很明显,是时候利用这些标准来重写Stubby,并将其适用性扩展到移动、物联网和云场景。

设计原则

●  服务非对象、消息非引用 —— 促进微服务的系统间粗粒度消息交互设计理念,同时避免分布式对象的陷阱和分布式计算的谬误。

●  普遍并且简单 —— 该基础框架应该在任何流行的开发平台上适用,并且易于被个人在自己的平台上构建。它在CPU和内存有限的设备上也应该切实可行。

●  免费并且开源 —— 所有人可免费使用基本特性。以友好的许可协议开源方式发布所有交付件。

●  互通性 —— 该报文协议(Wire Protocol)必须遵循普通互联网基础框架。

●  通用并且高性能 —— 该框架应该适用于绝大多数用例场景,相比针对特定用例的框架,该框架只会牺牲一点性能。

●  分层的 —— 该框架的关键是必须能够独立演进。对报文格式(Wire Format)的修改不应该影响应用层。

●  负载无关的 —— 不同的服务需要使用不同的消息类型和编码,例如protocol buffers、JSON、XML和Thrift,协议上和实现上必须满足这样的诉求。类似地,对负载压缩的诉求也因应用场景和负载类型不同而不同,协议上应该支持可插拔的压缩机制。

●  流 —— 存储系统依赖于流和流控来传递大数据集。像语音转文本或股票代码等其它服务,依靠流表达时间相关的消息序列。

●  阻塞式和非阻塞式 —— 支持异步和同步处理在客户端和服务端间交互的消息序列。这是在某些平台上缩放和处理流的关键。

●  取消和超时 —— 有的操作可能会用时很长,客户端运行正常时,可以通过取消操作让服务端回收资源。当任务因果链被追踪时,取消可以级联。客户端可能会被告知调用超时,此时服务就可以根据客户端的需求来调整自己的行为。

● Lameducking —— 服务端必须支持优雅关闭,优雅关闭时拒绝新请求,但继续处理正在运行中的请求。

● 流控 —— 在客户端和服务端之间,计算能力和网络容量往往是不平衡的。流控可以更好的缓冲管理,以及保护系统免受来自异常活跃对端的拒绝服务(DOS)攻击。

● 可插拔的 —— 数据传输协议(Wire Protocol)只是功能完备API基础框架的一部分。大型分布式系统需要安全、健康检查、负载均衡和故障恢复、监控、跟踪、日志等。实   现上应该提供扩展点,以允许插入这些特性和默认实现。

● API扩展 —— 可能的话,在服务间协作的扩展应该最好使用接口扩展,而不是协议扩展。这种类型的扩展可以包括健康检查、服务内省、负载监测和负载均衡分配。

● 元数据交换 —— 常见的横切关注点,如认证或跟踪,依赖数据交换,但这不是服务公共接口中的一部分。部署依赖于他们将这些特性以不同速度演进到服务暴露的个别API的能力。

● 标准化状态码 —— 客户端通常以有限的方式响应API调用返回的错误。应该限制状态代码名字空间,使得这些错误处理决定更清晰。如果需要更丰富的特定域的状态,可以使用元数据交换机制来提供。

gRPC设计动机和原则的更多相关文章

  1. 面向对象设计SOLID五大原则

    转载自:码农社区,http://w3croom.com/read.php?tid-4522.html 今天我给大家带来的是面向对象设计SOLID五大原则的经典解说.       我们知道,面向对象对于 ...

  2. auto_ptr的设计动机

    auto_ptr的设计动机 C++标准程序库提供的auto_ptr是一种智能型指针(smart pointer),帮助程序员防止“被异常抛出时发生资源泄露”. 函数的操作经常依以下模式进行: 1.获取 ...

  3. 二叉排序树、平衡二叉树、B树&B+树、红黑树的设计动机、缺陷与应用场景

    之前面试时曾被问到"如果实现操作系统的线程调度应该采用什么数据结构?",因为我看过ucore的源码,知道ucore是采用斜堆的方式实现的,可以做到O(n)的插入.O(1)的查找.我 ...

  4. 进阶篇:4.1)DFA设计指南:简化产品设计(kiss原则)

    本章目的:理解kiss原则,明确如何简化产品的设计. 1.前言:kiss原则,优化产品的第一原则 如果要作者选出一个优化产品的最好方法,那一定是kiss原则莫属.从产品的整体设计到公差的分析,kiss ...

  5. Mysql设计索引的原则

    内容来自书籍<深入浅出MySQL++数据库开发.优化与管理维护+第2版+唐汉明> 设计索引的原则1. 搜索的索引列,不一定是所要选择的列.换句话说,最适合索引的列是出现在 WHERE 子句 ...

  6. # 61条面向对象设计的经验原则-《OOD启思录》Arthur J.Riel

    61条面向对象设计的经验原则-<OOD启思录>Arthur J.Riel 原文 http://blog.csdn.net/cpluser/article/details/129291 61 ...

  7. 【转】面向对象设计的SOLID原则

    S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写. SRP The Single Responsibility ...

  8. 面向对象设计的SOLID原则

    S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写. SRP The Single Responsibility ...

  9. Delphi面向对象设计的经验原则(61条)

    (1)所有数据都应该隐藏在所在的类的内部. (2)类的使用者必须依赖类的共有接口,但类不能依赖它的使用者. (3)尽量减少类的协议中的消息. (4)实现所有类都理解的最基本公有接口[例如,拷贝操作(深 ...

随机推荐

  1. matplotlib学习日记(十)-共享绘图区域的坐标轴

    (1)共享单一绘图区域的坐标轴 ''' 上一讲介绍了画布的划分,有时候想将多张图放在同一个绘图区域, 不想在每个绘图区域只绘制一幅图形,这时候借助共享坐标轴的方法实现在一个绘图区 绘制多幅图形的目的. ...

  2. Redis基础篇(三)持久化:AOF日志

    Redis是内存数据库,但是一旦服务器宕机,内存中的数据将会全部丢失. 最简单的恢复方式是从后端数据库恢复,但这种方式有两个问题: 频繁访问数据库,会给数据库带来巨大的压力: 从数据库中读取相比从Re ...

  3. select * from 多张表的用法

    select * from 多张表的用法   其实就是 inner join   select * from Class c,Student s where c.ClassID=s.ClassID   ...

  4. HTML颜色

  5. application.properties 中文乱码问题解决

    1. 设置 File Encodings的Transparent native-to-ascii conversion为true,具体步骤如下:依次点击 File -> Settings -&g ...

  6. PO,BO,VO,DTO,POJO,DAO,DO是什么?

    PO (Persistent Object)   持久化对象,表示实体数据.BO (Business Object)        业务对象,主要是把逻辑业务封装为一个对象 .VO (Value/Vi ...

  7. String -- 从源码剖析String类

    几乎所有的 Java 面试都是以 String 开始的,String 源码属于所有源码中最基础.最简单的一个,对 String 源码的理解也反应了你的 Java 基础功底. String 是如何实现的 ...

  8. .net core 中使用Log4net输出日志到Mysql数据库中

    .net core 中使用Log4net输出日志到数据库中去 1.使用Nuget安装log4net 和 mysql.data 2.设置log4net 的配置文件 log4net.config 可以设置 ...

  9. 为什么 TCP 连接的建立需要三次握手

    TCP 的通讯双方需要发送 3 个包(即:三次握手)才能建立连接,本文将通过 3 副图来解释为什么需要 3 次握手才能建立连接. TCP 连接的建立过程本质是通信双方确认自己和对方都具有通信能力的过程 ...

  10. MySql中的有条件插入 insert where

    假设现在我们有这样的需求:当数据库中不存在满足条件的记录时,可以插入一条记录,否则程序退出.该怎么实现? 1年以上工作经验的人应该都能立即想到:去检查一下库里有没有记录,没有就插入,有就结束. int ...