From 3cadfb152fee3160be689ee4545e15dfcf8ebd37 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 14 Dec 2016 07:52:47 -0800 Subject: [PATCH 1/7] Started updating docs. --- doc/images/load-balancing.svg | 4 + doc/images/load_balancing_design.png | Bin 40354 -> 0 bytes doc/load-balancing.md | 128 +++++++++-------- doc/naming.md | 49 +++++-- doc/service_config.md | 201 +++++++++++++++++++++++++++ 5 files changed, 317 insertions(+), 65 deletions(-) create mode 100644 doc/images/load-balancing.svg delete mode 100644 doc/images/load_balancing_design.png create mode 100644 doc/service_config.md diff --git a/doc/images/load-balancing.svg b/doc/images/load-balancing.svg new file mode 100644 index 00000000000..425a9d33aa7 --- /dev/null +++ b/doc/images/load-balancing.svg @@ -0,0 +1,4 @@ + + + + diff --git a/doc/images/load_balancing_design.png b/doc/images/load_balancing_design.png deleted file mode 100644 index 86183966fb88e24a5a86dbd4b62ae2a308d0a542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40354 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 in bytes. The size which is measured is + # the serialized, uncompressed payload in bytes. This applies both + # to streaming and non-streaming requests. + # + # The actual value used is the minimum of the value specified here and + # the value set by the application via the gRPC client API. + # If either one is not set, then the other will be used. + # If neither is set, then the built-in default is used. + # + # If a client attempts to send an object larger than this value, it + # will not be sent and the client will see an error. + # Note that 0 is a valid value, meaning that the request message must + # be empty. + # + # The format of the value is that of the 'uint64' type defined here: + # https://developers.google.com/protocol-buffers/docs/proto3#json + 'maxRequestMessageBytes': string, + + # The maximum allowed payload size for an individual response or object + # in a stream (server->client) in bytes. The size which is measured is + # the serialized, uncompressed payload in bytes. This applies both + # to streaming and non-streaming requests. + # + # The actual value used is the minimum of the value specified here and + # the value set by the application via the gRPC client API. + # If either one is not set, then the other will be used. + # If neither is set, then the built-in default is used. + # + # If a server attempts to send an object larger than this value, it + # will not be sent, and the client will see an error. + # Note that 0 is a valid value, meaning that the response message must + # be empty. + # + # The format of the value is that of the 'uint64' type defined here: + # https://developers.google.com/protocol-buffers/docs/proto3#json + 'maxResponseMessageBytes': string + } + ] +} +``` + +# Architecture + +A service config is associated with a server name. The [name +resolver](naming.md) plugin, when asked to resolve a particular server +name, will return both the resolved addresses and the service config. + +TODO(roth): Design how the service config will be encoded in DNS. + + + + +The gRPC load balancing implements the external load balancing server approach: +an external load balancer provides simple clients with an up-to-date list of +servers. + +![image](images/load_balancing_design.png) + +1. On startup, the gRPC client issues a name resolution request for the service. + The name will resolve to one or more IP addresses to gRPC servers, a hint on + whether the IP address(es) point to a load balancer or not, and also return a + client config. +2. The gRPC client connects to a gRPC Server. + 1. If the name resolution has hinted that the endpoint is a load balancer, + the client's gRPC LB policy will attempt to open a stream to the load + balancer service. The server may respond in only one of the following + ways. + 1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client + call will fail. + 2. "I am a Load Balancer and here is the server list." (Goto Step 4.) + 3. "Please contact Load Balancer X" (See Step 3.) The client will close + this connection and cancel the stream. + 4. If the server fails to respond, the client will wait for some timeout + and then re-resolve the name (process to Step 1 above). + 2. If the name resolution has not hinted that the endpoint is a load + balancer, the client connects directly to the service it wants to talk to. +3. The gRPC client's gRPC LB policy opens a separate connection to the Load + Balancer. If this fails, it will go back to step 1 and try another address. + 1. During channel initialization to the Load Balancer, the client will + attempt to open a stream to the Load Balancer service. + 2. The Load Balancer will return a server list to the gRPC client. If the + server list is empty, the call will wait until a non-empty one is + received. Optional: The Load Balancer will also open channels to the gRPC + servers if load reporting is needed. +4. The gRPC client will send RPCs to the gRPC servers contained in the server + list from the Load Balancer. +5. Optional: The gRPC servers may periodically report load to the Load Balancer. + +## Client + +When establishing a gRPC _stream_ to the balancer, the client will send an initial +request to the load balancer (via a regular gRPC message). The load balancer +will respond with client config (including, for example, settings for flow +control, RPC deadlines, etc.) or a redirect to another load balancer. If the +balancer did not redirect the client, it will then send a list of servers to the +client. The client will contain simple load balancing logic for choosing the +next server when it needs to send a request. + +## Load Balancer + +The Load Balancer is responsible for providing the client with a list of servers +and client RPC parameters. The balancer chooses when to update the list of +servers and can decide whether to provide a complete list, a subset, or a +specific list of “picked” servers in a particular order. The balancer can +optionally provide an expiration interval after which the server list should no +longer be trusted and should be updated by the balancer. + +The load balancer may open reporting streams to each server contained in the +server list. These streams are primarily used for load reporting. For example, +Weighted Round Robin requires that the servers report utilization to the load +balancer in order to compute the next list of servers. + +## Server + +The gRPC Server is responsible for answering RPC requests and providing +responses to the client. The server will also report load to the load balancer +if a reporting stream was opened for this purpose. From 8fda5511cb8dea5cb7fcd163253893f3d89357a1 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 14 Dec 2016 08:05:55 -0800 Subject: [PATCH 2/7] Finish docs. --- doc/load-balancing.md | 44 ++++-------------------- doc/service_config.md | 78 +++++++------------------------------------ 2 files changed, 19 insertions(+), 103 deletions(-) diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 03c9bd2cbad..4ed938c9903 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -11,7 +11,7 @@ instruct the client how to send load to multiple backend servers. Prior to any gRPC specifics, we explore some usual ways to approach load balancing. -### Proxy Model +## Proxy Model Using a proxy provides a solid trustable client that can report load to the load balancing system. Proxies typically require more resources to operate since they @@ -21,7 +21,7 @@ latency to the RPCs. The proxy model was deemed inefficient when considering request heavy services like storage. -### Balancing-aware Client +## Balancing-aware Client This thicker client places more of the load balancing logic in the client. For example, the client could contain many load balancing policies (Round Robin, @@ -41,7 +41,7 @@ It would also significantly complicate the client's code: the new design hides the load balancing complexity of multiple layers and presents it as a simple list of servers to the client. -### External Load Balancing Service +## External Load Balancing Service The client load balancing code is kept simple and portable, implementing well-known algorithms (e.g., Round Robin) for server selection. @@ -56,7 +56,7 @@ servers to collect load and health information. # Requirements -### Simple API and client +## Simple API and client The gRPC client load balancing code must be simple and portable. The client should only contain simple algorithms (e.g., Round Robin) for @@ -68,7 +68,7 @@ unavailability or health issues. The load balancer will make any necessary complex decisions and inform the client. The load balancer may communicate with the backend servers to collect load and health information. -### Security +## Security The load balancer may be separate from the actual server backends and a compromise of the load balancer should only lead to a compromise of the @@ -90,13 +90,13 @@ However, there are only a small number of these (one of which is the are discouraged from trying to extend gRPC by adding more. Instead, new load balancing policies should be implemented in external load balancers. -## Load Balancing Policies +## Workflow Load-balancing policies fit into the gRPC client workflow in between name resolution and the connection to the server. Here's how it all works: -![image](images/load_balancing_design.png) +![image](images/load-balancing.svg) 1. On startup, the gRPC client issues a [name resolution](naming.md) request for the server name. The name will resolve to one or more IP addresses, @@ -130,33 +130,3 @@ works: received. 6. The gRPC client will send RPCs to the gRPC servers contained in the server list from the Load Balancer. - -## Client - -When establishing a gRPC _stream_ to the balancer, the client will send an initial -request to the load balancer (via a regular gRPC message). The load balancer -will respond with client config (including, for example, settings for flow -control, RPC deadlines, etc.) or a redirect to another load balancer. If the -balancer did not redirect the client, it will then send a list of servers to the -client. The client will contain simple load balancing logic for choosing the -next server when it needs to send a request. - -## Load Balancer - -The Load Balancer is responsible for providing the client with a list of servers -and client RPC parameters. The balancer chooses when to update the list of -servers and can decide whether to provide a complete list, a subset, or a -specific list of “picked” servers in a particular order. The balancer can -optionally provide an expiration interval after which the server list should no -longer be trusted and should be updated by the balancer. - -The load balancer may open reporting streams to each server contained in the -server list. These streams are primarily used for load reporting. For example, -Weighted Round Robin requires that the servers report utilization to the load -balancer in order to compute the next list of servers. - -## Server - -The gRPC Server is responsible for answering RPC requests and providing -responses to the client. The server will also report load to the load balancer -if a reporting stream was opened for this purpose. diff --git a/doc/service_config.md b/doc/service_config.md index 6093fc34453..7318b69f214 100644 --- a/doc/service_config.md +++ b/doc/service_config.md @@ -123,6 +123,9 @@ The service config is a JSON string of the following form: } ``` +Note that new per-method parameters may be added in the future as new +functionality is introduced. + # Architecture A service config is associated with a server name. The [name @@ -131,71 +134,14 @@ name, will return both the resolved addresses and the service config. TODO(roth): Design how the service config will be encoded in DNS. +# APIs +The service config is used in the following APIs: - -The gRPC load balancing implements the external load balancing server approach: -an external load balancer provides simple clients with an up-to-date list of -servers. - -![image](images/load_balancing_design.png) - -1. On startup, the gRPC client issues a name resolution request for the service. - The name will resolve to one or more IP addresses to gRPC servers, a hint on - whether the IP address(es) point to a load balancer or not, and also return a - client config. -2. The gRPC client connects to a gRPC Server. - 1. If the name resolution has hinted that the endpoint is a load balancer, - the client's gRPC LB policy will attempt to open a stream to the load - balancer service. The server may respond in only one of the following - ways. - 1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client - call will fail. - 2. "I am a Load Balancer and here is the server list." (Goto Step 4.) - 3. "Please contact Load Balancer X" (See Step 3.) The client will close - this connection and cancel the stream. - 4. If the server fails to respond, the client will wait for some timeout - and then re-resolve the name (process to Step 1 above). - 2. If the name resolution has not hinted that the endpoint is a load - balancer, the client connects directly to the service it wants to talk to. -3. The gRPC client's gRPC LB policy opens a separate connection to the Load - Balancer. If this fails, it will go back to step 1 and try another address. - 1. During channel initialization to the Load Balancer, the client will - attempt to open a stream to the Load Balancer service. - 2. The Load Balancer will return a server list to the gRPC client. If the - server list is empty, the call will wait until a non-empty one is - received. Optional: The Load Balancer will also open channels to the gRPC - servers if load reporting is needed. -4. The gRPC client will send RPCs to the gRPC servers contained in the server - list from the Load Balancer. -5. Optional: The gRPC servers may periodically report load to the Load Balancer. - -## Client - -When establishing a gRPC _stream_ to the balancer, the client will send an initial -request to the load balancer (via a regular gRPC message). The load balancer -will respond with client config (including, for example, settings for flow -control, RPC deadlines, etc.) or a redirect to another load balancer. If the -balancer did not redirect the client, it will then send a list of servers to the -client. The client will contain simple load balancing logic for choosing the -next server when it needs to send a request. - -## Load Balancer - -The Load Balancer is responsible for providing the client with a list of servers -and client RPC parameters. The balancer chooses when to update the list of -servers and can decide whether to provide a complete list, a subset, or a -specific list of “picked” servers in a particular order. The balancer can -optionally provide an expiration interval after which the server list should no -longer be trusted and should be updated by the balancer. - -The load balancer may open reporting streams to each server contained in the -server list. These streams are primarily used for load reporting. For example, -Weighted Round Robin requires that the servers report utilization to the load -balancer in order to compute the next list of servers. - -## Server - -The gRPC Server is responsible for answering RPC requests and providing -responses to the client. The server will also report load to the load balancer -if a reporting stream was opened for this purpose. +- In the resolver API, used by resolver plugins to return the service + config to the gRPC client. +- In the gRPC client API, where users can query the channel to obtain + the service config associated with the channel (for debugging + purposes). +- In the gRPC client API, where users can set the service config + explicitly. This is intended for use in unit tests. From b3f811c7397e06d5c80317bdbda900aed914cf4a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 14 Dec 2016 08:10:11 -0800 Subject: [PATCH 3/7] Add image in PNG format. --- doc/images/load-balancing.png | Bin 0 -> 27733 bytes doc/load-balancing.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 doc/images/load-balancing.png diff --git a/doc/images/load-balancing.png b/doc/images/load-balancing.png new file mode 100644 index 0000000000000000000000000000000000000000..18b68bfdad83d15b33f37eeeb98f582feb8ee0c0 GIT binary patch literal 27733 zcmeFZg;!M3_cwfJXb@>pDFFecrBjd)gOu))?qzK{e9Q_yzlc5ylXvox$tuCxhM8MXYYMJ`*VpSU3!CB*Am+_s3`Lm094P0pkTrK=5C6~4pEZi(E<|_PW{9#=c+`a$v&+x02TAkY;hvgR(Ub+AvA!n+UQXI$(4h8`D*&Njz-&%uR%J{R&WnhbP-`|Sh$-4yr zQ&Ib>M~a~{U>SJH(h3R|u3YeD-pBs-498LsfQ#Hgp$PwuP5rhO>6wCpwk-g!;ZI}7 zR=G!$l7?*$ygY?HvZt;w2-*?@@UgPH*?Tl#p{)LJ)srGyd;tC+A?LG~YQ2}W z2yC0x**Ms6%3Gw{c_>iilQ>FgdZtB?b^ih|lOk~sVuApfL@^4&F2n#*0e6pr1HZDS zH!w&5O=k)9ZN$vi2BwoA;USuu{AX?aDGjMcn`*eyzK>zTv%8wwqGlhYdAGw9EpQ?b z9&6c7PMqXOj~RCdum^(KdhB#%Nrvylod!e9vY~ZPz94*hui@dknhr=D)n_D^_czx* zuu0>XT{~R;@iG75F7DnEa!oLG?_C=5I?;lv8!qG;*u;>ZMKb6=u8C1_4z3$rbIalFhi(SPQ95 z4Ql#M5*wgUO%TuV-*%~NDAQNlj8+s}bD(-5La-NPjaG>w%y1=v*W)I9_HFeW^f4m! zs;p4o+UXiTEw4-B>N#35(G@PfgPPj;W|VF=JML}ZW-SERlP3n86y{9BuHLNTGYwF@ zKID8p&4K{gAWX` z6C!Yc9GM<6QIlj=+zZYj%2%t043X{HpQCagNoCW#+Uitoe#_*iLy+6})~=sUwCd;_|pre9Sf3mgmkD&Kf-?9#ITcomX}d^m}8 z7fc~X#y&ojUW~OKXf~Nm(wg*suM{gfTko z$>66@K!>@+QgvqFhrV@-`$D`RT9bF_j*foPlo_ZfMJz4@ zuKlYV|hGuH$AAJ?h;^Tfv<@lbAM$*LP0vmv(@5 zv#D*ebC?~AY3A=Ma4PV5b(>F5Zgkq$d>XT;omuLG@sZF^f0#RZoGmCV?7geMYIS5j zt*N+e>?{rT@VASoN$N29ZEjKThbp)Lzm+;2SPp8AM`7_B@%$l)>ixkZ1+CWa)S!`d z#sL<>sR7OqxsZgx!gIY9fGN7mUE|Ls^uNy-sHxJM8_xMU1@x7sI~`oS-_xW6)!P7j}uue8JwS-#Ej*fGzlY{XeUN zPZ^GeK)ryQ3%t6V002q$*M}^N0Dr{-4%dwikR9Zo=yEE3vaNA#D-Mw<2~HE+Ozvx% zU8UO{5_WIF*RhkA?T%OCH3=9&FU2-3hus|08Sz@h$BX@W2sV!0IIwqBn!xka^KE}o zOFcuC@mttduq&BgTjmR)*)_<_t?$*{-_!E=ESg8g&o=C_BLho|pr4HV-_5|zSRR{# zedF@K0d|Rg26^|Z@I|8h_Ox$~ecWh>c*0<7XKLg*Y4wM|z?}~M_xI_)Dxkprw+gaeHy;6( zgl5>e;Q##rtmEB#9mWi&z>a|&sV9ucLgYIwJDL_GcfPPca_ToN&TE* z>-1;qQ9mugmTn*gDW~bGOU>y2zOR&h>}!!iIsJa(NB%i1meA}SiykPdg&!nllVj1k zUSEOBg`UZRvV$Eb8D!@SD z5b8TMdBxsx(r(u_v`|R0AagP!TyNg3YaHa<(06s#MM}6(K!cQz;PIJO#I|rGC|&+4 z{|3zbJ8Ki&Kj{Gg!mO+hdXj}PiK8P<0c7p)t0}Yb$ zWt5Ab2|u;OT{v6SL3&eH?W`DUP@Ce~m(s&=Q&kkA4xN2c@qFN^hx5hCUB<)o8s-s< zs1bU`?OV;=!j-i2%hbvx!xEWb&%lUg9YV7mwce9E!uhd_{drsNj#{NVnq_WA$EZtKf=(CwbXLi$Z*WI z#5~&BjPj-`p={aBWo*5q5d@bmxLdfj0-Q}Prio}<6XWZIVsjHmYN}HCgrWvi z7)KmwY$N1XE;rHRGk$GiY6UwZO~0n{7%H2JR)hnu#nJPT@%?)?({j^E@Udgt9qVpB4TRICloK6x zla7r*eN8OFa|~{`3t@NbV{jW*MS7EN8nVL=4WN8Ip>j4!@v;dg{i`I;4-^M9H%ZKh z)lx;y1)rcI+K4&$|hosS_&Xzkz zcvZN$1G>|~eD2FUey+MHPfEWRPa%}&562>}Mq!zC#Aw|21T(T7O%rn`wRTOY_MCfj;vH>_jmL*W zgN$AWI*Er7c4?L-6x>9HI~`3w#vZQj2*($xuWpwo6HHD`ggT7nyaPpKDQ%4VT)dUo zfA`pt0&64k4g@{%fOQH;DrwjNFDojSSXY0pM7h_n#Gwe+RcoPHn5$4ZEeWT1d_UD1 zouKkjq(P0yHbRZa9;3`?K=YY6O>OKK@2UnEVPEYPBqI}QC)?Ai`KT^xRO9uhQ(V)Y zEEZiSG1JZpq{ND4TD6r5sXrZsHFjVut_c+bSDSH{LY%wJO4vb|8y8*~ZegTWwdL)* z=(wH_+u=6PA^b<)c($2(pR`R!lcATnb}s>vfD*@td1hsfBJ zOC4z7)DO{6A-^(uvck)GOQ6ODEpPvIM!1kjY$ii(V4@Oyi-c-G=icSA&04h<@Z79d zlP)<&*StTd9AS-D7Gs>%tC1U*pzVFVIy|(vkk7#wW>b0E5u{hqLI$(+AclkkfhJ6IwEvy-_J(2 zlpg~rpFTc02+O6(B<|Or=@WXA{Nj7AUPZPpj(7g0;3gd#D#qqOl@hb%vr){J?1ppMTUMJlVuv=65OHk2jSDq9du~u96cVm(Uu!?=rKPV zw|kY)>+-a={A4$&8+CG$^7Hs&Wh}OdOPYO0vy^FSUv_%>T=Z(472LCXA5%hK9yJ~K z4O=B8tlpdtaN;Sv&n41&b~dhwO9B85@_-Fm+36NlCb32$@&myOsES43YPM4tAVQW; zBuiw%6~xBp`CV{kTMEg(er{P+@TN+Q$b{-E7Usf+S)meY}OFf0HY*w~mD_}8&eOn-N~JVRaDpSKs;YbI@!)|i*B z83{@Tou@F-*UB_s{n2dV9tWTaOfMSvTR6`n$i%-BGw#i9&*lUT6|xEG365z-gJYPnMJ24kGGTUW*TBi;usM`<)&elmt>`t?=GYPu#W zM9yJ2(?@jTwb^p|Q!#QWmA&^<4aJ-He?6NiB&}E+pse4=<@%)uH3;^)oE&m()}eb6 zw?$tyyDh%ywLXJD9DYW*4W@_0$UEii6d`_DXE{+Y#HYu+%WCD9Ds;T095)Vtw9 zH0=kSP$+w7xVM=UvwQVkoc3!XEekga(FD3(b2)LYpvv|kxtdC-UiT&gGr1iI4I5 zr0L~~5UtO8b*akyv2@zL`)(a(*Rx)2#!cxw$ES()vd7rxYp#)AGsmlwMMLL^tCJSY zYs^m!-3^{+Nh5zS=_4$V;+g5g)`RDN0@15qF?M(P^e{i&rrjR;c90fajBT0F8kxYF zGJ;mPmfN;U)l{6~`*-?@%@|sb;-wkWq6Rd(F_$SWjN^&+(|p&i;l@77`Za|;Z-Sw* z9u2Om?H;490)RQ{NQL-zs?FI5gabkKToHaC>L9G@8_VBVt$)q6eO z)a-|#H*F4DF1`MnG4Du&FIXqtbiRYGhtF9A*YC#y*H4l7W4)|NffZ?+=4E?9lJP`4 zakOg@!v)GXYgzLy95GK{@}za+rKyzqFIq!pI9ot9f+QWCdeRWZ7c(f0**-~}tXzIR zAjwDL-$LHJRamry9u&7ZIJvujSJl*gSn7fS7WyLji=7Pg{*Tc~b2~lG|JHJ#vmxUfK%`BJR z%kkPKwxGq+>g+g!$CzJN9_hzT2bI?DaGAqM-7jl=BM*j^dGYIk95mWV>^$ zXibB}|06*=JlE#7Mi>7X39E8xQu<060QCuIai1g6e3Uz*-<)`?B_{xeb^CX31da$$ zrcp)&Jtzh>%A(t{P(4npnZ6EtGGR~088EsoafrLOU;W%ZVemsM<&FSD<(xmtW=^EU z$@7x3$>6bt@lIiYb+1QyJNY{2amvqwZ$F65U~(!G$$6SAzZ5KVfZn^G*k<~oINKav zzev|<=5WbZD96o&J!T`Xo+&D+v#9E+OdNNJ7?BA;r+9#&TDlfh@qWXzd(TqOSVYu- z=dKt=Jy`x>%VqMK?vifrshp09Wpmz9*#(GgNr+HQ?;A`Xp|*=gNr&C^48IG~pFR8y z!$wV>WT0^_j>6q5$Hzy^z6_ovf;gJj7d<>(bwd@s@OT2OeU?i~=-6`U0C#e7fqEh= z#dI%QKWDL%eIl|@UNqTqS~+Eu3c0^N(0Y-)ARm&%9q^~FrrzoY>2hLxl334gTD4ce zZgtQ|O^cX5gj+2KH(h2YZrdk`mz3BnqH|jW6!1v}Gm{FY~nIz*&BbdU2zzy^IJHdRZb{jc|GJ_6xGTc@B}(30Vs! zR4C|U@|bQoCVZ5K>amQun^%{}<+9;dZegH$+Mfb7=Srnof_M=yIEN;@M+&+BqE-%= zKJx6FEJ*zr%Z+l@@b%3{j!_euwa%w@;>@_3N~P~afoFpok@RQEbJN8@BAf&qB3t;r zUB4h0O=b76zrcOo&fi!Z>hV45HYIYtX)S%mLWgpf-QYsqMi4=V*PaBL&M+xa&KLcH zh;VXy4_L!<9o(V}@KE^oycv#9J3>d^q5T7LN#K$x&C?jrh*w7R)zO@T%Hhx*zEZC3 zT#V{>x{E8}kjR?Sk2qAxnoRB$)e7xVem!&C_a@ToX&o1;J{_nLsXOc9>VlOA7QulM zzrTCignY^K`KK3vwQ6r{=uPO?+jM#c3n5KU$dT3H43>%ZgRhY4e)nGYt8uYw&;~+0wvE{@2i-m76UpE&ahdLWE`v> zU`3PkW<=%@_FUHz4nv=rtr9K7x$3N}=eNFrh{un(w8yEC$>~qG@?Ddfy6m|kmK?urJ;p7YQrx<4)b#n;C<8fi2m;yGwH7fi zl$yYH1A?J)u>PE)`w4g7A;c23#l}R6vnwu>Idtl46ty#*3hzpGSr^JWh?~Y)7s+n< zR!hU2FQm+1F*||iIS}C<%cVTOl!u@Nw%Xt*HeEV94D+xu1&A)FS3O-Vh7QGuS3Q3ofb z(iG_%M0yP2omI;1y3-}11Z6H;N^=Rst`RCu@=%>M8;f7cYXz27EG81I+YcNJ`GWfo zbGmcXw;jLx<~vnP*X(RP3Yl|R4IoF3(jqTsngmh^#ue?S%lF#V9r`U!{A;~A?4lHpRP zJEBQ3u=?me97j}vv{(9(?4z{|>Blt9&zP>Mx$l}{Avb8<$0N~sKYdQ2m7Ubc3#9?f z?X&HnahJEH4d*kSw<1Q1>k@36K^W-|7Buq0D;v=4?Hys*Uk`HcU)k8#FE0wmv1dZW z0=veLV*W+{x#KB8cWa*C6OoGMqXM|D;-I}#BQl36upRxT=qEPW>CJ`q5StMhILUk9 z7HwAc)1CD!V_Rx{Bs6|--hQqxhkZ{6>*mv%CJEiSq9A|B9rQrn)w=Et_nlPc~o zm3zc7%&F=B@;Jxx&$MxO;rJxfz+Q==w6khp0FMH!0&O z12Zo65(>f(nvYGAS3BQy=16@t9BaL2tU5O(bLzvVQkzFVJ>*SCgA^b#Iv478L`E3pV48tqua6mYR#LT86i5LlO;{s) zOQ0LqpQ0D#cCz}0Aaa($!hBZqxBQ-R=2s?U(p;vl-5PM#mLUoqD!Y?-r*zz~&5jg0SLP$+3wt(_hRhej@y* zaFC5RuyXM34K_k_XoY*YAsd`0bxNv?*)0XcW~h)sa}_Zv^RaSB6~f-8+Zx6jge4!&la{1^DvA^r=fFO2!YdDd#?nvkmy9cR}@DI{fOJc&jL z?c8=ah^%RRsxhI}{wjj<_HOk3AA}r4zd>}|$PMCHkI;uWSa4ELamN?jkH4$TLomS? znLslPMnqFJiSd~w9PkTuTbTQW)&A-!7?=$8xC{^n)0{*?6LSCIlh?qQbon1J0zjmg zHB}KY4cnqb4n2?*^`gYH7~;o$QthoFUfHtA+XP=vbee^UcFgg3B; z>oru5J)UkK*@NMt;QpYiJ;JaN9PzxL!m+pDc2)Zauad+Nu6W0#Y6^(aOUen#QbmvR z)fFb2q*D-8`szVEZ9~~9;E(XQ78bY_7!kAz0kJniGui(jt*&8sWlbp}2#q5_n8gZ@ zwpe9o{s7xYc`j73RLxYPTtf9bq6$9~O`arSCnfVq7*v<}hXF6wyFmY?Eb%t0-}O4X z`ysv7Us;TE≶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 Date: Wed, 14 Dec 2016 08:12:39 -0800 Subject: [PATCH 4/7] Fix link. --- doc/naming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/naming.md b/doc/naming.md index 5d603061f8a..588f611f163 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -53,7 +53,7 @@ include: is in use). - The name of the balancer, if the address is a balancer address. This will be used to perform peer authorization. -- A [service config](service-config.md). +- A [service config](service_config.md). The plugin API allows the resolvers to continuously watch an endpoint and return updated resolutions as needed. From ce0105fac4986f63ea86d75cc4c8b0f46a71d372 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 17 Jan 2017 07:36:51 -0800 Subject: [PATCH 5/7] Ran generate_projects.sh --- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 4 files changed, 4 insertions(+) diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index fa9b7057c57..ffa167898cd 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -785,6 +785,7 @@ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/wait-for-ready.md \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index bca5652a463..0a12e458d64 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -785,6 +785,7 @@ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/wait-for-ready.md \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index ccbfe3a4e66..6e66ba0f39e 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -784,6 +784,7 @@ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/wait-for-ready.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index fc8fac32f0d..d8c2f197040 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -784,6 +784,7 @@ doc/naming.md \ doc/negative-http2-interop-test-descriptions.md \ doc/server-reflection.md \ doc/server_reflection_tutorial.md \ +doc/service_config.md \ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/wait-for-ready.md \ From b4227370fc8b84fdf8d11c3d1ba94492347da1a8 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 18 Jan 2017 09:21:20 -0800 Subject: [PATCH 6/7] Code review changes and other improvements. --- doc/images/load-balancing.png | Bin 27733 -> 28073 bytes doc/images/load-balancing.svg | 2 +- doc/load-balancing.md | 67 +++++++++++++++++++++------------- doc/naming.md | 18 ++++++--- 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/doc/images/load-balancing.png b/doc/images/load-balancing.png index 18b68bfdad83d15b33f37eeeb98f582feb8ee0c0..7c70465e653dcf732875e96ab80e65331ff7c67d 100644 GIT binary patch literal 28073 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எ zovxofG6*vO=hi6X6wBzzQ)1kAT33g+Wv!i9Iv@lm476@HDZkg!OjcS>qWR1eK?#5RSML$IyG z2uyvO!4AY|XRKqWe#fzLY_1`rmC8DI#D3OY+l%QnND@|4ILAr%6Y-1vY`DRWtI2l} zx-|NHf!ClW^BQRw@MS-{%umF`h0!GNsCf`G;;7r4@psYx>Gmz-E%;x$0R;bcQ)2vw z%wGn^N2nVpW&>pZZw$59lUKiI0uwv>@N76z@n1eXVgc}%45#yCN_Ic`^4!0UOm`=F zf<9XSK=1FEk4C1g=(1t{-~SEPkN#&XG5#e3%%L5m#He*ZpzhZjy{%__qvE>DqyGYX>j7;5 literal 27733 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≶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 - + diff --git a/doc/load-balancing.md b/doc/load-balancing.md index c5e59331c2d..1071961b116 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -1,17 +1,25 @@ Load Balancing in gRPC -======================= +====================== -# Objective +# Scope -To design a load balancing API between a gRPC client and a Load Balancer to -instruct the client how to send load to multiple backend servers. +This document explains the design for load balancing within gRPC. # Background +## Per-Call Load Balancing + +It is worth noting that load-balancing within gRPC happens on a per-call +basis, not a per-connection basis. In other words, even if all requests +come from a single client, we still want them to be load-balanced across +all servers. + +## Approaches to Load Balancing + Prior to any gRPC specifics, we explore some usual ways to approach load balancing. -## Proxy Model +### Proxy Model Using a proxy provides a solid trustable client that can report load to the load balancing system. Proxies typically require more resources to operate since they @@ -21,7 +29,7 @@ latency to the RPCs. The proxy model was deemed inefficient when considering request heavy services like storage. -## Balancing-aware Client +### Balancing-aware Client This thicker client places more of the load balancing logic in the client. For example, the client could contain many load balancing policies (Round Robin, @@ -41,7 +49,7 @@ It would also significantly complicate the client's code: the new design hides the load balancing complexity of multiple layers and presents it as a simple list of servers to the client. -## External Load Balancing Service +### External Load Balancing Service The client load balancing code is kept simple and portable, implementing well-known algorithms (e.g., Round Robin) for server selection. @@ -104,9 +112,7 @@ works: a load balancer address, and a [service config](service_config.md) that indicates which client-side load-balancing policy to use (e.g., `round_robin` or `grpclb`). -2. The client instantiates the load balancing policy, which is then - responsible for deciding which requests will be sent to which - addresses. +2. The client instantiates the load balancing policy. - Note: If all addresses returned by the resolver are balancer addresses, then the client will use the `grpclb` policy, regardless of what load-balancing policy was requested by the service config. @@ -114,19 +120,28 @@ works: by the service config. If no load-balancing policy is requested by the service config, then the client will default to a policy that picks the first available server address. -3. In the case of the `grpclb` policy, it opens a stream to one of the - balancer addresses returned by the resolver. It asks the balancer for - the server addresses to use for the server name originally requested by - the client (i.e., the same one originally passed to the name resolver). - - Note: Currently, the `grpclb` policy ignores any non-balancer - addresses returned by the resolver. However, in the future, it may - be changed to use these addresses as a fallback in case no balancers - can be contacted. -4. The gRPC servers to which the load balancer is directing the client - may report load to the load balancers, if that information is needed - by the load balancer's configuration. -5. The load balancer returns a server list to the gRPC client. If the - server list is empty, the call will block until a non-empty one is - received. -6. The gRPC client will send RPCs to the gRPC servers contained in - the server list from the Load Balancer. +3. The load balancing policy creates a subchannel to each server address. + - For all policies *except* `grpclb`, this means one subchannel for each + address returned by the resolver. Note that these policies + ignore any balancer addresses returned by the resolver. + - In the case of the `grpclb` policy, the workflow is as follows: + a. The policy opens a stream to one of the balancer addresses returned + by the resolver. It asks the balancer for the server addresses to + use for the server name originally requested by the client (i.e., + the same one originally passed to the name resolver). + - Note: The `grpclb` policy currently ignores any non-balancer + addresses returned by the resolver. However, in the future, it + may be changed to use these addresses as a fallback in case no + balancers can be contacted. + b. The gRPC servers to which the load balancer is directing the client + may report load to the load balancers, if that information is needed + by the load balancer's configuration. + c. The load balancer returns a server list to the gRPC client's `grpclb` + policy. The `grpclb` policy will then create a subchannel to each of + server in the list. +4. For each RPC sent, the load balancing policy decides which + subchannel (i.e., which server) the RPC should be sent to. + - In the case of the `grpclb` policy, the client will send requests + to the servers in the order in which they were returned by the load + balancer. If the server list is empty, the call will block until a + non-empty one is received. diff --git a/doc/naming.md b/doc/naming.md index 588f611f163..676aa9f2980 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -20,12 +20,18 @@ uses the syntax: scheme://authority/endpoint_name ``` -Here, `scheme` indicates the name-system to be used. Example schemes to -be supported include: +Here, `scheme` indicates the name-system to be used. Currently, we +support the following schemes: -* `dns` +- `dns` -* `etcd` +- `ipv4` (IPv4 address) + +- `ipv6` (IPv6 address) + +- `unix` (path to unix domain socket -- unix systems only) + +In the future, additional schemes such as `etcd` could be added. The `authority` indicates some scheme-specific bootstrap information, e.g., for DNS, the authority may include the IP[:port] of the DNS server to @@ -38,7 +44,7 @@ syntax of the endpoint name is dictated by the scheme in use. ### Resolver Plugins -The gRPC client library will switch on the scheme to pick the right +The gRPC client library will use the specified scheme to pick the right resolver plugin and pass it the fully qualified name string. Resolvers should be able to contact the authority and get a resolution @@ -46,7 +52,7 @@ that they return back to the gRPC client library. The returned contents include: - A list of resolved addresses, each of which has three attributes: - - The address itself, in IP:port form. + - The address itself, including both IP address and port. - A boolean indicating whether the address is a backend address (i.e., the address to use to contact the server directly) or a balancer address (for cases where [external load balancing](load-balancing.md) From e860359f231cdadc9ff1c8292ef869b91b8879d4 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 18 Jan 2017 09:22:26 -0800 Subject: [PATCH 7/7] Attempt to fix formatting. --- doc/load-balancing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 1071961b116..f56d2b0c73a 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -125,7 +125,7 @@ works: address returned by the resolver. Note that these policies ignore any balancer addresses returned by the resolver. - In the case of the `grpclb` policy, the workflow is as follows: - a. The policy opens a stream to one of the balancer addresses returned + 1. The policy opens a stream to one of the balancer addresses returned by the resolver. It asks the balancer for the server addresses to use for the server name originally requested by the client (i.e., the same one originally passed to the name resolver). @@ -133,10 +133,10 @@ works: addresses returned by the resolver. However, in the future, it may be changed to use these addresses as a fallback in case no balancers can be contacted. - b. The gRPC servers to which the load balancer is directing the client + 2. The gRPC servers to which the load balancer is directing the client may report load to the load balancers, if that information is needed by the load balancer's configuration. - c. The load balancer returns a server list to the gRPC client's `grpclb` + 3. The load balancer returns a server list to the gRPC client's `grpclb` policy. The `grpclb` policy will then create a subchannel to each of server in the list. 4. For each RPC sent, the load balancing policy decides which