From 4404865ba85be116c7d53d3696d78fe7b220077a Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Wed, 13 Aug 2014 12:39:15 -0400 Subject: [PATCH 01/15] update links --- 300_Aggregations/28_bucket_metric_list.asciidoc | 6 +++--- 300_Aggregations/60_cardinality.asciidoc | 2 +- 300_Aggregations/65_percentiles.asciidoc | 1 + 305_Significant_Terms.asciidoc | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/300_Aggregations/28_bucket_metric_list.asciidoc b/300_Aggregations/28_bucket_metric_list.asciidoc index a38a0bf61..734867e20 100644 --- a/300_Aggregations/28_bucket_metric_list.asciidoc +++ b/300_Aggregations/28_bucket_metric_list.asciidoc @@ -39,9 +39,9 @@ exact parameters. - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html[Extended Stats]: Same as stats, except it also includes variance, std deviation, sum of squares - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html[Value Count]: calculates the number of values, which may be different from the number of documents (e.g. multi-valued fields) - - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html[Cardinality]: calculates number of distinct/unique values (covered in more detail ) + - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html[Cardinality]: calculates number of distinct/unique values (covered in more detail <>) - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html[Percentiles]: calculates percentiles/quantiles for - numeric values in a bucket (covered in more detail ) + numeric values in a bucket (covered in more detail <>) - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html[Significant Terms]: finds "uncommonly common" terms - (covered in more detail ) + (covered in more detail <>) diff --git a/300_Aggregations/60_cardinality.asciidoc b/300_Aggregations/60_cardinality.asciidoc index 76f303fe2..e2b6bf2fb 100644 --- a/300_Aggregations/60_cardinality.asciidoc +++ b/300_Aggregations/60_cardinality.asciidoc @@ -1,4 +1,4 @@ - +[[cardinality]] === Finding Distinct Counts The first approximate aggregation provided by Elasticsearch is the `cardinality` diff --git a/300_Aggregations/65_percentiles.asciidoc b/300_Aggregations/65_percentiles.asciidoc index 81b146813..cb482be5d 100644 --- a/300_Aggregations/65_percentiles.asciidoc +++ b/300_Aggregations/65_percentiles.asciidoc @@ -1,3 +1,4 @@ +[[percentiles]] === Calculating Percentiles The other approximate metric offered by Elasticsearch is the `percentiles` metric. diff --git a/305_Significant_Terms.asciidoc b/305_Significant_Terms.asciidoc index e8fc852fa..ff6dbfb5a 100644 --- a/305_Significant_Terms.asciidoc +++ b/305_Significant_Terms.asciidoc @@ -1,4 +1,4 @@ - +[[sig-terms]] == Significant Terms include::300_Aggregations/70_sigterms_intro.asciidoc[] From 3ff530c0995903c2e9e919075deea471c73d383b Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Wed, 13 Aug 2014 13:27:43 -0400 Subject: [PATCH 02/15] add histo/barcharts, secondary example --- 300_Aggregations/30_histogram.asciidoc | 47 +++++++++++++++++++++++++ images/300_30_bar1.png | Bin 0 -> 20926 bytes images/300_30_histo1.png | Bin 0 -> 20210 bytes 3 files changed, 47 insertions(+) create mode 100644 images/300_30_bar1.png create mode 100644 images/300_30_histo1.png diff --git a/300_Aggregations/30_histogram.asciidoc b/300_Aggregations/30_histogram.asciidoc index fdabe481a..89c2d06f6 100644 --- a/300_Aggregations/30_histogram.asciidoc +++ b/300_Aggregations/30_histogram.asciidoc @@ -101,4 +101,51 @@ The response is fairly self-explanatory, but it should be noted that the histogram keys correspond to the lower boundary of the interval. The key `0` means `0-20,000`, the key `20000` means `20,000-40,000`, etc. +Graphically, you could represent the above data in a histogram like this: + +[[barcharts-histo1]] +image::images/300_30_histo1.png["Histogram of top makes per price range"] + +Of course, you can build bar charts with any aggregation which emits categories +and statistics, not just the `histogram` bucket. Let's build a bar chart of +popular makes, their average price, and then calculate the standard error +to add error bars on our chart. This will make use of the `terms` bucket +and an `extended_stats` metric: + +[source,js] +---- +GET /cars/transactions/_search?search_type=count +{ + "aggs": { + "makes": { + "terms": { + "field": "make", + "size": 10 + }, + "aggs": { + "stats": { + "extended_stats": { + "field": "price" + } + } + } + } + } +} +---- + +This will return a list of makes (sorted by popularity) and a variety of statistics +about each. In particular, we are interested in `stats.avg`, `stats.count`, +and `stats.std_deviation`. Using this information, we can calculate the standard error: + +................................ +std_err = std_deviation / count +................................ + +Which will allow us to build a chart like this: + +[[barcharts-bar1]] +image::images/300_30_bar1.png["Barchart of average price per make, with error bars"] + + diff --git a/images/300_30_bar1.png b/images/300_30_bar1.png new file mode 100644 index 0000000000000000000000000000000000000000..b611c8ef063843915cce2a543d28b315754dfac9 GIT binary patch literal 20926 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 Hu0mjffE0;g literal 0 HcmV?d00001 diff --git a/images/300_30_histo1.png b/images/300_30_histo1.png new file mode 100644 index 0000000000000000000000000000000000000000..9e64a197634db6fce33ff61b0db8bb07df931825 GIT binary patch literal 20210 zcmeFXV{oNm+bx)+W7|&0w$-t_W81ck?l>LW?%1|%bZpzs?4;lGov+TR`7wXy$IMAp zs`h@K>-L4U*1bc%%ZkB4V?zT00l`U#3(Ermfk*=Z0h2?50G`aQhW!Qt!jv@=68bJ7 zBt-b#-p1I>(g+Ah6{<|ljYCQ2etmxh={{v&&6sIoh-czDX_$4wQ3fgIs}L!cJPT2D z4(HcEvZ1(aMR`=oeBk7(WtE=$=hlhmw|njhhr7p>x&`h1n)x-8%$j*H-zedbP-vlK zV92Q8Y_1e6=oSxGXcSRk;7VZJP7wG|8^<`mwl>y>%z+m~0n>E39n<=^!X=+`-OKB! zJ20TCU#ooHQ|+6GI$wZB4sb*wfPof(cXKWof3Wa?F><3J2f7CR{IbA^Uk!1>*HO9H z99ff#1mr3M6#NxB2pbY8moW}z;1T>AcerFY%)Pl%I<-AczxyIRR3(T4m+3crA;usEU%2~rX-kBoluu9{GnB7y)Qsn zH&xkm;2l+Pu);{AS+sQVi#%C1c^^ z_hn@O=@-E4?Vf=U_D4iq;dO8Te|wrUfTr+;2Jz$n{Y?AF+-=oH4pJ{mh~x>1^qu_a zoTKMf+XoS1x5OvEqkq`X_jaxE7AboJuT_X60iz^ru3x=JnIL0WRi<=4)2>_E$8}5Q zqTkh_l~VgD3iRRIyxv8g|HeCUjlb91BsY~M$=kz46z>YRCczn;H6r^@4{*({-sbrA z3~L10+&8_8g=#p=fO&6`J_1o15b5`+E=hrTb5)^I_#K2M1J0^e0r(PVUdGNN!S&g! z8@U_PQiFHZ6|{xDPoVdY?;5M2a1>wfD-M{2*q35rLHR|L*FJ!HWHYUeCJ zpMx}+;AfJ=1WFkOn#6e{2@8A{up-i&A9#zF=-iJMgYl(~Y_FPa)VZsyg@K>^LiS*I z0VGHWotGsyEP!YF#Y-22#t+XH9A6hF+#M0}SLwDO^5PdJ0eB8r=q@{3=(qqXTO>_j zc0rWJFK2#YSs1YX`?glCU<92sNf0BDfYW8_{&_+8EtrEijDjR3m`>kcl_WA4Vk-ia z7)hKaCh$bW{x`{>-43jLgr+F=Z|*^%JOsC&t)d0d6@$p3f)W(mRKAi~&_!hCzUtZI z2g)pntA1oThX+Kpn6yIlS?rVC2PBS&ctZSH4w$}rowoYI4EC5Z;Yj`P+aXY$-x(>B zETxeOU=_m50v%pKnSUmC(db{QvXwF@!$PltJ)>^u~AtdIN2T zUk^R+iQ3+W1O-75Ovn4`>7zo?V*bVj#COh*Y;UZvA0F{^uMJ6Pp7g8U)D%dq+ zQTl{j7CG@S>9F^ZZR+pT;}q%S?zGY*>-6npTfRntNp@o1Lbgi*LiW0lj zib$dyr5q(4g&XY|b)d1Nk)&~^*`$F`9k1arOx7o@l&nmte5xv_NvNr>iLB9E6#g5& z==t}qTB&l?$YUhZB+;-z7eQ}AuVZj+jBliCID2?=xGFX`aGPxall-TG|BOF#ICJ7P z^giM~aw1S7a3a47x(cld{{jd*K?7d{zYCiS-aX+xauh=plpKW|{)9|MVymh)mNvwi z>soB9i<`;A;$!Wj=VSF_`9;JQ+JffRUfIa85Yd zq0?dJq2R&j!Sx~Ip->@zgGoc?f+K=wLM%cdLI}`0=-Ua2C^yNfbhZk5x(`!WT0Y1Dmzh7C08&KpkphDT>OFi5CbLh@rHdx$6-lz zcy)z+$dxa&TA!j(gJjzj z|FWL4BAD_`cAH_DpU#_4tFPp>QyS02%VgH=)(X{4Sjbr=tekW->0dXFgX4vcW2G}{ z>1o-l&NLgi6T73fF}1Nj*N>FW;hI<*Wti|;66tPQ{IFuQDAr51{HrHYZC}l0 zecP|zpJKjh8nC3gw6ok=iPjKN*=7cDLUVF;s=Xw&bY9u9>+4eKLSg5+U$m37w(Op#Y@e* zU!P=2xpFlxHAdZIVOp{?pRPe*y}gQFe|qO!a2j{2(q^}2y|&+`Lg5_8G@KR{Bv(99 zS`mHzV;#Z!$s5dj=8fx3?1lV`BS<8uG}sa79)v8!As8Ci7$^=H0m2)yKE6GbA<-<| zjpl)Rl7^}l2jdENE0I4dF-s1KJcGT7p-!BoqUh{mqzpH-%cy)=QT&wn&HTX=rt`z) z3K}(93;mr_nzg3HN|fuuLkYKV$s}nO8J-rHmJt^fjTrIijJ$;*@F5fV z->8{!^{Y88GcFx6tWsr5LLKCe6Wc6(wIpWi_syqP(iq}$G6d@;^%Z0Ri~%W(tvVj> z#nP6>w#F_AlJixinSZ_irgMgJif~dxcp^CBD{`rN+Ma&z%s$h+U5Wj5`HKV|VfS!X z2~UqR#?_E#o$OuI&sNa6>%RLm2q8={OcpPnAKSyRbg{YdEorf;XFxd;0*`=(k*1h> zmwt>&i(}Iz=RNOjXh{L2&|a1{9iH#?Cj4(QjuEnv$nL{cQee6nih)3qv@U8+g8iV84WEB2#y?%j_Y;J&l?$sZFkS$_Zs*IJf`lAhk8PV z#`|MpM^V;}#ZFp2rFReR4es|5_z@XT+GT6~?PFeJukNod8JPS{?7EB>rjyQq8X_}REk<5S;6*J`}C+! z>uE(B`YpfI2S!&n3>*~b;uaUk5CLe>eUlw*yCTg(>x(xr$#)2S6=D2GUuWGr{dC(W zR|ydM=v3KY?O$C9sFHl6i=8Yz!~;hY%Hw?Fls)mCtKB2L`~5mZ7c!*j)95 zS(Mo?S$Qp$ZTQSXR72EK{{}AZEos&G99{H;%&7JCjkB(tW_gqikW4IS7`LI<)7e0* z-Js$VaO!;F7kfVie)EeXEZi6)>dqEFP*s(BI1Fx!7W{F?%~ISw)q60(C{#6Or*!$q zt$^H(%2A5YB-gqzYE9Yb9iF z-@5v!>%5$F=xQ{7G#xq8K0R&X%(3GfpR?4m*RM6tIlek;IXFqV9fxoSS^Yhgz$0== zKPz6}Z|``}J<*ffZxcJ!a=~YJTDV2M7rn>2jeXAKp~Qm3RK)3qgF{f^jqoVo_a|sV zSV&w78%lJ`UCQ0AfR8kb@^bY$irD5bZnf?<(!aFoYKb^kC&MErFSwJTmX>R+ctT{% zWn#XsI*UCwNtjqLIW<}Ll6V@vy>gJ)2gV1ycU}U?t=qYo%Mo*trS0+SyZCkE+LG1?Q=k zT%OI6?rcwb;7vah!`&nJQ;^3%N8@RwX|zf`%SbGpmkJh7>(=*wZzdhaoqBeXF0-!E zcJU7O{GD+P%Sb#_p0K)HhH0b!vE<3+b^fGvPY<_(>F?h{Aa)VtoblaJmv?Ve%W;-@rycUy3+eOLH$#Sehq8Kp zPuQN!+?YIz#biRXGPn;t+Z)$z&b=|-FWB1z+pI-2$fdcqY^T3{HM7_K8#qt?k7Y7ZKr8j)&f8q0qXEtjnBm(&&=mOETbokv}u?dP3|TEd&P9i{9WZZR*M6nki= z=t{&2h7sbeff(G}m-dl)Sc~GfH{N>y~AO z>wC}wtn+w@{k4JLz)bDu1QVWVN{L>Czw8BW2{$(ev!$B;{t~(#jjY6PO6(x@DIlzx z%o@Bf-DBLkJc$WG;USNgGfSW6%2h7-PNzg-s7;yL`_2 zFoU*D>{&FE0s$BIh2`X?R!?}xZBr^pCA?yr+`a&rZ^=7d$1!W{y&h!G-?@`d_Dty7s73-xWeD>pwXm82jnMnFZ<`i!0H(^lKq`Oays8j@mf6h zmg-Ys;p${GGz^ym&rVT16%__g6^+hW^bOYO@0qWvNS z!rT>Ln{W|tDlkgko;y=8Qka^}9^}y8y)kYJXWXqg4Wt(4nG)@1N51_v7D9o&hSGsL zj7|!s1j&Lt6=hi}DVff0$9~wBZ)>S*Y{)BMz;7SV281BF!e1xT=NqBiqjIs%i?Pc=Y%}#h*&tb7w{CQwOu2 z<+nL(a)2_Eo9u(a% zo+6*3s2Ao<=#HEz^(tMZw`iRz^w@10ovupps_d0huS%P{&i2k)u1H#yoFui|JX}a7 z%Db4IkG!3K(fLW185t$r_V5PnCc{7erffOw*=#Dh?QqvH98}qNwtEwQH+RmDv9M1N zB*za^$~FY7wE=XTIg|yd38J;Z`whZEhz$~rQdB+qo`T#wygw`c0P-i8fuF=ct-i9J z5gF2QuvQn=Mzvj!tJw?wi9Qb)typZ?%5>Wo5b@t zs3J{$7y4maI$!yuykphl_2ST$i|F@hGym9rtI|FUxnft+W`((BiEyT!CZj)<;sSjr zTe7U|Vpva_$(tXY@$ajicxtrDYYWS*o(T>sv`B1e8i=I@*5^7NEfFYMkcRq~YD7fw2e0t6%c zgb9y?Otm7doBYP7hkE%ZlzmyVw05lml{NSI#_F2kcK59Q$8R=eW?DT)#nfUINEPJk zs>KuLagB2x++`wdPR(VtJ!klLZ)Lxxq6}Nen&s}A?`!xE2}beiJ)7C=H-lD3idCu% zN^GXd7;I+9ri$Cns|cJYJf94oIQ8y&69aS%I(?zg^q!k51NpWkjLK8m`h$*^gqo3-*|~l z9UX1C=;>WtT1^yx=ovXVIq4ag=$V*k0T#3lZq|-^uC&$;B>y`3AN>d$IT+ZR z**copSQCEqtEX?{C(WKQ6)BAQ2BR3Fltl~2`T@Oy~lKinBNZKgxNzw1bl9f{@431?H%j)uTl>w zv9ZGXb?Q*oh`vCegg}0_s7XkX5=7*X0ze>uM2@}c#{4wP8rg7TLqisq_7!u_87()TUy3+PcT5tfvs zT;eTuA|F}IavdXaBiH;pmpFk9qWZ1!ohF640R%rs|YvbfQ$J9 zNSqg;Vei=xbIK}QqBo8NbHmEITFer>Oqrhj7dwn%BxoBhr56|KmGuPX_*4fcHMa`HF!qJK2MJZ722Sf|O z!URn!#Yu9s&g)oflVHI~tV9erR<)YSg#QF9b6An~cHfBk96Evz@GUcdA}wA__i4D- z!lesU_d+P$y){Ax;^Bq_M>=ylY8ZGNTvAr%;oKQ`UF2ZFeIxxP zmn}?fqNucNu$uk55vo&idQ?3BYRlc;P zjJKU0xQoE0u8u-`{~DY^h=p6O;Xv%j*+iLXu0=g07#dnVB1>d*ZHP1XneiFrm<#q# zu91YSxyA24vha^%i&!3I0`6`!jq+&seoAR@fi$1ZvbA;(4_9p#hmN~22Gn$!hf2XL z?nqQAuPaB7(3IF)#cuy`aW|C{Dn>ybqT-s6MWf%ntarapmhE3uiMEkS#>)sbFRrFa zl3o3C1s;F~=}ITSV-uQyh)JKdfbQTUAC>}+=MiCrwj%l_C-cQh-_rht$Yrf$nE#w( zrJX^Q%2HBCqnZuvPddU*0yS6C)@~7cJvf$;Q8#3eLGDg-Rg{=QucD+Ls76*Pyhn6( zl#I^ijmi>V25dpX0gh%keQpeGc{%e{qk>D1Lb^$42V#9~ge*L}B%D)?y4JmQ?K^v4 z2G})suA;@n?A5e|yd_7h~KwXe#aq***4EO38heLwS)a3m4;n%JieAl)hAE>P28n#&N zh^`lcj>a;Z%I$AKDKt41sUmbLCOe7d9!chN3%b-*?Cx-yQFobGeer00IA3ilkq%-R z)$>LJtm^jJrWVtGbZjBwjC0uR6Dw5ABhc44`xPQV61N3Qs63XU=frRzH9!_Oe@0m zh>xagI!u>UCd1(fd({bTkBLz8E~;N|;$CC2XrZ+8mmWxgVa|c=k2aNqw@pM6l%4xy$$mwI=5}kF9Bou$%mbd&Jl<#m?X#@) zd>zZ{?M;5ya^}6A72WGCmm0gsV94n z)DWK%`qnBREf%+fzOB}j)!Jh3-Yri7ISb|nF8j8s(m-e1bPc0l(bW}CdF3s;73XRA ztzOSudT&{=Pt9_$6MaoXMM2z2;pcJM-P>RFEku3(s>fjXyteclAI|ZQSN=3kzqNPhedm^UADRHKq5`C%mLP>gY)@+oMx>zNOn{w%1P^6UM|c z@bG@HFtAR+g9Ik1wf7EbVCq9ev^xUi3YMqmgpH3i{ zj3dZ$Qqid%>&vv(!`#)Zm%CncAkq%=D@SO$y~1!wa|gcyW2y}|WTXn%B$@2ShM5b019?M;# z0>3m2zC&!^qIOSpnS(}hrY0lR`$58X$2+?I;mU*(hmxqBOhCOKw;YEvY>Oe`o$968 zUu7>9D?7ikD1&9Wx=ChZojW#iYd(yegVy@oGMSRO`nozNN5|HT_-VDa%o5w1r$iX_ zve$6pg%u@H1?(_d{t+4t?QucT(;;pf!vw8cy4b%=Q>b-LPLslx#g1(mTTkyG2K6Y$ zR42=3ZTGJ=M>3|w%T@zF`_JqU)J)7 zbI3jFMZV0p<&l*@*zzOGEI?O0dJ#pLhAovrhA zy6$R_!)lA&5cV=m!Q6X(RCdVM3e~SThiAqav9k85gfk(LESep?a9jb}U)9yr91ikL z<`_?aQHo?y5uXVes(c3$i?WD7H6a^Yo2v`i*5}&j5}QP)7UMR}GgI0cqZj;|3^Y-d ztmO6=MbG}guwlP1iJ$3z+xsR~NTykF1mizKeTqTa9KONC?fhHIpa)Y*OoU$Fad@@K z!CAbVnQ6H~q!w=3tMIJ6+z?@hyj$XmxaDxwtW!1_l}ROtW8F1-5l9h#h0PUUHm!X!*7iIW5#Ze)N=&SN78h8i0QNeIbog-DG(4E= zts&`LoJ6g4fO92V&cKxUJtsKx;)|N5h|^4qLAC2-Imku5Od4ecWsANkUyk%xwo`4v z{%}H&)ANPyc6xU)*z-Qav;+OrVT3IH7adV+uN&b zw&5WO;)PdTRt1@htj=D~plFfx1-rD`XHUe?Vi*eA8xcK}&=oUw+Ya&3GhMOt*ayqB zWZmfu{;6w)m^NF|TClx$JE|pWweq}Y^ z>-kt!hydk6M*kp+u|kqV&{oPksnCFuxdC^EyEw&|No18(SpB$PEu_1FsXqt>fZi){ zdYzv%V51mFR>hqv$ocadqCEiH60sX$GJFDjS1LfxFGgJw{2&Md|69Y*v_g4Ph)-ls zL=GST_6k3Ng+5Gu3jy6^NM_@G_7a!|U=xEfSm3aqrWpX}@AiK?VCOSBh?LKD$h6B( zC@j46hV4gkd{mck!X@E!-R5R>xfKQ4lJ zA@8d*Y$zOmbIWRW{Gc)Ljg5_MI-c9*3>FSfL{v2Lv=jMrUZ9x*ii)$LXw?2Tnp+XU zD&vL@XJNcG{=%*0$iVXCjHkONw=gOi8zra!@0S2>G9-Ljtc^ z*pFmVR2ict)5tfaHSi*S5z73W5|AG~HA8t)cBhw`JTAiLPInP^a%*AH1ax!!qh%oN zhyu~qLB#t1IM{cVE%hzX1c_c{&ut;Q#g}A8=;hWnsXEKT@r#e@9*BAVc>)k92suOfpxTm8OfxV2{(+Oh26#}$r$Yh(eC9W_zb4NGEG5Q$%EBeSLkiWk7^BRGJ0e#UI{_m zt8wp-P}?V*{kc`rxRqI7iN9`^-dh>1r->Fnh`E--h^QPg@N3Y37;iX?W4z|&^EWFZ zXcZ|0avG;*VfhK@snFLUnmOLYnmkIy^J2USTRzjhoY!c?9(eeVQprI=c6PSKLOCfZ zDb$_*oQ5C5(^5QR_244d8a^flMtt1YG(4MtEM7p~xC3EIoKWfJvnm8l55xVjs~iWv zcJ{JdSlbnm+9Nww3Hj;jh>*O%`^4mOf2&D?3UtlfSoeEOG9_W!EE)9w2_?RrY60F;6cR3K`(%fXtc+xzglue<)<)2p&tal;xfGqEqi}q@8CF)&N5m zD?*1L&<7=uxHkRagn%R;OsQMHV%0Ive@=bR%@t7zuW8y;f1Ns9t)hKO5*;0F=<4dq za<#c%GqW2hdg4E17!z4x{BtCAq5Zi(zHKV9zj<6?K#pbYD}vX3<{P6|Q)2#LcY?Iw zMC4>E*xR9`!uerLVs(uUMal6_T{raSn9}5aSj@(wDR`R?U&fWX0m-?~0NIu^(2l(@k{05Q^x6cG(AU%uEg(cbZ@nMFU^Y<6d} zmIVx@p@YUlXpfPWC}pX90e$Y>A)`Kng0yd`-Q#@%fd%3S>W51GoTWxD&bMcaXTVj{ zm`B4DcC2zk^qB?Sa%_rQ5*_Ni^T{elh2b$XLIzKA0fQ}!gY2n1-sums(+Q2 z>jet^qZpQ%x=Q@6Vf~q8PLWe-(-Fv1%W?31f*{dkLURzZz>i4O2Wvoop6N;uVZFzXA+lOzHtnE zuG8g)+TWZ)cFc9mIUMU6FKwylGp zWh;*OvcGQO^Mg5EeX?@2rvv5cb)j_daBx~J&a{-2L+yW0&;Kh^T5B{eA${b^+LgHs z+htL&!9pR0K`J^r?-WECV2EFU6ax>OY)Q2rda&towt~kP{_6DPucmzhd93kG<7+Pxfpe52rLMP&J{K#kpH`#agYScDt*Cv7wi?5cT%_Zs@H4`q*)6D+!Xsrbb?Jg@OEb}QUKN|_C@Oj)Tm z!i&s=JMd?OtXn~Lqtk5;WC4tm-a-?>!j1)c)eqm0{UJa6scZi9D*@`o?ir!=~+a(IBd6X=vH` zXyVkz66@;7ardILFtr0eK3jVn2DN}%;UXJ(CX_u%f&vQaH`{3j!%x!-X&{ktX7XD9&-#i8sHiYq53oR2krN&|6b!W~D+wGH1Tdn& z1)uh^Vpr^L&n0A`1$LX7zu$lA9wnFReatKRpvI$V#g0#lMqlootmTc4QpA3>H@12!SXlMMI!L6s zkoL~ja&E1%mwM!iD0W-e6YJ-G?m#vzVtOl`)#}eW?AtF0h52PtQgJbF)hF>c&--6v z%1l~h#>DE4Rh(u}pXu9cZ#Rr`EY=K`-704cDLmYrc!$EG4cU*mbT;ZMJhS^YbdXRv z-=B!N0Q>A`i^7mH1flzGO}__4oZvRXKU2=427{b15lhsM|z)F5m~Xd4XhkLy${9Lc3NeBlL53X!&X=!~vj2SyVfhMz1&ial7IUx#3=I zzcoa{!Y7(m8%@k(@`K&KJ6BI`Kiy!o+R;q(^QuP@88?Z8{M=CQU}+`TqqL*&iA78f_oO5L+5XA)lT zA=+!m9nA3LSa3x@{*6^R`s0&O!j?QBcDsvyuFZO5G!gudAPG_uCNmn0`E^76>Yt@@ zmwKC;@*kuAiridOeCjSEICwSSf-L{W-`)|!XZAdm%9@%;r|*L9tVD`pcHX~u%NUbT zAXm*ayihUwr&ir+itasu=v~wV>Eg>juqQ4Mt?WfQmJsFn*v@r)O%|&-p8o4=LbTww zD*_3_H8n!H6?qd@Zh%U+xyE(ufF7nv#VgUEkymfxGi5rgL3h*2W0}d3FQL;c7zE6TlHSgeMcj)-nN?|aS`zx}S>d4c|O0e=YZS?Lfa`X_LH5kF(h5q4|Gg`X+;mN}XO_4tGhtjgW z4~Ng3Er1`F3Oa4P3MKorpEbpWKN^En*-+T)hvo8rdNNI?BGohd&Y*!(jS)-YUNtZB zo%4ky`Rn|7by-Zj#?0Z*GKgcE(b$e=Ek`3GcTriHyl_B$XMX+~bHl3y{w|a?__&VA z`>`dE1b%-5cPRc+#iuA_5*CUaE1HuXGN_O7*14r-ShGd{;FXx*ux72Nyz*W%WO&_7 zwwWkCtY*Vo7fm_`OB~m@Zq8^wTBy6am_m5b*#&Tm{qkSZAGz>Ba^q~ZCAVOC{QV?a z42trEd4|f!nnF>F73tc9eKx4&ATdu8!@ESa?4{chi!_D6n>>0DgEvokjjSI>g;kEP zIY}I)0mCRfC8Te%U8jc0%VJzFC(Q`qsAHYN{;fvjGsO~75~dSrV5Tz6S~$PpFk-6E z)cfFYY_@}Ga*5$f&BTs{lunfBm-8QXIM!weGw#z5SutP7wn^;w&ChBck>}mtgxI?~ zUk_I-_}q;iHXr3a-l2QHMl>Kk#A9@QxIthBP}|W?Q<>OGq{eQonC#9FxA_%o7$DZ_ zE<9DL(`LC($%V5isUm)iaSJ5%ga+U6$=E#}k*cFjA+z%O9iHQK3?{qFy}t>2wOnSO z^VS(?<#arYdVbaiNLpZ#D~EaNdLnXul>u7ozd9z~Q-;y@6BmOHPIHzpK~_YMP$iGQ z$d<49o5`2W-;k_E>G|LEH*WPG9yDJsh6%jy_l|C*4o8By4%LZc(aek#|GX_MtoE@T4;l1^RPmI6XHJ zh^;@S@NWFEyX2a=x+2U@cWHNz`oL7yqgu;vjv7uX-05APdXfiNB>dKHO;ek=pHS2i*xxKX&8dxy^7X9%eXt>7s5KlY)z(_R)eH?Qv}->?w)-slKp9hvi?WoOi)*H(%2d~^%}XSV)DQsz!E>08BM1L8M*!X!GDy-4HW9`{1 z_E>3zyh zbZRmp`G;=CMyPJpk(LxfitgT9Tg5)FJaN_Xh=$wsPokCOQ8~3iJFjLdPH39z`~lPl z9w~wxP2wa`$J%}%k6+@$AGNJxV=gqB+g`_|)p>u-y*Zuz>2l5FVx#jqU|k=KWdGEFvpyb@Nf~2z$W{?Q_&y z_()GX&c{i~?n-{31WU?9wmT@J`mvZd8xYSL>qJned(NHP}pc%Ivu6cPHjKSAD)_XJYz zp&6PjN#WBrRce<-q8iJ_(`_ncMQz_#E?P#&W(MY#UTkR4Z-aPIn`|3rh#)>Zq#dnN zy)1zneV~Ke#nObt>_@H+koL0SsRb2p!J`?>z4}Twt6G!F`~6|qE(=T$2* zJ3PgjUV&CmIhi@`3X<|i@0!qraP>a*p_x=)v&ns_PIHDS)##M4MGLgZQ$%`{&3dhZ z!fYO4*gKI*i-dyqEW;ou(&bNLa$>gT4`>Pi!^|e*4?6kpGrQtO(Ko2O@^ zxCCJ5UUsplfAUidpfrn59)N%Pe=i0=j9SO#{r0K%ivtQgv0yIFXKW(s0F*CJhns(T z8ZqFyAp|tS`ZF*EJOL4PIX3kV;s<~ACI0`%VEt&E3N~}m0ZyxAm%se+Kk3GYkN)QR zRdbW!eHHt0V9&G!6-c(y4DyWHm`lU+Y| zs||at^E>}5&P5%o&h1f=*tfwKl9W?d*Q6@lCd#`qvYju)qmpZ@1Fe-w5n&a{eXYO_t7cFjElMOcUyF zBNH36v~w4w|MYAiV1AfJ3j18|Gvv+x91Wm;gryaeYUGSg#k9^QX_3-yg#)#HB32;K zm#>{3GLeI^Ql<0A{7ylY|LMdI>|tW3_Y|k?Qwji>{Vyc~aN8nJ;PnqX>i{C_WjJi( zvnirDfWHbH<=T9P&qWC!&UD<6a6jV=q z;x{X{{yDGzC-v|DEDi+me?2)u3j2h+8Y2&Y7)w>c3~I0VAM8N5@ddcp0d{p)McMMm z(sac89-_F#*h%qR+;L4R5eEn7P%d`Jaeq7=aIXP%7parZ$c5^$Z`_MPvhC8e%p}EG z^K5oUQ?3;&;E4@#u}NI2{7QY(M40WVYlv>;xuh#sl}h5pJ_ZGpCEG@LsFk zmeI_GCP|h1@>DNl6$Z!_Oz@*X>Nn?p?#w7rScHkj=qc^uI>IA2@ScArh-ba>#dVk66% zIi&a@Ej_wOMso=!(0gxN1x}1X@ghUG<sf=uOs#Ikj^naby|uX{R7 zvu&<+KC*JU>HkS7whR;&rX~DyA&dL>pA7c^b0MozAD36MbgzzJWyu$lVfM5e-$uEK z;0ya1Ergz6t|F0`>UR`MzmhE->Yjv#LNCT}l0TbwvLJ3?aI)#SU*>7jxiVT~ixY}` zh9)F8Fop=-iM{Z*&-h@F0ZXF?D9WJX|1e=UAk64AP0-!`B>=(bp7f9E2n5=#th?9o zcH9B3W#4=kqw}`q>a@LLLJiY#MtU@(ZJ=>u$ zdJ!(JORS2A)0W?{JGYMddN+6NpoBm!EWryy$ADBC35H=6k_l$#<%7tB3tD20uircE z@$|5%68UbXdxm_My)P<{Xtkv@r5XHs$;v=|*cAx5Wqi@S0)|4R>V(}^+;DVY!>{#Q z@|;r`b7jGc(kyPhTNH%)U}_IHux zIx~yeKt)GPt5b0LNtdb`v6A3|ZW`6PW;niina;!;na3s(3~Y0=3@kJ}Wj*NnOQ>m# zQh2uSeWgF^$wKq81=DQy>S6cJvaBaH3ehzu6CEs(5+l&C$s%$J1QBWwlOUA`M6GA# zGyPKv;H?7c2M+XX{X%q|Xc|qWUT9XnQoC|MDzEbNmX10*Z9Zm1Uatt*NOlEzg@E^j zD{IY8%_#Tsv8=#qC$;E)11pK_O7$==4mq`!AkcpKm90Bx7e~0%TN0UDxseTYS()xS z77k|~v)*%Kl6T*|#rBk#l`uu@uL-_XF6b?(IA%0#(Q0hS)&k;Kh)eGAgIkLYxn zHK&>^SZ&^{iLl0Xxjl0Fl5*=6(BCe9XDtCi2YI$f$KKcO35QaD>3_z`sUWA(W)A$! z=D1y%02`%x@O*bL*8TP#{ASAeBWr9i5qoN;C?djmeVqNq>~-$P-S!~l;Z*%^kKCmC ze)=N`xe2tjqy1I?jk_$thvnI7dNGa5*LeT%QOz85?ql5j?f#2f}p0LGhrYg0L zDrFT*?l;Lc$T^8aftvXLR{%!^xcUVb_GOb7m$0*7eSK+B7X6wGxh%pXBB9AZn;W7} zKfX#1Z%RwwtdvQPT{8uiznOzY~#l z&zCB5Qf0EG4TTL`7FwndT-cWv-&68s6{FYXmMVA0NFugt3;%t~e3yeK6FTG`SAb!Vt z|B*D6zNl$OqFj)X?Jg=ve?}xbU|NX_S-r-~7q^Z)R>%`=nL}QT5R9Rr>VsN?qOHh5Vdf zy&dIAaDj>Q4M^}N5O@CiAdCY_CTh-NZZv`l#rKM_OZ*slZhW+!ucJ2%l7!H z=Dvp0{t~$0(|`qcIeX6D^<_T_zdaTRx*|s+<`Qkr|LY~h@bT+f^;&gCo%PBUYu%3J z3Pa1OnAIn0x?W3Rp6JOVNzH3)yGtkPcdlJ#F?6?d>ms5e>+@=uqd$DFUbXdsg}l{e z@x0(^%YyTR%XFu9&C7Yb_S|#KXNL+hTBfjcx3udlg7lLF8gu56yw@(%!#}LAR_#>( z;1E@`)*brZ-{)48-haFEZ=cd#H*OA3DY&pN8cO7wQnkCZ^!{s|UG#5C{f$AZfX?o{g^*C^XL6uc8Xtnmy3pH{t(ARn^vTU0xv~;sz z)#@gA5HaYr#Z3BKo|;m)3?APYgVeKmyS(}#!P z;UHLbmqlA;KD~#k>EldYz`STarQm|ToQCe-MSWW(on93?`bs)_!Qic5?jc~*($^`u zTL!&QKoDH8`X&4FuT%I$555aeI9s#P=yYABdv8a(9{RAW?6SR}?%3)&m|(a2=)tqc zG3375T#`{~w{dKCov6|1e8q{|Y#dR%3GO(^ZCH_aI0iIf7FL0YVAU~Zy4{Y|3!uE@Ba4YktHdM{qu67UxSM_C4SAq zuffG4GPO52tXk01W@F{Zc3351Rwwb2-pQs Date: Mon, 18 Aug 2014 15:10:15 -0400 Subject: [PATCH 03/15] add timeseries graphs --- 300_Aggregations/35_date_histogram.asciidoc | 105 ++++++++++---------- images/300_35_ts1.png | Bin 0 -> 28343 bytes images/300_35_ts2.png | Bin 0 -> 44205 bytes 3 files changed, 51 insertions(+), 54 deletions(-) create mode 100644 images/300_35_ts1.png create mode 100644 images/300_35_ts2.png diff --git a/300_Aggregations/35_date_histogram.asciidoc b/300_Aggregations/35_date_histogram.asciidoc index b7f2823c7..be5103770 100644 --- a/300_Aggregations/35_date_histogram.asciidoc +++ b/300_Aggregations/35_date_histogram.asciidoc @@ -172,14 +172,19 @@ to tell Elasticsearch that we want buckets even if they fall _before_ the minimum value or _after_ the maximum value. The `extended_bounds` parameter does just that. Once you add those two settings, -you'll get a response that is easy to plug straight into your graphing libraries. +you'll get a response that is easy to plug straight into your graphing libraries +and give you a graph like this: + +[[date-histo-ts1]] +image::images/300_35_ts1.png["Line chart of cars sold per month"] === Extended Example Just like we've seen a dozen times already, buckets can be nested in buckets for more sophisticated behavior. For illustration, we'll build an aggregation -which shows the average price of the top-selling car each month. - +which shows the total sum of prices for all makes, listed by quarter. Let's also +calculate the sum of prices per individual make per quarter, so we can see +which car type is bringing in the most money to our business: [source,js] -------------------------------------------------- @@ -189,7 +194,7 @@ GET /cars/transactions/_search?search_type=count "sales": { "date_histogram": { "field": "sold", - "interval": "month", + "interval": "quarter", <1> "format": "yyyy-MM-dd", "min_doc_count" : 0, "extended_bounds" : { @@ -198,16 +203,18 @@ GET /cars/transactions/_search?search_type=count } }, "aggs": { - "top_selling": { + "per_make_sum": { "terms": { - "field": "make", - "size": 1 + "field": "make" }, "aggs": { - "avg_price": { - "avg": { "field": "price" } + "sum_price": { + "sum": { "field": "price" } <2> } } + }, + "total_sum": { + "sum": { "field": "price" } <3> } } } @@ -215,62 +222,52 @@ GET /cars/transactions/_search?search_type=count } -------------------------------------------------- // SENSE: 300_Aggregations/35_date_histogram.json +<1> Note that we changed the interval from `month` to `quarter` +<2> Calculate the sum per make +<3> And the total sum of all makes combined together Which returns a (heavily truncated) response: [source,js] -------------------------------------------------- { -... - "aggregations": { - "sales": { - "buckets": [ - { - "key_as_string": "2014-01-01", - "key": 1388534400000, - "doc_count": 1, - "top_selling": { - "buckets": [ - { - "key": "bmw", - "doc_count": 1, - "avg_price": { - "value": 80000 - } - } - ] - } +.... +"aggregations": { + "sales": { + "buckets": [ + { + "key_as_string": "2014-01-01", + "key": 1388534400000, + "doc_count": 2, + "total_sum": { + "value": 105000 }, - { - "key_as_string": "2014-02-01", - "key": 1391212800000, - "doc_count": 1, - "top_selling": { - "buckets": [ - { - "key": "ford", - "doc_count": 1, - "avg_price": { - "value": 25000 - } + "per_make_sum": { + "buckets": [ + { + "key": "bmw", + "doc_count": 1, + "sum_price": { + "value": 80000 } - ] - } - }, - { - "key_as_string": "2014-03-01", - "key": 1393632000000, - "doc_count": 0, - "top_selling": { - "buckets": []<1> - } + }, + { + "key": "ford", + "doc_count": 1, + "sum_price": { + "value": 25000 + } + } + ] } + }, ... } -------------------------------------------------- <1> Empty bucket because no cars were sold in March -As you would expect, we see a list of buckets corresponding to each month, -including months that had no car sales (e.g. March). Each month -then has bucket corresponding to the top selling make, and that -bucket contains a metric which calculates the average price for that month. \ No newline at end of file +We can take this response and put it into a graph, showing a line chart for +total sale price, and a bar chart for each individual make (per quarter): + +[[date-histo-ts2]] +image::images/300_35_ts2.png["Line chart of cars sold per month"] \ No newline at end of file diff --git a/images/300_35_ts1.png b/images/300_35_ts1.png new file mode 100644 index 0000000000000000000000000000000000000000..3a83fab6309f60dc16b94d567ef281d1f1d0fabd GIT binary patch literal 28343 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 G3;TaJcPVoK literal 0 HcmV?d00001 diff --git a/images/300_35_ts2.png b/images/300_35_ts2.png new file mode 100644 index 0000000000000000000000000000000000000000..318992f18484b334154d0ccfd72a8fe5101d158f GIT binary patch literal 44205 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
(d|vB^gMvqn`S)@fvGI68 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 Date: Wed, 20 Aug 2014 13:56:53 -0400 Subject: [PATCH 04/15] initial dump of cluster admin chapter --- 300_Aggregations/110_docvalues.asciidoc | 2 +- 500_Cluster_Admin.asciidoc | 34 +- 500_Cluster_Admin/10_intro.asciidoc | 17 + 500_Cluster_Admin/15_marvel.asciidoc | 29 ++ 500_Cluster_Admin/20_health.asciidoc | 222 +++++++++++++ 500_Cluster_Admin/30_node_stats.asciidoc | 396 +++++++++++++++++++++++ 6 files changed, 685 insertions(+), 15 deletions(-) create mode 100644 500_Cluster_Admin/10_intro.asciidoc create mode 100644 500_Cluster_Admin/15_marvel.asciidoc create mode 100644 500_Cluster_Admin/20_health.asciidoc create mode 100644 500_Cluster_Admin/30_node_stats.asciidoc diff --git a/300_Aggregations/110_docvalues.asciidoc b/300_Aggregations/110_docvalues.asciidoc index ee1c26137..71279c3ef 100644 --- a/300_Aggregations/110_docvalues.asciidoc +++ b/300_Aggregations/110_docvalues.asciidoc @@ -1,4 +1,4 @@ - +[[doc_values]] === Doc Values The default data structure for field data is called _paged-bytes_, and it is diff --git a/500_Cluster_Admin.asciidoc b/500_Cluster_Admin.asciidoc index cd91db951..8b090a090 100644 --- a/500_Cluster_Admin.asciidoc +++ b/500_Cluster_Admin.asciidoc @@ -1,21 +1,27 @@ [[cluster-admin]] -== Cluster management and monitoring (TODO) +== Cluster management and monitoring +include::500_Cluster_Admin/10_intro.asciidoc[] -This chapter discusses how cluster management and monitoring. +include::500_Cluster_Admin/15_marvel.asciidoc[] -=== Cluster health -. +include::500_Cluster_Admin/20_health.asciidoc[] +include::500_Cluster_Admin/30_node_stats.asciidoc[] -=== Cluster settings -. - - -=== Nodes stats -. - - -=== Nodes info -. +- management + - cluster settings + - dynamically changing logging + - index settings + +- monitoring + - marvel + - cluster health + - cluster stats + - node stats / node info + - rejections + - index stats + - hot threads + - pending tasks +- cat api \ No newline at end of file diff --git a/500_Cluster_Admin/10_intro.asciidoc b/500_Cluster_Admin/10_intro.asciidoc new file mode 100644 index 000000000..66b660c60 --- /dev/null +++ b/500_Cluster_Admin/10_intro.asciidoc @@ -0,0 +1,17 @@ + + + +Elasticsearch is often deployed as a cluster of nodes. There are a variety of +APIs that let you manage and monitor the cluster itself, rather than interact +with the data stored within the cluster. + +As with most functionality in Elasticsearch, there is an over-arching design goal +that tasks should be performed through an API rather than by modifying static +configuration files. This becomes especially important as your cluster scales. +Even with a provisioning system (puppet, chef, ansible, etc), a single HTTP API call +is often simpler than pushing new configurations to hundreds of physical machines. + +To that end, this chapter will be discussing the various APIs that allow you to +dynamically tweak, tune and configure your cluster. We will also cover a +host of APIs that provide statistics about the cluster itself so that you can +monitor for health and performance. \ No newline at end of file diff --git a/500_Cluster_Admin/15_marvel.asciidoc b/500_Cluster_Admin/15_marvel.asciidoc new file mode 100644 index 000000000..b8123cdb9 --- /dev/null +++ b/500_Cluster_Admin/15_marvel.asciidoc @@ -0,0 +1,29 @@ + +=== Marvel for Monitoring + +At the very beginning of the book (<>) we encouraged you to install +Marvel, a management monitoring tool for Elasticsearch, because it would enable +interactive code samples throughout the book. + +If you didn't install Marvel then, we encourage you to install it now. This +chapter will introduce a large number of APIs that emit an even larger number +of statistics. These stats track everything from heap memory usage and garbage +collection counts to open file descriptors. These statistics are invaluable +for debugging a misbehaving cluster. + +The problem is that these APIs provide a single data point -- the statistic +_right now_. Often you'll want to see historical data too, so that you can +plot a trend. Knowing memory usage at this instant is helpful, but knowing +memory usage _over time_ is much more useful. + +Furthermore, the output of these APIs can get truly hairy as your cluster grows. +Once you have a dozen nodes, let alone a hundred, reading through stacks of JSON +becomes very tedious. + +Marvel periodically polls these APIs and stores the data back in Elasticsearch. +This allows Marvel to query and aggregate the metrics, then provide interactive +graphs in your browser. There are no proprietary statistics that Marvel exposes; +it uses the same stats APIs that are accessible to you. But it does greatly +simplify the collection and graphing of those statistics. + +Marvel is free to use in development, so you should definitely try it out! \ No newline at end of file diff --git a/500_Cluster_Admin/20_health.asciidoc b/500_Cluster_Admin/20_health.asciidoc new file mode 100644 index 000000000..129de27d6 --- /dev/null +++ b/500_Cluster_Admin/20_health.asciidoc @@ -0,0 +1,222 @@ + +=== Cluster Health + +An Elasticsearch cluster may consist of a single node with a single index. Or it +may have a hundred data nodes, three dedicated masters, a few dozen clients nodes +...all operating on a thousand indices (and tends of thousands of shards). + +No matter the scale of the cluster, you'll want a quick way to assess the status +of your cluster. The _Cluster Health_ API fills that role. You can think of it +as a ten-thousand foot view of your cluster. It can reassure you that everything +is alright, or alert you to a problem somewhere in your cluster. + +Let's execute a Health API and see what the response looks like: + +[source,bash] +---- +GET _cluster/health +---- + +Like other APIs in Elasticsearch, Cluster Health will return a JSON response. +This makes it convenient to parse for automation and alerting. The response +contains some critical information about your cluster: + +[source,js] +---- +{ + "cluster_name": "elasticsearch_zach", + "status": "green", + "timed_out": false, + "number_of_nodes": 1, + "number_of_data_nodes": 1, + "active_primary_shards": 10, + "active_shards": 10, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 0 +} +---- + +The most important piece of information in the response is the `"status"` field. +The status may be one of three values: + +- *Green:* all primary and replica shards are allocated. Your cluster is 100% +operational +- *Yellow:* all primary shards are allocated, but at least one replica is missing. +No data is missing so search results will still be complete. However, your +high-availability is compromised to some degree. If _more_ shards disappear, you +might lose data. Think of Yellow as a warning which should prompt investigation. +- *Red:* at least one primary shard (and all of it's replicas) are missing. This means +that you are missing data: searches will return partial results and indexing +into that shard will return an exception. + +The Green/Yellow/Red status is a great way to glance at your cluster and understand +what's going on. The rest of the metrics give you a general summary of your cluster: + +- `number_of_nodes` and `number_of_data_nodes` are fairly self-descriptive. +- `active_primary_shards` are the number of primary shards in your cluster. This +is an aggregate total across all indices. +- `active_shards` is an aggregate total of _all_ shards across all indices, which +includes replica shards +- `relocating_shards` shows the number of shards that are currently moving from +one node to another node. This number is often zero, but can increase when +Elasticsearch decides a cluster is not properly balanced, a new node is added, +a node is taken down, etc. +- `initializing_shards` is a count of shards that are being freshly created. For +example, when you first create an index, the shards will all briefly reside in +"initializing" state. This is typically a transient event and shards shouldn't +linger in "initializing" too long. You may also see initializing shards when a +node is first restarted...as shards are loaded from disk they start as "initializing" +- `unassigned_shards` are shards that exist in the cluster state, but cannot be +found in the cluster itself. A common source of unassigned shards are unassigned +replicas. For example, an index with 5 shards and 1 replica will have 5 unassigned +replicas in a single-node cluster. Unassigned shards will also be present if your +cluster is red (since primaries are missing) + +==== Drilling deeper: finding problematic indices + +Imagine something goes wrong one day, and you notice that your cluster health +looks like this: + +[source,js] +---- +{ + "cluster_name": "elasticsearch_zach", + "status": "red", + "timed_out": false, + "number_of_nodes": 8, + "number_of_data_nodes": 8, + "active_primary_shards": 90, + "active_shards": 180, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 20 +} +---- + +Ok, so what can we deduce from this health status? Well, our cluster is Red, +which means we are missing data (primary + replicas). We know our cluster has +ten nodes, but only see 8 data nodes listed in the health. Two of our nodes +have gone missing. We see that there are 20 unassigned shards. + +That's about all the information we can glean. The nature of those missing +shards are still a mystery. Are we missing 20 indices with one primary shard each? +One index with 20 primary shards? Ten indices with one primary + one replica? +Which index? + +To answer these questions, we need to ask the Cluster Health for a little more +information by using the `level` parameter. + +[source,bash] +---- +GET _cluster/health?level=indices +---- + +This parameter will make the Cluster Health API to add a list of indices in our +cluster and details about each of those indices (status, number of shards, +unassigned shards, etc): + +[source,js] +---- +{ + "cluster_name": "elasticsearch_zach", + "status": "red", + "timed_out": false, + "number_of_nodes": 8, + "number_of_data_nodes": 8, + "active_primary_shards": 90, + "active_shards": 180, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 20 + "indices": { + "v1": { + "status": "green", + "number_of_shards": 10, + "number_of_replicas": 1, + "active_primary_shards": 10, + "active_shards": 20, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 0 + }, + "v2": { + "status": "red", <1> + "number_of_shards": 10, + "number_of_replicas": 1, + "active_primary_shards": 0, + "active_shards": 0, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 20 <2> + }, + "v3": { + "status": "green", + "number_of_shards": 10, + "number_of_replicas": 1, + "active_primary_shards": 10, + "active_shards": 20, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 0 + }, + .... + } +} +---- +<1> We can now see that the `v2` index is the index which has made the cluster Red +<2> And it becomes clear that all 20 missing shards are from this index + +Once we ask for the indices output, it becomes immediately clear which index is +having problems: the `v2` index. We also see that the index has 10 primary shards +and one replica, and that all 20 shards are missing. Presumably these 20 shards +were on the two nodes that are missing from our cluster. + +The `level` parameter accepts one more option: + +[source,bash] +---- +GET _cluster/health?level=shards +---- + +The `shards` option will provide a very verbose output, which lists the status +and location of every shard inside every index. This output is sometimes useful, +but due to the verbosity can difficult to work with. Once you know the index +that is having problems, other APIs that we discuss in this chapter will tend +to be more helpful. + +==== Blocking for status changes + +The Cluster Health API has another neat trick which is very useful when building +unit and integration tests, or automated scripts that work with Elasticsearch. +You can specify a `wait_for_status` parameter, which will make the call block +until the status is satisfied. For example: + +[source,bash] +---- +GET _cluster/health?wait_for_status=green +---- + +This call will block (e.g. not return control to your program) until the cluster +health has turned green, meaning all primary + replica shards have been allocated. +This is very important for automated scripts and tests. + +If you create an index, Elasticsearch must broadcast the change in cluster state +to all nodes. Those nodes must initialize those new shards, then respond to the +master that the shards are Started. This process is very fast, but due to network +latency may take 10-20ms. + +If you have an automated script that A) creates an index and then B) immediately +attempts to index a document, this operation may fail since the index has not +been fully initialized yet. The time between A) and B) will likely be <1ms... +not nearly enough time to account for network latency. + +Rather than sleeping, just have your script/test call the cluster health with +a `wait_for_status` parameter. As soon as the index is fully created, the cluster +health will change to Green, the call returns control to your script, and you may +begin indexing. + +Valid options are `green`, `yellow` and `red`. The call will return when the +requested status (or one "higher") is reached. E.g. if you request `yellow`, +a status change to `yellow` or `green` will unblock the call. + diff --git a/500_Cluster_Admin/30_node_stats.asciidoc b/500_Cluster_Admin/30_node_stats.asciidoc new file mode 100644 index 000000000..9902e208c --- /dev/null +++ b/500_Cluster_Admin/30_node_stats.asciidoc @@ -0,0 +1,396 @@ + +=== Monitoring individual nodes + +Cluster Health is at one end of the spectrum -- a very high-level overview of +everything in your cluster. The _Node Stats_ API is at the other end. It provides +an bewildering array of statistics about each node in your cluster. + +Node Stats provides so many stats that, until you are accustomed to the output, +you may be unsure which metrics are most important to keep an eye on. We'll +highlight the most important metrics to monitor (but note: we'd encourage you to +log all the metrics provided -- or use Marvel -- because you'll never know when +you need one stat or another) + +The Node Stats API can be executed with the following: + +[source,bash] +---- +GET _nodes/stats +---- + +Starting at the top of the output, we see the cluster name and our first node: + +[source,js] +---- +{ + "cluster_name": "elasticsearch_zach", + "nodes": { + "UNr6ZMf5Qk-YCPA_L18BOQ": { + "timestamp": 1408474151742, + "name": "Zach", + "transport_address": "inet[zacharys-air/192.168.1.131:9300]", + "host": "zacharys-air", + "ip": [ + "inet[zacharys-air/192.168.1.131:9300]", + "NONE" + ], +... +---- + +The nodes are listed in a hash, with the key being the UUID of the node. Some +information about the node's network properties are displayed (transport address, +host, etc). These values are useful for debugging discovery problems, where +nodes won't join the cluster. Often you'll see that the port being used is wrong, +or the node is binding to the wrong IP address/interface. + +==== Indices section + +The indices section lists aggregate statistics for all the indices that reside +on this particular node. + +[source,js] +---- + "indices": { + "docs": { + "count": 6163666, + "deleted": 0 + }, + "store": { + "size_in_bytes": 2301398179, + "throttle_time_in_millis": 122850 + }, +---- + +- `docs` shows how many documents reside on +this node, as well as the number of deleted docs which haven't been purged +from segments yet. + +- The `store` portion indicates how much physical storage is consumed by the node. +This metric includes both primary and replica shards. If the throttle time is +large, it may be an indicator that your disk throttling is set too low +(discussed later in TODO). + +[source,js] +---- + "indexing": { + "index_total": 803441, + "index_time_in_millis": 367654, + "index_current": 99, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0 + }, + "get": { + "total": 6, + "time_in_millis": 2, + "exists_total": 5, + "exists_time_in_millis": 2, + "missing_total": 1, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 123, + "query_time_in_millis": 531, + "query_current": 0, + "fetch_total": 3, + "fetch_time_in_millis": 55, + "fetch_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 1128, + "total_time_in_millis": 21338523, + "total_docs": 7241313, + "total_size_in_bytes": 5724869463 + }, +---- + +- `indexing` shows how many docs have been indexed. This value is a monotonically +increasing counter, it doesn't decrease when docs are deleted. Also note that it +is incremented any time an _index_ operation happens internally, which includes +things like updates. ++ +Also listed are times for indexing, how many docs are currently being indexed, +and similar statistics for deletes. + +- `get` shows statistics about get-by-ID statistics. This includes GETs and +HEAD requests for a single document + +- `search` describes the number of active searches (`open_contexts`), number of +queries total and how much time has been spent on queries since the node was +started. The ratio between `query_total / query_time_in_milis` can be used as a +rough indicator for how efficient your queries are. The larger the ratio, +the more time each query is taking and you should consider tuning or optimization. ++ +The fetch statistics details the second half of the query process (the "fetch" in +query-then-fetch). If more time is spent in fetch than query, this can be an +indicator of slow disks or very large documents which are being fetched. Or +potentially search requests with too large of paginations (`size: 10000`, etc). + +- `merges` contains information about Lucene segment merges. It will tell you +how many merges are currently active, how many docs are involved, the cumulative +size of segments being merged and how much time has been spent on merges in total. ++ +Merge statistics can be important if your cluster is write-heavy. Merging consumes +a large amount of disk I/O and CPU resources. If your index is write-heavy and +you see large merge numbers, be sure to read the section on optimizing for indexing +(TODO). ++ +Note: updates and deletes will contribute to large merge numbers too, since they +cause segment "fragmentation" which needs to be merged out eventually. + +[source,js] +---- + "filter_cache": { + "memory_size_in_bytes": 48, + "evictions": 0 + }, + "id_cache": { + "memory_size_in_bytes": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "segments": { + "count": 319, + "memory_in_bytes": 65812120 + }, + ... +---- + +- `filter_cache` describes how much memory is used by the cached filter bitsets, +and how many times a filter has been evicted. A large number of evictions +_could_ be indicative that you need to increase the filter cache size, or that +your filters are not caching well (e.g. churn heavily due to high cardinality, +such as caching "now" date expressions). ++ +However, evictions are a difficult metric to evaluate. Filters are cached on a +per-segment basis, and evicting a filter from a small segment is much less +expensive than a filter on a large segment. It's possible that you have a large +number of evictions, but they all occur on small segments, which means they have +little impact on query performance. ++ +Use the eviction metric as a rough guideline. If you see a large number, investigate +your filters to make sure they are caching well. Filters that constantly evict, +even on small segments, will be much less effective than properly cached filters. + +- `id_cache` shows the memory usage by Parent/Child mappings. When you use +parent/children, the `id_cache` maintains an in-memory-join table which maintains +the relationship. This statistic will show you how much memory is being used. +There is little you can do to affect this memory usage, since it is a fairly linear +relationship with the number of parent/child docs. It is heap-resident, however, +so a good idea to keep an eye on it. + +- `field_data` displays the memory used by field data, which is used for aggregations, +sorting, etc. There is also an eviction count. Unlike `filter_cache`, the eviction +count here is very useful: it should be zero, or very close. Since field data +is not a cache, any eviction is very costly and should be avoided. If you see +evictions here, you need to re-evaluate your memory situation, field data limits, +queries or all three. + +- `segments` will tell you how many Lucene segments this node currently serves. +This can be an important number. Most indices should have around 50-150 segments, +even if they are terrabytes in size with billions of documents. Large numbers +of segments can indicate a problem with merging (e.g. merging is not keeping up +with segment creation). Note that this statistic is the aggregate total of all +indices on the node, so keep that in mind. ++ +The `memory` statistic gives you an idea how much memory is being used by the +Lucene segments themselves. This includes low-level data structures such as +posting lists, dictionaries and bloom filters. A very large number of segments +will increase the amount of overhead lost to these data structures, and the memory +usage can be a handy metric to gauge that overhead. + +==== OS and Process Sections + +The OS and Process sections are fairly self-explanatory and won't be covered +in great detail. They list basic resource statistics such as CPU and load. The +OS section describes it for the entire OS, while the Process section shows just +what the Elasticsearch JVM process is using. + +These are obviously useful metrics, but are often being measured elsewhere in your +monitoring stack. Some stats include: + +- CPU +- Load +- Memory usage +- Swap usage +- Open file descriptors + +==== JVM Section + +The JVM section contains some critical information about the JVM process which +is running Elasticsearch. Most importantly, it contains garbage collection details, +which have a large impact on the stability of your Elasticsearch cluster. + +.Garbage Collection Primer +********************************** +Before we describe the stats, it is useful to give a crash course in garbage +collection and it's impact on Elasticsearch. If you are familar with garbage +collection in the JVM, feel free to skip down. + +Java is a _garbage collected_ language, which means that the programmer does +not manually manage memory allocation and deallocation. The programmer simply +writes code, and the Java Virtual Machine (JVM) manages the process of allocating +memory as needed, and then later cleaning up that memory when no longer needed. + +When memory is allocated to a JVM process, it is allocated in a big chunk called +the _heap_. The JVM then breaks the heap into two different groups, referred to as +"generations": + +- Young (or Eden): the space where newly instantiated objects are allocated. The +young generation space is often quite small, usually 100mb-500mb. The young-gen +also contains two "survivor" spaces +- Old: the space where older objects are stored. These objects to be long-lived +and persist for a long time. The old-gen is often much larger than then young-gen, +and Elasticsearch nodes can see old-gens as large as 30gb. + +When an object is instantiated, it is placed into young-gen. When the young +generation space is full, a young-gen GC is started. Objects that are still +"alive" are moved into one of the survivor spaces, and "dead" objects are removed. +If an object has survived several young-gen GCs, it will be "tenured" into the +old generation. + +A similar process happens in the old generation: when the space becomes full, a +garbage collection is started and "dead" objects are removed. + +Nothing comes for free, however. Both the young and old generation garbage collectors +have phases which "stop the world". During this time, the JVM literally halts +execution of the program so that it can trace the object graph and collect "dead" +objects. + +During this "stop the world" phase, nothing happens. Requests are not serviced, +pings are not responded to, shards are not relocated. The world quite literally +stops. + +This isn't a big deal for the young generation; its small size means GCs execute +quickly. But the old-gen is quite a bit larger, and a slow GC here could mean +1s or even 15s of pausing...which is unacceptable for server software. + +The garbage collectors in the JVM are _very_ sophisticated algorithms and do +a great job minimizing pauses. And Elasticsearch tries very hard to be "garbage +collection friendly", by intelligently reusing objects internally, reusing network +buffers, offering features like <>, etc. But ultimately, +GC frequency and duration is a metric that needs to be watched by you since it +is the number one culprit for cluster instability. + +A cluster which is frequently experiencing long GC will be a cluster that is under +heavy load with not enough memory. These long GCs will make nodes drop off the +cluster for brief periods. This instability causes shards to relocate frequently +as ES tries to keep the cluster balanced and enough replicas available. This in +turn increases network traffic and Disk I/O, all while your cluster is attempting +to service the normal indexing and query load. + +In short, long GCs are bad and they need to be minimized as much as possible. +********************************** + +Because garbage collection is so critical to ES, you should become intimately +familiar with this section of the Node Stats API: + +[source,js] +---- + "jvm": { + "timestamp": 1408556438203, + "uptime_in_millis": 14457, + "mem": { + "heap_used_in_bytes": 457252160, + "heap_used_percent": 44, + "heap_committed_in_bytes": 1038876672, + "heap_max_in_bytes": 1038876672, + "non_heap_used_in_bytes": 38680680, + "non_heap_committed_in_bytes": 38993920, + +---- + +- The `jvm` section first lists some general stats about heap memory usage. You +can see how much of the heap is being used, how much is committed (actually allocated +to the process), and the max size the heap is allowed to grow to. Ideally, +`heap_committed_in_bytes` should be identical to `heap_max_in_bytes`. If the +committed size is smaller, the JVM will have to resize the heap eventually... +and this is a very expensive process. If your numbers are not identical, see +this section <> in the next chapter to configure it correctly. ++ +The `heap_used_percent` metric is a useful number to keep an eye on. Elasticsearch +is configured to initiate GCs when the heap reaches 75% full. If your node is +consistently >= 75%, that indicates that your node is experiencing "memory pressure". +This is a warning sign that slow GCs may be in your near future. ++ +If the heap usage is consistently >=85%, you are in trouble. Heaps over 90-95% +are in risk of horrible performance with long 10-30s GCs at best, Out-of-memory +(OOM) exceptions at worst. + +[source,js] +---- + "pools": { + "young": { + "used_in_bytes": 138467752, + "max_in_bytes": 279183360, + "peak_used_in_bytes": 279183360, + "peak_max_in_bytes": 279183360 + }, + "survivor": { + "used_in_bytes": 34865152, + "max_in_bytes": 34865152, + "peak_used_in_bytes": 34865152, + "peak_max_in_bytes": 34865152 + }, + "old": { + "used_in_bytes": 283919256, + "max_in_bytes": 724828160, + "peak_used_in_bytes": 283919256, + "peak_max_in_bytes": 724828160 + } + } + }, +---- + +- The `young`, `survivor` and `old` sections will give you a breakdown of memory +usage of each generation in the GC. These stats are handy to keep an eye on +relative sizes, but are often not overly important when debugging problems. + +[source,js] +---- + "gc": { + "collectors": { + "young": { + "collection_count": 13, + "collection_time_in_millis": 923 + }, + "old": { + "collection_count": 0, + "collection_time_in_millis": 0 + } + } + } +---- + +- `gc` section shows the garbage collection counts and cumulative time for both +young and old generations. You can safely ignore the young generation counts +for the most part: this number will usually be very large. That is perfectly +normal. ++ +In contrast, the old generation collection count should remain very small, and +have a small `collection_time_in_millis`. These are cumulative counts, so it is +hard to give an exact number when you should start worrying (e.g. a node with a +1-year uptime will have a large count even if it is healthy) -- this is one of the +reasons why tools such as Marvel are so helpful. GC counts _over time_ are the +important consideration. ++ +Time spent GC'ing is also important. For example, a certain amount of garbage +is generated while indexing documents. This is normal, and causes a GC every +now-and-then. These GCs are almost always fast -- a millisecond or two -- and +do not impact the node. This is much different from 10 second GCs. ++ +Our best advice is to collect collection counts and duration periodically (or use Marvel) +and keep an eye out for frequent GCs. You can also enable slow-GC logging, +discussed in <> + +==== Threadpool Section + + + From 09b40b8f11237a877ffa453c4276d142f478614c Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Thu, 21 Aug 2014 14:15:44 -0400 Subject: [PATCH 05/15] wrap up node stats --- .../100_circuit_breaker_fd_settings.asciidoc | 2 +- 500_Cluster_Admin/30_node_stats.asciidoc | 145 ++++++++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/300_Aggregations/100_circuit_breaker_fd_settings.asciidoc b/300_Aggregations/100_circuit_breaker_fd_settings.asciidoc index ed57ab557..44ed74086 100644 --- a/300_Aggregations/100_circuit_breaker_fd_settings.asciidoc +++ b/300_Aggregations/100_circuit_breaker_fd_settings.asciidoc @@ -60,7 +60,7 @@ recommended in various articles on the internet as a good "performance tip". It is not. Never use it! ==== - +[[circuit_breaker]] ==== Circuit Breaker An astute reader might have noticed a problem with the field data size settings. diff --git a/500_Cluster_Admin/30_node_stats.asciidoc b/500_Cluster_Admin/30_node_stats.asciidoc index 9902e208c..4cdd491cf 100644 --- a/500_Cluster_Admin/30_node_stats.asciidoc +++ b/500_Cluster_Admin/30_node_stats.asciidoc @@ -392,5 +392,150 @@ discussed in <> ==== Threadpool Section +Elasticsearch maintains a number of threadpools internally. These threadpools +cooperate to get work done, passing work between each other as necessary. In +general, you don't need to configure or tune the threadpools, but it is sometimes +useful to see their stats so you can gain insight into how your cluster is behaving. + +There are about a dozen threadpools, but they all share the same format: + +[source,js] +---- + "index": { + "threads": 1, + "queue": 0, + "active": 0, + "rejected": 0, + "largest": 1, + "completed": 1 + } +---- + +Each threadpool lists the number of threads that are configured (`threads`), +how many of those threads are actively processing some work (`active`) and how +many work units are sitting in a queue (`queue`). + +If the queue fills up to its limit, new workunits will begin to be rejected and +you will see that reflected in the `rejected` statistic. This is often a sign +that your cluster is starting to bottleneck on some resources, since a full +queue means your node/cluster is processing at maximum speed but unable to keep +up with the influx of work. + +.Bulk Rejections +**** +If you are going to encounter queue rejections, it will most likely be caused +by Bulk indexing requests. It is easy to send many Bulk requests to Elasticsearch +using concurrent import processes. More is better, right? + +In reality, each cluster has a certain limit at which it can not keep up with +ingestion. Once this threshold is crossed, the queue will quickly fill up and +new bulks will be rejected. + +This is a _good thing_. Queue rejections are a useful form of back-pressure. They +let you know that your cluster is at maximum capacity, which is much better than +sticking data into an in-memory queue. Increasing the queue size doesn't increase +performance, it just hides the problem. If your cluster can only process 10,000 +doc/s, it doesn't matter if the queue is 100 or 10,000,000...your cluster can +still only process 10,000 docs/s. + +The queue simply hides the performance problem and carries real risk of data-loss. +Anything sitting in a queue is by definition not processed yet. If the node +goes down, all those requests are lost forever. Furthermore, the queue eats +up a lot of memory, which is not ideal. + +It is much better to handle queuing in your application by gracefully handling +the back-pressure from a full queue. When you receive bulk rejections you should: + +1. Pause the import thread for 3-5 seconds +2. Extract the rejected actions from the bulk response, since it is probable that +many of the actions were successful. The bulk response will tell you which succeeded, +and which were rejected. +3. Send a new bulk request with just the rejected actions +4. Repeat at step 1. if rejections were encountered again + +Using this procedure, your code naturally adapts to the load of your cluster and +naturally backs off. + +Rejections are not errors: they just mean you should try again later. +**** + +There are a dozen different threadpools. Most you can safely ignore, but a few +are good to keep an eye on: + +- `indexing`: threadpool for normal indexing requests +- `bulk`: bulk requests, which are distinct from the non-bulk indexing requests +- `get`: GET-by-ID operations +- `search`: all search and query requests +- `merging`: threadpool dedicated to managing Lucene merges + +==== FS and Network sections + +Continuing down the Node Stats API, you'll see a bunch of statistics about your +filesystem: free space, data directory paths, disk IO stats, etc. If you are +not monitoring free disk space, you can get those stats here. The Disk IO stats +are also handy, but often more specialized command-line tools (`iostat`, etc) +are more useful. + +Obviously, Elasticsearch has a difficult time functioning if you run out of disk +space...so make sure you don't :) + +There are also two sections on network statistics: + +[source,js] +---- + "transport": { + "server_open": 13, + "rx_count": 11696, + "rx_size_in_bytes": 1525774, + "tx_count": 10282, + "tx_size_in_bytes": 1440101928 + }, + "http": { + "current_open": 4, + "total_opened": 23 + }, +---- + +- `transport` shows some very basic stats about the "transport address". This +relates to inter-node communication (often on port 9300) and any TransportClient +or NodeClient connections. Don't worry yourself if you see many connections here, +Elasticsearch maintains a large number of connections between nodes + +- `http` represents stats about the HTTP port (often 9200). If you see a very +large `total_opened` number that is constantly increasing, that is a sure-sign +that one of your HTTP clients is not using keep-alive connections. Persistent, +keep-alive connections are important for performance, since building up and tearing +down sockets is expensive (and wastes file descriptors). Make sure your clients +are configured appropriately. + +==== Circuit Breaker + +Finally, we come to the last section: stats about the field data circuit breaker +(introduced in <>): + +[source,js] +---- + "fielddata_breaker": { + "maximum_size_in_bytes": 623326003, + "maximum_size": "594.4mb", + "estimated_size_in_bytes": 0, + "estimated_size": "0b", + "overhead": 1.03, + "tripped": 0 + } +---- + +Here, you can determine what the maximum circuit breaker size is (e.g. at what +size the circuit breaker will trip if a query attempts to use more memory). It +will also let you know how many times the circuit breaker has been tripped, and +the currently configured "overhead". The overhead is used to pad estimates +since some queries are more difficult to estimate than others. + +The main thing to watch is the `tripped` metric. If this number is large, or +consistently increasing, it's a sign that your queries may need to be optimized +or that you may need to obtain more memory (either per box, or by adding more +nodes). + + From 3db65b60cebcff5ae8b8dbfdc84f8befb7e7e2aa Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Thu, 21 Aug 2014 16:59:59 -0400 Subject: [PATCH 06/15] other stats --- 500_Cluster_Admin.asciidoc | 2 + 500_Cluster_Admin/40_other_stats.asciidoc | 160 ++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 500_Cluster_Admin/40_other_stats.asciidoc diff --git a/500_Cluster_Admin.asciidoc b/500_Cluster_Admin.asciidoc index 8b090a090..745f66ddf 100644 --- a/500_Cluster_Admin.asciidoc +++ b/500_Cluster_Admin.asciidoc @@ -8,6 +8,8 @@ include::500_Cluster_Admin/20_health.asciidoc[] include::500_Cluster_Admin/30_node_stats.asciidoc[] +include::500_Cluster_Admin/40_other_stats.asciidoc[] + - management - cluster settings - dynamically changing logging diff --git a/500_Cluster_Admin/40_other_stats.asciidoc b/500_Cluster_Admin/40_other_stats.asciidoc new file mode 100644 index 000000000..fa8178b6e --- /dev/null +++ b/500_Cluster_Admin/40_other_stats.asciidoc @@ -0,0 +1,160 @@ + +=== Cluster Stats + +The _Cluster Stats_ API provides very similar output to the Node Stats. There +is one crucial difference: Node Stats shows you statistics per-node, while +Cluster Stats will show you the sum total of all nodes in a single metric. + +This provides some useful stats to glance at. You can see that your entire cluster +is using 50% available heap, filter cache is not evicting heavily, etc. It's +main use is to provide a quick summary which is more extensive than +the Cluster Health, but less detailed than Node Stats. It is also useful for +clusters which are very large, which makes Node Stats output difficult +to read. + +The API may be invoked with: + +[source,js] +---- +GET _cluster/stats +---- + +=== Index Stats + +So far, we have been looking at _node-centric_ statistics. How much memory does +this node have? How much CPU is being used? How many searches is this node +servicing? Etc. etc. + +Sometimes it is useful to look at statistics from an _index-centric_ perspective. +How many search requests is _this index_ receiving? How much time is spent fetching +docs in _that index_, etc. + +To do this, select the index (or indices) that you are interested in and +execute an Index Stats API: + +[source,js] +---- +GET my_index/_stats <1> + +GET my_index,another_index/_stats <2> + +GET _all/_stats <3> +---- +<1> Stats for `my_index` +<2> Stats for multiple indices can be requested by comma separating their names +<3> Stats indices can be requested using the special `_all` index name + +The stats returned will be familar to the Node Stats output: search, fetch, get, +index, bulk, segment counts, etc + +Index-centric stats can be useful for identifying or verifying "hot" indices +inside your cluster, or trying to determine while some indices are faster/slower +than others. + +In practice, however, node-centric statistics tend to be more useful. Entire +nodes tend to bottleneck, not individual indices. And because indices +are usually spread across multiple nodes, index-centric statistics +are usually not very helpful because it aggregates different physical machines +operating in different environments. + +Index-centric stats are a useful tool to keep in your repertoire, but are not usually +the first tool to reach for. + +=== Pending Tasks + +There are certain tasks that only the master can perform, such as creating a new +index or moving shards around the cluster. Since a cluster can only have one +master, only one node can ever process cluster-level metadata changes. In +99.9999% of the time, this is never a problem. The queue of metadata changes +remains essentially zero. + +In some _very rare_ clusters, the number of metadata changes occurs faster than +the master can process them. This leads to a build up of pending actions which +are queued. + +The _Pending Tasks_ API will show you what (if any) cluster-level metadata changes +are pending in the queue: + +[source,js] +---- +GET _cluster/pending_tasks +---- + +Usually, the response will look like this: + +[source,js] +---- +{ + "tasks": [] +} +---- + +Meaning there are no pending tasks. If you have one of the rare clusters that +bottlenecks on the master node, your pending task list may look like this: + +[source,js] +---- +{ + "tasks": [ + { + "insert_order": 101, + "priority": "URGENT", + "source": "create-index [foo_9], cause [api]", + "time_in_queue_millis": 86, + "time_in_queue": "86ms" + }, + { + "insert_order": 46, + "priority": "HIGH", + "source": "shard-started ([foo_2][1], node[tMTocMvQQgGCkj7QDHl3OA], [P], s[INITIALIZING]), reason [after recovery from gateway]", + "time_in_queue_millis": 842, + "time_in_queue": "842ms" + }, + { + "insert_order": 45, + "priority": "HIGH", + "source": "shard-started ([foo_2][0], node[tMTocMvQQgGCkj7QDHl3OA], [P], s[INITIALIZING]), reason [after recovery from gateway]", + "time_in_queue_millis": 858, + "time_in_queue": "858ms" + } + ] +} +---- + +You can see that tasks are assigned a priority (`URGENT` is processed before `HIGH`, +etc), the order it was inserted, how long the action has been queued and +what the action is trying to perform. In the above list, there is a Create Index +action and two Shard Started actions pending. + +.When should I worry about Pending Tasks? +**** +As mentioned, the master node is rarely the bottleneck for clusters. The only +time it can potentially bottleneck is if the cluster state is both very large +_and_ updated frequently. + +For example, if you allow customers to create as many dynamic fields as they wish, +and have a unique index for each customer every day, you're cluster state will grow +very large. The cluster state includes (among other things) a list of all indices, +their types, and the fields for each index. + +So if you have 100,000 customers, and each customer averages 1000 fields and 90 +days of retention....that's nine billion fields to keep in the cluster state. +Whenever this changes, the nodes must be notified. + +The master must process these changes which requires non-trivial CPU overhead, +plus the network overhead of pushing the updated cluster state to all nodes. + +It is these clusters which may begin to see cluster state actions queuing up. +There is no easy solution to this problem, however. You have three options: + +- Obtain a beefier master node. Vertical scaling just delays the inevitable, +unfortunately +- Restrict the dynamic nature of the documents in some way, so as to limit the +cluster state size. +- Spin up another cluster once a certain threshold has been crossed. +**** + + + + + From bd6fba28672ac12fa17b6e729d06d82ea5d68134 Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Fri, 22 Aug 2014 12:34:28 -0400 Subject: [PATCH 07/15] add cat api --- 500_Cluster_Admin/40_other_stats.asciidoc | 204 ++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/500_Cluster_Admin/40_other_stats.asciidoc b/500_Cluster_Admin/40_other_stats.asciidoc index fa8178b6e..bc48ebe60 100644 --- a/500_Cluster_Admin/40_other_stats.asciidoc +++ b/500_Cluster_Admin/40_other_stats.asciidoc @@ -154,6 +154,210 @@ cluster state size. - Spin up another cluster once a certain threshold has been crossed. **** +==== Cat API + +If you work from the command line often, the _Cat_ APIs will be very helpful +to you. Named after the linux `cat` command, these APIs are designed to be +work like *nix command line tools. + +They provide statistics that are identical to all the previously discussed APIs +(Health, Node Stats, etc), but present the output in tabular form instead of +JSON. This is _very_ convenient as a system administrator and you just want +to glance over your cluster, or find nodes with high memory usage, etc. + +Executing a plain GET against the Cat endpoint will show you all available +APIs: + +[source,shell] +---- +GET /_cat + +=^.^= +/_cat/allocation +/_cat/shards +/_cat/shards/{index} +/_cat/master +/_cat/nodes +/_cat/indices +/_cat/indices/{index} +/_cat/segments +/_cat/segments/{index} +/_cat/count +/_cat/count/{index} +/_cat/recovery +/_cat/recovery/{index} +/_cat/health +/_cat/pending_tasks +/_cat/aliases +/_cat/aliases/{alias} +/_cat/thread_pool +/_cat/plugins +/_cat/fielddata +/_cat/fielddata/{fields} +---- + +Many of these APIs should look familiar to you (and yes, that's a cat at the top +:) ). Let's take a look at the Cat Health API: + +[source,shell] +---- +GET /_cat/health + +1408723713 12:08:33 elasticsearch_zach yellow 1 1 114 114 0 0 114 +---- + +The first thing you'll notice is that the response is plain text in tabular form, +not JSON. The second thing you'll notices is that there are no column headers +enabled by default. This is designed to emulate *nix tools, since it is assumed +that once you become familiar with the output you no longer want to see +the headers. + +To enable headers, add the `?v` parameter: + +[source,shell] +---- +GET /_cat/health?v + +epoch timestamp cluster status node.total node.data shards pri relo init unassign +1408723890 12:11:30 elasticsearch_zach yellow 1 1 114 114 0 0 114 +---- + +Ah, much better. We now see the timestamp, cluster name, the status, how many +nodes are in the cluster, etc. All the same information as the Cluster Health +API. + +Let's look at Node Stats in the Cat API: + +[source,shell] +---- +GET /_cat/nodes?v + +host ip heap.percent ram.percent load node.role master name +zacharys-air 192.168.1.131 45 72 1.85 d * Zach +---- + +We see some stats about the nodes in our cluster, but it is very basic compared +to the full Node Stats output. There are many additional metrics that you can +include, but rather than consulting the documentation, let's just ask the Cat +API what is available. + +You can do this by adding `?help` to any API: + +[source,shell] +---- +GET /_cat/nodes?help + +id | id,nodeId | unique node id +pid | p | process id +host | h | host name +ip | i | ip address +port | po | bound transport port +version | v | es version +build | b | es build hash +jdk | j | jdk version +disk.avail | d,disk,diskAvail | available disk space +heap.percent | hp,heapPercent | used heap ratio +heap.max | hm,heapMax | max configured heap +ram.percent | rp,ramPercent | used machine memory ratio +ram.max | rm,ramMax | total machine memory +load | l | most recent load avg +uptime | u | node uptime +node.role | r,role,dc,nodeRole | d:data node, c:client node +master | m | m:master-eligible, *:current master +... +... +---- +(Note that the output has been truncated for brevity) + +The first column shows the "fullname", the second column shows the "short name", +and the third column offers a brief description about the parameter . Now that +we know some column names, we can ask for those explicitly using the `?h` +parameter: + +[source,shell] +---- +GET /_cat/nodes?v&h=ip,port,heapPercent,heapMax + +ip port heapPercent heapMax +192.168.1.131 9300 53 990.7mb +---- + +Because the Cat API tries to behave like *nix utilities, you can pipe the output +to other tools such as sort, grep, awk, etc. For example, we can find the largest +index in our cluster by using: + +[source,shell] +---- +% curl 'localhost:9200/_cat/indices?bytes=b' | sort -rnk8 + +yellow test_names 5 1 3476004 0 376324705 376324705 +yellow .marvel-2014.08.19 1 1 263878 0 160777194 160777194 +yellow .marvel-2014.08.15 1 1 234482 0 143020770 143020770 +yellow .marvel-2014.08.09 1 1 222532 0 138177271 138177271 +yellow .marvel-2014.08.18 1 1 225921 0 138116185 138116185 +yellow .marvel-2014.07.26 1 1 173423 0 132031505 132031505 +yellow .marvel-2014.08.21 1 1 219857 0 128414798 128414798 +yellow .marvel-2014.07.27 1 1 75202 0 56320862 56320862 +yellow wavelet 5 1 5979 0 54815185 54815185 +yellow .marvel-2014.07.28 1 1 57483 0 43006141 43006141 +yellow .marvel-2014.07.21 1 1 31134 0 27558507 27558507 +yellow .marvel-2014.08.01 1 1 41100 0 27000476 27000476 +yellow kibana-int 5 1 2 0 17791 17791 +yellow t 5 1 7 0 15280 15280 +yellow website 5 1 12 0 12631 12631 +yellow agg_analysis 5 1 5 0 5804 5804 +yellow v2 5 1 2 0 5410 5410 +yellow v1 5 1 2 0 5367 5367 +yellow bank 1 1 16 0 4303 4303 +yellow v 5 1 1 0 2954 2954 +yellow p 5 1 2 0 2939 2939 +yellow b0001_072320141238 5 1 1 0 2923 2923 +yellow ipaddr 5 1 1 0 2917 2917 +yellow v2a 5 1 1 0 2895 2895 +yellow movies 5 1 1 0 2738 2738 +yellow cars 5 1 0 0 1249 1249 +yellow wavelet2 5 1 0 0 615 615 +---- + +By adding `?bytes=b` we disable the "human readable" formatting on numbers and +force them to be listed as bytes. This output is then piped into `sort` so that +our indices are ranked according to size (the 8th column). + +Unfortunately, you'll notice that the Marvel indices are clogging up the results, +and we don't really care about those indices right now. Let's pipe the output +through `grep` and remove anything mentioning marvel: + +[source,shell] +---- +% curl 'localhost:9200/_cat/indices?bytes=b' | sort -rnk8 | grep -v marvel + +yellow test_names 5 1 3476004 0 376324705 376324705 +yellow wavelet 5 1 5979 0 54815185 54815185 +yellow kibana-int 5 1 2 0 17791 17791 +yellow t 5 1 7 0 15280 15280 +yellow website 5 1 12 0 12631 12631 +yellow agg_analysis 5 1 5 0 5804 5804 +yellow v2 5 1 2 0 5410 5410 +yellow v1 5 1 2 0 5367 5367 +yellow bank 1 1 16 0 4303 4303 +yellow v 5 1 1 0 2954 2954 +yellow p 5 1 2 0 2939 2939 +yellow b0001_072320141238 5 1 1 0 2923 2923 +yellow ipaddr 5 1 1 0 2917 2917 +yellow v2a 5 1 1 0 2895 2895 +yellow movies 5 1 1 0 2738 2738 +yellow cars 5 1 0 0 1249 1249 +yellow wavelet2 5 1 0 0 615 615 +---- + +Voila! After piping through `grep` (with `-v` to invert the matches), we get +a sorted list of indices without marvel cluttering it up. + +This is just a simple example of the flexibility of Cat at the command line. +Once you get used to using Cat, you'll see it like any other *nix tool and start +going crazy with piping, sorting, grepping. If you are a system admin and spend +any length of time ssh'd into boxes...definitely spend some time getting familiar +with the Cat API. From e0db2077a1d0e36c17bef6c7044b8b096c9c676e Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Mon, 25 Aug 2014 14:47:07 -0400 Subject: [PATCH 08/15] cleanup, titles --- 500_Cluster_Admin.asciidoc | 19 ------------------- 500_Cluster_Admin/10_intro.asciidoc | 3 +-- 500_Cluster_Admin/15_marvel.asciidoc | 2 +- 500_Cluster_Admin/20_health.asciidoc | 6 +++--- 500_Cluster_Admin/30_node_stats.asciidoc | 14 +++++++------- 500_Cluster_Admin/40_other_stats.asciidoc | 8 ++++---- 6 files changed, 16 insertions(+), 36 deletions(-) diff --git a/500_Cluster_Admin.asciidoc b/500_Cluster_Admin.asciidoc index 745f66ddf..b872a5d92 100644 --- a/500_Cluster_Admin.asciidoc +++ b/500_Cluster_Admin.asciidoc @@ -1,5 +1,4 @@ [[cluster-admin]] -== Cluster management and monitoring include::500_Cluster_Admin/10_intro.asciidoc[] include::500_Cluster_Admin/15_marvel.asciidoc[] @@ -9,21 +8,3 @@ include::500_Cluster_Admin/20_health.asciidoc[] include::500_Cluster_Admin/30_node_stats.asciidoc[] include::500_Cluster_Admin/40_other_stats.asciidoc[] - -- management - - cluster settings - - dynamically changing logging - - index settings - - -- monitoring - - marvel - - cluster health - - cluster stats - - node stats / node info - - rejections - - index stats - - hot threads - - pending tasks - -- cat api \ No newline at end of file diff --git a/500_Cluster_Admin/10_intro.asciidoc b/500_Cluster_Admin/10_intro.asciidoc index 66b660c60..9e659a960 100644 --- a/500_Cluster_Admin/10_intro.asciidoc +++ b/500_Cluster_Admin/10_intro.asciidoc @@ -1,6 +1,5 @@ - - +== Cluster management and monitoring Elasticsearch is often deployed as a cluster of nodes. There are a variety of APIs that let you manage and monitor the cluster itself, rather than interact with the data stored within the cluster. diff --git a/500_Cluster_Admin/15_marvel.asciidoc b/500_Cluster_Admin/15_marvel.asciidoc index b8123cdb9..ea4e22eb8 100644 --- a/500_Cluster_Admin/15_marvel.asciidoc +++ b/500_Cluster_Admin/15_marvel.asciidoc @@ -1,5 +1,5 @@ -=== Marvel for Monitoring +== Marvel for Monitoring At the very beginning of the book (<>) we encouraged you to install Marvel, a management monitoring tool for Elasticsearch, because it would enable diff --git a/500_Cluster_Admin/20_health.asciidoc b/500_Cluster_Admin/20_health.asciidoc index 129de27d6..174a3ff86 100644 --- a/500_Cluster_Admin/20_health.asciidoc +++ b/500_Cluster_Admin/20_health.asciidoc @@ -1,5 +1,5 @@ -=== Cluster Health +== Cluster Health An Elasticsearch cluster may consist of a single node with a single index. Or it may have a hundred data nodes, three dedicated masters, a few dozen clients nodes @@ -73,7 +73,7 @@ replicas. For example, an index with 5 shards and 1 replica will have 5 unassig replicas in a single-node cluster. Unassigned shards will also be present if your cluster is red (since primaries are missing) -==== Drilling deeper: finding problematic indices +=== Drilling deeper: finding problematic indices Imagine something goes wrong one day, and you notice that your cluster health looks like this: @@ -185,7 +185,7 @@ but due to the verbosity can difficult to work with. Once you know the index that is having problems, other APIs that we discuss in this chapter will tend to be more helpful. -==== Blocking for status changes +=== Blocking for status changes The Cluster Health API has another neat trick which is very useful when building unit and integration tests, or automated scripts that work with Elasticsearch. diff --git a/500_Cluster_Admin/30_node_stats.asciidoc b/500_Cluster_Admin/30_node_stats.asciidoc index 4cdd491cf..2bf9ddaad 100644 --- a/500_Cluster_Admin/30_node_stats.asciidoc +++ b/500_Cluster_Admin/30_node_stats.asciidoc @@ -1,5 +1,5 @@ -=== Monitoring individual nodes +== Monitoring individual nodes Cluster Health is at one end of the spectrum -- a very high-level overview of everything in your cluster. The _Node Stats_ API is at the other end. It provides @@ -43,7 +43,7 @@ host, etc). These values are useful for debugging discovery problems, where nodes won't join the cluster. Often you'll see that the port being used is wrong, or the node is binding to the wrong IP address/interface. -==== Indices section +=== Indices section The indices section lists aggregate statistics for all the indices that reside on this particular node. @@ -206,7 +206,7 @@ posting lists, dictionaries and bloom filters. A very large number of segments will increase the amount of overhead lost to these data structures, and the memory usage can be a handy metric to gauge that overhead. -==== OS and Process Sections +=== OS and Process Sections The OS and Process sections are fairly self-explanatory and won't be covered in great detail. They list basic resource statistics such as CPU and load. The @@ -222,7 +222,7 @@ monitoring stack. Some stats include: - Swap usage - Open file descriptors -==== JVM Section +=== JVM Section The JVM section contains some critical information about the JVM process which is running Elasticsearch. Most importantly, it contains garbage collection details, @@ -390,7 +390,7 @@ Our best advice is to collect collection counts and duration periodically (or us and keep an eye out for frequent GCs. You can also enable slow-GC logging, discussed in <> -==== Threadpool Section +=== Threadpool Section Elasticsearch maintains a number of threadpools internally. These threadpools cooperate to get work done, passing work between each other as necessary. In @@ -468,7 +468,7 @@ are good to keep an eye on: - `search`: all search and query requests - `merging`: threadpool dedicated to managing Lucene merges -==== FS and Network sections +=== FS and Network sections Continuing down the Node Stats API, you'll see a bunch of statistics about your filesystem: free space, data directory paths, disk IO stats, etc. If you are @@ -508,7 +508,7 @@ keep-alive connections are important for performance, since building up and tear down sockets is expensive (and wastes file descriptors). Make sure your clients are configured appropriately. -==== Circuit Breaker +=== Circuit Breaker Finally, we come to the last section: stats about the field data circuit breaker (introduced in <>): diff --git a/500_Cluster_Admin/40_other_stats.asciidoc b/500_Cluster_Admin/40_other_stats.asciidoc index bc48ebe60..9938ec1c6 100644 --- a/500_Cluster_Admin/40_other_stats.asciidoc +++ b/500_Cluster_Admin/40_other_stats.asciidoc @@ -1,5 +1,5 @@ -=== Cluster Stats +== Cluster Stats The _Cluster Stats_ API provides very similar output to the Node Stats. There is one crucial difference: Node Stats shows you statistics per-node, while @@ -19,7 +19,7 @@ The API may be invoked with: GET _cluster/stats ---- -=== Index Stats +== Index Stats So far, we have been looking at _node-centric_ statistics. How much memory does this node have? How much CPU is being used? How many searches is this node @@ -60,7 +60,7 @@ operating in different environments. Index-centric stats are a useful tool to keep in your repertoire, but are not usually the first tool to reach for. -=== Pending Tasks +== Pending Tasks There are certain tasks that only the master can perform, such as creating a new index or moving shards around the cluster. Since a cluster can only have one @@ -154,7 +154,7 @@ cluster state size. - Spin up another cluster once a certain threshold has been crossed. **** -==== Cat API +=== Cat API If you work from the command line often, the _Cat_ APIs will be very helpful to you. Named after the linux `cat` command, these APIs are designed to be From 3d21c58e035c8a081902d6e963a085ef411da5c6 Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Wed, 27 Aug 2014 11:43:05 -0400 Subject: [PATCH 09/15] start deployment chapter --- 500_Cluster_Admin/30_node_stats.asciidoc | 1 + 510_Deployment.asciidoc | 43 +++++---- 510_Deployment/10_intro.asciidoc | 16 +++ 510_Deployment/20_hardware.asciidoc | 118 +++++++++++++++++++++++ 510_Deployment/30_other.asciidoc | 98 +++++++++++++++++++ 5 files changed, 258 insertions(+), 18 deletions(-) create mode 100644 510_Deployment/10_intro.asciidoc create mode 100644 510_Deployment/20_hardware.asciidoc create mode 100644 510_Deployment/30_other.asciidoc diff --git a/500_Cluster_Admin/30_node_stats.asciidoc b/500_Cluster_Admin/30_node_stats.asciidoc index 2bf9ddaad..df9c980d9 100644 --- a/500_Cluster_Admin/30_node_stats.asciidoc +++ b/500_Cluster_Admin/30_node_stats.asciidoc @@ -228,6 +228,7 @@ The JVM section contains some critical information about the JVM process which is running Elasticsearch. Most importantly, it contains garbage collection details, which have a large impact on the stability of your Elasticsearch cluster. +[[garbage_collector_primer]] .Garbage Collection Primer ********************************** Before we describe the stats, it is useful to give a crash course in garbage diff --git a/510_Deployment.asciidoc b/510_Deployment.asciidoc index 06f098578..c02a359ea 100644 --- a/510_Deployment.asciidoc +++ b/510_Deployment.asciidoc @@ -1,27 +1,34 @@ [[deploy]] -== Deploying Elasticsearch (TODO) +include::510_Deployment/10_intro.asciidoc[] -This chapter discusses the issues to be aware of when it comes time to deploy -Elasticsearch into production. +include::510_Deployment/20_hardware.asciidoc[] -=== Node communication -. +include::510_Deployment/30_other.asciidoc[] +-Prereqs -=== How many shards do I need? -. + - Hardware + -memory, cpu, etc + - disable swap on node and VM host + - ssd noop + - Talking to the cluster + - language clients + - TransportClient vs NodeClient + - Proxies, load balancers, etc + - JVM -=== Memory requirements -. - - -=== Reindexing data -. - - -=== Backing up your data -. - +- Configs to change before production + - elasticsearch.yml + - cluster settings api + - changing logging dynamically + - don't touch these: + - GC, threadpools +- index performance tips + - Mike's blog +- security + - none lololol +-snapshot/restore + - fs must be accessible from all nodes diff --git a/510_Deployment/10_intro.asciidoc b/510_Deployment/10_intro.asciidoc new file mode 100644 index 000000000..d642bbbca --- /dev/null +++ b/510_Deployment/10_intro.asciidoc @@ -0,0 +1,16 @@ +== Deploying Elasticsearch to Production + +If you have made it this far in the book, hopefully you've learned a thing or +two about Elasticsearch and are ready to deploy your cluster to production. +This chapter is not meant to be an exhaustive guide to running your cluster +in production, but it will cover the key things to consider before putting +your cluster live. + +There are three main areas that will be covered: + +- Logistical considerations, such as hardware recommendations and deployment +strategies +- Configuration changes that are more suited to a production environment +- Post-deployment considerations, such as security, maximizing indexing performance +and backups + diff --git a/510_Deployment/20_hardware.asciidoc b/510_Deployment/20_hardware.asciidoc new file mode 100644 index 000000000..86529d303 --- /dev/null +++ b/510_Deployment/20_hardware.asciidoc @@ -0,0 +1,118 @@ + +=== Hardware Considerations + +If you've been following the normal development path, you've probably been playing +with Elasticsearch on your laptop, or a small cluster of machines laying around. +But when it comes time to deploy Elasticsearch to production, there are a few +recommendations that you should consider. Nothing is a hard-and-fast rule; +Elasticsearch is used for a wide range of tasks and on bewildering array of +machines. But they provide good starting points based on our experience with +production clusters + +==== Memory + +If there is one resource that you will run out of first, it will likely be memory. +Sorting and aggregations can both be memory hungry, so enough heap space to +accommodate these are important. Even when the heap is comparatively small, +extra memory can be given to the OS file system cache. Because many data structures +used by Lucene are disk-based formats, Elasticsearch leverages the OS cache to +great effect. + +A machine with 64gb of RAM is the ideal sweet-spot, but 32gb and 16gb machines +are also very common. Less than 8gb tends to be counterproductive (you end up +needing many, many small machines) and greater than 64 has problems which we will +discuss in <> + +==== CPUs + +Most Elasticsearch deployments tend to be rather light on CPU requirements. As +such, the exact processor setup matters less than the other resources. You should +choose a modern processor with multiple cores. Common clusters utilize 2-8 +core machines. + +If you need to choose between faster CPUs or more cores...choose more cores. The +extra concurrency that multiple cores offers will far outweigh a slightly faster +clock-speed. + +==== Disks + +Disks are important for all clusters, and doubly so for indexing-heavy clusters +(such as those that ingest log data). Disks are the slowest subsystem in a server, +which means that write-heavy clusters can easily saturate their disks which in +turn becomes the bottleneck of the cluster. + +If you can afford SSDs, they are by far superior to any spinning media. SSD-backed +nodes see boosts in both query and indexing performance. If you can afford it, +SSDs are the way to go. + +.Check your IO Scheduler +**** +If you are using SSDs, make sure your OS I/O Scheduler is configured correctly. +When you write data to disk, the I/O Scheduler decides when that data is +_actually_ sent to the disk. The default under most *nix distributions is a +scheduler called `cfq` (Completely Fair Queuing). + +This scheduler allocates "time slices" to each process, and then optimizes the +delivery of these various queues to the disk. It is optimized for spinning media: +the nature of rotating platters means it is more efficient to write data to disk +based on physical layout. + +This is very inefficient for SSD, however, since there are no spinning platters +involved. Instead, `deadline` or `noop` should be used instead. The deadline +scheduler optimizes based on how long writes have been pending, while noop +is just a simple FIFO queue. + +This simple change can have dramatic impacts. We've seen a 500x improvement +to write throughput just by using the correct scheduler. +**** + +If you use spinning media, try to obtain the fastest disks possible (high +performance server disks 15k RPM drives). + +Using RAID 0 is an effective way to increase disk speed, for both spinning disks +and SSD. There is no need to use mirroring or parity variants of RAID, since +high-availability is built into Elasticsearch via replicas. + +Finally, avoid network-attached storages (NAS). People routinely claim their +NAS solution is faster and more reliable than local drives. Despite these claims, +we have never seen NAS live up to their hype. NAS are often slower, display +larger latencies with a wider deviation in average latency, and are a single +point of failure. + +==== Network + +A fast and reliable network is obviously important to performance in a distributed +system. Low latency helps assure that nodes can communicate easily, while +high bandwidth helps shard movement and recovery. Modern datacenter networking +(1gigE, 10gigE) is sufficient for the vast majority of clusters. + +Avoid clusters that span multiple data-centers, even if the data-centers are +colocated in close proximity. Definitely avoid clusters that span large geographic +distances. + +Elasticsearch clusters assume that all nodes are equal...not that half the nodes +are actually 150ms distant in another datacenter. Larger latencies tend to +exacerbate problems in distributed systems and make debugging and resolution +more difficult. + +Similar to the NAS argument, everyone claims their pipe between data-centers is +robust and low latency. This is true...until it isn't (a network failure will +happen eventually, you can count on it). From our experience, the hassle of +managing cross-datacenter clusters is simply not worth the cost. + +==== General Considerations + +It is possible nowadays to obtain truly enormous machines. Hundreds of gigabytes +of RAM with dozens of CPU cores. Conversely, it is also possible to spin up +thousands of small virtual machines in cloud platforms such as EC2. Which +approach is best? + +In general, it is better to prefer "medium" to "large" boxes. Avoid small machines +because you don't want to manage a cluster with a thousand nodes, and the overhead +of simply running Elasticsearch is more apparent on such small boxes. + +At the same time, avoid the truly enormous machines. They often lead to imbalanced +resource usage (e.g. all the memory is being used, but none of the CPU) and can +add logistical complexity if you have to run multiple nodes per machine. + + diff --git a/510_Deployment/30_other.asciidoc b/510_Deployment/30_other.asciidoc new file mode 100644 index 000000000..33ec45b98 --- /dev/null +++ b/510_Deployment/30_other.asciidoc @@ -0,0 +1,98 @@ + +=== Java Virtual Machine + +You should always run the most recent version of the Java Virtual Machine (JVM), +unless otherwise stated on the Elasticsearch website. Elasticsearch, and in +particular Lucene, is a very demanding piece of software. The unit and integration +tests from Lucene often expose bugs in the JVM itself. These bugs range from +mild annoyances to serious segfaults, so it is best to use the latest version +of the JVM where possible. + +Java 7 is strongly preferred over Java 6. Either Oracle or OpenJDK are acceptable +-- they are comparable in performance and stability. + +If your application is written in Java and you are using the TransportClient +or NodeClient, make sure the JVM running your application is identical to the +server JVM. There are a few locations in Elasticsearch where Java's native serialization +is used (IP addresses, exceptions, etc). Unfortunately, Oracle has been known +change the serialization format between minor releases, leading to strange errors. +This happens rarely, but it is best practice to keep the JVM versions identical +between client and server. + +.Please do not tweak JVM settings +**** +The JVM exposes dozens (hundreds even!) of settings, parameters and configurations. +They allow you to tweak and tune almost every aspect of the JVM. + +When a knob is encountered, it is human nature to want to turn it. We implore +you to squash this desire and _not_ use custom JVM settings. Elasticsearch is +a complex piece of software, and the current JVM settings have been tuned +over years of real-world usage. + +It is easy to start turning knobs, producing opaque effects that are hard to measure, +and eventually detune your cluster into a slow, unstable mess. When debugging +clusters, the first step is often to remove all custom configurations. About +half the time this alone restores stability and performance. +**** + +=== Garbage Collector + +As briefly introduces in <>, the JVM uses a garbage +collector to free unused memory. This tip is really an extension of the last tip, +but deserves it's own section for emphasis: + +Do not change the default garbage collector! + +The default GC for Elasticsearch is Concurrent-Mark and Sweep (CMS). This GC +runs concurrently with the execution of the application so that it can minimize +pauses. It does, however, have two stop-the-world phases. It also has trouble +collecting large heaps. + +Despite these downsides, it is currently the best GC for low-latency server software +like Elasticsearch. The official recommendation is to use CMS. + +There is a newer GC called the Garbage First GC (G1GC). This newer GC is designed +to minimize pausing even more than CMS, and operate on large heaps. It works +by dividing the heap into regions and predicting which regions contain the most +reclaimable space. By collecting those regions first ("garbage first"), it can +minimize pauses and operate on very large heaps. + +Sounds great! Unfortunately, G1GC is still new and fresh bugs are found routinely. +These bugs are usually of the segfault variety, and will cause hard crashes. +The Lucene test suite is brutal on GC algorithms, and it seems that G1GC hasn't +had the kinks worked out yet. + +We would like to recommend G1GC someday, but for now, it is simply not stable +enough to meet the demands of Elasticsearch and Lucene. + +=== TransportClient vs NodeClient + +If you are using Java, you may wonder when to use the TransportClient vs the +NodeClient. As discussed at the beginning of the book, the TransportClient +acts as a communication layer between the cluster and your application. It knows +the API and can automatically round-robin between nodes, sniff the cluster for you, +etc. But it "external" to the cluster, similar to the REST clients. + +The NodeClient, on the other hand, is actually a node within the cluster (but +does not hold data, and cannot become master). Because it is a node, it knows +the entire cluster state -- where all the nodes reside, which shards live in which +nodes, etc. This means it can execute APIs with one less network-hop. + +There are uses-cases for both clients: + +- TransportClient is ideal if you want to decouple your application from the +cluster. For example, if your application quickly creates and destroys +connections to the cluster, a TransportClient is much "lighter" than a NodeClient, +since it is not part of a cluster. ++ +Similarly, if you need to create thousands of connections, you don't want to +have thousands of NodeClients join the cluster. The TC will be a better choice + +- On the flipside, if you only need a few long-lived, persistent connection +objects to the cluster, a NodeClient can be a bit more efficient since it knows +the cluster layout. But it ties your application into the cluster, so it may +pose problems from a firewall perspective, etc. + + + + From 9493d5fb4fcf8eaa6860a99aff73f4d49c112fb7 Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Thu, 28 Aug 2014 15:50:11 -0400 Subject: [PATCH 10/15] more work on monitor and deploy --- 07_Admin.asciidoc | 8 + 500_Cluster_Admin.asciidoc | 2 + 500_Cluster_Admin/10_intro.asciidoc | 1 - 500_Cluster_Admin/15_marvel.asciidoc | 2 +- 500_Cluster_Admin/20_health.asciidoc | 6 +- 500_Cluster_Admin/30_node_stats.asciidoc | 14 +- 500_Cluster_Admin/40_other_stats.asciidoc | 6 +- 510_Deployment.asciidoc | 8 + 510_Deployment/10_intro.asciidoc | 2 - 510_Deployment/20_hardware.asciidoc | 8 +- 510_Deployment/30_other.asciidoc | 12 + 510_Deployment/40_config.asciidoc | 254 ++++++++++++++++++++++ 510_Deployment/50_heap.asciidoc | 155 +++++++++++++ book.asciidoc | 4 +- 14 files changed, 458 insertions(+), 24 deletions(-) create mode 100644 07_Admin.asciidoc create mode 100644 510_Deployment/40_config.asciidoc create mode 100644 510_Deployment/50_heap.asciidoc diff --git a/07_Admin.asciidoc b/07_Admin.asciidoc new file mode 100644 index 000000000..238a1ad98 --- /dev/null +++ b/07_Admin.asciidoc @@ -0,0 +1,8 @@ +[[administration]] += Administration, Monitoring and Deployment + +[partintro] +-- +Something something something +-- + diff --git a/500_Cluster_Admin.asciidoc b/500_Cluster_Admin.asciidoc index b872a5d92..997313149 100644 --- a/500_Cluster_Admin.asciidoc +++ b/500_Cluster_Admin.asciidoc @@ -1,4 +1,6 @@ [[cluster-admin]] +== Monitoring + include::500_Cluster_Admin/10_intro.asciidoc[] include::500_Cluster_Admin/15_marvel.asciidoc[] diff --git a/500_Cluster_Admin/10_intro.asciidoc b/500_Cluster_Admin/10_intro.asciidoc index 9e659a960..b1143976d 100644 --- a/500_Cluster_Admin/10_intro.asciidoc +++ b/500_Cluster_Admin/10_intro.asciidoc @@ -1,5 +1,4 @@ -== Cluster management and monitoring Elasticsearch is often deployed as a cluster of nodes. There are a variety of APIs that let you manage and monitor the cluster itself, rather than interact with the data stored within the cluster. diff --git a/500_Cluster_Admin/15_marvel.asciidoc b/500_Cluster_Admin/15_marvel.asciidoc index ea4e22eb8..b8123cdb9 100644 --- a/500_Cluster_Admin/15_marvel.asciidoc +++ b/500_Cluster_Admin/15_marvel.asciidoc @@ -1,5 +1,5 @@ -== Marvel for Monitoring +=== Marvel for Monitoring At the very beginning of the book (<>) we encouraged you to install Marvel, a management monitoring tool for Elasticsearch, because it would enable diff --git a/500_Cluster_Admin/20_health.asciidoc b/500_Cluster_Admin/20_health.asciidoc index 174a3ff86..129de27d6 100644 --- a/500_Cluster_Admin/20_health.asciidoc +++ b/500_Cluster_Admin/20_health.asciidoc @@ -1,5 +1,5 @@ -== Cluster Health +=== Cluster Health An Elasticsearch cluster may consist of a single node with a single index. Or it may have a hundred data nodes, three dedicated masters, a few dozen clients nodes @@ -73,7 +73,7 @@ replicas. For example, an index with 5 shards and 1 replica will have 5 unassig replicas in a single-node cluster. Unassigned shards will also be present if your cluster is red (since primaries are missing) -=== Drilling deeper: finding problematic indices +==== Drilling deeper: finding problematic indices Imagine something goes wrong one day, and you notice that your cluster health looks like this: @@ -185,7 +185,7 @@ but due to the verbosity can difficult to work with. Once you know the index that is having problems, other APIs that we discuss in this chapter will tend to be more helpful. -=== Blocking for status changes +==== Blocking for status changes The Cluster Health API has another neat trick which is very useful when building unit and integration tests, or automated scripts that work with Elasticsearch. diff --git a/500_Cluster_Admin/30_node_stats.asciidoc b/500_Cluster_Admin/30_node_stats.asciidoc index df9c980d9..ce1c642bf 100644 --- a/500_Cluster_Admin/30_node_stats.asciidoc +++ b/500_Cluster_Admin/30_node_stats.asciidoc @@ -1,5 +1,5 @@ -== Monitoring individual nodes +=== Monitoring individual nodes Cluster Health is at one end of the spectrum -- a very high-level overview of everything in your cluster. The _Node Stats_ API is at the other end. It provides @@ -43,7 +43,7 @@ host, etc). These values are useful for debugging discovery problems, where nodes won't join the cluster. Often you'll see that the port being used is wrong, or the node is binding to the wrong IP address/interface. -=== Indices section +==== Indices section The indices section lists aggregate statistics for all the indices that reside on this particular node. @@ -206,7 +206,7 @@ posting lists, dictionaries and bloom filters. A very large number of segments will increase the amount of overhead lost to these data structures, and the memory usage can be a handy metric to gauge that overhead. -=== OS and Process Sections +==== OS and Process Sections The OS and Process sections are fairly self-explanatory and won't be covered in great detail. They list basic resource statistics such as CPU and load. The @@ -222,7 +222,7 @@ monitoring stack. Some stats include: - Swap usage - Open file descriptors -=== JVM Section +==== JVM Section The JVM section contains some critical information about the JVM process which is running Elasticsearch. Most importantly, it contains garbage collection details, @@ -391,7 +391,7 @@ Our best advice is to collect collection counts and duration periodically (or us and keep an eye out for frequent GCs. You can also enable slow-GC logging, discussed in <> -=== Threadpool Section +==== Threadpool Section Elasticsearch maintains a number of threadpools internally. These threadpools cooperate to get work done, passing work between each other as necessary. In @@ -469,7 +469,7 @@ are good to keep an eye on: - `search`: all search and query requests - `merging`: threadpool dedicated to managing Lucene merges -=== FS and Network sections +==== FS and Network sections Continuing down the Node Stats API, you'll see a bunch of statistics about your filesystem: free space, data directory paths, disk IO stats, etc. If you are @@ -509,7 +509,7 @@ keep-alive connections are important for performance, since building up and tear down sockets is expensive (and wastes file descriptors). Make sure your clients are configured appropriately. -=== Circuit Breaker +==== Circuit Breaker Finally, we come to the last section: stats about the field data circuit breaker (introduced in <>): diff --git a/500_Cluster_Admin/40_other_stats.asciidoc b/500_Cluster_Admin/40_other_stats.asciidoc index 9938ec1c6..c1e19dc83 100644 --- a/500_Cluster_Admin/40_other_stats.asciidoc +++ b/500_Cluster_Admin/40_other_stats.asciidoc @@ -1,5 +1,5 @@ -== Cluster Stats +=== Cluster Stats The _Cluster Stats_ API provides very similar output to the Node Stats. There is one crucial difference: Node Stats shows you statistics per-node, while @@ -19,7 +19,7 @@ The API may be invoked with: GET _cluster/stats ---- -== Index Stats +=== Index Stats So far, we have been looking at _node-centric_ statistics. How much memory does this node have? How much CPU is being used? How many searches is this node @@ -60,7 +60,7 @@ operating in different environments. Index-centric stats are a useful tool to keep in your repertoire, but are not usually the first tool to reach for. -== Pending Tasks +=== Pending Tasks There are certain tasks that only the master can perform, such as creating a new index or moving shards around the cluster. Since a cluster can only have one diff --git a/510_Deployment.asciidoc b/510_Deployment.asciidoc index c02a359ea..eb76208a1 100644 --- a/510_Deployment.asciidoc +++ b/510_Deployment.asciidoc @@ -1,10 +1,18 @@ [[deploy]] +== Production Deployment + include::510_Deployment/10_intro.asciidoc[] include::510_Deployment/20_hardware.asciidoc[] include::510_Deployment/30_other.asciidoc[] +include::510_Deployment/40_config.asciidoc[] + +include::510_Deployment/50_heap.asciidoc[] + +=== Post-Deployment + -Prereqs - Hardware diff --git a/510_Deployment/10_intro.asciidoc b/510_Deployment/10_intro.asciidoc index d642bbbca..cf0f6cb95 100644 --- a/510_Deployment/10_intro.asciidoc +++ b/510_Deployment/10_intro.asciidoc @@ -1,5 +1,3 @@ -== Deploying Elasticsearch to Production - If you have made it this far in the book, hopefully you've learned a thing or two about Elasticsearch and are ready to deploy your cluster to production. This chapter is not meant to be an exhaustive guide to running your cluster diff --git a/510_Deployment/20_hardware.asciidoc b/510_Deployment/20_hardware.asciidoc index 86529d303..d94468500 100644 --- a/510_Deployment/20_hardware.asciidoc +++ b/510_Deployment/20_hardware.asciidoc @@ -1,5 +1,5 @@ - -=== Hardware Considerations +[[hardware]] +=== Hardware If you've been following the normal development path, you've probably been playing with Elasticsearch on your laptop, or a small cluster of machines laying around. @@ -20,8 +20,8 @@ great effect. A machine with 64gb of RAM is the ideal sweet-spot, but 32gb and 16gb machines are also very common. Less than 8gb tends to be counterproductive (you end up -needing many, many small machines) and greater than 64 has problems which we will -discuss in <> +needing many, many small machines) and greater than 64gb has problems which we will +discuss in <> ==== CPUs diff --git a/510_Deployment/30_other.asciidoc b/510_Deployment/30_other.asciidoc index 33ec45b98..bc713b94c 100644 --- a/510_Deployment/30_other.asciidoc +++ b/510_Deployment/30_other.asciidoc @@ -93,6 +93,18 @@ objects to the cluster, a NodeClient can be a bit more efficient since it knows the cluster layout. But it ties your application into the cluster, so it may pose problems from a firewall perspective, etc. +=== Configuration Management +If you use configuration management already (puppet, chef, ansible, etc) you can +just skip this tip. + +If you don't use configuration management tools yet...you should! Managing +a handful of servers by parallel-ssh may work now, but it will become a nightmare +as you grow your cluster. It is almost impossible to edit 30 configuration files +by hand without making a mistake. + +Configuration management tools help make your cluster consistent by automating +the process of config changes. It may take a little time to setup and learn, +but it will pay itself off handsomely over time. diff --git a/510_Deployment/40_config.asciidoc b/510_Deployment/40_config.asciidoc new file mode 100644 index 000000000..6bd240dd5 --- /dev/null +++ b/510_Deployment/40_config.asciidoc @@ -0,0 +1,254 @@ +=== Important Configuration Changes +Elasticsearch ships with _very good_ defaults, especially when it comes to performance- +related settings and options. When in doubt, just leave +the settings alone. We have witnessed countless dozens of clusters ruined +by errant settings because the administrator thought they could turn a knob +and gain 100x improvement. + +[IMPORTANT] +==== +Please read this entire section! All configurations presented are equally +important, and are not listed in any particular "importance" order. Please read +through all configuration options and apply them to your cluster. +==== + +Other databases may require tuning, but by-and-far, Elasticsearch does not. +If you are hitting performance problems, the solution is usually better data +layout or more nodes. There are very few "magic knobs" in Elasticsearch. +If there was...we'd have turned it already! + +With that said, there are some _logistical_ configurations that should be changed +for production. These changes are either to make your life easier, or because +there is no way to set a good default (e.g. it depends on your cluster layout). + + +==== Assign names + +Elasticseach by default starts a cluster named `elasticsearch`. It is wise +to rename your production cluster to something else, simply to prevent accidents +where someone's laptop joins the cluster. A simple change to `elasticsearch_production` +can save a lot of heartache. + +This can be changed in your `elasticsearch.yml` file: + +[source,yaml] +---- +cluster.name: elasticsearch_production +---- + +Similarly, it is wise to change the names of your nodes. You've probably +noticed by now, but Elasticsearch will assign a random Marvel Superhero name +to your nodes at startup. This is cute in development...less cute when it is +3am and you are trying to remember which physical machine was "Tagak the Leopard Lord". + +More importantly, since these names are generated on startup, each time you +restart your node it will get a new name. This can make logs very confusing, +since the names of all the nodes are constantly changing. + +Boring as it might be, we recommend you give each node a name that makes sense +to you - a plain, descriptive name. This is also configured in your `elasticsearch.yml`: + +[source,yaml] +---- +node.name: elasticsearch_005_data +---- + + +==== Paths + +By default, Elasticsearch will place the plugins, logs and -- +most importantly -- your data in the installation directory. This can lead to +unfortunate accidents, where the installation directory is accidentally overwritten +by a new installation of ES. If you aren't careful, you can erase all of your data. + +Don't laugh...we've seen it happen more than a few times. + +The best thing to do is relocate your data directory outside the installation +location. You can optionally move your plugin and log directories as well. + +This can be changed via: + +[source,yaml] +---- +path.data: /path/to/data1,/path/to/data2 <1> + +# Path to log files: +path.logs: /path/to/logs + +# Path to where plugins are installed: +path.plugins: /path/to/plugins +---- +<1> Notice that you can specify more than one directory for data using comma +separated lists. + +Data can be saved to multiple directories, and if each of these directories +are mounted on a different hard drive, this is a simple and effective way to +setup a "software RAID 0". Elasticsearch will automatically stripe +data between the different directories, boosting performance + +==== Minimum Master Nodes + +This setting, called `minimum_master_nodes` is _extremely_ important to the +stability of your cluster. This setting helps prevent "split brains", a situation +where two masters exist in a single cluster. + +When you have a split-brain, your cluster is at danger of losing data. Because +the master is considered the "supreme ruler" of the cluster, it decides +when new indices can be created, how shards are moved, etc. If you have _two_ +masters, data integrity becomes perilous, since you have two different nodes +that think they are in charge. + +This setting tells Elasticsearch to not elect a master unless there are enough +master-eligible nodes available. Only then will an election take place. + +This setting should always be configured to a quorum (majority) of your master- +eligible nodes. A quorum is `(number of master-eligible nodes / 2) + 1`. +Some examples: + +- If you have ten regular nodes (can hold data, can become master), a quorum is +`6` +- If you have three dedicated master nodes and 100 data nodes, the quorum is `2`, +since you only need to count nodes that are master-eligible +- If you have two regular nodes...you are in a conundrum. A quorum would be +`2`, but this means a loss of one node will make your cluster inoperable. A +setting of `1` will allow your cluster to function, but doesn't protect against +split brain. It is best to have a minimum of 3 nodes in situations like this. + +This setting can be configured in your `elasticsearch.yml` file: + +[source,yaml] +---- +discovery.zen.minimum_master_nodes: 2 +---- + +But because Elasticsearch clusters are dynamic, you could easily add or remove +nodes which will change the quorum. It would be extremely irritating if you had +to push new configurations to each node and restart your whole cluster just to +change the setting. + +For this reason, `minimum_master_nodes` (and other settings) can be configured +via a dynamic API call. You can change the setting while your cluster is online +using: + +[source,js] +---- +PUT /_cluster/settings +{ + "persistent" : { + "discovery.zen.minimum_master_nodes" : 2 + } +} +---- + +This will become a persistent setting that takes precedence over whatever is +in the static configuration. You should modify this setting whenever you add or +remove master-eligible nodes. + +==== Recovery settings + +There are several settings which affect the behavior of shard recovery when +your cluster restarts. First, we need to understand what happens if nothing is +configured. + +Imagine you have 10 nodes, and each node holds a single shard -- either a primary +or a replica -- in a 5 primary / 1 replica index. You take your +entire cluster offline for maintenance (installing new drives, etc). When you +restart your cluster, it just so happens that five nodes come online before +the other five. + +Maybe the switch to the other five is being flaky and they didn't +receive the restart command right away. Whatever the reason, you have five nodes +online. These five nodes will gossip with eachother, elect a master and form a +cluster. They notice that data is no longer evenly distributed since five +nodes are missing from the cluster, and immediately start replicating new +shards between each other. + +Finally, your other five nodes turn on and join the cluster. These nodes see +that _their_ data is being replicated to other nodes, so they delete their local +data (since it is now redundant, and may be out-dated). Then the cluster starts +to rebalance even more, since the cluster size just went from five to 10. + +During this whole process, your nodes are thrashing the disk and network moving +data around...for no good reason. For large clusters with terrabytes of data, +this useless shuffling of data can take a _really long time_. If all the nodes +had simply waited for the cluster to come online, all the data would have been +local and nothing would need to move. + +Now that we know the problem, we can configure a few settings to alleviate it. +First, we need give Elasticsearch a hard limit: + +[source,yaml] +---- +gateway.recover_after_nodes: 8 +---- + +This will prevent Elasticsearch from starting a recovery until at least 8 nodes +are present. The value for this setting is up to personal preference: how +many nodes do you want present before you consider your cluster functional? +In this case we are setting it to `8`, which means the cluster is inoperable +unless there are 8 nodes. + +Then we tell Elasticsearch how many nodes _should_ be in the cluster, and how +long we want to wait for all those nodes: + +[source,yaml] +---- +gateway.expected_nodes: 10 +gateway.recover_after_time: 5m +---- + +What this means is that Elasticsearch will: + +- Wait for 8 nodes to be present +- Begin recovering after five minutes, OR after 10 nodes have joined the cluster, +whichever comes first. + +These three settings allow you to avoid the excessive shard swapping that can +occur on cluster restarts. It can literally make recover take seconds instead +of hours. + + +==== Prefer Unicast over Multicast + +Elasticsearch is configured to use multicast discovery out of the box. Multicast +works by sending UDP pings across your local network to discover nodes. Other +Elasticsearch nodes will receive these pings and respond. A cluster is formed +shortly after. + +Multicast is excellent for development, since you don't need to do anything. Turn +a few nodes on and they automatically find each other and form a cluster. + +This ease of use is the exact reason you should disable it in production. The +last thing you want is for nodes to accidentally join your production network, simply +because they received an errant multicast ping. There is nothing wrong with +multicast _per-se_. Multicast simply leads to silly problems, and can be a bit +more fragile (e.g. a network engineer fiddles with the network without telling +you...and all of a sudden nodes can't find each other anymore). + +In production, it is recommended to use Unicast instead of Multicast. This works +by providing Elasticsearch a list of nodes that it should try to contact. Once +the node contacts a member of the unicast list, it will receive a full cluster +state which lists all nodes in the cluster. It will then proceed to contact +the master and join. + +This means your unicast list does not need to hold all the nodes in your cluster. +It just needs enough nodes that a new node can find someone to talk to. If you +use dedicated masters, just list your three dedicated masters and call it a day. +This setting is configured in your `elasticsearch.yml`: + +[source,yaml] +---- +discovery.zen.ping.multicast.enabled: false <1> +discovery.zen.ping.unicast.hosts: ["host1", "host2:port"] +---- +<1> Make sure you disable multicast, since it can operate in parallel with unicast + + + + + + + + + + diff --git a/510_Deployment/50_heap.asciidoc b/510_Deployment/50_heap.asciidoc new file mode 100644 index 000000000..e411b5354 --- /dev/null +++ b/510_Deployment/50_heap.asciidoc @@ -0,0 +1,155 @@ +[[heap_sizing]] +=== Heap: Sizing and Swapping + +The default installation of Elasticsearch is configured with a 1gb heap. For +just about every deployment, this number is far too small. If you are using the +default heap values, your cluster is probably configured incorrectly. + +There are two ways to change the heap size in Elasticsearch. The easiest is to +set an environment variable called `ES_HEAP_SIZE`. When the server process +starts, it will read this environment variable and set the heap accordingly. +As an example, you can set it via the command line with: + +[source,bash] +---- +export ES_HEAP_SIZE=10g +---- + +Alternatively, you can pass in the heap size via a command-line argument when starting +the process, if that is easier for your setup: + +[source,bash] +---- +./bin/elasticsearch -Xmx=10g -Xms=10g <1> +---- +<1> Ensure that the min (`Xms`) and max (`Xmx`) sizes are the same to prevent +the heap from resizing at runtime, a very costly process + +Generally, setting the `ES_HEAP_SIZE` environment variable is preferred over setting +explicit `-Xmx` and `-Xms` values. + +==== Give half your memory to Lucene + +A common problem is configuring a heap that is _too_ large. You have a 64gb +machine...and by golly, you want to give Elasticsearch all 64gb of memory. More +is better! + +Heap is definitely important to Elasticsearch. It is used by many in-memory data +structures to provide fast operation. But with that said, there is another major +user of memory that is _off heap_: Lucene. + +Lucene is designed to leverage the underlying OS for caching in-memory data structures. +Lucene segments are stored in individual files. Because segments are immutable, +these files never change. This makes them very cache friendly, and the underlying +OS will happily keep "hot" segments resident in memory for faster access. + +Lucene's performance relies on this interaction with the OS. But if you give all +available memory to Elasticsearch's heap, there won't be any leftover for Lucene. +This can seriously impact the performance of full-text search. + +The standard recommendation is to give 50% of the available memory to Elasticsearch +heap, while leaving the other 50% free. It won't go unused...Lucene will happily +gobble up whatever is leftover. + +[[compressed_oops]] +==== Don't cross 32gb! +There is another reason to not allocate enormous heaps to Elasticsearch. As it turns +out, the JVM uses a trick to compress object pointers when heaps are less than +~32gb. + +In Java, all objects are allocated on the heap and referenced by a pointer. +Ordinary Object Pointers (oops) point at these objects, and are traditionally +the size of the CPU's native _word_: either 32 bits or 64 bits depending on the +processor. The pointer references the exact byte location of the value. + +For 32bit systems, this means the maximum heap size is 4gb. For 64bit systems, +the heap size can get much larger, but the overhead of 64bit pointers means there +is more "wasted" space simply because the pointer is larger. And worse than wasted +space, the larger pointers eat up more bandwidth when moving values between +main memory and various caches (LLC, L1, etc). + +Java uses a trick called "https://wikis.oracle.com/display/HotSpotInternals/CompressedOops[compressed oops]" +to get around this problem. Instead of pointing at exact byte locations in +memory, the pointers reference _object offsets_. This means a 32bit pointer can +reference 4 billion _objects_, rather than 4 billion bytes. Ultimately, this +means the heap can grow to around 32gb of physical size while still using a 32bit +pointer. + +Once you cross that magical ~30-32gb boundary, the pointers switch back to +ordinary object pointers. The size of each pointer grows, more CPU-memory +bandwidth is used and you effectively "lose" memory. Infact, it takes until around +40-50gb of allocated heap before you have the same "effective" memory of a 32gb +heap using compressed oops. + +The moral of the story is this: even when you have memory to spare, try to avoid +crossing the 32gb Heap boundary. It wastes memory, reduces CPU performance and +makes the GC struggle with large heaps. + +.I have a machine with 1TB RAM! +**** +The 32gb line is fairly important. So what do you do when your machine has a lot +of memory? It is becoming increasingly common to see super-servers with 300-500mb +of RAM. + +First, we would recommend to avoid such large machines (see <>). + +But if you already have the machines, you have to practical options: + +1. Are you doing most full-text search? Consider giving 32gb to Elasticsearch +and just let Lucene use the rest of memory via the OS file system cache. All that +memory will cache segments and lead to blisteringly fast full-text search + +2. Are you doing a lot of sorting/aggregations? You'll likely want that memory +in the heap then. Instead of one node with 32gb+ of RAM, consider running two or +more nodes on a single machine. Still adhere to the 50% rule though. So if your +machine has 124mb of RAM, run two nodes each with 32gb. This means 64gb will be +used for heaps, and 64 will be leftover for Lucene. ++ +If you choose this option, set `cluster.routing.allocation.same_shard.host: true` +in your config. This will prevent a primary and a replica shard from co-locating +to the same physical machine (since this would remove the benefits of replica HA) +**** + +==== Swapping is the death of performance + +It should be obvious, but it bears spelling out clearly: swapping main memory +to disk will _crush_ server performance. Think about it...an in-memory operation +is one that needs to execute quickly. + +If memory swaps to disk, a 100 microsecond operation becomes one that take 10 +milliseconds. Now repeat that increase in latency for all other 10us operations. +It isn't difficult to see why swapping is terrible for performance. + +The best thing to do is disable swap completely on your system. This can be done +temporarily by: + +[source,bash] +---- +sudo swapoff -a +---- + +To disable it permanently, you'll likely need to edit your `/etc/fstab`. Consult +the documentation for your OS. + +If disabling swap completely is not an option, you can try to lower swappiness. +This is a value that controls how aggressively the OS tries to swap memory. +This prevents swapping under normal circumstances, but still allows the OS to swap +under emergency memory situations. + +For most linux systems, this is configured using the sysctl value: + +[source,bash] +---- +vm.swappiness = 1 <1> +---- +<1> A swappiness of `1` is better than `0`, since on some kernel versions a swappiness +of `0` can invoke the OOM-killer. + +Finally, if neither approach is possible, you should enable `mlockall`. + file. This allows the JVM to lock it's memory and prevent +it from being swapped by the OS. In your `elasticsearch.yml`, set this: + +[source,yaml] +---- +bootstrap.mlockall: true +---- \ No newline at end of file diff --git a/book.asciidoc b/book.asciidoc index 30194b440..40ff41c6c 100644 --- a/book.asciidoc +++ b/book.asciidoc @@ -101,9 +101,7 @@ include::410_Scaling.asciidoc[] // Part 7 -[[administration]] - -= Administration and internals (TODO) +include::07_Admin.asciidoc[] include::500_Cluster_Admin.asciidoc[] From 763b31f4628014c07612f324c0b99e31866ac20b Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Thu, 28 Aug 2014 22:02:15 -0400 Subject: [PATCH 11/15] fd, dont touch section --- 510_Deployment.asciidoc | 2 + 510_Deployment/30_other.asciidoc | 30 ------- 510_Deployment/45_dont_touch.asciidoc | 87 +++++++++++++++++++++ 510_Deployment/60_file_descriptors.asciidoc | 61 +++++++++++++++ 4 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 510_Deployment/45_dont_touch.asciidoc create mode 100644 510_Deployment/60_file_descriptors.asciidoc diff --git a/510_Deployment.asciidoc b/510_Deployment.asciidoc index eb76208a1..b46a041ee 100644 --- a/510_Deployment.asciidoc +++ b/510_Deployment.asciidoc @@ -11,6 +11,8 @@ include::510_Deployment/40_config.asciidoc[] include::510_Deployment/50_heap.asciidoc[] +include::510_Deployment/60_file_descriptors.asciidoc[] + === Post-Deployment -Prereqs diff --git a/510_Deployment/30_other.asciidoc b/510_Deployment/30_other.asciidoc index bc713b94c..1452c09bc 100644 --- a/510_Deployment/30_other.asciidoc +++ b/510_Deployment/30_other.asciidoc @@ -35,36 +35,6 @@ clusters, the first step is often to remove all custom configurations. About half the time this alone restores stability and performance. **** -=== Garbage Collector - -As briefly introduces in <>, the JVM uses a garbage -collector to free unused memory. This tip is really an extension of the last tip, -but deserves it's own section for emphasis: - -Do not change the default garbage collector! - -The default GC for Elasticsearch is Concurrent-Mark and Sweep (CMS). This GC -runs concurrently with the execution of the application so that it can minimize -pauses. It does, however, have two stop-the-world phases. It also has trouble -collecting large heaps. - -Despite these downsides, it is currently the best GC for low-latency server software -like Elasticsearch. The official recommendation is to use CMS. - -There is a newer GC called the Garbage First GC (G1GC). This newer GC is designed -to minimize pausing even more than CMS, and operate on large heaps. It works -by dividing the heap into regions and predicting which regions contain the most -reclaimable space. By collecting those regions first ("garbage first"), it can -minimize pauses and operate on very large heaps. - -Sounds great! Unfortunately, G1GC is still new and fresh bugs are found routinely. -These bugs are usually of the segfault variety, and will cause hard crashes. -The Lucene test suite is brutal on GC algorithms, and it seems that G1GC hasn't -had the kinks worked out yet. - -We would like to recommend G1GC someday, but for now, it is simply not stable -enough to meet the demands of Elasticsearch and Lucene. - === TransportClient vs NodeClient If you are using Java, you may wonder when to use the TransportClient vs the diff --git a/510_Deployment/45_dont_touch.asciidoc b/510_Deployment/45_dont_touch.asciidoc new file mode 100644 index 000000000..0f5a8af4e --- /dev/null +++ b/510_Deployment/45_dont_touch.asciidoc @@ -0,0 +1,87 @@ + +=== Don't touch these settings! + +There are a few hotspots in Elasticsearch that people just can't seem to avoid +tweaking. We understand: knobs just beg to be turned. + +But of all the knobs to turn, these you should _really_ leave alone. They are +often abused and will contribute to terrible stability or terrible performance. +Or both. + +==== Garbage Collector + +As briefly introduces in <>, the JVM uses a garbage +collector to free unused memory. This tip is really an extension of the last tip, +but deserves it's own section for emphasis: + +Do not change the default garbage collector! + +The default GC for Elasticsearch is Concurrent-Mark and Sweep (CMS). This GC +runs concurrently with the execution of the application so that it can minimize +pauses. It does, however, have two stop-the-world phases. It also has trouble +collecting large heaps. + +Despite these downsides, it is currently the best GC for low-latency server software +like Elasticsearch. The official recommendation is to use CMS. + +There is a newer GC called the Garbage First GC (G1GC). This newer GC is designed +to minimize pausing even more than CMS, and operate on large heaps. It works +by dividing the heap into regions and predicting which regions contain the most +reclaimable space. By collecting those regions first ("garbage first"), it can +minimize pauses and operate on very large heaps. + +Sounds great! Unfortunately, G1GC is still new and fresh bugs are found routinely. +These bugs are usually of the segfault variety, and will cause hard crashes. +The Lucene test suite is brutal on GC algorithms, and it seems that G1GC hasn't +had the kinks worked out yet. + +We would like to recommend G1GC someday, but for now, it is simply not stable +enough to meet the demands of Elasticsearch and Lucene. + +==== Threadpools + +Everyone _loves_ to tweak threadpools. For whatever reason, it seems people +cannot resist increasing thread counts. Indexing a lot? More threads! Searching +a lot? More threads! Node idling 95% of the time? More threads! + +The default threadpool settings in Elasticsearch are very sensible. For all +threadpools (except `search`) the threadcount is set to the number of CPU cores. +If you have 8 cores, you can only be running 8 threads simultaneously. It makes +sense to only assign 8 threads to any particular threadpool. + +Search gets a larger threadpool, and is configured to `# cores * 3`. + +You might argue that some threads can block (such as on a disk I/O operation), +which is why you need more threads. This is not actually not a problem in Elasticsearch: +much of the disk IO is handled by threads managed by Lucene, not Elasticsearch. + +Furthermore, threadpools cooperate by passing work between each other. You don't +need to worry about a networking thread blocking because it is waiting on a disk +write. The networking thread will have long since handed off that work unit to +another threadpool and gotten back to networking. + +Finally, the compute capacity of your process is finite. More threads just forces +the processor to switch thread contexts. A processor can only run one thread +at a time, so when it needs to switch to a different thread, it stores the current +state (registers, etc) and loads another thread. If you are lucky, the switch +will happen on the same core. If you are unlucky, the switch may migrate to a +different core and require transport on inter-core communication bus. + +This context switching eats up cycles simply doing administrative housekeeping + -- estimates can peg it as high as 30us on modern CPUs. So unless the thread + will be blocked for longer than 30us, it is highly likely that that time would + have been better spent just processing and finishing early. + + People routinely set threadpools to silly values. On 8 core machines, we have + run across configs with 60, 100 or even 1000 threads. These settings will simply + thrash the CPU more than getting real work done. + + So. Next time you want to tweak a threadpool...please don't. And if you + _absolutely cannot resist_, please keep your core count in mind and perhaps set + the count to double. More than that is just a waste. + + + + + + diff --git a/510_Deployment/60_file_descriptors.asciidoc b/510_Deployment/60_file_descriptors.asciidoc new file mode 100644 index 000000000..f14a12829 --- /dev/null +++ b/510_Deployment/60_file_descriptors.asciidoc @@ -0,0 +1,61 @@ + +=== File Descriptors and MMap + +Lucene uses are _very_ large number of files. At the same time, Elasticsearch +uses a large number of sockets to communicate between nodes and HTTP clients. +All of this requires available file descriptors. + +Sadly, many modern linux distributions ship with a paltry 1024 file descriptors +allowed per process. This is _far_ too low for even a small Elasticsearch +node, let alone one that is handling hundreds of indices. + +You should increase your file descriptor count to something very large, such as +64,000. This process is irritatingly difficult and highly dependent on your +particular OS and distribution. Consult the documentation for your OS to determine +how best to change the allowed file descriptor count. + +Once you think you've changed it, check Elasticsearch to make sure it really does +have enough file descriptors. You can check with: + +[source,js] +---- +GET /_nodes/process + +{ + "cluster_name": "elasticsearch__zach", + "nodes": { + "TGn9iO2_QQKb0kavcLbnDw": { + "name": "Zach", + "transport_address": "inet[/192.168.1.131:9300]", + "host": "zacharys-air", + "ip": "192.168.1.131", + "version": "2.0.0-SNAPSHOT", + "build": "612f461", + "http_address": "inet[/192.168.1.131:9200]", + "process": { + "refresh_interval_in_millis": 1000, + "id": 19808, + "max_file_descriptors": 64000, <1> + "mlockall": true + } + } + } +} +---- +<1> The `max_file_descriptors` field will inform you how many available descriptors +the Elasticsearch process can access + +Elasticsearch also uses a mix of NioFS and MMapFS for the various files. Ensure +that the maximum map count so that there is ample virtual memory available for +mmapped files. This can be set temporarily with: + +[source,js] +---- +sysctl -w vm.max_map_count=262144 +---- + +Or permanently by modifying `vm.max_map_count` setting in your `/etc/sysctl.conf` + + + + From e3e67e3dcaf2ad242aafd19cbc668a1aa6d0e1b8 Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Thu, 28 Aug 2014 23:27:45 -0400 Subject: [PATCH 12/15] start post-deployment --- 510_Deployment.asciidoc | 31 +------ 510_Deployment/45_dont_touch.asciidoc | 18 ++--- 510_Deployment/80_cluster_settings.asciidoc | 2 + 520_Post_Deployment.asciidoc | 23 ++++++ .../10_dynamic_settings.asciidoc | 37 +++++++++ 520_Post_Deployment/20_logging.asciidoc | 80 +++++++++++++++++++ book.asciidoc | 2 + 7 files changed, 155 insertions(+), 38 deletions(-) create mode 100644 510_Deployment/80_cluster_settings.asciidoc create mode 100644 520_Post_Deployment.asciidoc create mode 100644 520_Post_Deployment/10_dynamic_settings.asciidoc create mode 100644 520_Post_Deployment/20_logging.asciidoc diff --git a/510_Deployment.asciidoc b/510_Deployment.asciidoc index b46a041ee..3cecc0808 100644 --- a/510_Deployment.asciidoc +++ b/510_Deployment.asciidoc @@ -9,36 +9,9 @@ include::510_Deployment/30_other.asciidoc[] include::510_Deployment/40_config.asciidoc[] +include::510_Deployment/45_dont_touch.asciidoc[] + include::510_Deployment/50_heap.asciidoc[] include::510_Deployment/60_file_descriptors.asciidoc[] -=== Post-Deployment - --Prereqs - - - Hardware - -memory, cpu, etc - - disable swap on node and VM host - - ssd noop - - - Talking to the cluster - - language clients - - TransportClient vs NodeClient - - Proxies, load balancers, etc - - JVM - -- Configs to change before production - - elasticsearch.yml - - cluster settings api - - changing logging dynamically - - don't touch these: - - GC, threadpools - -- index performance tips - - Mike's blog -- security - - none lololol - --snapshot/restore - - fs must be accessible from all nodes diff --git a/510_Deployment/45_dont_touch.asciidoc b/510_Deployment/45_dont_touch.asciidoc index 0f5a8af4e..50639a896 100644 --- a/510_Deployment/45_dont_touch.asciidoc +++ b/510_Deployment/45_dont_touch.asciidoc @@ -68,17 +68,17 @@ will happen on the same core. If you are unlucky, the switch may migrate to a different core and require transport on inter-core communication bus. This context switching eats up cycles simply doing administrative housekeeping - -- estimates can peg it as high as 30us on modern CPUs. So unless the thread - will be blocked for longer than 30us, it is highly likely that that time would - have been better spent just processing and finishing early. +-- estimates can peg it as high as 30μs on modern CPUs. So unless the thread +will be blocked for longer than 30μs, it is highly likely that that time would +have been better spent just processing and finishing early. - People routinely set threadpools to silly values. On 8 core machines, we have - run across configs with 60, 100 or even 1000 threads. These settings will simply - thrash the CPU more than getting real work done. +People routinely set threadpools to silly values. On 8 core machines, we have +run across configs with 60, 100 or even 1000 threads. These settings will simply +thrash the CPU more than getting real work done. - So. Next time you want to tweak a threadpool...please don't. And if you - _absolutely cannot resist_, please keep your core count in mind and perhaps set - the count to double. More than that is just a waste. +So. Next time you want to tweak a threadpool...please don't. And if you +_absolutely cannot resist_, please keep your core count in mind and perhaps set +the count to double. More than that is just a waste. diff --git a/510_Deployment/80_cluster_settings.asciidoc b/510_Deployment/80_cluster_settings.asciidoc new file mode 100644 index 000000000..72fcb2b64 --- /dev/null +++ b/510_Deployment/80_cluster_settings.asciidoc @@ -0,0 +1,2 @@ + +=== \ No newline at end of file diff --git a/520_Post_Deployment.asciidoc b/520_Post_Deployment.asciidoc new file mode 100644 index 000000000..8d76aee3f --- /dev/null +++ b/520_Post_Deployment.asciidoc @@ -0,0 +1,23 @@ +[[post_deploy]] +== Post-Deployment + +Once you have deployed your cluster in production, there are some tools and +best practices to keep your cluster running in top shape. In this short +section, we'll talk about configuring settings dynamically, how to tweak +logging levels, indexing performance tips and how to backup your cluster. + +include::520_Post_Deployment/10_dynamic_settings.asciidoc[] + +include::520_Post_Deployment/20_logging.asciidoc[] + + + +- index performance tips + - Mike's blog +- security + - none lololol + +-snapshot/restore + - fs must be accessible from all nodes + +rolling restarts \ No newline at end of file diff --git a/520_Post_Deployment/10_dynamic_settings.asciidoc b/520_Post_Deployment/10_dynamic_settings.asciidoc new file mode 100644 index 000000000..74d48e87c --- /dev/null +++ b/520_Post_Deployment/10_dynamic_settings.asciidoc @@ -0,0 +1,37 @@ + +=== Changing settings dynamically + +Many settings in Elasticsearch are dynamic, and modifiable through the API. +Configuration changes that force a node (or cluster) restart are strenuously avoided. +And while it's possible to make the changes through the static configs, we +recommend that you use the API instead. + +The _Cluster Update_ API operates in two modes: + +- Transient: these changes are in effect until the cluster restarts. Once +a full cluster restart takes place, these settings are erased + +- Persistent: these changes are permanently in place unless explicitly changed. +They will survive full cluster restarts and override the static configuration files. + +Transient vs Persistent settings are supplied in the JSON body: + +[source,js] +---- +PUT /_cluster/settings +{ + "persistent" : { + "discovery.zen.minimum_master_nodes" : 2 <1> + }, + "transient" : { + "indices.store.throttle.max_bytes_per_sec" : "50mb" <2> + } +} +---- +<1> This persistent setting will survive full cluster restarts +<2> While this transient setting will be removed after the first full cluster +restart + +A complete list of settings that are dynamically updateable can be found in the +http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/cluster-update-settings.html[online reference docs]. + diff --git a/520_Post_Deployment/20_logging.asciidoc b/520_Post_Deployment/20_logging.asciidoc new file mode 100644 index 000000000..ba836e8a0 --- /dev/null +++ b/520_Post_Deployment/20_logging.asciidoc @@ -0,0 +1,80 @@ + +=== Logging + +Elasticsearch emits a number of logs, which by are placed in `ES_HOME/logs`. +The default logging level is INFO. It provides a moderate amount of information, +but is designed to be rather light so that your logs are not enormous. + +When debugging problems, particularly problems with node discovery (since this +often depends on finicky network configurations), it can be helpful to bump +up the logging level to DEBUG. + +You _could_ modify the `logging.yml` file and restart your nodes...but that is +both tedious and leads to unnecessary downtime. Instead, you can update logging +levels through the Cluster Settings API that we just learned about. + +To do so, take the logger you are interested in and prepend `logger.` to it. +Let's turn up the discovery logging: + +[source,js] +---- +PUT /_cluster/settings +{ + "transient" : { + "logger.discovery" : "DEBUG" + } +} +---- + +While this setting is in effect, Elasticsearch will begin to emit DEBUG-level +logs for the `discovery` module. + +INFORMATION: Avoid TRACE, it is extremely verbose, to the point where the logs +are no longer useful. + +==== Slowlog + +There is another log called the _Slowlog_. The purpose of this log is to catch +queries and indexing requests that take over a certain threshold of time. +It is useful for hunting down user-generated queries that are particularly slow. + +By default, the slowlog is not enabled. It can be enabled by defining the action +(query, fetch or index), the level that you want the event logged at (WARN, DEBUG, +etc) and a time threshold. + +This is an index-level setting, which means it is applied to individual indices: + +[source,js] +---- +PUT /my_index/_settings +{ + "index.search.slowlog.threshold.query.warn" : "10s", <1> + "index.search.slowlog.threshold.fetch.debug": 500ms", <2> + "index.indexing.slowlog.threshold.index.info": 5s" <3> +} +---- +<1> Emit a WARN log when queries are slower than 10s +<2> Emit a DEBUG log when fetches are slower than 500ms +<3> Emit an INFO log when indexing takes longer than 5s + +You can also define these thresholds in your `elasticsearch.yml` file. Indices +that do not have a threshold set will inherit whatever is configured in the +static config. + +Once the thresholds are set, you can toggle the logging level like any other +logger: + +[source,js] +---- +PUT /_cluster/settings +{ + "transient" : { + "logger.index.search.slowlog" : "DEBUG", <1> + "logger.index.indexing.slowlog" : WARN <2> + } +} +---- +<1> Set the search slowlog to DEBUG level +<2> Set the indexing slowlog to WARN level + + diff --git a/book.asciidoc b/book.asciidoc index 40ff41c6c..67d607740 100644 --- a/book.asciidoc +++ b/book.asciidoc @@ -107,6 +107,8 @@ include::500_Cluster_Admin.asciidoc[] include::510_Deployment.asciidoc[] +include::520_Post_Deployment.asciidoc[] + [[TODO]] [appendix] = TODO From e171432182d22d51c341bc46ce0ba73f4cc3d870 Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Fri, 29 Aug 2014 17:32:19 -0400 Subject: [PATCH 13/15] indexing perf --- 520_Post_Deployment.asciidoc | 2 + 520_Post_Deployment/30_indexing_perf.asciidoc | 188 ++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 520_Post_Deployment/30_indexing_perf.asciidoc diff --git a/520_Post_Deployment.asciidoc b/520_Post_Deployment.asciidoc index 8d76aee3f..5a987e832 100644 --- a/520_Post_Deployment.asciidoc +++ b/520_Post_Deployment.asciidoc @@ -10,7 +10,9 @@ include::520_Post_Deployment/10_dynamic_settings.asciidoc[] include::520_Post_Deployment/20_logging.asciidoc[] +include::520_Post_Deployment/30_indexing_perf.asciidoc[] +include::520_Post_Deployment/40_security.asciidoc[] - index performance tips - Mike's blog diff --git a/520_Post_Deployment/30_indexing_perf.asciidoc b/520_Post_Deployment/30_indexing_perf.asciidoc new file mode 100644 index 000000000..4880b5e78 --- /dev/null +++ b/520_Post_Deployment/30_indexing_perf.asciidoc @@ -0,0 +1,188 @@ + +=== Indexing Performance Tips + +If you are in an indexing-heavy environment, such as indexing infrastructure +logs, you may be willing to sacrifice some search performance for faster indexing +rates. In these scenarios, searches tend to be relatively rare and performed +by people internal to your organization. They are willing to wait several +seconds for a search, as opposed to a consumer facing search which must +return in milliseconds. + +Because of this unique position, there are certain tradeoffs that can be made +which will increase your indexing performance. + +.These tips only apply to Elasticsearch 1.3+ +**** +This book is written for the most recent versions of Elasticsearch, although much +of the content works on older versions. + +The tips presented in this section, however, are _explicitly_ version 1.3+. There +have been multiple performance improvements and bugs fixed which directly impact +indexing. In fact, some of these recommendations will _reduce_ performance on +older versions due to the presence of bugs or performance defects. +**** + +==== Test performance scientifically + +Performance testing is always difficult, so try to be as scientific as possible +in your approach. Randomly fiddling with knobs and turning on ingestion is not +a good way to tune performance. If there are too many "causes" then it is impossible +to determine which one had the best "effect". + +1. Test performance on a single node, with a single shard and no replicas +2. Record performance under 100% default settings so that you have a baseline to +measure against +3. Make sure performance tests run for a long time (30+ minutes) so that you can +evaluate long-term performance, not short-term spikes or latencies. Some events +(such as segment merging, GCs, etc) won't happen right away, so the performance +profile can change over time. +4. Begin making single changes to the baseline defaults. Test these rigorously, +and if performance improvement is acceptable, keep the setting and move on to the +next one. + +==== Using and Sizing Bulk requests + +Should be fairly obvious, but use bulk indexing requests for optimal performance. +Bulk sizing is dependent on your data, analysis and cluster configuration, but +a good starting point is 5-15mb per bulk. Note that this is physical size. +Document count is not a good metric for bulk size. For example, if you are +indexing 1000 documents per bulk: + +- 1000 documents at 1kb each is 1mb +- 1000 documents at 100kb each is 100mb + +Those are drastically different bulk sizes. Bulks need to be loaded into memory +at the coordinating node, so it is the physical size of the bulk that is more +important than the document count. + +Start with a bulk size around 5-15mb and slowly increase it until you do not +see performance gains anymore. Then start increasing the concurrency of your +bulk ingestion (multiple threads, etc). + +Monitor your nodes with Marvel and/or tools like `iostat`, `top, and `ps` to see +when resources start to bottleneck. If you start to receive `EsRejectedExecutionException` +then your cluster is at-capacity with _some_ resource and you need to reduce +concurrency. + +When ingesting data, make sure bulk requests are round-robin'ed across all your +data nodes. Do not send all requests to a single node, since that single node +will need to store all the bulks in memory while processing. + +==== Storage + +- Use SSDs. As mentioned elsewhere, they are superior to spinning media +- Use RAID 0. Striped RAID will increase disk IO, at the obvious expense of +potential failure if a drive dies. Don't use "mirrored" or "parity" RAIDS since +replicas provide that functionality +- Alternatively, use multiple drives and allow Elasticsearch to stripe data across +them via multiple `path.data` directories +- Do not use remote-mounted storage, such as NFS or SMB/CIFS. The latency introduced +here is antithetical with performance. +- If you are on EC2, beware EBS. Even the SSD-backed EBS options are often slower +than local drives. + +==== Segments and Merging + +Segment merging is computationally expensive, and can eat up a lot of Disk IO. +Merges are scheduled to operate in the background because they can take a long +time to finish, especially large segments. This is normally fine, because the +rate of large segment merges is relatively rare. + +But sometimes merging falls behind the ingestion rate. If this happens, Elasticsearch +will automatically throttle indexing requests to a single thread. This prevents +a "segment explosion" problem where hundreds of segments are generated before +they can be merged. Elasticsearch will log INFO level messages stating `now +throttling indexing` when it detects merging falling behind indexing. + +Elasticsearch defaults here are conservative: you don't want search performance +to be impacted by background merging. But sometimes (especially on SSD, or logging +scenarios) the throttle limit is too low. + +The default is 20mb/s, which is a good setting for spinning disks. If you have +SSDs, you might consider increasing this to 100-200mb/s. Test to see what works +for your system: + +[source,js] +---- +PUT /_cluster/settings +{ + "persistent" : { + "indices.store.throttle.max_bytes_per_sec" : "100mb" + } +} +---- + +If you are doing a bulk import and don't care about search at all, you can disable +merge throttling entirely. This will allow indexing to run as fast as your +disks will allow: + +[source,js] +---- +PUT /_cluster/settings +{ + "transient" : { + "indices.store.throttle.type" : "none" <1> + } +} +---- +<1> Setting the throttle type to `none` disables merge throttling entirely. When +you are done importing, set it back to `merge` to re-enable throttling. + +If you are using spinning media instead of SSD, you need to add this to your +`elasticsearch.yml`: + +[source,yaml] +---- +index.merge.scheduler.max_thread_count: 1 +---- + +Spinning media has a harder time with concurrent IO, so we need to decrease +the number of threads that can concurrently access the disk per index. This setting +will allow `max_thread_count + 2` threads to operate on the disk at one time, +so a setting of `1` will allow 3 threads. + +For SSDs, you can ignore this setting. The default is +`Math.min(3, Runtime.getRuntime().availableProcessors() / 2)` which works well +for SSD. + +Finally, you can increase `index.translog.flush_threshold_size` from the default +200mb to something larger, such as 1gb. This allows larger segments to accumulate +in the translog before a flush occurs. By letting larger segments build, you +flush less often, and the larger segments merge less often. All of this adds up +to less disk IO overhead and better indexing rates. + +==== Other + +Finally, there are some other considerations to keep in mind: + +- If you don't need near-realtime accuracy on your search results, consider +dropping the `index.refresh_interval` of each index to `30s`. If you are doing +a large import, you can disable refreshes by setting this value to `-1` for the +duration of the import. Don't forget to re-enable it when you are done! + +- If you are doing a large bulk import, consider disabling replicas by setting +`index.number_of_replicas: 0`. When documents are replicated, the entire document +is sent to the replica node and the indexing process is repeated verbatim. This +means each replica will perform the analysis, indexing and potentially merging +process. ++ +In contrast, if you index with zero replicas and then enable replicas when ingestion +is finished, the recovery process is essentially a byte-for-byte network transfer. +This is much more efficient than duplicating the indexing process. + +- If you don't have a natural ID for each document, use Elasticsearch's auto-ID +functionality. It is optimized to avoid version lookups, since the autogenerated +ID is unique. + +- If you are using your own ID, try to pick an ID that is http://blog.mikemccandless.com/2014/05/choosing-fast-unique-identifier-uuid.html[friendly to Lucene]. Examples include zero-padded +sequential IDs, UUID-1 and nanotime; these IDs have consistent, "sequential" +patterns which compress well. In contrast, IDs such as UUID-4 are essentially +random, which offer poor compression and slow down Lucene. + + + + + + + + From 2c4c429ff865485d9d8eb6f84479ba34c392354c Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Tue, 2 Sep 2014 10:49:27 -0400 Subject: [PATCH 14/15] rolling restarts and backup --- 07_Admin.asciidoc | 15 +- 520_Post_Deployment.asciidoc | 11 +- .../40_rolling_restart.asciidoc | 66 +++ 520_Post_Deployment/50_backup.asciidoc | 472 ++++++++++++++++++ 4 files changed, 554 insertions(+), 10 deletions(-) create mode 100644 520_Post_Deployment/40_rolling_restart.asciidoc create mode 100644 520_Post_Deployment/50_backup.asciidoc diff --git a/07_Admin.asciidoc b/07_Admin.asciidoc index 238a1ad98..d56ef8ed7 100644 --- a/07_Admin.asciidoc +++ b/07_Admin.asciidoc @@ -3,6 +3,19 @@ [partintro] -- -Something something something +The majority of this book has been aimed at building applications using Elasticsearch +as the backend. This section is a little different. Here, you will learn +how to manage Elasticsearch itself. Elasticsearch is a very complex piece of +software, with many moving parts. There are a large number of APIs designed +to help you manage your Elasticsearch deployment. + +In this chapter, we will cover three main topics: + +- Monitoring your cluster's vital statistics, what behaviors are normal and which +should be cause for alarm, and how to interpret various stats provided by Elasticsearch +- Deploying your cluster to production, including best-practices and important +configuration which should (or should not!) be changed +- Post-deployment logistics, such as how to perform a rolling restart or backup +your cluster -- diff --git a/520_Post_Deployment.asciidoc b/520_Post_Deployment.asciidoc index 5a987e832..c071407cd 100644 --- a/520_Post_Deployment.asciidoc +++ b/520_Post_Deployment.asciidoc @@ -12,14 +12,7 @@ include::520_Post_Deployment/20_logging.asciidoc[] include::520_Post_Deployment/30_indexing_perf.asciidoc[] -include::520_Post_Deployment/40_security.asciidoc[] +include::520_Post_Deployment/40_rolling_restart.asciidoc[] -- index performance tips - - Mike's blog -- security - - none lololol +include::520_Post_Deployment/50_backup.asciidoc[] --snapshot/restore - - fs must be accessible from all nodes - -rolling restarts \ No newline at end of file diff --git a/520_Post_Deployment/40_rolling_restart.asciidoc b/520_Post_Deployment/40_rolling_restart.asciidoc new file mode 100644 index 000000000..9427c51ab --- /dev/null +++ b/520_Post_Deployment/40_rolling_restart.asciidoc @@ -0,0 +1,66 @@ + +=== Rolling Restarts + +There will come a time when you need to perform a rolling restart of your +cluster -- keeping the cluster online and operational, but taking nodes offline +one at a time. + +The common reason is either an Elasticsearch version upgrade, or some kind of +maintenance on the server itself (OS update, hardware, etc). Whatever the case, +there is a particular method to perform a rolling restart. + +By nature, Elasticsearch wants your data to be fully replicated and evenly balanced. +If you were to shut down a single node for maintenance, the cluster will +immediately recognize a loss of a and begin re-balancing. This can be irritating +if you know the node maintenance is short term, since the rebalancing of +very large shards can take some time (think of trying to replicate 1TB...even +on fast networks this is non-trivial). + +What we want to do is tell Elasticsearch to hold off on rebalancing, because +we have more knowledge about the state of the cluster due to external factors. +The procedure is as follows: + +1. If possible, stop indexing new data. This is not always possible, but will +help speed up recovery time + +2. Disable shard allocation. This prevents Elasticsearch from re-balancing +missing shards until you tell it otherwise. If you know the maintenance will be +short, this is a good idea. You can disable allocation with: ++ +[source,js] +---- +PUT /_cluster/settings +{ + "transient" : { + "cluster.routing.allocation.enable" : "none" + } +} +---- + +3. Shutdown a single node, preferably using the _Shutdown API_ on that particular +machine: ++ +[source,js] +---- +PUT /_cluster/nodes/_local/_shutdown +---- + +4. Perform maintenance/upgrade +5. Restart node, confirm that it joins the cluster +6. Repeat 3-5 for the rest of your nodes +7. Re-enable shard allocation using: ++ +[source,js] +---- +PUT /_cluster/settings +{ + "transient" : { + "cluster.routing.allocation.enable" : "all" + } +} +---- ++ +Shard re-balancing may take some time. At this point you are safe to resume +indexing (if you had previously stopped), but waiting until the cluster is fully +balanced before resuming indexing will help speed up the process + diff --git a/520_Post_Deployment/50_backup.asciidoc b/520_Post_Deployment/50_backup.asciidoc new file mode 100644 index 000000000..56dd26568 --- /dev/null +++ b/520_Post_Deployment/50_backup.asciidoc @@ -0,0 +1,472 @@ + +=== Backing up your Cluster + +Like any software that stores data, it is important to routinely backup your +data. Elasticsearch replicas provide high-availability during runtime; they allow +you to tolerate sporadic node loss without an interruption of service. + +Replicas do not provide protection from catastrophic failure, however. For that, +you need a real backup of your cluster...a complete copy in case something goes +wrong. + +To backup your cluster, you can use the _Snapshot_ API. This will take the current +state and data in your cluster and save it to a shared repository. This +backup process is "smart". Your first snapshot will be a complete copy of data, +but all subsequent snapshots will save the _delta_ between the existing +snapshots and the new data. Data is incrementally added and deleted as you snapshot +data over time. This means subsequent backups will be substantially +faster since they are transmitting far less data. + +To use this functionality, you must first create a repository to save data. +There are several repository types that you may choose from: + +- Shared filesystem, such as a NAS +- Amazon S3 +- HDFS +- Azure Cloud + +==== Creating the repository + +Let's set up a shared filesystem repository: + +[source,js] +---- +PUT _snapshot/my_backup <1> +{ + "type": "fs", <2> + "settings": { + "location": "/mount/backups/my_backup" <3> + } +} +---- +<1> We provide a name for our repository, in this case it is called `my_backup` +<2> We specify that the type of the repository should be a shared file system +<3> And finally, we provide a mounted drive as the destination + +INFORMATION: The shared file system path must be accessible from all nodes in your +cluster! + +This will create the repository and required metadata at the mount point. There +are also some other options which you may want to configure, depending on the +performance profile of your nodes, network and repository location: + +- `max_snapshot_bytes_per_sec`: When snapshotting data into the repo, this controls +the throttling of that process. The default is `20mb` per second +- `max_restore_bytes_per_sec`: When restoring data from the repo, this controls +how much the restore is throttled so that your network is not saturated. The +default is `20mb` per second + +Let's assume we have a very fast network and are ok with extra traffic, so we +can increase the defaults: + +[source,js] +---- +POST _snapshot/my_backup/ <1> +{ + "type": "fs", + "settings": { + "location": "/mount/backups/my_backup", + "max_snapshot_bytes_per_sec" : "50mb", <2> + "max_restore_bytes_per_sec" : "50mb" + } +} +---- +<1> Note that we are using a POST instead of PUT. This will update the settings +of the existing repository +<2> Then add our new settings + +==== Snapshotting all open indices + +A repository can contain multiple snapshots. Each snapshot is associated with a +certain set of indices (all indices, some subset, a single index, etc). When +creating a snapshot, you specify which indices you are interested in and +give the snapshot a unique name. + +Let's start with the most basic snapshot command: + +[source,js] +---- +PUT _snapshot/my_backup/snapshot_1 +---- + +This will backup all open indices into a snapshot named `snapshot_1`, under the +`my_backup` repository. This call will return immediately and the snapshot will +proceed in the background. + +.Blocking for completion +**** +Usually you'll want your snapshots to proceed as a background process, but occasionally +you may want to wait for completion in your script. This can be accomplished by +adding a `wait_for_completion` flag: + +[source,js] +---- +PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true +---- + +This will block the call until the snapshot has completed. Note: large snapshots +may take a long time to return! +**** + +==== Snapshotting particular indices + +The default behavior is to back up all open indices. But say you are using marvel, +and don't really want to backup all the diagnostic `.marvel` indices. You +just don't have enough space to backup everything. + +In that case, you can specify which indices to backup when snapshotting your cluster: + +[source,js] +---- +PUT _snapshot/my_backup/snapshot_2 +{ + "indices": "index_1,index_2" <1> +} +---- + +This snapshot command will now backup only `index1` and `index2`. + +==== Listing information about snapshots + +Once you start accumulating snapshots in your repository, you may forget the details +relating to each...particularly when the snapshots are named based on time +demarcations (`backup_2014_10_28`, etc). + +To obtain information about a single snapshot, simply issue a GET reguest against +the repo and snapshot name: + +[source,js] +---- +GET _snapshot/my_backup/snapshot_2 +---- + +This will return a small response with various pieces of information regarding +the snapshot: + +[source,js] +---- +{ + "snapshots": [ + { + "snapshot": "snapshot_1", + "indices": [ + ".marvel_2014_28_10", + "index1", + "index2" + ], + "state": "SUCCESS", + "start_time": "2014-09-02T13:01:43.115Z", + "start_time_in_millis": 1409662903115, + "end_time": "2014-09-02T13:01:43.439Z", + "end_time_in_millis": 1409662903439, + "duration_in_millis": 324, + "failures": [], + "shards": { + "total": 10, + "failed": 0, + "successful": 10 + } + } + ] +} +---- + +For a complete listing of all snapshots in a repository, use the `_all` placeholder +instead of a snapshot name: + +[source,js] +---- +GET _snapshot/my_backup/_all +---- + +==== Deleting Snapshots + +Finally, we need a command to delete old snapshots that are no longer useful. +This is simply a DELETE HTTP call to the repo/snapshot name: + +[source,js] +---- +DELETE _snapshot/my_backup/snapshot_2 +---- + +It is important to use the API to delete snapshots, and not some other mechanism +(deleting by hand, automated cleanup tools on S3, etc). Because snapshots are +incremental, it is possible that many snapshots are relying on "old" data. +The Delete API understands what data is still in use by more recent snapshots, +and will only delete unused segments. + +If you do a manual file delete, however, you are at risk of seriously corrupting +your backups because you are deleting data that is still in use. + +=== Restoring + +Once you've backed up some data, restoring it is very easy: simply add `_restore` +to the ID of the snapshot you wish to restore into your cluster: + +[source,js] +---- +POST _snapshot/my_backup/snapshot_1/_restore +---- + +The default behavior is to restore all indices that exist in that snapshot. +If `snapshot_1` contains five different indices, all five will be restored into +our cluster. Like the Snapshot API, it is possible to select which indices +we want to restore. + +There are also additional options for renaming indices. This allows you to +match index names with a pattern, then provide a new name during the restore process. +This is useful if you want to restore old data to verify it's contents, or perform +some other processing, without replacing existing data. Let's restore +a single index from the snapshot and provide a replacement name: + +[source,js] +---- +POST /_snapshot/my_backup/snapshot_1/_restore +{ + "indices": "index_1", <1> + "rename_pattern": "index_(.+)", <2> + "rename_replacement": "restored_index_$1" <3> +} +---- +<1> Only restore the `index_1` index, ignoring the rest that are present in the +snapshot +<2> Find any indices being restored which match the provided pattern... +<3> ... then rename them with the replacement pattern + +This will restore `index_1` into your cluster, but rename it to `restored_index_1`. + +.Blocking for completion +**** +Similar to snapshotting, the restore command will return immediately and the +restoration process will happen in the background. If you would prefer your HTTP +call to block until the restore is finished, simply add the `wait_for_completion` +flag: + +[source,js] +---- +POST _snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true +---- +**** + +==== Monitoring Snapshot progress + +The `wait_for_completion` flag provides a rudimentary form of monitoring, but +really isn't sufficient when snapshotting or restoring even moderately sized clusters. + +There are two additional APIs that will give you more detailed status about the +state of the snapshotting. First you can execute a GET to the snapshot ID, +just like we did earlier get information about a particular snapshot: + +[source,js] +---- +GET _snapshot/my_backup/snapshot_3 +---- + +If the snapshot is still in-progress when you call this, you'll see information +about when it was started, how long it has been running, etc. Note, however, +that this API uses the same threadpool as the snapshot mechanism. If you are +snapshotting very large shards, the time between status updates can be quite large, +since the API is competing for the same threadpool resources. + +A better option is to poll the `_status` API: + +[source,js] +---- +GET _snapshot/my_backup/snapshot_3/_status +---- + +The Status API returns immediately and gives a much more verbose output of +statistics: + +[source,js] +---- +{ + "snapshots": [ + { + "snapshot": "snapshot_3", + "repository": "my_backup", + "state": "IN_PROGRESS", <1> + "shards_stats": { + "initializing": 0, + "started": 1, <2> + "finalizing": 0, + "done": 4, + "failed": 0, + "total": 5 + }, + "stats": { + "number_of_files": 5, + "processed_files": 5, + "total_size_in_bytes": 1792, + "processed_size_in_bytes": 1792, + "start_time_in_millis": 1409663054859, + "time_in_millis": 64 + }, + "indices": { + "index_3": { + "shards_stats": { + "initializing": 0, + "started": 0, + "finalizing": 0, + "done": 5, + "failed": 0, + "total": 5 + }, + "stats": { + "number_of_files": 5, + "processed_files": 5, + "total_size_in_bytes": 1792, + "processed_size_in_bytes": 1792, + "start_time_in_millis": 1409663054859, + "time_in_millis": 64 + }, + "shards": { + "0": { + "stage": "DONE", + "stats": { + "number_of_files": 1, + "processed_files": 1, + "total_size_in_bytes": 514, + "processed_size_in_bytes": 514, + "start_time_in_millis": 1409663054862, + "time_in_millis": 22 + } + }, + ... +---- +<1> A snapshot that is currently running will show `IN_PROGRESS` as it's status +<2> This particular snapshot has one shard still transferring (the other 4 have already completed) + +The Stats displays the total status of the snapshot, but also drills down into +per-index and per-shard statistics. This gives you an incredibly detailed view +of how the snapshot is progressing. Shards can be in various states of completion: + +- `INITIALIZING`: The shard is checking with the cluster state to see if it can +be snapshotted. This is usually very fast +- `STARTED`: Data is being transferred to the repository +- `FINALIZING`: Data transfer is complete, the shard is now sending snapshot metadata +- `DONE`: Snapshot complete! +- `FAILED`: An error was encountered during the snapshot process, and this shard/index/snapshot +could not be completed. Check your logs for more information + +==== Monitoring Restore operations + +The restoration of data from a repository piggybacks on the existing recovery +mechanisms already in place in Elasticsearch. Internally, recovering shards +from a repository is identical to recovering from another node. + +If you wish to monitor the progress of a restore, you can use the Recovery +API. This is a general purpose API which shows status of shards moving around +your cluster. + +The API can be invoked for the specific indices that you are recovering: + +[source,js] +---- +GET /_recovery/restored_index_3 +---- + +Or for all indices in your cluster, which may include other shards moving around, +unrelated to your restore process: + +[source,js] +---- +GET /_recovery/ +---- + +The output will look similar to this (and note, it can become very verbose +depending on the activity of your clsuter!): + +[source,js] +---- +{ + "restored_index_3" : { + "shards" : [ { + "id" : 0, + "type" : "snapshot", <1> + "stage" : "index", + "primary" : true, + "start_time" : "2014-02-24T12:15:59.716", + "stop_time" : 0, + "total_time_in_millis" : 175576, + "source" : { <2> + "repository" : "my_backup", + "snapshot" : "snapshot_3", + "index" : "restored_index_3" + }, + "target" : { + "id" : "ryqJ5lO5S4-lSFbGntkEkg", + "hostname" : "my.fqdn", + "ip" : "10.0.1.7", + "name" : "my_es_node" + }, + "index" : { + "files" : { + "total" : 73, + "reused" : 0, + "recovered" : 69, + "percent" : "94.5%" <3> + }, + "bytes" : { + "total" : 79063092, + "reused" : 0, + "recovered" : 68891939, + "percent" : "87.1%" + }, + "total_time_in_millis" : 0 + }, + "translog" : { + "recovered" : 0, + "total_time_in_millis" : 0 + }, + "start" : { + "check_index_time" : 0, + "total_time_in_millis" : 0 + } + } ] + } +} +---- +<1> The `type` field will tell you the nature of the recovery -- this shard is being +recovered from a snapshot +<2> The `source` hash will describe the particular snapshot and repository that is +being recovered from +<3> And the `percent` field will give you an idea about the status of the recovery. +This particular shard has recovered 94% of the files so far...it is almost complete + +The output will list all indices currently undergoing a recovery, and then a +list of all shards in each of those indices. Each of these shards will have stats +about start/stop time, duration, recover percentage, bytes transferred, etc. + +==== Canceling Snapshot and Restores + +Finally, you may want to cancel a snapshot or restore. Since these are long running +processes, a typo or mistake when executing the operation could take a long time to +resolve...and use up valuable resources at the same time. + +To cancel a snapshot, simply delete the snapshot while it is in-progress: + +[source,js] +---- +DELETE _snapshot/my_backup/snapshot_3 +---- + +This will halt the snapshot process, then proceed to delete the half-completed +snapshot from the repository. + +To cancel a restore, you need to delete the indices being restored. Because +a restore process is really just shard recovery, issuing a Delete Index API +alters the cluster state, which will in turn halt recovery. For example: + +[source,js] +---- +DELETE /restored_index_3 +---- + +If `restored_index_3` was actively being restored, this delete command would +halt the restoration as well as deleting any data that had already been restored +into the cluster. + + + + From 869141d1cdeffc28d1cff4a7bb55ab252af65e03 Mon Sep 17 00:00:00 2001 From: Zachary Tong Date: Tue, 2 Sep 2014 10:52:56 -0400 Subject: [PATCH 15/15] update graphs --- 300_Aggregations/30_histogram.asciidoc | 4 +- 300_Aggregations/35_date_histogram.asciidoc | 4 +- 300_Aggregations/65_percentiles.asciidoc | 4 +- images/300_30_bar1.png | Bin 20926 -> 0 bytes images/300_30_bar1.svg | 344 ++++++++++++++ images/300_30_histo1.png | Bin 20210 -> 0 bytes images/300_30_histo1.svg | 375 ++++++++++++++++ images/300_35_ts1.png | Bin 28343 -> 0 bytes images/300_35_ts1.svg | 269 +++++++++++ images/300_35_ts2.png | Bin 44205 -> 0 bytes images/300_35_ts2.svg | 470 ++++++++++++++++++++ images/300_65_percentile1.png | Bin 24415 -> 0 bytes images/300_65_percentile1.svg | 376 ++++++++++++++++ images/300_65_percentile2.png | Bin 34139 -> 0 bytes images/300_65_percentile2.svg | 402 +++++++++++++++++ 15 files changed, 2242 insertions(+), 6 deletions(-) delete mode 100644 images/300_30_bar1.png create mode 100644 images/300_30_bar1.svg delete mode 100644 images/300_30_histo1.png create mode 100644 images/300_30_histo1.svg delete mode 100644 images/300_35_ts1.png create mode 100644 images/300_35_ts1.svg delete mode 100644 images/300_35_ts2.png create mode 100644 images/300_35_ts2.svg delete mode 100644 images/300_65_percentile1.png create mode 100644 images/300_65_percentile1.svg delete mode 100644 images/300_65_percentile2.png create mode 100644 images/300_65_percentile2.svg diff --git a/300_Aggregations/30_histogram.asciidoc b/300_Aggregations/30_histogram.asciidoc index 89c2d06f6..1fde824a6 100644 --- a/300_Aggregations/30_histogram.asciidoc +++ b/300_Aggregations/30_histogram.asciidoc @@ -104,7 +104,7 @@ means `0-20,000`, the key `20000` means `20,000-40,000`, etc. Graphically, you could represent the above data in a histogram like this: [[barcharts-histo1]] -image::images/300_30_histo1.png["Histogram of top makes per price range"] +image::images/300_30_histo1.svg["Histogram of top makes per price range"] Of course, you can build bar charts with any aggregation which emits categories and statistics, not just the `histogram` bucket. Let's build a bar chart of @@ -145,7 +145,7 @@ std_err = std_deviation / count Which will allow us to build a chart like this: [[barcharts-bar1]] -image::images/300_30_bar1.png["Barchart of average price per make, with error bars"] +image::images/300_30_bar1.svg["Barchart of average price per make, with error bars"] diff --git a/300_Aggregations/35_date_histogram.asciidoc b/300_Aggregations/35_date_histogram.asciidoc index be5103770..2fcf608ee 100644 --- a/300_Aggregations/35_date_histogram.asciidoc +++ b/300_Aggregations/35_date_histogram.asciidoc @@ -176,7 +176,7 @@ you'll get a response that is easy to plug straight into your graphing libraries and give you a graph like this: [[date-histo-ts1]] -image::images/300_35_ts1.png["Line chart of cars sold per month"] +image::images/300_35_ts1.svg["Line chart of cars sold per month"] === Extended Example @@ -270,4 +270,4 @@ We can take this response and put it into a graph, showing a line chart for total sale price, and a bar chart for each individual make (per quarter): [[date-histo-ts2]] -image::images/300_35_ts2.png["Line chart of cars sold per month"] \ No newline at end of file +image::images/300_35_ts2.svg["Line chart of cars sold per month"] \ No newline at end of file diff --git a/300_Aggregations/65_percentiles.asciidoc b/300_Aggregations/65_percentiles.asciidoc index cb482be5d..7f131f7c0 100644 --- a/300_Aggregations/65_percentiles.asciidoc +++ b/300_Aggregations/65_percentiles.asciidoc @@ -23,14 +23,14 @@ metric is easily skewed by just a single outlier. This graph visualizes the problem. If you rely on simple metrics like mean or median, you might see a graph that looks like this: [[percentile-mean-median]] -image::images/300_65_percentile1.png["Assessing website latency using mean/median"] +image::images/300_65_percentile1.svg["Assessing website latency using mean/median"] Everything looks fine. There is a slight bump, but nothing to be concerned about. But if we load up the 99th percentile (the value which accounts for the slowest 1% of latencies), we see an entirely different story: [[percentile-mean-median-percentile]] -image::images/300_65_percentile2.png["Assessing website latency using percentiles"] +image::images/300_65_percentile2.svg["Assessing website latency using percentiles"] Woah! At 9:30 AM, the mean is only 75ms. As a system administrator, you wouldn't look at this value twice. Everything normal! But the 99th percentile is telling diff --git a/images/300_30_bar1.png b/images/300_30_bar1.png deleted file mode 100644 index b611c8ef063843915cce2a543d28b315754dfac9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20926 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 Hu0mjffE0;g diff --git a/images/300_30_bar1.svg b/images/300_30_bar1.svg new file mode 100644 index 000000000..c4424ef47 --- /dev/null +++ b/images/300_30_bar1.svg @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/300_30_histo1.png b/images/300_30_histo1.png deleted file mode 100644 index 9e64a197634db6fce33ff61b0db8bb07df931825..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20210 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/300_35_ts1.png b/images/300_35_ts1.png deleted file mode 100644 index 3a83fab6309f60dc16b94d567ef281d1f1d0fabd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28343 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 G3;TaJcPVoK diff --git a/images/300_35_ts1.svg b/images/300_35_ts1.svg new file mode 100644 index 000000000..8a496f67f --- /dev/null +++ b/images/300_35_ts1.svg @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/300_35_ts2.png b/images/300_35_ts2.png deleted file mode 100644 index 318992f18484b334154d0ccfd72a8fe5101d158f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44205 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
(d|vB^gMvqn`S)@fvGI68 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/300_65_percentile1.png b/images/300_65_percentile1.png deleted file mode 100644 index b1c28830c262013951e3f6bc92dd94742ea056e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24415 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 ZKO)3KJA1mW_u%mw-P;CQl^S->{{!xnZdU*R diff --git a/images/300_65_percentile1.svg b/images/300_65_percentile1.svg new file mode 100644 index 000000000..d8e750b37 --- /dev/null +++ b/images/300_65_percentile1.svg @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/300_65_percentile2.png b/images/300_65_percentile2.png deleted file mode 100644 index b546de2e71b617a0d4e6156b4342bfb10b411836..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34139 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 IF{8l$1B~R + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +