diff --git a/bin/generate-javadocs.sh b/bin/generate-javadocs.sh index 112684f..da9f32d 100755 --- a/bin/generate-javadocs.sh +++ b/bin/generate-javadocs.sh @@ -18,17 +18,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BASE_DIR=$DIR/.. -VERSION=$1 -JAVADOC_DIR=$BASE_DIR/docs/learn/documentation/$VERSION/api/javadocs - -if test -z "$VERSION"; then - echo - echo " USAGE:" - echo - echo " ${BASH_SOURCE[0]##*/} 0.7.0" - echo - exit 0 -fi +JAVADOC_DIR=$BASE_DIR/docs/learn/documentation/versioned/api/javadocs cd $BASE_DIR ./gradlew javadoc diff --git a/bin/publish-site.sh b/bin/publish-site.sh index 8da57a9..6fe70ff 100755 --- a/bin/publish-site.sh +++ b/bin/publish-site.sh @@ -19,29 +19,30 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BASE_DIR=$DIR/.. DOCS_DIR=$BASE_DIR/docs -VERSION=$1 -COMMENT=$2 -USER=$3 +COMMENT=$1 +USER=$2 -if test -z "$VERSION" || test -z "$COMMENT" || test -z "$USER"; then +if test -z "$COMMENT" || test -z "$USER"; then echo echo " USAGE:" echo - echo " ${BASH_SOURCE[0]##*/} 0.7.0 \"updating welcome page\" criccomini" + echo " ${BASH_SOURCE[0]##*/} \"updating welcome page\" criccomini" echo exit 0 fi echo "Using uer: $USER" -echo "Using version: $VERSION" echo "Using comment: $COMMENT" echo "Generating javadocs." -$BASE_DIR/bin/generate-javadocs.sh $VERSION +$BASE_DIR/bin/generate-javadocs.sh echo "Building site." cd $DOCS_DIR bundle exec jekyll build +echo "Replacing version" +./replace-versioned.sh + echo "Checking out SVN site." SVN_TMP=`mktemp -d /tmp/samza-svn.XXXX` svn co https://svn.apache.org/repos/asf/incubator/samza/ $SVN_TMP diff --git a/docs/README.md b/docs/README.md index de5fc23..5ea6320 100644 --- a/docs/README.md +++ b/docs/README.md @@ -30,6 +30,11 @@ To compile the website in the \_site directory, execute: bundle exec jekyll build +* assume you are in the master branch. Because the links in sidebar always point to master version, in order +to make them work, open a new command window, and run + + ./replace-versioned.sh + ## Versioning The "Learn" section of this website is versioned. To add a new version, copy the folder at the version number-level (0.7.0 to 0.8.0, for example). diff --git a/docs/_config.yml b/docs/_config.yml index 2f2f895..5e076b0 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -21,3 +21,5 @@ markdown: redcarpet exclude: ['_notes'] redcarpet: extensions: ['with_toc_data', 'smart'] +exclude: [replace-versioned.sh] +version: master \ No newline at end of file diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index 5bea47a..2ed6379 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -49,14 +49,14 @@
diff --git a/docs/archive/index.html b/docs/archive/index.html new file mode 100644 index 0000000..beb91c7 --- /dev/null +++ b/docs/archive/index.html @@ -0,0 +1,28 @@ +--- +layout: page +title: Documentation +--- + + +

0.7.0 Release

+ + diff --git a/docs/img/0.7.0/learn/documentation/comparisons/mupd8-samza.png b/docs/img/0.7.0/learn/documentation/comparisons/mupd8-samza.png deleted file mode 100644 index 5882cea1ad03c50c9768e26904f90598af5ac0ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8217 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 Lv1SSE4)Xs2QFNC> diff --git a/docs/img/0.7.0/learn/documentation/comparisons/mupd8.png b/docs/img/0.7.0/learn/documentation/comparisons/mupd8.png deleted file mode 100644 index ca7998269004d1aae0f328da16df8149536d16c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7308 zcmc(Ec|6qZyZ>O+NHi&H(iA0x5Rq+)Xb`d+3@Ky}*$rcQB1&b?P9f{q*BRuAFxD39 z7*xh&k6{KgI8)EJ=X<`t*Y9=Cd7blno!|Y(TywA2^||lszV7RKUopmpx?G2Z4gmlF zF4zri699k>$o!uUI>7wpk9ckX00^7Hw6B^4O)L|=pE~&?yL^s47BFUsyz#`s_Uh}x zbC1WMxe^j_aRMbBHz$W45MJs%yjteCe_OBWG*OAb1Ji~TcyzovL8x?Xh`4qFq(pEi zYEKA|u5vXXJn zt125Rc=Ug3umUHba^aG03K=ZbqxyX}I$JgQ+k$bC^k z!LJL2dK|zGwhb6}s^PZ}i%&~SQ#}CG27+FurLnL;AZMU&`}z)p9zO=KC@3f}>#RWL zQp`ypFmpN^>zV&|0|uTVn&t>2xE$TZ#V&4OH22B$lgjr|x(f$If*b-ETWiUf{8M2+ zuF~8(!oTN5TgYRciKs8^J)IoXpf8oMwQsIx-lEqZYog*8G3SDUGxyqGM$U{?-C6kp z6h3cdE)c|6>mt79*y@fKmEyMvr7rn+>#QK@)bcA}##^LN%c>9?crqgq*-My~!#b^c zs>yr%jm`?Ppx**6pSljPBS69;PdLk2C9;$SW+)COb zX<*4#WK5DDl7T7Qqvd9!LEMjGRD|2$EV;38E3Hn37jd7xeyuTX} zbT^v^%=obw-l2XnkJF$F09|_r8n_OgeGH3iv9Dc0>`J24`wH)+sf?}!x zbH+c(zvs+s{ST^t$+aT*OPqfZ;PAi7^B-6L=h6mnf*BujG*o0K>5RAhZCB_!n!9g; zSb%TXfjOZ|G3^4qq0?Ifv<^1NSmplG;=Zzgpp|L)58^eqYEEVEzH39;U-)$zD3*44m@7}USs#gkTwO(a zaRXhlkkqBp2!De~0Q!@j9$_nX|Hlve0gbhJI(cog#4@Mi@*%K?q{Pj`bv~P2x;bey zFT`Hq<-zIwy6HV+)nA8r0N5*5pq1>K3t8QtTn>ym0lg20%@5HVkXx@Qw8XoQIiZyw z@*kY{lFvWC+O~Xh^*HCR!*hV%zXE+RQjg17E;(}}VXfoSbms1N)rz#1y><1P=es*D zbE^gJd!}uh*qR31?#Y_by&)$GU-OY&#&XS@woT$x6X)etGLo|FySLp!;EeavOO1FI zzl>>~o0!7y&+xaZMaXIyRaaz8(f3TFa_>$DtFOA)Z=c$sZWf3d^$!-*)2kM}GoSl; zH}ve&vu!k#HFfqz895m+XO{M!p6kg4%bWczgPZ*?f8YX_2>a^v&gZ-MrPv0XXLuWh z@;Yaye|r(>6Mu)S;jDRTtYJS%d4FO$>`r(YHC&UCtf}dmp@i}4TUwm6(Y$1&Ojs6C z+YqM=S_&g*$29%%t!~&W6|tk4y8H=W8Ary?b*&KiAy$VI=D(D!%Q-mD^@|H|`6R}hYQ-u4l@aSIM!?PCtafr z3NG}@`AYMYZfn+f|Gqkvl_stGHTG)7(YdYp$-<Xb9btj zJaOA_+=ZH@r_zNFh)i3#k2YJ_w%vQPBu*Hqd>9~d9b-Mvz!NPjyMGKaCJdg1lXo|C z>P9ac`X(-BgeC&d(?n_KVPTHqnv}qV9Hp!HmR=3NoMWmnc^y!yIVv59Mf9qO$yDc1 zZ6`#YLZS8Z1j~dTkHp!F)6tnWj-nNH(DCpH-)FoP+u5}QQaXtetnQPsdNn~8TB!!k z?{f_W$!nKmkjV!nOb=b7Ad-(Z$!>>>*H6$BqF#h4(L|jbHBtv_$?>rDn1^9Xa*12| z2IN&7f+GZ9fE!8CS81rX#kcZMwq-uA@leJKAEjklemzf4@xAP0L2{~JMbrq3?`u&{ z8Xx#=9Pjl4D|VM2l&&r?9^D!0%V} z>Xzv%PqvUtr{MQrhztZ^Hw5~6UmjEU@aOj2#->$s{$=hRQp@F&^a?$%SID|HJi$rg zTk}o~`@O)I!cFKFGWbwe_Wl4OU!~HxcPK}~5LwvtHua>cp-J+fSe}Q}v={pFC6+3l zo|5jxbkD-h5lO8#S73gs!i5<9z(yS&Ozl1DNl^}KP`Q9|Tdo60t!l{> zH;%db53f`|U(6Y-`nZ!FG_Oj=i5R=CZol#^j`AoBI|&~lZY2<>zco2Xe-|1Wn)B;b-gTz@fkpN6{S>$6-tho4QP?gcmt_ve-tj(uj^mW z(O>eWoK`@h5{GTxz2{8ay2E&w_@F`wBU4XDd(`i ztG)gi1P5YT&Q0JtPxTJt)!k;Ebb!v~R<|*oA8jLaj-9Ofl&n8}R1D)Ud(?%H{$CJ=t0< zRl$EDpHXx=MvG)}g5VRvzD|_by0>4EN6`~Dzc8%0sPz5!>yPF#$8Vlp_R8_Q(TV%6 zP;AV9c8VCQs^vcs+vc?A4%(X{*dudkZV#?Xyz>*O+hCDctMQcG^XuHYB# zGBmo@uP=cDZE!~#+9-`y;+vhH2;KeZ&is6E+Y2KdZe0%MnHQ3>`PTA@efqMQC@c)# zT_V-u9YKu6divZnNx@4dyN7Ccy8CG4@YTCz^{yqss{8qKC+>bXO4!ZIb4N;Vc{0SFxi{+G)LRahA&95A|9O8(KcV3}ZlY=mT} zel766o(Bh<)^r#A)aonYr0pm%BV;VRAZ=$BK%&*#mQZ>Ym&qmw_A8tacLAsAV3OZ9 z;xmn(dCOiZgJ*j+lGF+u^?J?f$NTioyY`fS;e%CHKVK@v9v6j-5uwIXoe#d9;RyL! zI8Y@yyfXCMETqm15y$@=`%XhLUfIlg zT*Z3cfj zXT{U882^%C(Da#oNXSvJyC^Ewi`72v_^{2b#2l=XZGUv}OE#eDx1{UaG6B&u^`#`z zZpVNQnaliHs+C??fmh#jhP5Fd*Z=^El3W7n`TKY)DVIEwDz~wwdc1yg5i)iX`T{Le zl>k&vHdbG5wAi_4GnM$l{A}_cQqs1HYmHH^X1%r=_C~h`!rgn?B&`-1rfK4GeF2*r zgmf2UI$q8M=8}M)x3K+F+OM9(l*)eYzE4KjDpZ)Xo~MnC3KK9=3Mp+1!-gN!b13$ z(fZn1oV#tH>VXDnl)Gy$6}O(2>5i?CV{2dg)}_k{RP0dz3{7>J?vNFD{%lR7}A(5Wg9Sfef0rN!E-4m*c`9+?*2Eu2R2%c^+ll8-bU=LaFVPdM7 z6>$oMx@{vv$|g@W5QeojCw2>}@G#jJnZ4R_J|d5-Rsm zWZu+6CmNA@iG>wfd0U`6K%&t^Io~`_dWe;+?vgz<9*S8T*K*f%$?yuaL=5hI>*r%& zIY2Tk8z0AYHP++DKfKm$UlRO0N@0W8*SDN}q404;}<*nu$xv87HzN{0NP zATsVDbjXXctT#@rp>QE48oH${RWoiGQ6|Z89&~M zb4jrRQ4R{wN`rR?m>1&>2e3Q`L5Ut^;LQ)B(UG$^v|5boJ|a}3WmK%V>dQ0%e_CLRaqqBiCs^8h6-OD=JOzF#46>NquXBSM8;uxNXE7wW z@_P^G89qz?AUuq%JPbAyU8^=KVJyYasLloiAc3b@!LEl_k?wXVZ@`eDj?cuEQW z5O8^ceKWtq36=Xko#cY`)y2x|-fL_waqCRUB*(I}zb4F7)Rohp;0&$?l9DY4R$A#R z<6quI|C9w%?y=a}X`v!r+uLC^FwgACP~RBRLOHNPU(mw~@01Fi=iC1JL^iyb20PNe z6*#Uv~t}K)XZC~0-OVTYzm`GCRcHkf$>Bm4Oi|+6`+k$ zG=yU6)kI1e7k#eg`;l=R>cHL3H*mUpK`Y0evU$hasi?oR`N*v@vYuE2{>JmZwKB5) z1x{d3yL=c{=jj9SLzYI+sQcoy((UX>AoODU!9?E3dZTY;1=IYGS>Q&jZei;S|4uYY4rL&&9?Nm0NCI#2+msGRUOSrw>Vw$MruU#Qz|>U zQ3PP7744>&x00U}f)|BY*+MXu@hj&bMXY|jtuCf4Xw=-z%fw5kxIbgybr~p#dJ!=? z&gpa%H7^k5@C|DGPB1n2edqDWToJD^8Pdz!HJ;T6L53$ldtUtw7297W)QTG|{0!6) z0Ap#!GNX@yXtE#xup;1&p8knEt-9D-ft_6d4{87O_Xz04(~zS4R?sDdiDUOUYC{g) zX&sAvW)1_6G6F80$iO=38A6={~vvBS`2$X+to-kW?JO!0I-D{SQWe2gcDe@lx zd&K30t~8C;3~FG@jU*ABje6Ee+otm(M*3Fx8b;PAzj`e<*yHB7qB*4KY|E$fDUEt; zwhOop^T194Xr%9(13?o;NlXZ+pQ z{}g7LFTsyVk;wqcVSk5Z9Wlg6fLIQ#JZdBea#Np8H(&<^yf+1+g+7ig za}|9_@?1OtQTEFg0s}9ZBK*Z;ENsuN0NP#I+I!!FfN7#HR=*B`t1soB^Qyl2wLnBD zC0`vD5+a*e=_2CnQ1dpA7|4IIS><+=uJdE#xrmV$^&Y8=(_KZjvR&P)#9%IzgBTM6 zanPfkW54BJXX$;6X}xVoW=X~O=u@TS5+B!7=g~dh9n8>7l<0J(vF` zIp2Fsh&jdO&-psrWbtA)^n9a*XHVr3<|`raYi!0(?2@1;SS!-k_^H$#fOajDPm(Wn zl$_pl5}D!ncc>`(q_9qH{2MGYtf)kIo5uAIT&#UMj5&MiSETq4h_ljBooy49ZSXn6 zL`nu?#pTle40?4=o9VZ_{f&A$JhClyo!!?z(*D^204{sBIIdc+r& z#OBi{Y9Ej#)2E=7El%cqTHkHp)gt&b_G5sbf$48{tW0*s*~Mb_n2u_eIF_5m89Dl9 zeMt59fS&DVy_}##ZJqX9Y!M0KGbD~QsRzLjQ)w@{sXtQ zdPIWQhYv_itnN!t9ps^v)?|qq7IeC{?Yocb`Qv$SKC}M*9;;Ww(#eBKa8H)@fv!(y z$n#@A8H^Z3EMh6qFG%#Po`r*LKS(_{tq%UiSAOBMXgiPJBL2NG{})vFFU0hpcr-DpDLZbc$-9&rn6tI9yE5F(h(ywL*@3@O z1|bH}AEh^ctOu!wKxTYG4@2L6qcY!6OFmE#PJ|QuqX;=DfSUQJ7!lt8eEr^Tj~v_8 zu&$GVeVk4rZ+F~OzMijozCUGQCVeQ!asBEvZEX}PElm&%KFY%C?CcDM{!S4cJqmGfc4nrG z{`&(ye1zT~v3BXtV{%9{Qi4EU6)z^c?}eL=$uZd%?;Vj~J9^WaKl8f;lha(dJ;V-j f=KoJgFWftF*ruh#`fYb* diff --git a/docs/img/0.7.0/learn/documentation/container/checkpointing.svg b/docs/img/0.7.0/learn/documentation/container/checkpointing.svg deleted file mode 100644 index 676cd7c..0000000 --- a/docs/img/0.7.0/learn/documentation/container/checkpointing.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/img/0.7.0/learn/documentation/container/stateful_job.png b/docs/img/0.7.0/learn/documentation/container/stateful_job.png deleted file mode 100644 index e48607949b40a424293ecae0c297a0835d261079..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26142 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 - - - diff --git a/docs/img/0.7.0/learn/documentation/introduction/dag.graffle b/docs/img/0.7.0/learn/documentation/introduction/dag.graffle deleted file mode 100644 index d743ea4..0000000 --- a/docs/img/0.7.0/learn/documentation/introduction/dag.graffle +++ /dev/null @@ -1,1009 +0,0 @@ - - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGrafflePro.MacAppStore - 139.18 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {576.00002479553223, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2013-07-28 22:58:14 +0000 - Creator - Jay Kreps - DisplayScale - 1 0/72 in = 1 0/72 in - GraphDocumentVersion - 8 - GraphicsList - - - Bounds - {{43.000001907348633, 12}, {208, 22}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 39 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs36 \cf0 A Multjob Dataflow Graph} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - Head - - ID - 37 - Info - 2 - - ID - 38 - Points - - {236.00000190734863, 144} - {231.00000190734863, 224} - {147.00000190734863, 292} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 23 - Info - 1 - - - - Bounds - {{113.00000190734863, 292}, {68, 27}} - Class - ShapedGraphic - ID - 37 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Stream F} - VerticalPad - 0 - - - - Class - LineGraphic - Head - - ID - 37 - Info - 2 - - ID - 36 - Points - - {147.00000190734863, 268} - {147.00000190734863, 292} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 6 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 6 - - ID - 35 - Points - - {147.00000190734863, 204} - {147.00000190734863, 232} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 27 - - - - Class - LineGraphic - Head - - ID - 6 - Info - 2 - - ID - 34 - Points - - {60.000001907348633, 204} - {147.00000190734863, 232} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 31 - - ID - 33 - Points - - {60.000001907348633, 144} - {60.000001907348633, 177} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 28 - - - - Bounds - {{26.000001907348633, 177}, {68, 27}} - Class - ShapedGraphic - ID - 31 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Stream D} - VerticalPad - 0 - - - - Bounds - {{113.00000190734863, 177}, {68, 27}} - Class - ShapedGraphic - ID - 27 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Stream E} - VerticalPad - 0 - - - - Class - LineGraphic - Head - - ID - 27 - Info - 2 - - ID - 29 - Points - - {236.00000190734863, 144} - {147.00000190734863, 177} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 23 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 27 - Info - 2 - - ID - 28 - Points - - {60.000001907348633, 144} - {147.00000190734863, 177} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - Head - - ID - 23 - - ID - 26 - Points - - {236.00000190734863, 72} - {236.00000190734863, 108} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 22 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 23 - Info - 2 - - ID - 25 - Points - - {151.00000190734863, 72} - {236.00000190734863, 108} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 21 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 5 - Info - 2 - - ID - 24 - Points - - {151.00000190734863, 72} - {60.000003814697266, 108} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 21 - Info - 1 - - - - Bounds - {{191.00000190734863, 108}, {90, 36}} - Class - ShapedGraphic - ID - 23 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Diamond - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Job 2} - VerticalPad - 0 - - - - Bounds - {{202.00000190734863, 45}, {68, 27}} - Class - ShapedGraphic - ID - 22 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Stream C} - VerticalPad - 0 - - - - Bounds - {{117.00000190734863, 45}, {68, 27}} - Class - ShapedGraphic - ID - 21 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Stream B} - VerticalPad - 0 - - - - Class - LineGraphic - Head - - ID - 5 - - ID - 20 - Points - - {60.000001907348633, 72} - {60.000003814697266, 108} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 19 - Info - 1 - - - - Bounds - {{26.000001907348633, 45}, {68, 27}} - Class - ShapedGraphic - ID - 19 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Stream A} - VerticalPad - 0 - - - - Bounds - {{102.00000190734863, 232}, {90, 36}} - Class - ShapedGraphic - ID - 6 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Diamond - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Job B} - VerticalPad - 0 - - - - Bounds - {{15.000003814697266, 108}, {90, 36}} - Class - ShapedGraphic - ID - 5 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Diamond - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs22 \cf0 Job 1} - VerticalPad - 0 - - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2013-07-28 23:08:05 +0000 - Modifier - Jay Kreps - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612.00002479553223, 792} - - NSPrintReverseOrientation - - int - 0 - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{424, 6}, {711, 872}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{0, 0}, {576, 733}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 1 - - - - - diff --git a/docs/img/0.7.0/learn/documentation/introduction/dag.png b/docs/img/0.7.0/learn/documentation/introduction/dag.png deleted file mode 100644 index d0df7e3a66df2e254bc9c9e6fc7eff606ef27f82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34869 zcmd3O^P}9wJU&+vteRCZp7GC?HCI>|p;d#F% zTV0F^GlV*dsFkj9%z=?QKCx9(GPDiLi;5uvP&|MF9K{o4(38sprwnMx_yp0Io=obe zZ$2|c`d%(i(PT7lG&j#LlKTmrv=W}<`5PC{4Ex&b4lp_g?8izvzk?%Sm+oJFxbW08 zoQ;H5{)mI9IEt)|{no51)Zk9?LGAzJ#@ll{F6X){mz^S^Ix>5|QP_c=aDEn~U-8QK<_<2;{#tbZYc z=thIr0SWhn5*+xLH)YLM8*$`1{Buphc{y#Td2#L&iOfO$JXHD^f3W3`!6ci{SB)PB z30+wqf3DAx!*0y(m8T7)2eySdFZW=WZaOAW|9qH(To%G9=0&bI?fVyPJc9c;Nkv)X zjMiCai0@x~nLXx_G$c>;xNN*K!$;zF=UUAvrUlc9-cC&`%Fsb0oI4caXS53Qbl3s} z*%Z%@$OD+HqT&@B7X7^lb=^&cg&Ym~=;NCGn%QeS*x*?y1#UrHLp(4i@m%Ysrt@|2 zA)X-2Fb`56!WLDmZ_uO!&%TXvE&nKZ945BF_lKT&rD;#)_$cFaw1J=S`L_SPlb#Aq z^zSA9PR}i0L5iC<7eHOw*z~VHotpC-j$R>%n~a=6S`lcOAcwgUYp1gHdr}J$s@8<9 zKY`{rmZNXb@d!RFs)oan3OQ7OBWY~qw<@#fuf}&S^S(sI$kKoJUV7aA{OZx>`QSBA z?^A#8-)3*8a*qjw2eT4r-rG6X9@#>BjC^ZtTtwX^onB`imoFhS!G+aMuga zZhLJLb=+#IL#?Bp!>@LajzP>?+{FniI+WZ4oBEZzQ3z8E1@%**Hg+d@pFP?y*(Kjz zg%wER3U2*En>cN)Wja4$0RGq}GMHxT{~jr0(j-lV2;4z7{GPEvm4V-{yASac)41z| z9JSp!oLI-A!Fq-Z7ZAjUV zpx5~M{Zs0gKN8`bs~=aOFIzOkBSQRfq^xw=L_EY=Bih>dINB>JTi+IKDX_{{OKfd= z(J)|#%G76DT}nN2D*gP*w?1jwtp%e4=dG%J$`x+XTN$qd=S%hPNwd}Qutyut1w1tL zL-D+~LvN}rrz^utUcm!)wwytbI`u>JH-a%yLN`lW@&*%`8}kOap8M1F{f<+5BUoc| zNpd@NtUI-XhDC%J`H0s337m${XNMkq;EJS^xhOKV`Y~pUV}~>KM)i69xU zm`(ij^Udm4B=Q010RAl_nXZWM9l?t5N>-%mOyYa%*Lv_#_vNEw9?+W}!7JU7y;Z!o zk*WAd*QjdyXYgC0ozsb{_>ayLbw7XQOa(!C9q>p{^M~u)<0m6Y4b$*8yr24-0O>Ox z5>}C?Z%d<-==i}_hhC&~W!Z49%nJF4gu$%dsHhoQZjX{sY{2ia79}v|mC2-zoo7C@ zdF}iO`~4r$;|HrhN-*I8XB&T=y5YSC+tX-jK}l&$bXaesve=lD3r1-$Himp z$R3J;*_*oAK;WFlIftq0E*n8j%ZJUQm&>m%F2zMfGwT1OLa(jfU0=H_f6<76G)9=D zqUaV{v-Kw|p=fDkgDK4Oak#aIsoTuX_H}nJfF%htUIs01yh1jh%LGv0v8ko$wkWY+ zYp2y<^MQShd-#{=`jeX~NbO02P)-;h3=a7uT06C1JUhkn)bL$OAgin7l~ zc;vKy?(n6!owiKZFKvs*zdJ)8XGY>z#xMSZ7iw)jR;r)W|E@0$QK;|6x5E@Lc)lYU zh1G(E9U56To*BwU)YVtjn~ zbweHH@%yziHiUObNi9| zWDM<)4JX5WCP~&`$?!q;1KS~TD!LIO&IJa>FWPrcqB9|&jlajy=_u3`G0@Rv zQyI@zk1L`(-|cN%HAUPSdq;{PzG!c`de6P}|VWNjW*sBd7U1S*xJ)TbRZ zZUGVy1B!>_?^jABZ_Nb2KmX?$K>iQ_o%)Bsr)=VO0VX;T;&v2|!rxsa0wjX1!EJv5 zU_Y?Wz~A@ahd>A)N&8!~zkvRQA=oPL6CfmL{}-GHs6Fuc?|bm0{YJw&%3bxii{-@f z?YO`Hm$fCwsIL8r@0}eonj<$?x0l@fqv)_gDyX83Nx#wj=R~_LLYFLagvb99%-rt- z!mpO=&Z&UGrKHCBdcI3>JVCdS-2M}yrWQgTaP;M8*VU3PdnlpY<=dszyMTp8 z?t16mRZJP{>JLzSs%AvBe4w^oA%_R=OdjajXXngsGS2xEL_Bm?AMQleK`UDBVLiu| zCR=||0GR>Wv0PD%=q_sIr9ThkwrbG4c9f>=++K5|c9*-on;X^pXFEeYKeO%C_4~n8 z_?Ttbu(ABTPJ>aRb}(An`TObglXO-hY<1G=8GN9A0R{!4fwXr4tiV~_7vWt{(K?(C zQ(l?T%W+qpl0w4|i}cShUQV&N{KsyxgPW1COCO-mRB35}d-D?i%9DC#1)J2I_9RKg2h-!$}aCi%RLFM&gQ;zSUNk*NGhQ ztuUPZ##ZsoyEgx-WVL-u>eLq_Ce$XR=!&!#f>nk~bP+)x_ep`gDm`mMgX)QNw9L*`>Wm z-l1hmd5{<%tUS|TzyxN{(_NoaLuFqm;5F;4Z^6dIZDdH>t^ zuthpv&M_CM+u%EFIW>1S>-LbmA^#V?aga5&GhcG=vACL>$ci!U^r_zVo(oIgTFO;L zMMmvY@}<6SD`Vq6v)^J8)Y$VO!Wf*hrW48&A*O!Ebnc+$v5%V1IOuu z@xlVz=c@#c)xzz>N$S;yj+6UPlIfpEk?f1~4##du_l9=9B}k_ppT=nPfe6HTXp_Mbw!tw|4Hr!rkn~*~72)r)o4z(5@?PWZ+v&L5p!) z>UrkX&Uu)fMoesjJWZ~y2+xDn5(8~CI;+z4zKDy+9+7^u#+1n_|3>e#m-F`{evXOs z=(|=h4zfaV8*Z*e#?Qu3-hzk*$VOxij`^GfN3*#1#P7K%W?gx*EBMIHeHejqLS<%o zgSSO5d7^bD863Ydf{C9CVRz^B*=?kuv0=kK+TpKUj=nj>4F}Ui_W8l7EqrSW>35TE zxt=XbeUoDEAjdBdbn1}4lH?TlL-}YgyH8fL;`hOj^ZnfMm&5&5h=iWQjhT<64NKW; z*8}l(|YMj|D@&X^L>uJ^KE>LtMS@k zSmanZ@Emb4a;j&r_UBRv>A#jcGR-P4aAj~dWnBHVqNuCU@z)u1(m_&;UbkKYzD^$O z8>Rc0xwN(yT5g=rZp{xL+;i=l%v&S;|h*b z6WdE%b~y^(Xz zKqbL_!L3Vkd}C27j7jm$Soh3-s;Mw;Mh>Wg6;&VJB#mc=PDw!h_z|>qiKO5|oS}~< zaYJk^_qwlBqb6TOezJ@E{gfpEN%k_Wq8nfy=5A_>S^mDPKP(waL>0?`{~KIQp*Vc^ z_`4kf$AHtdC(+wj(EwOw*vy9*@3GyzI#pcBcP#h=X~#G_#s^~!!ufE_*@YV zis$=Sy&rJOcxB(DcERQ$K0xbUa7y76#tD0tIv3wPUSlMeNU{1%?#n(NVj-&*Ce3+Q zd$>4xE5u1o%vDJ!q+E(mPZzDEZ+P9wSmE4D>;BNnTeMB1cT%AFbjl=_t>x!q#W9L2JvGFg{rhv9K9}Yqje2X2{mf1P0w|wUX)~WBiDv}-x|Ua z{Gj>N{Mcs2hF#~O;8M$poX+=VPE%Atr&)dMW6Y1FLVc%5^H~1-^2k#?%+=<(o}HrZ z@XGqE&9LSJ(+#4V4buZbj}D`Ikj6mVVrJ{v7unn~e-u`cC-+7Be4(l)pUDyK;keX}_%hfGgrPyJ`tB zb~?{1`+R0hE3;s8kKna=iLVy0Xh69lROeBM>d~=96_kB7{hnc2?xgr;UZ}kst3k6NG_Mo8`rV5{?oo)XmRv^hbM&o{3k+v*@EiR+R?w)dmv2xYi&wBMzFf+SvP9vW;>hz!& zBH%;rB&yb&qjTxc!i{7vd4(#NA3Y7KA4rU<+thv8{MnZPOx^LatFGd4|~4Tq*=)Zh&?yX?efu!iTekz#ZJc zGmcig7WHT8bNqs4dhXK_(09}WRsv3?@GIWJt$@6Ew_EP7PidHFFKov+#&>${1SAc@ zXeix#rtP0&292%tcLr~Mc1w(9@Hv_BS;+9GYH!1%JkD?ATxb_0WKSpK@{f}NpYVOfp`FIAW#Wd5PtT@5ywI7Hl(<^VpezXDy;J-X`jv~>eeLp_ za7%0h>oP_3qokhOcna|96isnw(WLY{PXiAEi>QgH7NS_D*W+r>>bs~Y+$E#FP*U@I z9+Pt&G1C;uy7&*Bdz5;z<={p4vo{d%qH6H%0xn3D1bj?x_gs)o>VdI_cZI zYRf)LDgELar)JuibsnwwFodrz;aNpi?InlPz$v$73KQ0J8fC}%S2cxa92UtwwP^5V z@*-*7Pg@p6p5Elt1$L@?o8b#t1&ix4hi9r>&$y@eIg|HT#OW22IOogC^EIonWqrLr zk9=|OZ;OYp>2J~g0l8m4XLD~`JafyJCAyd{LHOO8Gu_)*F1QEs730x0TWzrDlV5@#GKRQT12e8owy4U`cP^~rhB?KUPQr7aL(I4K`l5j>o8$IH~-bJ zj`?MCV05yHwqc-=Z0W3;QC2!1D~#*6PnHkaCC`??vJpd)^>Cow>j$<}*qk@gHEiVC z=>2K@on%r>K?3io=%1>5Nhhb3KgJ8(Cd1EYc_gDoJv&)h)OJRmv#yCA2G%`LY0Nul z2zb=z&%eebe=K(>ZD&|EQd5o+j5>!AQ5+sqrvlif?3t*Bt0YfCbC3P->6468A?7GF z5fxT({)c@#KVEaj5l|b%aXLctVehcISi9=8JkcY1M08kX51VOdB&6Cu&H=mR@Oz*O zn$v;An$szx!p!Ng^CENX4!Ur#gQp7zn@cnB&z%2$2L8SWKj;)`!_EJvfd*mFnbExo z!VCQmxc`3sANU=F5#SC9fxiI%cHX4-2&6W*rsPjt+)L_ar;5=2l4o^VzTjAT=<7^% zkAw`>-)>oi7#tR3Tkg_@H`ycIS<~l_b`crAx#Pa`Bjkks+yo&HkEdALRBeumhoI+>H{#nn6>%VvyRF?M+A;J4W`4>qLXaZQ3ubl3(S+umba zdQ=(aHl9YAO3T?}kzb-XqV$o;-&K^P=`gdX+K5`d8porJM;bBA)q@@-bickGRM+9x z9n8{CUw=t>aio%x&C+y2%;!V`){@|aLWCF#Qwh$dLXsKy8^Hk=0vp`iO|bCl?aSGM z$9eeMmOk1bhKbkI=OFnO=POV{z0}202FgSPsX9Y;EuXKLbr&&)@J~VD`5I0oRi@7YQrwIKH#5}8It9g=x zEV=h3UVyji4PuO_W6wxGtZ-=<6{v%tjii4mSe2os_k}tD|Ng+&bxbra`am^ z)@#^6f)yy(K* z1tUx#Q=Q`dzI7%`)CxGwQ1-1#K)xBiiyetqbMM&Fq=x0_i{|KiQWGP4bM$k{uPIZ* z#@tZ_+v2_8G#q9cZztT|E5Snwi>f!hH6!)_aj!;J=W*AKe~zr7F|~>P2pdD+x|FBb ziUYJlYtd-y$uTA@sq3<7f`jCG zSgPU4Jpg5M(`=VnUe3>Jn&M&|GudX&Vb<&&#*Wf>l5}$lsFe6us`+5nVV)$&5?*Ag z%Pi>pAUIH3dHN1&kKw944rzA!-4~@kqeC`T)SEx~p_Kt@bAaif4+07#UJ6*wxp2(URjo zlh2d1k*&y^R2msWMn8?%dBW!Wfd@t>hTrj?wsw92 zwNk|W-Lf1y28I}uI6M4#LPJKFa>p8xWB2(?k-9a61v?oR5_t>M^o=vY5|^aS800}p z37#xe&Y8TI>hX8#-B}$y78N7*=XnNBy1yNrF@}))RmvL(U1JY_!1ELQIQbeIQy11T8U1TlCG#k8_A6 zMnve9S)hnZe9naI!Am4>7IX)Zc!l@`gTlod2UP7%JC}XmviW>O^dFbDJkgM*_!FO#*`%A7m6ibaNG1b zh}qiM5^n7i+Ucj2b61f0I5mr|Z|D6O#!d|5n_e`&-h%3s4ysydyAO0?k07b*>?KVj zR@eN$o<|)Sv8!K<963)r2)}WwuL&~iW7=Epd9fi9U+w*_w#c+P$7MhknfAcA%V=BazBR@yv6mBS~4GTti(0 zbuM2mlv);+`q&zIrZF_$i*NVNME~9vp{B%pp`p~&)Bw9Dnwm?vO0-PC$_-mhrsL(l z+Z$!^aNY`$zA>flX9ll-jF%E4i9*YC!2`e$)P?tCn*5YwNRdu4F|zuY3?w5likj&A zaJuML+ZKW>HNEgqXEVGExWlh3(h1FR`(wzhB}IrCG7nAWMYRfcsz#)= zBRBE4>f#V|Q)bt%iC<8kKn<;EQ>cP+GpLYxaaCr}HP+^$4z{#0=Bgd%YVwxHaG-=S z5Mk6%Ro=Fu!zluNkP7*nr8pSOU?~CI?PT&*It=Bt;_)qAy8OC3J*fA*1|bZLI=}tp zr8Gt)iFgDE*aeSEh2sHbp}A(ziBC?GvxWsbx+$;6UG*oSFq$t`kRa=gm2aJts&`?Q zdVpEAo^`e3GjSm%fHcy8)mc1mifZHAhf~qr*(rz0-?P3=V|IXo%R#a_txS=XJz5~b z94E-0=zDEyPel|E)SHuSA5nz!KJ z$1RiQy>5Hsh&--DOc85^J64VvF9s&nKw&HH%=R z3YSBSm}b4o0$9gk?V)nmAHx1sH*f2`J-kt7xBgYUQ3UL*Tstl>7G1mYO_=G3(i>-# z)E+LkB+16bW$L`%IG|W+QmS6d*?m*{bpIw!wqKdZBw48{1381|I-o!*nAA#~?Sz`- zjCj+QSUV>=T=HC(XMWm>qlB>7L%zebM<-%TGaLfgzeX7`F1Jf?0HR?+O_x<>Y9FYq zf*B=02$@yu@5On30ngG{*mL8&CQ(cW$77mN-rp0C4C6u+J| zM4ICi`}kO33b*q|?Qj*0Atn(rD^c3hI3+P+jC#z+OtBBdfV}2=^ijy0aWDwI*;Ak- zc9L!6Mwi`GUk~6Bycuy9m)Z@LJh+hS@)geiuE%#Uvf{?8yq`OvP|h7!eqL z7f@*HzUiX>OB>$=pjMgk7w-(=g$*1Ci9Eb%dC9B3{;5-69!NMAMkfz-$s7oRS1INb zB+m(fUbQ09+HmA5!7Y5l0+m$H(da6ve3)pN56&yxF*{~4CR;KQ#IgTiUyEo60tn4@-7Dhn?^AClh_^XdHmGveOc-9ZEvj`cEiqW;UInwv7g|6sM9# zT5AN9>0C6C5V!ubDwH?ar=7mCSkz zl<~($zi+OS`ScDv5QP}DRRRFjfNC5P-x+j3qDLBx;W8>FWZga?uo6$YaUX*sv3)f< znxGJ^g@x=QFX9+nVQCk;95my0e5{oj(^BDC?&2HW)#=_ zNC2&n);>o@tp|VsFPHV(T95f60DwX6h(X8@&R&oz4+po zqj9IM4Lxp5LM(DaN(EKnG3~g54*=?q<~wQ`i&xClkOG>WA+Q1xjrJiMAyE^)5&727 z3e0)0{XL8i8+~$p0U$0&$T$K<$HKN7BBeCG-wAp%LzYQ+VNQyp@_5Z^>in*5u{ceN zLsLlzUxuj)`*R@ZnWy??Ya}nB7I_ao#IW7^z*8uMclSl-b#l)g9~i92K{(9kDc7bz zp6(&701p6+QF?EQPwGrs`sdKBiKV!uDEF^oAX09M4Dd}+C3f**!co@cf0CZ+Y1{{| z4xO#u-3?)QqWOo6e}bVZ`amX}fatMd)rD{*dZFwQY0fz!P$oo*(hD?jV2s&&OLX%7 zKIlWQ-hpw;O#~aakf>IPLua^`Y?H%8B4jLz0uQS0$&JvdKck}of-txDjPXshIu62X z`Dq-!hDRz3Xc1A_)=TNad>jRs5=qCp9_>gaI0}pO0zh$3D>Q=Eo7duLHj$o#vUAQ0 z-5-behFSy|F!t7#-4PXe6TFV~jpu~qZjQLXs2rn)*p%8lBrdF>pZO!i5K5|V%pt#T zF@DFf&Rl3naeLbjX_xMJF5R5h(1Q20?@ z)q3+`79@+LwXfLS{taH);d*Pv?Pqma_kwTUy_B}D_846s=&iK}f(VrL#p{}^X@hC0 z+L##2&f5}oNPOrSieJ?H_$@Ap!r2FnnCczr)}QiwV`Kw1V3bkdVciY6pFsqgSf)i) zgctWCE<8BdmQhPD%^#rk~>gcR6=m5fb+1YTVB6M;wKWXO+L3LF?{C z5+8nGU_RldsW}Q4Sxy<65h#cph2R1TTy8hN-^GEvmIjyoBrx5lW3UA-Fif!R5`B_V z+Pkmv5VIql7U2du0Kjp7SIWK`d23mKm6X|GOKfs;tCF;~fu6xuzbT#OF{-G7noF)^!7M(Hie)ReOo2{B}>Cj&YqFzc9}5?zZN$0F(eRZSQ% zXp8{I>-i_VN|$+>iC6EQaN(OiuY?E?!K@vQmV3<8x5IPhEE%mT$EW~6b=_#QPCR)L z-^3%*{uUV+0<3mz1Vw}&UIEqcUMp4xqRwkK$EgjUo$>Ajv9(`MH0F0pul6d^%Qu;P%9?PfpauZSu z5JMHm$|s3;%>0VKhG(^+j+AshLK$aP$b7Tb#N@O=--w5A6Ph%UJkuDm#w%USq;&a7 zU^dDM#4A6ze0>{14%+W16Wk%__xR=)TTm_^rKt@yYQxRxm0nVk{VV~=`gGwM!W&eb zea3Q~ZG=e8LROCA4|hu;7#{+=CR|nSJk`HETWbHkAl^tyvz;Bi4hFInz^;()6 zuriYd^+L(;k=}bsiyR;|6zF&2#fss1_Q@8Z3vq&kxk))V$y7G8J3d9cm<$rNF-Vt_ zTCqDk%Nz#?vbXr$T57*q(}u1*PT9OSfm=+Zlj?9EzpGhFt1qzS^aGiUH6sZ16)zs! z6yH19_7^S<8im%DKi%$lrm2gI0>yXY=_W0d*`GAfC4O8at2>&y;C}-eZ8nYG@=U9k z5EHec;ux9pw2H&7XiN@HvHh8Pt$wI|GXY)f$DCBOMW!{^i|!Zn0H6gAPQq*r?|t=a zLp#MG6UnE{O4Gm%^fghANjWY`1*@Od3LDg7vvGl-)F(D6-<*uW1f#0zY@|80*=gJKiTj02no#FX(?ms3dfcCT(bDa7m<$9b}Zz{d>Eo zun%>3YX1k}xleNZQ3GEw%PmYAA>%mOlY!Q_LY)t#H9H)N_7sK8pU>-j3@vtd{v!ON7R^o z^OsbrXTs#Zf!8`pacm&`$MID&R@LV_8TUt=@_3_1)Pm7TLTR~~>jp_3&_Wo^tW!)LuJ zdc+7^+7d&a4&28J>dBt7tXr_#I8ume3S=hQs_Pmb2%hvS1I1HdfodEoFZpxaF!8Cp z0F{^tCPqLD!tr#{${uQ%$zZj5A$Wav^@$(o%E0fOxyCi8vLDAq`!!(nf+4~aI{+>J zV$GxEp7I~uDPu;zceKx11}p~_a6vYO=7QWHCd||U@<=hdgHT@PPDzQIJ77Mei@$~0 zwo4i~DM{ojDN&kY_H`Cv26q(SHFzOq<@{4xLrl7K%Qr&9N+;0>OpV%|*o0S|`T8D7~E~ zu8p1mKEcg_Y@MOr3+w0OCSu@461nwnKHcgL)TTXEc$|ZRb65THhGlUvpcKvi;PHE1 z^+RW)&a#jv)l~!ZPkqXo>$qqfdQSB;D>LLCoow^Yt+T|vK2J1M4$=eldH75&kl5EuF_jX)9HB|`m+bFJJmMSguGLUJ+*}?zI=5jFlVVjOz>U@x2Ft!yqY|OtE@Oqx$tmbn3y+ z#K36+4MVXtm*9-C=v(W@^5cS}09BF+lpMrMF;yLqpr!U-u=m?l8@^x406x zyx4UV`PSdIOZ|_%t^w)z%j!DIqgW;qZqz*#lZf0j*N;&GS9?wAu-o#p-F=8Ahorx5V=5yfUjb zg#iOYmZLyHg4cP7J>HzNK>j~C03urGDBwYazZm@Iuw1Jijb2eJGASdRHzEj)8=tBf z_srqcV}NnU5Ga1V>=WYo)6yUXPa)t{pj)pcc}}MbK@CmzK}}fgfMug{ZXKZIcEX$* zu3nhT2oM!@r71PilPN%PdX+1Boca=Gs}~@EXt0n9p@wH9@d89Zt|r7~c%Z<8gfJTc zSdAIhwVP45gCw;wa2wc@wBBm~DD%cG>zaAYBmfwMgRyTbU8*M?H^|;5y2pB%793(c z^e876pu&=xAR9i$2NdI=^{X%)T0lIBBct@26*NUS9?Br7x@vR)7D@sEUI`BfvhEXU z84zqvW7@O;17a<)SKN{gE3}3rIN4k&Hc!^^m2k9NM-wy=#zke?fGsb$>H#tXz7Kjz{jPod zsC0}C&VT;7$Me2w_3d;VvuK=g90Ou-32;9lTB@Fx%+bwOWyI+OZZjCLSl!1beL3LO zEd04?MRw7t7+5&L?)^4}gBbc_|Jf=n68;ivR}F0VrI4j3*0! zEuIs%y*xKF-(|cbnyn@M)Hk}XdJ^`@%<0Ue-O}qwaUqOOV+9(K11a& z{mo@sJdo-C3PF*6+;{*-OYtZRJakF=iPQQop{&rYi_`tVTtq9=q7Njf^A;z9I$EgQ z(b3W7`XuJs`-k}DPQYum#TfA3qU4t82O3QdCn@!_*57(CqKwL<1rvXnPN07z8x;Y?sIO zVDHhDPQy1>Wv@i&6nHzN%@tm zwZ?8_z=y0gz;{0jiNgD^cF_75hM51m zfC5yds(*cPh(cx@_gtm`-Bu3%4#>0Hx8i(Lbf{nD{a=sxCqUj_iHCiD!}Qw6{b`Xu z-^^nvdd!PO=~q8iFeaVHjh)S%FXW_{a1@}>_W^OnhiM#5R;V_&mC_V-H%i%KmmS#+ zxWl5wV<-;rMb&S*3$*Cs%5#uN35zV7q+rHbPQgE)6rf7}k@8Z~eZBZk2;vZ0Ap zSO~Pe`m=*H@7l%*+Gg!&^{&*8UKw$lmwD!3T|de{-D`JQF+IqI(Ab`E#zr1*#!s4vq@kgyijxc&{Bx2vAe28CuR)`tHnlEXad~&KI? z`5Z{t5YzSMhL)eAgNfdVIk1eU|1pwQFQk*cl8_yrcKI&v==*|KH;wZ-FWxwSjZ<;- z?wq!mgzS_DZ19gM#G40w*f>0k<%8vInw{~z)*L&_y}2Gh%7 z)h(ruM{dT+K5gJtBvk2N4K377-qhJNFI_A!OYk4C@cRUY&ATt_nQ*KwC$?W2p**^Y z(-$o2P{iL83qPHvPFTc$^(eJYW8Vz`FVTXY3@gfpHuh}ezpt?Mz$macA6ATilDp=S zTb5Q|v-d#YE>qay{Ws9y4^n4QH150tlj?Sul2M;H#|KP-<$0XZNp4h{8m)rhFDS6W zHUaPc=sO{}91X3rdNRFe#ua77?9}F&cHT9zgD!DglNrPSg8+}YPF=Wl%SpgP45P-A z-y}AQib+$du^aP92sm&JEQfK%*ojS2SD)e=OWUioDVvFpaQXfkY5HSWM}ohs z$NHBGSa2%p@}z&`WFxndU5;v{y_Kb&$1`;p#d{(4FnA--=cN=Aq2*yTgOLB-UFv>hQ}c9 zq>^`5s*4=>e`4i1t7VZh!x^j@7-G#QI9Xn9SCewE6?X0_vmL}4;QLEz2Z0uP2nG*@ zd?H2TtPpx(Yy6f|r1O9z9tL-DjCr+kMp;7JI_=U|obAE^-s9Qo`b{cS+uA+tP28f#w>nd(Es`fP^shO3kB%M+8R zRsS-yaKrgT9&OQb(!rnUhHp72v#siOu6%IEAgv~rqeU2 zugos+<4cd5gX}7887#udyZR7o2k_>rTlba26#f->$%_f6xOu~jLjzg?re-*4K0-4q z+#;~(D*BS`ln3t5)(F3QN8wb((Lv2S;~Rl=ZR$mom>*5@|0pYWNGE3gBX{`?%}g1| zUV7BE{C>(HJ})nC04(XKi?(_T2@yoRG%LH?V1^U1Md^>M{MviFAk1>%ozS`)5CJkUsRf|5vxttVQ^r3BN)jY#bP+`+Icv z{r=9krh{QMMN`wP7Shg{6P?t9Ph~B++S~)JLOY$?Q_qCYf)>9$@DTbXC`4^Hs7jwi znhBquGS@!Qq5Uf@*v9+Q@il7;Z2sni@nD-3P1FtG}!4R&@faQ zV3*_7Zko0$ji_EI7%PIIby6=%HP0H)9PSou@%CZ{)J|vke3j5Gy(jBsnNjG(lwqoo z!Rm^tps&FXfUyFESfv6~SgL?PIZbwEvv;3vEzgs#*tbjvcYLC%yC9VB17gDd!1}xa z{?WU_@u;2%p|4K;*R({aj2?&0`W|gQ^B}O~!Vlc6>I!MxX_iiw^Y@wNd^@#Y^M=x6 zwP7_kQkldi$^#TSl-S5L%;Mf&oCFD`+G8y8$?g#uk27d;Ng zbO{G#kBwdoD5QdCec0kb849ZsHL+(jRfSo3;RtjAfW1=wt8}I@qGD)HZOz33Z41W- z;kQ?(E9AZd3XCi)*wV+)2Nne}vE>D$8}ORzCGw~~B10+LvlBBcblYZrttjgVdOL9s zTV!P;zyttVSQOt&`})$O?|e{(>45VsY%KgZ&|N}ZUCWcYnewUz{kQ7Pw{>)O-kJPh zzlFUO5d3fP>-kvKMsF=W?nML+zh341W;?k&lgxg<@QcVrBh8?7n(skSG8X2){0hLD z)(X=!X-g1QOEmvhqzqJ?UUa+VD9x0KNx^X=H{{y+PD|kEuPl5cY(*A2Z0|^?*OZcv z`1=eL%YS+4ax{#p4fjM%q~hC@aDJvlfrT#tJMdQ_Ca{O|xY!!Y;(a{PkCilaYcZ4# z9WEcX&R0A|B+lStHDxRF<>Rcjo13t{?*DE8UUwe`Ea*Ot%K=f_G8!%+;AZ%@R{~a&q19>!t_0mbaH$6GJKuqU zXLo-qabSVx;IaCYX*UxNm9m>H9-DTBlA`#(XcRQ#!#t);S?$+rp15!+G~iWA)P#Bt zbc+e_{0Ho5vQ>w}1f_U}U>;0hLxZhvG{&6NKGZW{Q)CiP(n>|6uoD1l41ZsVn!qjz zto0@+@J5TLZsugtg-0Qja$sVk%V1@14obNdf9S)Gzs@fDO`P@Io{;~iuBFKmRHC5` zJqST#iUMOAel({fP3g94j6{jkvx6K13^8PJvSuDMU`wnOAHXM^a#n9~QxPq4PnEa)T7uSx9!( zq*+GDA=vwh02w(j633VxvHG{3!$Me$C{nQvH(2ms>jHtWEM>WcM{hu;9}7@2@EE#!AzX0mUzU)UAK727zb` zwnNi23K`7}slV&iIi~%^{FZDSFe=7PF2Df5i9!VxXclWiMoSRPye1=3jW9*H=HMK!Q~B=AUtI zPL*AqD5Bq!HtVFQ6CWA0i4N&?brFLEx}>*{w1e{p`V=T0r)U~oG{m6G0jTXCb&C25 z&295^1lQ2D>uhk8S#bc_{}fksyos}OcNzU;jC`r_wN_$W?MIjB(CShiA*c$8NLb$6 zpd29RX0A1by=#s&?cNvI7R=$)pe~kjM(o4f7hmyo57RVeh2q3y3HiseGRU*gk#bRX|-DYQ1TnxQ=*LHwI%HqZO0g^gEa@hfIDV%n4+%IMu}Zm+YcjwMdtMOyj1#&mE$u6?IQ6*3mD~Ouy8gbYwv#PYi=}Q~Hluf9Yj= zOcR*(k(BEH?i3xG=+eRxC%6gMe9Qt4wM2`n!WfK-hdOS9!$q|y!O^>U5jiCs&@G$F z;C~^~)oA`C3&%Bk30~v7Thjyz1btIlC4tHOwa=dkN84Pi?iaJC+}0)Vsk2>eMb#qW zpkqsw^i#u^K|N(B{!LWUT z4h+1A0RHC>b_r^w#u+59HL5yMkHP6Nz@`B2aq?JyBLRF=_RuY9k+SV9w`Q)5KD*y; zufzMVPLlCnTENniL)mrK;^+|eH;Rc;?hqSr(hBt(=5vC8VAtscFHghWpWf`}G`-6hH{R*x3FuEi=r^cK{(`K<~?)g-aB{ZzE({{%$1-@n$%L=?rZ@S5jv;JV=vgppm(eAfl7z9 zYj%9+0L=W`g3wQQJXr6b*`?=qRL1L^h#sy#fVKbu7$Gb#g<$QFt%=B2U_GRs3~*@C zxCE^V1DUl(iJP69wZe(SCD@~=#6m-xet;SKc`{?U%;EMFBqF3N_udV|ibN$l7480@ zhBcb|=E^u2{Z0f)^`jR@a?gctIwdR`cw&^a6Hxp%OzCK9K4FBV9IeMIsk-~1UmwpU zEU%j0NmJJ_Cl@UnToUg(0y2)xpGbOp&643%cteL^EDLEb(UNJA==IHM!)+y0sc|9}q$!J)pf;S2K~i z4i+X<^=GtIt*p7_@fJeRnuF_$Ut5@WM!Vc7s9z+UuKJIG(gQ8Jbs7(7(y@r(bR_w* z1wksup^gDLi4#Fr5h}~8H_1VmJfyo9a5sO6eQQ?zH+@AW*qL(eJ^VEx&Rw8fY)H+ z5jh=SvhVE@ED97PU%Tyv)c8tH=AET9aQ|gJjJBWkbqEFmy7i6d;W_8$FG8BsZSo*M02h< z>ZehNS?@Cr|HPJSyKKThZMmX{^SWn*o)bM1HaXRou?==zxvM5(T%86?k54Bb@w)6| z*Ljm4cEX4SptNdl1GR8Vg(0jc^OudXHB`+qJdN!I;Vjn8dYzu@Rm^0RM%szZQYEvc zz&o^tCPD91u3-hEA+w-4 z6vOsCkdMLRRqKP3mGzCxVCp<^;93vO@RL~acRRo|YleHEymk6whA3zrG&-w^pn*#U z4t*2tQ0guEAsN?QoAey57u9A2CV>N4*F6x7exFYK$rTtkxe$W2=ZJ0OsMw^8nWq30 zri%7KEJAB*|1iD7^cztg8Sdfh+oYh7Dp#JuOEp$fMj;U>r`oA=hDcDe1kTwJAJOw1 zboms$nD>cJO_3fD)a$7=PfOy)8ZA>Se`o_5JA_-z__|VO3zRz1%BO?K zIG}gI!X@&Uh3k{Cr4TYBny|R{<)Jjg1~M;SVX}r^FrDi;F-&L;uA;?T0N6Z;w}{Wz~?4=b(xC1QU^gO2F9( z;TN@(R>wRTFijIJo^S4DyJ0y%>g5p7UIOMuXL3;9!7@gACXt%>t8Yx+hUDQ zR&}8O?pvc0S@(NHp|{gOgy9+$LJ>>`(Q{@bJu0VmO#^F>knWHhmwd~-+&nYk)t?H2%rPCnY5XLk+ zdmEfGw_K}iHiq)1;)d2>GeseaeF%^r!1-0rez`Be@L~sd*QSdS0?=M@UhF>x5{VVik-b?@j(O_Mi~LqlE1$f6fOIwD^#)+y|%7g}5jXczU&^w4u8PE5kSwsuw`2KiI|6CRV zxZXAQtRV&am}d7UX(m2i zx}&4-=}Z)Sfa7JvNwQVS{V`^7Nv-5$EtcdzR`tum5=Uqh>ac<% z)_DN-QD|bib+Bo%f{YT=pFfHoD62+&5=uGQ#;gsw4(v4pCcM^W&v*QTjPud=t8G1Gw z;NbCR8NU#!3j<-jn!-oRGHv7(n2p1)=yqke1zEhdR*qc&Q^NgzxFrgWKGYF`Kj?tj z%3g`W1@Ht~?k;T`nX@H;YjU-^B_vrj<>kBOAoBS6o{^$1-d+Z^(pDGiV@&G*7ar?2 z|NWYI#a0!)_`R2tzuO61w1+v_ z3uU&(I1sYy8gFqjj+x$Vs6IaE%HY`piCpIi>0!Tj*u_QjI1^ulDDW zmhM|&NNL)N2scGhb%>?*TT9f_)T1_mKZg+2;t0z25Xw<-5i>2YXQ3H0GZT+HNS+nN z8M4v5ShNi9dzQHLmkuq(YQMgF$ONber5fi06r0PO$L2PaD#}A70jEjeJx^|RzP_Tw-bL-yMfG#K^@OtIE*Sv*eXlHznOu*-` z7Ex^Sw;jVxPL-8%**VPLh2QmB$=TI1_QN71Mga`N_tmmH_J^-6PQ5Ike|GlmT{Sh? zb(w-J3i2fET$1*0^uur8Ek&OuZwV!l5NWXfj!@!_ac0h|As;&Bl<6QJwW1&1ktKXo zD_d$2gqIpwtU(fTy$vMFK2+mk2O#?K_wW$CA`=(5bUd%)e09M!{He=&32qtv(2Z4V zao5XWi~Sbt*X7~Pl5AmEUnGGI6>JM}CH1oejIm(wP#|9vRngc?Vy4#7k^JMhK;T6} zI6F+DPsD9OHc5(-x!)JijyisTJR-7&?5;V_mKUA04~v^}^(Mr=fSeQ}CzJ0&_G`N! zA@LE^x8FiC$i4L_@q3b$GR!$O!jD9pY6zcvv1 zcZX63+g&{f*AB9?NONlt$)cjTck$jvpYa7_d^sm(4W^>(of(xaoOi`GSw`V4S3&9h z36kvU@Nr2yh^Mx71waBGa>(#C{!?cwEFRWiR~!}6haimDKhLLaH*EAba#e;}ijWbB z_x(tjGCcBmIH)=+Ycs$mJj0LyYEhgA6E(1f`akE-SbhS{QM2`8&rLh1Oq{(y$QBjn z{WobWPoa3}#s>dTTp^|#q472#>U0c69r#(ruSk_|2mk6Rkhx;NsYjrTp>X4ARH3<1 zYL;$@sny|O{G~y@Fs=||d&gg}D@gr_PBP0^74nOsi9rWvd^#K*9UT1mT&w-9ng*gC z2235Y=`oz>^6hRFYDNW+f=CYc2l^!S$krx)IYT!qNz|USgO~`=s~FqA_|0RjE27DM zVMA5*ux*m#kU6;yv^iwIC2GA>vKK(p0*X32Eo1#Vbz@ot^=)d#XeHRjFR|pjwzpqy zKI}9oUqTw{Jd8>#nkJBPKJ-Caoe5;9?-IR;cyz$$o}RVwuX?6L8y%rAh>J=as|^G$ zVhap0kUt`3dJ1l_J_IJve%wm}lmGm6I&Fi;D30zV!-7} zF76f*0Rg!S*$rsR!|Y!mU$H#7?am_5AHT?B85QkstKr% ztRrMwzjPIW-{97;L*ZVmR@hZB9150oUh}F5J@>f8vTMISH9HIyN&=eaZqF*U>+~gzZ^aB| z@ij=Nj7uZ$M%-K`U@6PyCRH+RmE{tyG9>vBv>hP{v$I3+P`wvcC892C#h#i5())lY z=DwSsnP*P;S_8#DmZ^OCXQTrH^@wqJe9kcQb$-d(`{HkcS{!2}Mv*0x!Cl9ZXzGl1NxQw~E$8zX!Fst50ic!2^7;yn8$X92zX0-DG?<;wI`}fFg z66$k?jU}?;={;Us-`3dm`}?gdx_|d`C|f!u;)qV*;IcqZ(gjB^l_`Ld6EYKZ#p;2 zwqp{oA-RhlwP~Cq_*jS4tU23R+w=hrL%?Rg8w+R6+|Jl5A*3R&9nN`(((WZ5VUOFc zxbB`=%}S^u0dk0NK6i1K(bAf|d_T!HGmhVwd}J!?#$HVy(|p2yjjOWDa}Jj9RU(Z( zszX&5!-_K>AGd58ZP1Hy_O31n3U$2QaoOL?%T_!hD`)L1H8bfq->B@Bu}N1ort6yv z`q${c@;eB8`o-nIg(ihFQF(B2++`h^S=652`Qw=7el^*v-?wi|cY*x$tFjlw_10$B z)iy1hIh#gBXm)ltS)1VIv9Vb+IiAn_htX}C=L}yij4WPb8kwklkO_+?CM%WJ*%R$t zzP|ZDETr=~{>2lc#!?1Jd(GI)ua-CVpd0#R zTvM`r+hohX9(SMWzGx*)T$R|vT}tzfjN`M$s*StA7t|Lg z8GniB$>MC4V|_cY+gLpa%2wa4udC$cs*#Gh{J$RZgN?gI#_#Q7~f_^ zD$QP7i5z)u8D*$##Inqc5wtF;&8cEpK3MG1igc@TsH7!X?TGnj^J-FzH30PYNL zEJ{z-5+!Nx3~4IEf0M<3B@q6?I+b>szZJ_VT!^rGEsCE+; zv393OK-LW#{NXib_LN3ILU{t?x$Wl^twKI$Q1rMiye3k2{He-FS;Nx<(NSA=Y?#fo zifmtNz=4&1l}cZQW=Vu&Nw)III#nG~Wq{gS^b90;Qa<;!127`}yHB{CJfiztI14oSqY>a^|Yr&XQCUA@4o zMNKhc}<|Za8u~4N>?xR-X)GV3^$EGIp7YB26#zH5>9r z4oZJpZ5bOW-J9`TE%ivOTC74q59Np(xVI6o{yOaLq=PGgu`-UXZC%V)!KQWj%Po7xBJegQcWbP%N zT>HL$`@S3g0`~H)TymIx$6YzPQ`M{lbuw610CR!jvb@S@4z}Je8RkTqA3#@2f;AXm zbbrd~-=K!$xZjBsI=sfxyUy>9w3-SAa#B%9gfcjLxcN9+$C~~OD4N=)=AWs zOuYWp9rdn?wZ*T$uUjvs!m>8}=#Q5 z`*_M~^wHj`LSuNi9`r4i)kkl-j9*EPNP}PQ6XQhXHV2*&;SP}gI{sK`c2}8NO}?Du%?$a94eHEuxv~RT0Hi zo1)kG^2qL4#nZ)ZIXoFZ@JvJWIi`gZ8FV*uiJ4{!^@Q*C+)GiqPQ5j?ag{cT{pGZj zmI+N^vQm;~#}M;w_GT4$@E)GgCYbybx3|J2_#1QFs8$!fadW=#N$XCuOS9&0a*V;R zY0f;~zU`^dYseoJ5+dUtuX_VF!b8kLjPjBBMGWAc6ET01kX=-a6f(HLH(DF3Ps?df z*T1@Oz(5x zG*YoEGnJjDmNSw0&bF^J_X}oc!n!*$kh2NtyJRDOWAs7RgHyb~rJ`;XBhq2xm=2$-K2HmaERhGeOu~)`V0BK2I;U?! z2)ibFAm>B`6wb+;kpDmBM3-yl1fH<4R$4T#%vJdTvS$~|IsJFiAb>M>S%cy2h8e*# zJ|XxJJx~x6kln?${A#J*L7cZ9m;iel%6-#F=A=Q{JF`w#a;?H zy#&{iWVLc_=GRu^>Lr;!bw_hEMO!M+AOd#WcdDZ6VP|K!lDgAWBLQ)H0__2Luq^cA zXQTZ$Lw_oN=(~O)L&GW)uJUFUsRBYxsT+4-co>+B(W!KJxJe za2O}S&Q9R#u%Cp+09rPJ5cE2pYczIJXd-}0pLf8LWu|E6J3U2Jyg54nY#RV~2v(@& z1h&H@MS$%@*y(ST`t5CiTMntY9jwoF)aTqZ@fRSy((LxyVtpmV=` zWnJB=T89#aEL!J9nk_-tt&Xt!=c!&Cn`_!2aCZ`&(8PdYw3(}y&cS@~Z0;;vtyo`Q zKcIU+hJ}E-A$sNQZgLXwuv-AMW0FyvL9%CYDu@cDLZNtndjG0Z6i>SI2Vqo$gf27( zRdS%VvwfhDueuJ9wxlbb0JSWtw~LeV`^GC)c|MR^z=u;{ox2Zos_7A&)->-=Z$2+&FdWb*_p>$ zT768wNO#$Xk1_cI&rVU4-fp`tFmR!V2jJ_o^??6>%!VABUsXC8%d{uV^!9Q+T?C){ z@)$x1X{MHPZy7p)JDc8d37MEKvW_q>E(BquK&MJ|5Z0OPkdkHWx>Ud%v7q!Za8?oc zN7Gmyq*-ua)BPUAi;iBHznEgp={%*$Q$uJOB&vCDkk|u)kfReg6$M-KIkF7= zi=sKEABA}CX8xAkXVReyPf9wJ+&J>?Pt1Tisc}5WCBO~tL&V1qumPGe*qD4A41Bgf z0sLh%Rk?EBo5rR>k46QYC6Lr*5K1X|$;99N-&P)Oa^@*Ko2Xz`VJ2p#|5>2drw=_Q z>)?vE%$?!oy-XlLfmqg5Z3Fby+rRC-oo1Dq#^X!<5EGO)gVz3Z4s;p~N1268&;9Z&E8Q6HyN zoDCw0gfGn?`gq=cP0y@^*SYoM>X5`ILG{R@FF2zBg+GCpwv_O`Cwnpw-3Y9|I$X?O z#c1(X+r%G)!4*?YUB}vWl9Q6z2=pHMr`>T{#r+d*!zBa9mpZsoEIa1rb{qjr2Y8w^ za&Cg*OOYNrU>pi!J~J+_>r@4kjk~Q6934CQt(If>{B=@Z7yTfRs((dokFpS$$W0L{ z`x^|$-Mzi&vF_S4Y0QM)CxNxDWy5V|4Joojp-`#TFb99|EfFA*(6^-OVaLVu3ix!| zk#rXqiIze^G4F0GDCfNU_Oq0PRg|dWzQzzLS4*L397VzT>Rorf_ZI6T4 zZ1z;;I@MFKJddf4$LWR*_|Cq{qri~$A_fMIYpN;&3*kK5B-NIdUF}~IX?J@eazZ8~ zL63=4b{-3|(}c&r`g;Y|q^m4gRe14XnFa|eB;@(S)vqzet;1WlB-(Tc5ms#Mz|_S5+0#)dzC?xEwZ zcxb1glfc{jE61G+OH2M46%~6Gua`X_sGRLap2z;URUV>GgJ#5+XU|*G#v;V-)6S+s z+}%BnUGBB)Zg+O(%SKpc2oHoEkFMlz*>wbAvol!!rZk=t_@cwyFFV{uLe1eCx#t1V z(Qz|J4Hr*u9;IOW@Y}KZ`73V^I*Eyz6kNN)kPnK(lp8C}f&`Nod5$8`&CZdDVl~~V zJLATeF;wm2dLBC|U{#TVFYY0dr~BvEt8Vb8>#ktsoc#LV{xjj<)t%Jz@9IvP`LDMA zqkpm!diU>|PP+bIHT@5J{T35=(^n{)m{Ki0GCZOvu&!8^T@> z*#)zJc)URA=3dl)-MDY!2C1?0OtpIo!##)ZhypSLH+hkF`KJdfcQ`)vQIeO4+=aJ= zAAh`4k4u_dCnEZuEV;-LS%~b0+@()}$E1hrD*Yj3DAw|M+*W`?6Bw!Ji(?mqaFhVA z^y(|Ao}k=FB9^EAOu>+LOE&{QcM}m2wSg#nHvHlwas8PoOM5dEIVd zspz;!QE?t8_b4fVYZCC5=-CfS-(hm{dHksVUY}<9YDB~ z8F@yZAu^F4)HkTHb~iR2$9a2u`;T)OsDX4d>6uUFy~3Shw+gnax2xvy<40Tlw`o@e z!PAg#U&EcL;3C&wl#rA>hOp&FN&Wq~0rEanW;;`o$9&g2=5=cJup6PAUmoAL8~mJ(tOYGQXH9W%^5;SbV&*oAoa6O2kaB8oc`;FPgX5~wS{k_i*|TTouP8CE z!3=*6f4~kSXe~uMR00X*INnfVFc?VVVb0UkF%hRmlBi6)iIvr??81)${_r%nvWaFO z9z@hX2Gqf2_+usTGiLf-(5cZ2Sx+UowCZNM7>MW;{Cz46V#FXr@=~)Of5lRf^l)X( zqT%Wu)NpXm86r#}dOC$s2BPGK1r1y}ZxDOvRV7xh-^O9hBk@>mYG2=5c8aBql1*!c zw2|vBh-(FXhK*B~EJfR(3WT9PRwsQLz0U&DF)E04T-n>@2RmO_yDjS0Cr8^3B|2BK z+8&C@)WpUPGgMfP-e&87#Uv0!+~io5be-rjZZNDC1+o)FIz4Ej-K;dB(i62*hFDDP zX69FP%s^^Cr2I=hxe-A-F1@{I>R)4DJakr$zF)syzvT#F#OS4}V2#?i6DLtMVJoAL;zmO&?CeR_P(t zL(s%WLJX-hbY~lFhH{s$>RnZU_Zfw_bA(EammOQHy*C2ZY{Cu%0Lh>QQKx&P6qvp zOl^=Z(Uui>!rHctk^ISk&||pbo`}l@NI7TQeobHe`(m|2v@@4nH!h?ZhHa8|D3xZ| zckfDk)N!|3$qQl^lJJbsJ=x&=#ey1{6d{Wz43#S)pKp;FhR0Nu`WJ90aH}6uMvEFi zk8+xvg903d`ZZYz4dJ}x%LG{W& z`J#WosEgRB%3Wap{_LrfW@dSLPXyCtOS&&TUIkgpC8ed?*cadY4*D;OgcQ;UFlw|j zn$BVP7+@hitvzmmRjxP1=FthEzhwlQJJAiZs+P8vrEH(m9AZsyb+;DWn*k? zyw|J3KV4@#)f74J+{~hLzCa9Gay^kAZuDAtaXBu0G055mGD?qPOci%4wV`lYe0vdQ z@jB}0iqtBy(VpLNZ8JACj_+g$@84KjT52y4cH3VrolWOn7_v%L;|B>ndsLpzqu&xU zedkDT7RErNA2)qBC?D><{V;ABr!(Nk=bvxiI7?UJ*}kc^q7#x&3dy-w-W4;s_%!m5 z*LX$3^d*lQ&q#ypURBfgmkdmJhn@$xRH@Vh2 zE6{6eo1*WLS^`|3#JnzMTMYQ5{KN*u;c8uX zh(`{-x@Yr2a?D5sAyq4CP5vufe6OT*x0xrqbh9L}c!GxdRr~3(qIGLB3}IM-w)w+l zyFSw~-*JEZvwEt`A@)TVO?pb>8`;%bkF`d+9AHSNmuGx(3Elnlo%#n4vmY-jXFkpi zWJFOgRkjiYw3m?6l_Kfk;N7dtS=CGbW70XE7YbqfIpbM=^0}YXKMbutI$-9rrIT!z zkZ5~+ybMU;^6CyNHsP<{F+1AzM7)?A=@T~+B1}2Q-#1RCUQLS))K67$Na+2%U)a3! z=g+tPqKUkvzEyMsEDwPXoNt7O@%Vt)Yk11puGCZ+klR#n*R?TkD45Pjcbv~JFM*06 zp`lVYB5aj-9c*p)Z5gV~P%t3$=2S-fRU4Y#Gl^F5b&Jg{-ELVA2rK)CI;lDLuhy4s zru`rv?0qVpv26i&D_Tl(+^+tS&)TWsy^KGz`tt{lZBbs!d!>9fyL8Okc5l!;dYW6W zo+Q7lgJ8c(Usz`?I`OlenvxYh^f{{AsBqHN$Be@bsV`gadXeuok@Ge;#=)@*os;gi zSE1ymwL2B$=@}+r4fUksux*=Xc+giBe_;-{@O@ibTLITnYlL%C=+2%x2TFH;^v^5X z)9@Hp`+8xVCVuS2eP^mP_{YGhciFUlylXKSMkAmmeCjedeNNTtMqKC;Y+9eCMLX4$lfrpzGISFMv$COgRSdYDwHHk)ZF3QgCK!| z=+me3VHYQ=LWs9QHyeHIvQPe`&dc$pM)aD%%4En*o0OgD(mg6Kv&zdSC= ztcWyX^y^o2mcW?SYl64hyI>YmCJLVirJ2hHZYx-ob1(o{%ab@vix2euVbO->ww8E?I)th!6%+N zW|B9EhzjIH;fc!20lReYL;c0@&?83kLSx%!YyM)*1t9fAtb~V89w$Y(r}0DsyUe6#E6~7fZE|8>?29RfSn)WZZ2$K=7%-xSw3<&b#ny&`|q;xqt&r*zEt8C+AU#DtUvX`lMOWfJ{=KQL=hriy=OtVFoOjh@GNy`Qx z#;U8Ik(BU!wqHyZnQvK|l8hbZf+EUTDpJobIx>B+68}P|yY`%urzW%xlLbNwPF7a9 zV|!Z5>=f50-dhpme>Ge;n+u*69B-g?}aP8RZnBPmSd4IGd>#-C&ytAP) zUw`~}@xaG#ZDqd~8qcS4+|23FSwBKj%&*=hwm2e{=JuS6w_bM(mEg0-ahP3EFx2?(+}p(9`~LS1TNhCCA;wi@ zUBp;VopZJP1>ORef^~d7{aJrTc~5;b)oIR?uHxSU!4laZD~L;xgg4tcJWJ#DzLFVX zTg?2@%xBaM3+w8O49tXABwdIN+$CSv{;K;-LYH{Jnk#6k)c?3xBZ{ zJG;zhTh#oVwJ*{q#P{wqLRCrmu|yMC-&iKy8jJFBJHF&uC95-D2Pk52 zYLZ5)#>9tob(7W@Ke!2TF|)Ax^JTwJ4T@IVc`q8XcNAj$n>&C_&&hCaMUQUU6s31L zT-fQ6QsZC}z10*I+sx*_w*Sm8EL~mQ{ZWM%6-BCb4}zz?Zjs3?pm3M&OUGWoSx;WE z8q+5!1Y$9Z$;0l)=x;alg$sPHQ9p?|ICa0X)#S~E_@D=#?mYEww(+74B_$2&T`a!2 zwL1;}iws?rT1RACHJD)q^9AGkJKYXlG;LeD0#|>3b^lUe29gFivcVTt9e%ve7HfQo zyOZOh{C??Vgn`J?J7E_WzU1Vsn&pPI!T6txoQ@J&^GgR7ql<32Kns5QG^wxU1@$nU ztzG?Gb}%NoYb!dk``r}HUgS8fX2liPiXk{HNtO53DXsu{r2^2cf(nvk1y`t9R_`v( z3~J`85)m$*x{!KU){@)_{MPYQ?05`^n$=`4F;F_My4hXTzT1adT(&KE9&ZtlnyPz+ z32ANlQb#GPNP0-6FVXtbOSX?24rgVih=^cUVR@)uVBiloaEq zFer5nCrXj~c1!j!Nxo^*_aifNZep6);+4B*=4Sdy|^*4;y+4y+Hd_FR@ zLV7%jo?A?B&YH0)18hc*uR*U>ZoX_r-u8-{)n#|k~ zAZ!_6Svu6;ci+ZM)Am>4H&T|K0h!KdmVJrC{U~kt5yFxK#c`87JYb!>q5}TZGX3v# z(=3~uuzyoIo8kL0^wJlCPAIUU2nNp78$Qu&Z?pB{UD`(L;VYxm=Ij9Q$BGk*5QVR- zd|8g=cskZAY17*T^dfXZJMSGCqYosxZ+*P?{f7;ghZwE;75_4i4F|}x za+n9NCSO9fy`J%miai~rCO}-e-bJ_e;bKpIqgCIDFZ}_sPYOkIQ=g0s4qIoj&3IEs26X3f%nA1Fc8BRr6 z9?oopdyFSU*AtXz&E{*)zEqh~Lu-0dd*8jRgP?|6$g|Tw8c(H2CZAOQ&{4AR^R-pT zTQ;xfm_JQjXbR&i%nk=5%knyqwbh&ni%V`wbtI1}u1u3*)1=h0rgd32k~93z<_OI&NdGeds$Znp$*TZz&a zHS#&{$tJtI>8!UnsfHyZEgL^QeD@Cj@B#c-AJN}18=OC?kZ`h#xQzLWv6wINy(zW) zRV$=wwDur)cUfJ0Sv6f{?sRk%C9lX#Aza>8jpAzdby;tBesQjIn61q}+S#n=^lKc% zMjQJwmxe~u1(H~#ICRvo(sa!SHs7b*_nnk+j#_%nmQ=dv zj|{{Uf2*+pb?TT?iVY zTXjwaO7g%?`&`3IxP_nJi#j)XLg4vTw7=| zOiq?3)GfYE{xWonw9zkPa=$50M+!H{$6y>Da>KdCn)PZljd3(K|D{0^GVP+_sffHw zw)r@bS$%WoA!+EMTjOR<(x^w7u;KJnLwrNid6rE|sU-V}a1+`ack*P2;zzF~SE;W_ zw|>9p*>$LfFAMPB%^O{z#@*nqp_R3rGLH`w>8y_AaBb|OJ>yb#I)fa8VLEmN;qGgN zjQ#Yr9Bf-5zM?Rmbhr$WXuhuKy_s(XFQ>U6*{xlE7MsJq!Eo%O;9Kn?)ln9g!&1|S z{90!jqDOa7;t3t2*dgc2f<8is{kp4KcNh^Z^unzdji~a4E^*N>j*QB4FtjK?qsi?@ zXQPYGD4EBl!-vS8>lH={pwBA43txU^VPZ#%(HAAZn`%|e8#hh+`f>VAa18!O`JvqN z`ks*dz2$i1KkKamO|1CmZoRUfRo#a-`Ie^H1|JxeMI9Q$Y07sDros&D9`T$tD+WYR zmGNp)!%o+WCu*RA<455_|5C=!NVu^@>5o185OYdH=T7cw+R<}Rq-z`s7^Dg}J|4FF z)mCdPzbQN?ChjJilf*GNW%By1b zI=~>0Lt-bfpK~&>u zWV(Hs0Cn`UkTTs(Sfyi$JO3)1{b*aUfwFTIl2kVm&t?uc^^u zBY5e~l@hb8+ymb?DRVI0fN@f;&F%2GVxb3=be0)rjXX)l4fd1!4SI#v7udKBre_x` z*qdN@f`=9$lb=e%ZBp1FutFCQz5j8xbAdmP=by2?&=96mj{RPEv%P^!6aME~-M6DH z3y=D$;QVi5DiF4%m?{H09(iN0z~6ge#Rh9AQv0=Sk1t;Fz+MyNg~gMGg~+_kWJp{< z#$lutx8SYkj3+hlS$s2?r>y9DJt7WH`V`se6-NW5nnF9LPROVH$Ld-0$*CBeyr`CS z)6gA7lAqzP@lZP&ktzSJQo&~+6%$5I+WaUybF%QB%wY^j_XjqCYPow8xO+Lv z$=}_s*wQM^KD$nrP4IQpWw#GXj_oUsiTdv zA-v|h6iemo(Z=GqAI~N0WV9VM?MFgPD3A?vv(^{5)PGHA_Fs#J@h@yf%g%!fwVA zjwx@~BciH++1ij^J$}F{Ra3c8=X%&>d|BdTOnxc=tyHn*QaZ~m4P5!Eszb*sszuQk zz{W=N_=beh6=vX`Vau}!;dXZqonvYLqpywk8a=u&cMbeOPDfVRyxVt~s$3fxb^}<_zKM zY;PPYw;s4+s{8H==(pHo1s!uq!g;PSJBs6KGh+tsQ2<1Ty->8Ucs)XK;}7{de?F>@5)<}t)X~`vxQ%9K z6~SiAw`(8i0V=F2aDjAtl1%SVdG?4qyF*G#++3yXpp${x$fV8}fxAx$-mscTGJtfy z))ZNwcZZr8bc=&VOB>2Qt)Go{yc*M#tA8(Les0I-=~G98O!YoM(H3inu!fp3G)(#q zPV)1V-n`ce!@6ecFAu%9mH?-r)arIBpJN-)4QTXRuDH&GB$7hiT=D4=;l4}$)<)H$ zYfxEFq0thHg3c8osx{ZP0%Q5hwU_M-?nPTJUEc)zTWw_gX_nSv!kQfSx|vk z@-?f53_YcDQDVg#9d8F%dMPC*?I4I3hR5^x-tEfcv-4oPQrukjVrp~$A)%8dAI($@ zM4p%P!F{HR&HzCw5Fs~L?hzM6-)U;qJ@--fqJFXex?HK6U}sq)ZQCFp{pk6{WRu$! z`P#VMSs2R7@JfkD3W&Efsfh%NNyFQUG3;=x9{s)-VQuOM7n1T46fVJ8^`dLE{&nK< z=(J=Y{XVmW$1fD%^0W=Q>>5kiT9V&2pj*mxouvxqgy^mCjHv-WKKrtHResJX7|CMB zp9?RJ!4tnaG=*v6Gw9VM&*LQ|j&kAf{Tk4UrCUE!&TqKNl~*@OI}Yc9q^?B*H+!_m zRqx0dQPz0xr>K7dvtr8eY1MqN#SdI(i;V>RE#~@nVZ2!f-F;<&nW& z1O&nrN2w>UuLj}+Y>L#KP5QupY}5NTtiL?J>%6tL9W%Uuot*S~oSXMgngg8DC7qGr__DTL1{KT>~~ JFK-g`e*ojPzQ6zg diff --git a/docs/img/0.7.0/learn/documentation/introduction/group-by-example.png b/docs/img/0.7.0/learn/documentation/introduction/group-by-example.png deleted file mode 100644 index 8584600b6c532ce1c455ee609188b0e08d1cd422..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17509 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 E0L9QI=Kufz diff --git a/docs/img/0.7.0/learn/documentation/introduction/job.graffle b/docs/img/0.7.0/learn/documentation/introduction/job.graffle deleted file mode 100644 index 2c5a994..0000000 --- a/docs/img/0.7.0/learn/documentation/introduction/job.graffle +++ /dev/null @@ -1,512 +0,0 @@ - - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGrafflePro.MacAppStore - 139.18 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {576.00002479553223, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2013-07-28 22:09:17 +0000 - Creator - Jay Kreps - DisplayScale - 1 0/72 in = 1 0/72 in - GraphDocumentVersion - 8 - GraphicsList - - - Bounds - {{41, 144}, {81, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 36 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 Ouput Streams} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{47, 21}, {75, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 35 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs24 \cf0 Input Streams} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - ID - 34 - Points - - {100.76664679221969, 109} - {100.76665277122837, 143} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - ID - 32 - Points - - {59.5, 108} - {59.500005979008677, 142} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - Head - - ID - 19 - Info - 3 - - ID - 23 - Points - - {99.5, 38} - {100.00000220537189, 71} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - Head - - ID - 19 - Info - 2 - - ID - 22 - Points - - {81.5, 37} - {81.500001470248037, 71} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - Head - - ID - 19 - Info - 1 - - ID - 21 - Points - - {63.5, 37} - {63.000000275671482, 71} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{44.5, 71}, {74, 37}} - Class - ShapedGraphic - ID - 19 - Magnets - - {-0.59628479784302701, -1.1925696134567261} - {1.9868216701487083e-08, -1.3333333730697632} - {0.59628487781105233, -1.1925696134567261} - {1.1925696134567272, -0.59628480672836304} - {1.3333333730697643, 1.5894572413799324e-07} - {1.1925696134567272, 0.59628473564567486} - {0.59628465308492307, 1.1925697326660156} - {1.1842379282265398e-15, 1.3333333730697632} - {-0.5962849488937394, 1.1925696134567261} - {-1.1925697326660152, 0.5962844398368361} - {-1.3333333730697625, -6.3578289655197295e-07} - {-1.1925696134567256, -0.59628480672836304} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs28 \cf0 Samza \ -Job} - VerticalPad - 0 - - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2013-07-28 22:21:28 +0000 - Modifier - Jay Kreps - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612.00002479553223, 792} - - NSPrintReverseOrientation - - int - 0 - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{364, 6}, {711, 872}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{0, 0}, {576, 733}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 1 - - - - - diff --git a/docs/img/0.7.0/learn/documentation/introduction/job.png b/docs/img/0.7.0/learn/documentation/introduction/job.png deleted file mode 100644 index 4a90b8c60b9a42f958535471ab04968ab367c7f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8954 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 diff --git a/docs/img/0.7.0/learn/documentation/introduction/job_detail.graffle b/docs/img/0.7.0/learn/documentation/introduction/job_detail.graffle deleted file mode 100644 index 1583d55..0000000 --- a/docs/img/0.7.0/learn/documentation/introduction/job_detail.graffle +++ /dev/null @@ -1,1320 +0,0 @@ - - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGrafflePro.MacAppStore - 139.18 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {576.00002479553223, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2013-07-28 22:34:27 +0000 - Creator - Jay Kreps - DisplayScale - 1 0/72 in = 1 0/72 in - GraphDocumentVersion - 8 - GraphicsList - - - Bounds - {{59.583091735839844, 17}, {71, 17}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 59 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs28 \cf0 Samza Job} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{101.5, 113.67618703842163}, {53, 34}} - Class - ShapedGraphic - ID - 38 - Magnets - - {-0.59628479784302701, -1.1925696134567261} - {1.9868216701487083e-08, -1.3333333730697632} - {0.59628487781105233, -1.1925696134567261} - {1.1925696134567272, -0.59628480672836304} - {1.3333333730697643, 1.5894572413799324e-07} - {1.1925696134567272, 0.59628473564567486} - {0.59628465308492307, 1.1925697326660156} - {1.1842379282265398e-15, 1.3333333730697632} - {-0.5962849488937394, 1.1925696134567261} - {-1.1925697326660152, 0.5962844398368361} - {-1.3333333730697625, -6.3578289655197295e-07} - {-1.1925696134567256, -0.59628480672836304} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 Task 2} - VerticalPad - 0 - - - - Bounds - {{126.51412229515523, 156.70258726469865}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 53 - Line - - ID - 51 - Position - 0.37774357199668884 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 1} - VerticalPad - 1 - - Wrap - NO - - - Bounds - {{102.02543265311756, 155.54622220993042}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 52 - Line - - ID - 50 - Position - 0.30659866333007812 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 0} - VerticalPad - 1 - - Wrap - NO - - - Class - LineGraphic - ID - 51 - Points - - {142.95187377929688, 143.38228750228882} - {110.02543265311758, 197.17618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - ID - 50 - Points - - {114.74999684095383, 147.67618703842163} - {86.294020898085591, 196.17618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 38 - Info - 9 - - - - Bounds - {{83.310078640505097, 156.09778326749802}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 49 - Line - - ID - 47 - Position - 0.31154739856719971 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 1} - VerticalPad - 1 - - Wrap - NO - - - Bounds - {{59.583090066240111, 154.42674145102501}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 48 - Line - - ID - 32 - Position - 0.28351658582687378 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 0} - VerticalPad - 1 - - Wrap - NO - - - Class - LineGraphic - ID - 47 - Points - - {78.249995261430769, 147.67618703842163} - {107.33091014225297, 197.17618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 37 - Info - 7 - - - - Bounds - {{74.999992370605469, 197.17618703842163}, {46, 26}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 46 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs22 \cf0 Output \ -Stream C} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{137.96903325656112, 78.093316394752037}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 45 - Line - - ID - 42 - Position - 0.4247739315032959 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 1} - VerticalPad - 1 - - Wrap - NO - - - Bounds - {{106.55560185205636, 77.46781401806038}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 44 - Line - - ID - 41 - Position - 0.41218578815460205 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 0} - VerticalPad - 1 - - Wrap - NO - - - Bounds - {{115.5, 41.796580791473389}, {46, 26}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 43 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs22 \cf0 Input \ -Stream B} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - Head - - ID - 38 - Info - 3 - - ID - 42 - Points - - {142.5, 63.986382961273193} - {141.25000157952311, 113.67618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - Head - - ID - 37 - Info - 2 - - ID - 41 - Points - - {142.5, 63.986382961273193} - {65.000001053015481, 113.67618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 42 - - - - Bounds - {{72.487797844925495, 76.103014686803647}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 40 - Line - - ID - 22 - Position - 0.39506399631500244 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 1} - VerticalPad - 1 - - Wrap - NO - - - Bounds - {{47.596244023754139, 75.593161679834566}, {8, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica-Light - Size - 10 - - ID - 39 - Line - - ID - 21 - Position - 0.38497579097747803 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 0} - VerticalPad - 1 - - Wrap - NO - - - Bounds - {{38.5, 113.67618703842163}, {53, 34}} - Class - ShapedGraphic - ID - 37 - Magnets - - {-0.59628479784302701, -1.1925696134567261} - {1.9868216701487083e-08, -1.3333333730697632} - {0.59628487781105233, -1.1925696134567261} - {1.1925696134567272, -0.59628480672836304} - {1.3333333730697643, 1.5894572413799324e-07} - {1.1925696134567272, 0.59628473564567486} - {0.59628465308492307, 1.1925697326660156} - {1.1842379282265398e-15, 1.3333333730697632} - {-0.5962849488937394, 1.1925696134567261} - {-1.1925697326660152, 0.5962844398368361} - {-1.3333333730697625, -6.3578289655197295e-07} - {-1.1925696134567256, -0.59628480672836304} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 Task 1} - VerticalPad - 0 - - - - Bounds - {{28.596244812011719, 41.796580791473389}, {46, 26}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 35 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs22 \cf0 Input \ -Stream A} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - Head - - ID - 50 - Info - 1 - - ID - 32 - Points - - {54.596244812011719, 147.67618703842163} - {86.294020898085591, 196.17618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - Head - - ID - 38 - - ID - 22 - Points - - {51.5, 63.136671841144562} - {114.75000019744039, 113.67618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 21 - - - - Class - LineGraphic - Head - - ID - 37 - Info - 1 - - ID - 21 - Points - - {51.5, 63.136671841144562} - {51.750000197440386, 113.67618703842163} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{25, 96.176187038421631}, {136.5, 67}} - Class - ShapedGraphic - ID - 19 - Magnets - - {-0.59628479784302701, -1.1925696134567261} - {1.9868216701487083e-08, -1.3333333730697632} - {0.59628487781105233, -1.1925696134567261} - {1.1925696134567272, -0.59628480672836304} - {1.3333333730697643, 1.5894572413799324e-07} - {1.1925696134567272, 0.59628473564567486} - {0.59628465308492307, 1.1925697326660156} - {1.1842379282265398e-15, 1.3333333730697632} - {-0.5962849488937394, 1.1925696134567261} - {-1.1925697326660152, 0.5962844398368361} - {-1.3333333730697625, -6.3578289655197295e-07} - {-1.1925696134567256, -0.59628480672836304} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Pattern - 1 - - - Text - - VerticalPad - 0 - - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2013-07-28 22:49:23 +0000 - Modifier - Jay Kreps - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612.00002479553223, 792} - - NSPrintReverseOrientation - - int - 0 - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{706, 6}, {711, 872}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{0, 0}, {576, 733}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 1 - - - - - diff --git a/docs/img/0.7.0/learn/documentation/introduction/job_detail.png b/docs/img/0.7.0/learn/documentation/introduction/job_detail.png deleted file mode 100644 index 31f67070c2737880f38514b90587226c72a536bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18176 zcmcfpbx<8a*F6fO!GddWmmmjs3&EWL!4Gc14i?-Y5ZoPtLvVK|!5xCTySskF^SnR# zZq@zwQbnDiPj^pGPxtP%_gb5u%8F8`$b`sHP*A8c(&Ar$&m|}*XkNs3z!mFVMmF$) z1d-Nqgn~jheEWqi5-GFwg7AYtE-o%CE*va&4(1>>K0ZDWD?5mtof)XX?C56eWa!Fl>qzzA zPX1Rv;--$q4weunOFLWgw|)(c?3|s1C@J4=^uK@pJ5DD{v;T7^TgU%-EZ_k_Z{L8} zSXe>-yKkVW;9DvGXFD5+gQ=q<(7!O3;D2iV|CRlp`~0`QvW1!UQA^a_qOj`5momy!!?0LlI{7imeHlQB#rv7l z8CzpQjfm)v4~Ge-+l5jJBZq;}*oifr5MC6ho)h9*q|wyB?f%*8b#>yP!o0wICFLY# ze?NtP?6Q3-`^&F`DRt+A^w*T0Fx|XUeC!+d|}ZbD4^EL#qWzY%PHoW``q&;*bQ?=VNGwP{B85wiRB$H4<~B@ z=%eZf8XXVn4cm!2JA(qlDI17|E6c`FLQ5c@dpVca=i3&p8O@#tqOG4L73~Yh?T;t6 znQlAwEho)~tQ`pF^ACUgV(=TyGu?VelG%EM?$!c+R(3t|?Iiaoq_F=LdVRV)`Gc(# z4l`Sb?=V;L!OhR(q-nP_O5|Z8%IxO4AkFq0)w0jat`B$VE=KQsjk$ni&-rFwOMaqu zaY6X&{jXPhyY~A69Rol3rPr6!*XBM_kKwkLheO&qvb#=%*xHVl>x$)?G2ug6`Q$Y` zEt8n72cPFzpQg9+0k>yps?(O0>+;kgmfQ68>mbjE!4K9gM# zVzw1zfc+EVIUIN7L0uQj~I`-lBPx_eN^lS9W|P8j!7+w1dbLv1`}(K2_?)$!AXH3Er~vceZHs3(?|qm9-3 zQ5ScGj%QiMvMrjcm%GiV3b*fN0nd0k*6ZdYsiw!f_tLMCF0DOw_48&gV?HmA3Qf5V z-Lr06mIu?nU)oN+DqaUQ+BbY27gr+(qQ*RTIKarzuQNJ!G?u?SFJwecTQ48%fNux5 z;Lz5!t;*_JCB<4^8akdw$Xu4}NwZUU?Q=TLdx_$%8dkkqemRcv>C~^ky@)3?ful7I zu$$>?FOeO!+oFwXY<5Hdli%ZXp|I)L<>TtBFvF)Qher$Pu2|jAYn&U4t5H5rn_JD2 zt{tQNhjTS__)>f1$m#q#svUs)?;fE0W!+u;8`5av zziOKnD{n(Qjk1*CvSOK=Qm;Vh@Oo7!Qs>ceKVo-83e(5o{rb3SC;iwb@-iVT&a>+2 z*wbd%fzbee^>vtQR=40~W@v+2T9GPqN^R=6aWhg;m4dEIrMLsz3b!8ftBy?_WWZZ% zs`YA8E^?LA5_y|eAvL~zD^bUmPj%3`c0!VCmhb*7SmfwRj9YitzaaXgc1n?hW{iD^ zDK2lnRzap04c)eB8?SKRV1%CoCtGESxoInwtJSEi{`qDxn0nw;425~Ce#PC2&QGp9 zVz8^9QQ<(q{hzvq^HbGppnt%zuTA}YZ#}B;T^G8xgI5p<=$9nRZJ7R3ced*%Y0iA7 zUw41#zJ*Tnk5M>jP0PFa`sZgVH&#m6cfsRxBC=WvSgLx>A7|!H=-L0pO{4A8gxXdj zFH<<~!5W?F@MNv6SI{T?xfw&YPLOanLzaUMXSLF46j0dOZMvUW|Gbkf?;`_zcfNe$FjRUan%^wm;TowwPptV(-FGmH& zERR#$)7`=)IS-97uyPX;*lE)FN7FD(&tnL<24AisG4Ki4YPl^R>P)A#-S_h|I753A z9YVF&Q@B z09MOHn9sj=W#(f^snM;z>pFZx*E=H4)^yL26r=BH1QU5;E?1yj_Wy?cj-j#2e$aPtI(4q zjutJSXCYxv`mYbO#}6OO(+xem2>A#n^FdCN1y1b{&#f4#1>tOA{_j7_f^(yU7iz1H zR15ZNem$4!dtLwY(w1{y^}0>j!5J|jkIdJ+z|wrRd%dw+ub%B2avf~D$~28N=ttkE z_vKF(qABZWtxW(Yl6sGD&0bA5&hN0KwOT6|?gPs#=e5x1fv!Sj3{0=^S3bdK(WXI* zR7+L!A_u1L2mhnPsrPLQ$Lr)H__&_onRq>U#2QX7H$q56=e_koACHPf6W4S-vC{&fvJ)Le7u98m=$z8ZSZ<1T@1ooHgx_haU32^4ynzRTDyM7=J zfzfz3Yn(wf2hI zFV8b}UH~_|FYn`*N`zHeldM173`pt%`Y?qE&G1zN-SSlHk&(5&2l`+PIIJ3t*#^3e zIexfXGlh^N>weIUa*kvIx{a`&?LzF zH>cl5f;Oh4mrLP81D4=nr_btl% zsiuJDYsmNY)&AGKw7TUQJQ^#Jaum-J8!n}mG?L8H(QlAn~B%={@Y3C@_R{!Q_w ztZBULNr_amj$fSuM%EtTh30$*hRvN}OOv-wA1dbif+d}R@J_OEx_^x(MB#uj;vH&c zI7AvNF;DA{6znCYD|ZM)D$pG{IWm;S=De>!AuVxB{-@b_*^k6jl&CWkCo*krHeYy+R##+h^4mU&0)8ls2-z_GQV_hefhkn1r*I+nCdH z{-?fP|15kp{u!?iq`Tzv`pl7gANcruM{tEXe1nX81SNlIB9!`g5%IYWK15pZR&?9Zz_Fm1 zsP*`Cua-iT%W_%+!_~o_!R7=%^fxXeB(yAh4>qq5`M%yiH|rz$5ruuYUG?$#94kfU zHC=W015WM)ktv4uCIDxE!;66wofYBYs%pj)_E!8e1q9i}%6!f*MIm6n$5@c2 zRw&a7;E(d+6p;sxlT_G+6v~=DD9P^niiypNA5+-=+Q3e(kL}GK={2AXcei$U!vI{z zX2pajvrBuM1ImcRA6Lnq))4R{WxGz84RUIe6#aH15|FvqM};4)b({eBwiC%kHut)J zXM)_hPU^OW8Rkkj>+R(UyI6|sM+J8UoTJ+>0MeV!aGuec*`+Ajj%QF!_m9>jsIqBT zo~im9{WVVoRR^i?mv=M#ly%KQIbDgTH8cVGR21(9A{}mr0``XqF{wO0NorM?uNbbZ zjC1d9=NCU&CDxfqC*ejt_Cen)6HMHRwm$(U1y86${5%v)b)~1M<4DL?r9Y3x&q^4H z>=s3oSrJqHe>YT784)((9W*_-g=a+_vI=Ff}RUfyT3k7vIR*q#q zQPT*i4~otE$#t>iP+R}Dn+8~u;4^mN>kCWS&?Lufk*Bksw$j!(tAI6@7|wzb*e+IA z8xmKWa(6Gag<&qwf%fwVyE|0wIdXfu4J7-viTbdPlE_Z{@o}`vZt{WOR-MdY1VKu~9@s6H=sZCW|a5u6DE7EA6iEJX9x9 z+iXle&8h5v8dFsowC2|za5Z$-zt0&W)EGshYcvWvbO6vZnD4m#w(V3QlO!zD>voyP zg>0%J*@}zmq~qbBgynEqdY56LZ@-%0m{Xb8OMEivl596&`s+R9V|?9@q`L1@Ccti} z<%`^~px399qpKl$%{cY!OP9dcw#eQZq9@|(82ngrClg2OhI;-|*@ITX;IT8D;@usH zbo2LLZ$m!nXlU)H@85S^>El=g@UU&J5)wjp38@n0TUxD|)9QJavY50=T+5W&n7+1x zeIZtP-u8Eb2SvH5!W^FFe>$7uSBF?yh9}GGX0*X~Y&YJ4-oZ&%md#Q7mz)E1lMj}; z5!@FS54SBx)nV7rmd*eAw5W);FBKIt1yg#u15@N?W!~j@1Jm1(qys^`@i$ZdB9b3J zRm66EP*QOd4?U8~HDr|$-8!c$vgQjLO97^rzuBOI^J~8@v!i*R!*Rwsqs@+KQ1BUX z=qFt!LG>IPncr9HFlX$C=pPL1VgjLm)Z`9{L64F?QwluuPV8am*Q&C@A=T#BUkYdj zFuCD)ubOU_kCxpIeit&KB0`BdUTRCt^T9L^(5BtJ`B!z9w%2Sh!H@~=7gFy#!?Bh> z2q{tGJVkUc_=MjN%NpF>E*|oezzaiYqgJx}TCnhgSiJnK3f+}w-NZ8b7e2r~5X!~* zQPMVM$0bZ^!>h{^?uh%7h zD#l}aUD!;qWOiCn6qd%UUx16!R=Llmlh_Hkpj3wFhr)0g?LP;&(0t{10i<}mpy#r@ zZK?@&)F1rdvt-{lU-vflzP^k)1|J9ax_Y+MLD;r}msUEVWxR2X{xyu`vmAcm^+0TS z9VBYKL_>!Cvkiqfh|HT8v9F0=uphy*0?|w{_!By#e22?DmdKjIsOVl6e0%13Ig(`Z z3qZOf7~IE=p(Lh^!(#7qgX-2fX&eas;;K8V|7e6A=1P{XLi{$Aa^p}8KJ_fac=;Qo9Z zIqE?P35Pq1*Usa?FiRz7+5teQNWANhx(#(_bwcUa<@+q3`H^7M%!Vkm; zBPEOk3AL&!3H^H>>UawCa)l+E8vV1b4f5f#ISvhQP^yQYTaz@+l$`PZAdh<9YsTqM zkewV_OF2DE4zXNLq~5f0c>}{^MBhxNC;TdH?=O-%bYVrYPqv@`X^%|*yY7~B({7m? zasV9q9p?7f`#C}+;gEIcxT;uVkBPAr0IxxQKrFPvg6u)01Aq@d>wK?I&Dp zFmm=rWSEvJC>pbIm}tK0lEkeg=b+6Jgg6YePTq5!fMiLiH6-zFx801SdsgjAZ7>tz zow265d$B}a{%rRG;NF?-lqocM-eWWZ>#FZ2Ff}1fODirc-1dthPt)O&ZOgG)G}==n za)#%{zz$zT4TyB^4@#EZ8ISy_lI;E3oAVefbyMDQk~%;-*&~ohtm$$lOzggwZJTCO zUv-6;TPZ_wiYtf6`VAu38~T%hw0oX;!ziheIi}yX7@Fv^Yyfj@4K2#iK@<| z_q?@NPX0d{4*iC3a9iXHl9E^RWC*Elk7~vUKNlfvFb?3ewt=O0fA%e}Ly=9e1{M0$ zJp6d{bm~bh)f%Di2D|Um(D|cvSi`Zr-F<=U>ydBIkK%9Qwr6}kM36k0Gb6PkgHI4eFJn!02!$=0dr2Ko2yN^qgY!aj^}9!7@kU0hu2o zW4t|GIuXC06<2ru2PzcjU?u#t%efoFNW9;=XmE$r+{yE#1|vTtFni&RF?E#f1Bt@q zgc_qd^HGy@)Vq3HbXn6qPvr;v+f4Etc%g;`i54|+2c8GzTUfPilQs}%Sqhue%a<`( z)P^KK9`ZANKvW9Tc+lK2qp*8o9);$vU2oF$kUtFJf%-}<|16MQ91i*1z|1;B$WnsM zHs1sQqY?SNH;0aD8aK?TRGacT5?21h?TUvTM_-Q+0(}5e$?JD*45`NNjne^~8Ih2E zT7$G;Kd#=v(!+y@iYd!Ydv7#@aQP6!=%sPu9=k5CEj(`RFA12o^a-@bF7ZJ8rD8qq0O5&ZE#dYgq?C81itLCP~-G+lD|CKfjS#IX-~z692=xSb_mo^=-gM zLOX|o6nj1V#<)}bQyb`W0ws7;gUHsR=N5@@i258JK{FSzm0xY4+X|Ygp3A&x(tI;o zM@411@mAQhFv1-6UzubEs!SpnIQFUL8#xP*sk&riraz*oX1&_QBoJ&mgzlMe?~yzE zc>ms%Q`?mW-0lFbK@)L4m?k7Iv~7^;KHBD)JvM3quZ)+iFFcZdPehi-opHW%U$;iG zmCD;8Mg-sT24h92kuec%yYHuI;^xZ`uk+vi7+79GVHkXG+4bc;?@tmOwksJwBDfP> z#ca}a71tSb7(5jnzUQK1WfGM&hf1YN)EhBBJ$lV!Vw(5*cul=`0qDYWtfKHTYh6d- z)BS#X=gXdE(-&yk^4W4}W=FuOE)CJvHY1!&gL&fG$*&VHKKavL<5L*rKu}H)L*0d{yic zbSBO2d2R7`>)R%LuDN2^vn$pNJ&f$PB3V!_zJX=WwP6!fc}Kl8Q)RD9$K$f0TWO|9 zpK|HCiTVk=Gq{HdF536KDTe*~kl*Ab3GBtEmKkFrudQxh4;fEH9_Pp0{Tgp-+YK38 zFNjt(eSMY4I!${ZXirU)r;WDBs6p(D_ibn0D9g+ZOB=qPB@5HYKAaMG?D9$rXpz)e z?S8(3IO0JcoC7Fg-+7{1ZrE7?@EbLl;;0)1qzg;mLuG7(l~t`%lhxw#DfC?_VxP?L zaItu25`x+$$0%>l+TxU-9P3W+9s$h+ITFzz;T;&h_zAI()(Vf3Wi3l0Jh^1tZP}Vi z<@0I#qivYOpS>SeSOqr7W$B$ntX2dl2U%%0-wK(`uBq&b)c=-p@vf6@HW5Z{SgUPTI+kUlHeJ(qG$VjXcTsv0!eEjqZV}=kKFg( z^?JLN$6FfPZeZ_w(~g@3D-Q;*)|;b;8SAottvT`TUE}wrNqRGk-*vv+PAQ2T<1Wlw zX`j%9gS&U&jgywhreP_#JPgCpzFmG>;KC`;+ozjMTC}?4_OdjH+UDF3Iy8K7h7q~; zN7}R0$#1$Q9C*@o9NC7K+2w*CD~*cst8GuYeRpnz(}?9EF>ZAe#8QPsqESXL30@Ed zp~Jlbu=#tsPwD#wsmldo?oVl~hW<%OJ(^k@&!qMSMKh4$+!nuue>a}3a!Amh+oaeA zkc^;7X+y(pCx%lvNHm{I`xJ$))pR&!7Bjw=lxvR85fjMzm29-f%sBo?gSp}-_&8Od zK-6-pohRB7;zJ&a$z40oO(CcOHrd2e|Eog+F`$Q6tnowBWaWLsJt|WMCjgZ~%LG?v z@VQyF8JMpTiYp+J;wT+|3tQ48k38v4?MIAm8|J@K;*}lB8C~a^1 zdEG47>QFDXx`&m_&%1N*U07Nh(8u1t2UieAbpBf-jlW#FGhzN&2Jdc`9LMIpmtoNb zqZ5Y9&;7dmO`q=0-#vEra~t=*?+f8WR{Ibl=-jJ}tcyDf(elq0V$+#rZo8U{OhyP? zE2BHkm`}Cqc)sDN;g+ncowD$HFchqi-6D1siHFhHW-x6NH7JWR4LxIJh6DNkZH^SF zjr?*c!1O%fz>fQd?heBU9xgvdKt3DFrFiESxBrk6k>l z&K+BY1_LcBFw^UDgr_He%LQvmx&g#%L*5oYpVe%4nnc zqOD1k(cKhRZYW_>NhX$UZiInO6ov1%oW5{~w*xT|AjI7r@;L)hf!t`^&{|JP{26Z6 z-VYv6+7|k+lz=O(Bv%%d@_CQ3;r?u`8^$A*8wSZ$vB(~k0rzB}p=-qhY$@@|si2zl z8k~%IYNfjdHu#jL$USI+FMA{PktduGcTI5et7P8FWRL}jw;Gly8Rt|Ge0 z3!@oTZSroRNfkvQq=caZX`*Z7k&hhAFn##EdcxUh)q`GR9xKMA=$3w)pCzx_H*%Rn{cmq2q-E8q9*RPew%+ke2nex90J)|WFpZ! z-`}RRZ5N6>TY|D{%;PXT+yob$&p=f}#OkpvakImPpeUt4Qp)SCd@c<@YYmNYe*J@;72FAlD z_5;LwD$xU_8h6K#zBI>H& zu3PX(_R^$CXZ3x&!ZMcGd!m<1C+j?LC^vKse!Z9WoL`j31(W!2O z+Bcix#Yz5WqS6T46^K9Y9;nSY(54{%kN?fXb}mBrQzRO4M4Li7;^)ZK#}_;7G!hx{{63nexBk^zQUwN(-#QjIySjMNZ`;MtrA zy4TtE8?Mh_G*e6&_>yo@SD{_59wbwzP5iJJ2GxSbfjGLBe_wS*YNL6Rt9OoQCZtM{ zK&l34@G6`Y0qi-*&X*rPv;_$!;`}@_e1^^5r$J`HwDM=+(6(%8<&dX= zqv+Cu$}=a7Gk;$^gw-hvLx2ZSWjYz6<}R4;G+V{u5;=HbB7OzeV@6p>s-~-H%^E^w zNQC3Hq0OeN+tJN_)ii|PH0}>LwppX|@6}%rWXU`11$p(k3xL$YYrsYonA*!u2$)or zO=sPI&mHX{0moo1>04H9KeEF~MMN|wT9qVW9d7)71ZAih4Ly((b19ayFyp)S!$l_v z<3;gbY;#6^SdA%3P#j&we&B5LBnr555LeJ| zw?aca-HMeo=&P=3PysK}+{fcd{DvLxdAbY!GXzrCta-z3fsJ?sN@4!BS_2`pk20OD z@d{w7i0dY}p&`E6A^N3<&xWP$GgmqF@j>B9VP996%PrhZKvA6zO!f8L(a(0?mqZoU zF|!N#I{&8QVP&goYr(2@sfSU*4@I+?sm@P^!6Y*{)^)V1GIXi9uJAQi*mR2WosM0V z@xk|X7lr&-)Ozka}|sV$(WEk|E7>feXX4jt1V-uz93a)%GH zlb(%0@zm?unI-HFH8x2w>Mbz3NVt%nFBY$sWV80xDt7<24y|C=k*L(7#zjdrh~B z#+F9W=yBJq{%iU$#gxm6QD!~!e!=^! z)Njwit<;0Uiff4bZ1!Hde{(rgLY5R%;SiuNvY!|CuKu_-DT?W-aJ5cv{IY)VX>>@L z!bRva6$Ap+rom`o}xO@fAPu~OKPp_MQapWd6174^Eu+9a~ zY{4QxSjyVO_#uBUy8v@rm@3nsc&EHDJiJ=)ygIYenRv?KB~SePp^8`L_O%CpREAMpi35f)ZR6f_7a{S z{b2Dvqj~y^Tne7rO&a*XVl49?Yn*cD(Pv62P1US^7*ldG{4)EFJphedvl9*JEfa4| z52<}L#7GUYOKDIcs4=QtM1`?Mg*BexJyJoj;rZ&MGjO(?UeP~$DH648$ zAdmRTCEDJ}jEiglA~>U2C`^o)lET0lmUdEc?LvVBGcmf@+ua5i1Y$bso-Dr4p!tL$ z>t-85IqBrJ6?Jw&K`BUK+81l>n(LuwWH{TETE%o2+xMpgp`JQ|evj8fwM#uogaQg6 zizwJ2xbn7-M#cSp>+4Y5X;0hvVyc6!3B8^%u-ZyZOA`+uORsJh8-3@%V_r zt^c*&ZbT%P5@>1(ut5d!fL$(TXRa4;AO|5JN4%No)`-Y^N`%1;sH(kGXx6%^0x_6b zMR+!atxi^ZC_$B+vmJnvbmPOnjG#t9d>qyXfBcVi|8KM6K|e7V4JX&Kk5fi1R0tOi zS^smu@b82X7kxxPM$%O$%P&; z3yyU>5RNK%+X5}X848oXzH z?+d+~osHF4MUaK@74P3WaS#mFj8&TG9#(rcY>cLFb;@5qFnl$;VL;7vPpHDqn-U{< z{F*-sF!5D{hn9M(rk$DYXTzz<*AV5hLS3^Qu8_~_@HKgTni>jiMDf0 z-2wU<_?_QE>({gTcJDeo$3vpp{^IGF2;XBX2^vBUTQ#o5wUF^r5Q%QrLC)w{OWs~B zhhxCR0_*Of_v#|OV)HY)&=yWncd<$(Ivt!IU6FO4Mna52cH~i}uf#Gyy)mglEU>e~ zFu4oV|1gJKz4CSTOUiRg^wfo^7AiW&(JEBm*$go^r0bcZKCh$u%$<+{(L_Z|izUFx z%EY0B((hyUwfyLIfV3{#7rFKVAie|c1q-S)@Ju1u^raY;?!0)b$Zc3G+JP zG%l;J)tvpZvqM&%YMMj4`7s25R42rcq#(qJA0z`+CDC~YgU~0oftW?J$&b^XbHvAX zts)xS`b0YDDSsSdLmG075ePaJXlo3I#3pUz9#03zRrY$=#m`mnorsJ)X_cshoze#DZU5p z5nMBnR(VS!=IRyq!+An~)HUhRg2glJV=XacRO{?y!eA z#!Grm6A}gc>WzDZ%ph63ncyo^p{f;0OI4&vN^TxZwM_C037IKG6eRW9^r{OhvQcbL z)@Z?*Hpv#qL7j^k+X@a7RTH-~g4=yOk3QX4`Lm3O$Bi|}Pp(=9GlAIZW({dx-m~sg zzW3Sham2o}L49?LpEQX@mc=;1GTq0lF|KR<$73P=~xp zvkTUXX}Bo+W!dspMbZd$mW9Kpx!1?mY>|I;W&VE0BH2HMiiSr~N;`??p{Vh>6G#so(z{Et}^fJZ3ChUl2GnfMV zYcf47f=mmo@--b_ICmV8rK?VD6rw^M~Zav$;ybHh$C}~0>{&A zValDh*3i-YQ?dv27Mhsj`-RUyY)Nl!_6Fem zNW1}3a#WA5Grj3IGE83&V9UM0`XEr&?9!MvXKrV3tE47~JUvGuAy&UjrWMLpu#wet z3Q)@$*kDSl%q#3SzQkbgHac`dBe-VExbc^~$I>juZ*|YEF#d2{pxEgHh)iAFpz9L< z1*W>wDPK=jD*fj@*ZuM|l%=jUtsuvKF0C(Mv2>pQe129YTRU%-=Cs#W|63Gk)g1p|(3kfSbW)v1qp^XXbfM zlEN_7oy7%o(Z`7R&IuV9>T49HN>Nl{QxO5B&T25?IC%WYLkX zvQa@?25{!=OSTU{2Va<+ej~N{prwOzms_&^U0YK{V!a=U`2AO3(KK45zIIh_7aAe4 z3JfhU+d#_~FbEl%;sedpn{yMkA;1#%`wp40bnS!lP+ksCF5H_vHS;3?%czIqeZ9m@XkL50r!C>>beZGc~@b?H5T)-TY%xXCYkuoP02qmrk z-+XaS&gqkA@^{=vldT~k+a+EU!vv7axh|k>DGb`6>8FYjd&I?Q&q%}$O*vBqC( z9GOzWnHltnuP$*|51h@Vd!lXJ8weXfU~IeWJX?lTnao)~h5%`xAEyq1U+Xy6Mt*Lg31GhVaU%|_c5Vc zO$6ARfmv%D2D_sg+skin>gBUP%PbAU7dxUDXt00>6YQz-QZ0ej``BS?eIW)G2K5fAWyUff_X0NHZ>7G z^D_LBw}9lcmhQSvm7XK?)0gntZyYr+UZvVJmTn;A^f}n~pS_;!8h?Bw6pZ!8M1~>9 z@kQIiT?Qm0wwn<=%opJR5J5{l3(U2(y)7Q_6n3j7iY+d8zkTCE^ zper2lDBK%U|31yGeI9eKTEoMjqT{7m$6VPpX-^4XT z*sGc1OHgQ~QoMPk4L}yWNx&ax8rp-hod9VvxfY4XQ59D%ivBI2PG7VXQjfzM3J*Zz zFM4;42gy=Zt({707}FYSP7!H?@2mv6^u)l%_XIe6|NVi*G65 zjf(HvW3`;5F68qB1d`_I_CGv!Qp~@V+l!rD158ol4!@`CUUqP-RWO-%W1Nq!!^(ld zLan9kOsN(cGo^EPhp5YnTjAr%Z9BeV-0H*2-Qw!Y&OrkuePO$u7O+8#7Vyn=H)}4K_vEvrqu8% zoSg7^x%_1XhsIGz_serKyFdvWrf-%{p|pw~f9e+}8~?Ntyx%&NjrLkUdRgtHENZwX zAaBvrUZanCauOGsSShtM&?Xln1tOnWP9EKLW*yaQ4Xr@$aV%t0!6?j+O)z_`#?>>PyzSX^tshO6DQN5#=F44kpNl?&fW z0CCyVE)r-|@KWBVpCXug_gQend{xO-qZH^bng1mpBD(`?n;EVfVHXCOxIzL{acT zLFJCk=NiuuVb+mJjeB>TMs5$gvbq_EYCEU@sHH6GQ_4yPSci~xK4joAEh-0VryWO1 zZ`%WERD{;quYSiMBab;dBfGdZdhQ1Sn&Cp_&^08LuW;GpW;aigDLI|aC?K@W2!Ia<>g5prsN*q^D$iCU)mkbSl6hTC zRHuE>ex8`5MmRiY&;iV2n_#!&7E9tbg2)~8w=X_`38+`cVBPLaNJ7o}IK=^*m>^`W zb4)rT4v?-lrCD1?fBTq8Ifbm5c^fQZ2-OXJ2nu}U!eDI&nj!kl|F9@ z?C39owU07D%E(nR?_*%17(Ec3o$}^pt||$J zExKa)hgj5orji!};b{c{s%nUKBNcnK)w&CmhMxUG5Anl>_eR2y=3V!$P{P^j4kR&1 zU_zVID-m;Pa}S-R6X`TwI{tyro+FXFzwzpwA{C3>|F# zKy(Umf+1=gYHNM^Jgt-wg2v|DPUqipu3g*4X8KM>Dz|Y2S}H4uyMKV1OmWHD9Qme< zSpI|%=62J&f=Rw>mYDtVU;wo3a%{Ot!J5Aeg1Xfz5!r%tyzjT4 zC5db}&Di9PKX?%Yxqk}H`3A;%o(Z|x(0Wie!)X+@Cw!D;+6`(|ubF`kK}30F65|bm zsB_rhTqGh*0C{OcrA(-^XhK)Y95r8xN`81qu)tX-R7uWLI=?qwp@(=KsSlSYBUgVS z-UHHYF8x(1FuNg2(Vn!r&@JLBvTa!p{MG;dL=$x8GF3PkivK9qewk5{xp&Qq--i<_ zHHD{g;y~8@B|x-k6i92qjQhDWkk#rBKcFOR%gLo>-h%IA6!oKwvpOcGcPRdMzDf4V zE7K0BJ?AXabS)fwq1lyDYdJ6$F=67F1%=SIBPQ*DN4ot^VBbv`K4KN_1p-ohek87) z)byYU%sJzL!XsgvZKQc-;B|wAU(Tb_a*M_IbR2FDR$gCjqZ0lF|2D3CqO+jkP1=f@ z<^#5n^JtAO-{cgJ+BKrm+2Gej}uxNwH?`=j9z(jb_{I z2C$I%<9B2eI~M@bxLd)BN|%LrwcBs@(#VA1v<$Nkg(FQQnS>y4y`?(zM6RS~5v=FK zFH(t8R2CSy_oH;IdOyyC^_stzQ^g+@vOTOTl>5dcZWWi5v!h_^I&_C5jHU@oI+G!0 z_dX$$>y#?flLhR44Wz|l)uM-@&A*(kIMq(TJ!P2DG7&rF^Hqj3-f^DQnG)ei961zGceNWYA! zo}qVvNEg6nWr{Nq^!neI?4_)zrqnVm0q^uiK8&jFZJ8dQ|7QFR(OHK#Gl9j`S}&A$ zRlcSYw|t5MKz^SjoBwjI356t7R(a`dFIMch=1rfkvH28<4ZS#cu#-KI;oFQF_ttK% zXp3l)8IGjuL_DRZX0tMjs$wAMiw7`Mv!uV86GK(rQ>;lyq9FYtr9$`~gG`q&9gsEz zgTiF62!jZpwv71Aoj-}%*4~$u949=h@r0boLUr8~ zimm1g@O&~pRMn^Ff|SNN4OcKB*6P=%t6y+z3zczfTJ=pui}d z!hnLK&@~r7`f-nwxhFpP$-eu6Eq--)Dg0Vny5}lxQwYeY8?H0{$wYEjoZFeOBtcK? z`m-l20)su)ew4Fv(TcjD)`A2;-Ruvh6M!=poo754wk?-u^tOD$ee{M#_Rn7 zgTKeRLRC9EefhUoCF(}JFsO(`BLynb*uKdr3jhNaEY>~57vF!B16ozyws6FpZc+U9 zYD%f4Va0uDpe0RcGE$rFvLy1dR`pZGpiSY4p&T}Rc^>IovTR1Wtimx%SZp3{^&X^K z(EftM5kTDv4sHF={)|VjnTW<02Iq}V?ciH1`*UOl;k!*JQ?kO{*aMKbn$o9lQ;yr zRrYQe`Fijzu~re}F}2Xtcf}sia5H#@kC8|;gu|`W zt2}hUQ`Gd-X1ekk_hD*iZ+TOlE`RNa92IDI;pi|Z=t7#8nAMJ;gVzd>J|#t^8JmPn z`vB+2p~zThN}S;z4dW>!xpA!0-KKOFaCH5xTe|dvCjciZKguWSMj3U!MYtQv zyoSLV;$dBW3OIT)se;?IDVv}Ah(mgZNNP$wK2&nf1MyvjGq}nF<-@z~4L zzK$dP=V_%@Xl)KwoFH3qC_hsA9&jR9L{6I%u|M@7#VgoRe4F1(ROht<`Q7pcWjP=h zOhk(de73zgnlGU5YJ2AwS6Dx9j(qoTz;TgS@sQ*D7nZ}Z|JBJme!54301`w~UuOq4lqmT;K5wIO#2~MM%XS2D30iSy`Pt^JfTO;G8UWb_mjy zJrMIM0QGIs5{Fndl6qdUwk$w;P?v$+>iGD`s0AP^d>@CHt!d_94WO578zXRK7<-IQ zE@wjt)DI)#26At6)wv6!f+FTD9XZ%N&jQGtke@7UMU4|Cs{K`(=EX5Kw_%8*JGBIP z1gp{}CZx!Y>k4Z2_<-n93yr|@)l^$SI-W?RCL}x*qw3w+a4)PUAj1Naf93)&a+r^D zR-6FYHl3}_z+KIThD37m!5+tTcxWh55Ew=*mc#X6vKt^|Q~!*qBq%Pc!2Yu78zL-z z88c=5T(KjPM!wq2>_uK*w!pKk@r<|seiwe{QB~Z#H0%=rC#M7r_~IT z61j(w_h((YkKaNpWakVc*oE~FRBUOLGOhRTrP5D+V$;!@S}dEwh!aM*CPwaq{P1c* zc-N;ffAhYfU$RaSi_r*D|l&TTRz=5*fm#9mX?e zR~sc$X4?0DuuU;dlnI4DFIkzj1=7+7XnD~p=^{I$W6KWhX2;^~}RH4a1q?2#vzOVbow}!_*bmP1N89 zXhLO(EL80OZ+n5=&N)rmy99o!&5di6xV-$?*IqVL--@Q@>L$U`S;u;%(+l`tW`DGh z2NpU{A4i{#;ac^g!c)?d>EYh9E7;#KIxU%S=waB|_1D5ppKJJUDKlpDyno;2~ zJIAYh@(uNn8_A%#!pmE(O|Jz`vq?lnh-|AmXEN`&X^gTzSNy}Lf4*(spBuazc-%-v z^Clh!osjnn=lV(a6)L0#OJ?kK0PW5Yvaq?c2Ns*p}fK z+5gBj?!QmvY1!5q;0D`;(;pl2@vuLV%1hX#WR@ZVEY9;psx0ju9{@I{?i?s_%{id~ zVrhISsyWv95ID)w__FK9gh0@4-oO`6fAlaP2DS*8FNYV_gTYBrAy38rOH;!T?lI8pH}p d8*$0}sDHJnSM1b>MiI~%HJ+}1F6*2UngDUqC>8(! diff --git a/docs/img/0.7.0/learn/documentation/introduction/samza-ecosystem.png b/docs/img/0.7.0/learn/documentation/introduction/samza-ecosystem.png deleted file mode 100644 index 4eb9f334271e5d3d712b3797946d5ed2000479c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2473 zcmZ`*dpy)x8z0kX)6H$m+l(~XdsjgVVv8n>9(xd=1ZU%T(SpMBqV-}A?Fp7WgV^PK1Tob!A?C(Yk) z`--LLr3eIK1xO+WA`n_2tW%dPh9y7fJ%m8$`~(s`g6KW6ymdhsU!#=mL^G^jYHI2d zqBb%y)m@sql<29A3`o4?9u#Dz2b(>$3*n_ZtS?1jk+6c*)7M{uLh9=$zPPU_h?`&D zp3|C=HF368ksGZW9vfSUq2|BL%PVex&-~ZW+$SG;g zzEJI{bP9TDK70ElQ!}08>6~8m!qxd>rTc|-AiXZW^&sc@53Bd=Jy9`IN--mF@@zsL z)ep523w$Z!^vvY3kz4g1*I*>qehZ=VEafO94H1p-t;yeo##$ZE(g&rai)JHF=X!aJGY?p*;MqO(K;~tg@RPSH;N3 z$^?0z>jKp0B$deyEK+}bsI$SHT$jLtYg09s>ECb8=kA>Q?%gcDcE0So(!?wDJP48H zcUHi0E%jUSg=F&4e~=U%+=YT5Zjz;qKjCf@&)?LT5Z@m*prM|fiE<;2=@=G*Oe z8mlLa9!$lk<|I`V&mPUufh;B2zN%axD_{Zeg$?qGpqaLd6Uxljt1~U0);y2X0aF}3 z&^n0(tt#wra96~yof_8#LcxQ~Npj$WK;}B9V#=6>XydAF3T5#MID-E{K3ZS3-h4>t zwYSmW<5}DVe<&{*=+!pg+hG}Zo#wzRrp*zzngF8bfK+{p=1f-8P1khSMr%q3=B8PC z4seXghN$RsR=KZ5N_xP}&3Gf{&#`6)zO6q4$Rbo^aaES(V^d-D%#EXrFn`E-XjE8g zdcP;un9$g26&ePl0q--~J4Wy^mBod2a`L51G_Ux1-z$&SHElC2z?^VOOi>i4Ynyjp z4j(q?Vq!QFk^xJ)TtdB?3xvO?W{xjDK6`g!H}OIOwy8QNUQtw1;S}S`fQ~VWqL;?4 zbpC=Kw<`(kD7W3R;e%&K_K`;$KR7oJY|*m8PuWY**GgK#^6}uFZ*@x^)CbD;H;&9sYI_q!P%&cX(TvW&x>6V0#4_D`vEq$*RN=wg%%(V$eyW-~CEDm^_{8Kx^xd7?dsjwh_F9$N zv%=>G=F6%F!UMSS2UCk`#s=S3g%coaEpUD+?TBD><3=o3EOAIbPehjEYibSp$$n45 zwtKNBD&MpoyzW}24`u>K;PbvK*nC7M&U47J2!%WcI!2sz0#7%s z2{vo$X7dcC!I@?eu?7cYrQYK!p_NmDNS$sbg zXeqdUy1QQL^6;Od7`r-;wD{|dEn=4Ru!@jMs=&@PG*bZr20D=>+%Sq^eE+dM+jyt) zF{L;5_2IB~SE_waz{3>icBDElTf7Q5+#|wMxa>wOxh7E}qoewV0njb8dH#o|H%e248uHbDZQR$GOu&bI4i%OehtBj2J;=zMlGV zWVX`YaF^ZFBwyuYp4gfVnDwiEw z_E}!7oG3@;y9_Kv8JY6plPB z%%+!)cp11l;6|Hg+mX=4EB&O3K1jGEc^V%eM}sHc1>-`3x7AyjGY(4doA__5*^3Q~ z4s9{I1hA!-!;MQd6r!XLA7TNvnXaW8vBJNLUEf6WvHMz_2ksxDK%0;c_!2 zu3f&)Qq~{zI`kL6nhYS}gZIsv*C7*ct~CnldZ{Oz?007G=K-VXDlJgN0W#Lu`qrsv zzkpPmk+H1eRabZ|k2bl?52{8Zd21?C05(q?=*Jkx4KdByK%X;YDBp<1v+dM}atR<> z@GOQglEq@`7N7I0m($T8TA_C1{WLRjY5$&=bQ41m+q7`+xIFt{@?7;Y@3spn3pU59 znk{|lU2&u#IwS0g8(gA*UalK(YSB^alEs9ly{ OjG(6<@y^!$NxuQvb9#vY diff --git a/docs/img/0.7.0/learn/documentation/introduction/samza-hadoop.png b/docs/img/0.7.0/learn/documentation/introduction/samza-hadoop.png deleted file mode 100644 index 2142f949356da03d4c4f160f0a47a8f4e8aad1f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2542 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 diff --git a/docs/img/0.7.0/learn/documentation/introduction/samza-yarn-integration.png b/docs/img/0.7.0/learn/documentation/introduction/samza-yarn-integration.png deleted file mode 100644 index 2748713274151a0af04b8131732566670f15e27b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9400 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 - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGrafflePro.MacAppStore - 139.18 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {576.00002479553223, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2013-07-24 20:59:23 +0000 - Creator - Jay Kreps - DisplayScale - 1 0/72 in = 1 0/72 in - GraphDocumentVersion - 8 - GraphicsList - - - Bounds - {{354.00000274926424, 96.386200297623873}, {56, 16}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 50 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 2 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 DB Queries} - VerticalPad - 2 - - Wrap - NO - - - Class - LineGraphic - Head - - ID - 32 - Info - 2 - - ID - 47 - Points - - {375.94502185497402, 143.5769404965329} - {400.50000206194818, 131} - {428.74999985404742, 131} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 27 - - - - Class - LineGraphic - Head - - ID - 32 - Info - 2 - - ID - 46 - Points - - {317.00000015459955, 138} - {351.50000206194818, 118} - {384.50000206194818, 118} - {429.25000015459955, 131} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 29 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 32 - Info - 2 - - ID - 45 - Points - - {274.95482065734831, 134.82683104667493} - {320.50000206194818, 106} - {382.50000206194818, 108} - {429.25000015459955, 131} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 28 - Position - 0.96286928653717041 - - - - Bounds - {{282.7798816413071, 176.46626249661199}, {70, 16}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 44 - Line - - ID - 41 - Position - 0.41301777958869934 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 2 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 Output Stream} - VerticalPad - 2 - - Wrap - NO - - - Bounds - {{265.50000206194818, 145.99999260902405}, {104, 12}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 43 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 Stateless Samza Tasks} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - ID - 42 - Points - - {361.63447776995599, 166} - {362.63447776995599, 211} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - ID - 41 - Points - - {317.62499995563974, 166.49998140404247} - {318, 210} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 26 - - - - Class - LineGraphic - ID - 40 - Points - - {277.25000206194818, 166} - {278.25000206194818, 210} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{408.75000015459955, 131}, {41, 35}} - Class - ShapedGraphic - ID - 32 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Cylinder - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 DB} - VerticalPad - 0 - - - - Bounds - {{241.50000274926424, 49.500000346451998}, {62, 16}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 31 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 2 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 Input Stream} - VerticalPad - 2 - - Wrap - NO - - - Class - LineGraphic - ID - 30 - Points - - {281.09627582033107, 65.500000346451998} - {359.00000015459955, 138} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - - - - Class - LineGraphic - ID - 29 - Points - - {276.92236275888934, 65.500000346451998} - {317.00000015459955, 138} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - - - - Class - LineGraphic - Head - - ID - 25 - - ID - 28 - Points - - {272.75397078450942, 65.500000346451984} - {275.03969108280035, 137.50025175082229} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 31 - - - - Bounds - {{343.50000015459955, 138}, {32, 28}} - Class - ShapedGraphic - ID - 27 - Shape - Rectangle - Style - - shadow - - Draws - NO - - - - - Bounds - {{301.50000015459955, 138}, {32, 28}} - Class - ShapedGraphic - ID - 26 - Shape - Rectangle - Style - - shadow - - Draws - NO - - - - - Bounds - {{259.50000015459955, 138}, {32, 28}} - Class - ShapedGraphic - ID - 25 - Shape - Rectangle - Style - - shadow - - Draws - NO - - - - - Bounds - {{59.223656370973515, 185.64922458224424}, {70, 16}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 24 - Line - - ID - 22 - Position - 0.36017578840255737 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 2 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 Output Stream} - VerticalPad - 2 - - Wrap - NO - - - Bounds - {{46.00000206194818, 167.9414598941803}, {96, 12}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 17 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 Stateful Samza Tasks} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - ID - 23 - Points - - {134.13447776995599, 171} - {135.13447776995599, 216} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Class - LineGraphic - ID - 22 - Points - - {94.068093287685457, 179.9414598941803} - {94.50000206194818, 218} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 17 - - - - Class - LineGraphic - ID - 21 - Points - - {49.75000206194818, 171} - {49.75000206194818, 221} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - - - Bounds - {{130.75000206194818, 151}, {11.5, 12}} - Class - ShapedGraphic - ID - 20 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Cylinder - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{88.75000206194818, 151}, {11.5, 12}} - Class - ShapedGraphic - ID - 48 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Cylinder - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{49.75000206194818, 151}, {11.5, 12}} - Class - ShapedGraphic - ID - 49 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Cylinder - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{110.13448295556009, 98.386206388473497}, {49, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 16 - Line - - ID - 15 - Position - 0.37310343980789185 - RotationType - 0 - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 1 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 changelog} - VerticalPad - 1 - - Wrap - NO - - - Class - LineGraphic - Head - - ID - 10 - Info - 1 - - ID - 15 - Points - - {136.50000015459955, 82.999999999999986} - {131.50000015459955, 143} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 12 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 9 - Info - 1 - - ID - 14 - Points - - {136.19166917030824, 83.393614022499548} - {89.500000154599547, 143} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 12 - Info - 1 - - - - Class - LineGraphic - Head - - ID - 5 - - ID - 13 - Points - - {136.11642027561359, 83.320733458135152} - {64.383577368540188, 143.30073769681798} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 12 - Info - 1 - - - - Bounds - {{116.00000015459955, 48}, {41, 35}} - Class - ShapedGraphic - ID - 12 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Cylinder - Style - - shadow - - Draws - NO - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 DB} - VerticalPad - 0 - - - - Bounds - {{14.00000274926424, 54.500000346451998}, {62, 16}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Color - - w - 0 - - Font - Helvetica - Size - 10 - - ID - 11 - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 2 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 Input Stream} - VerticalPad - 2 - - Wrap - NO - - - Class - LineGraphic - ID - 10 - Points - - {53.596275820331059, 70.500000346451998} - {131.50000015459955, 143} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 11 - - - - Class - LineGraphic - ID - 9 - Points - - {49.422362758889307, 70.500000346451998} - {89.500000154599547, 143} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 11 - - - - Class - LineGraphic - Head - - ID - 5 - - ID - 8 - Points - - {45.253970784509427, 70.500000346451984} - {47.53969108280036, 142.50025175082229} - - Style - - stroke - - HeadArrow - FilledArrow - Legacy - - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 11 - - - - Bounds - {{116.00000015459955, 143}, {32, 28}} - Class - ShapedGraphic - ID - 7 - Shape - Rectangle - Style - - shadow - - Draws - NO - - - - - Bounds - {{74.000000154599547, 143}, {32, 28}} - Class - ShapedGraphic - ID - 6 - Shape - Rectangle - Style - - shadow - - Draws - NO - - - - - Bounds - {{32.000000154599547, 143}, {32, 28}} - Class - ShapedGraphic - ID - 5 - Shape - Rectangle - Style - - shadow - - Draws - NO - - - - - Bounds - {{288.00001239776611, 12}, {111, 22}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 4 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs36 \cf0 Remote State} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{39.223648071289062, 12}, {91, 22}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 3 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs36 \cf0 Local State} - VerticalPad - 0 - - Wrap - NO - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2013-07-24 21:26:31 +0000 - Modifier - Jay Kreps - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612.00002479553223, 792} - - NSPrintReverseOrientation - - int - 0 - - NSPrinter - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAlOU1ByaW50ZXIAhIQITlNPYmplY3QAhZKEhIQITlNTdHJpbmcBlIQBKxdEZWxsIExhc2VyIFByaW50ZXIgMTcxMIaG - - NSPrinterName - - string - Dell Laser Printer 1710 - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{364, 6}, {711, 872}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{0, 0}, {576, 733}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 1 - - - - - diff --git a/docs/img/0.7.0/learn/documentation/introduction/samza_state.png b/docs/img/0.7.0/learn/documentation/introduction/samza_state.png deleted file mode 100644 index 80a2df667066ce1d64ed54858ac352aefc4e5b63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40635 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 - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGrafflePro.MacAppStore - 139.18 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {576.00002479553223, 733}} - Class - SolidGraphic - ID - 2 - Style - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - BaseZoom - 0 - CanvasOrigin - {0, 0} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2013-07-28 22:22:56 +0000 - Creator - Jay Kreps - DisplayScale - 1 0/72 in = 1 0/72 in - GraphDocumentVersion - 8 - GraphicsList - - - Bounds - {{61, 10}, {138, 18}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 99 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs30 \cf0 A Partitioned Stream} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{241.5, 93.238006591796875}, {57, 12}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - ID - 98 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs20 \cf0 next append} - VerticalPad - 0 - - Wrap - NO - - - Class - LineGraphic - ID - 97 - Points - - {236, 99} - {199, 143.73800659179688} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 0.5 - - - Tail - - ID - 96 - - - - Class - LineGraphic - ID - 96 - Points - - {236, 99} - {186, 99} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 0.5 - - - - - Class - LineGraphic - ID - 95 - Points - - {236, 99} - {212, 55} - - Style - - stroke - - HeadArrow - StickArrow - Legacy - - LineType - 1 - TailArrow - 0 - Width - 0.5 - - - Tail - - ID - 96 - - - - Bounds - {{12, 138.72201098632814}, {50, 13}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica-Light - Size - 11 - - ID - 92 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs22 \cf0 partition 2} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{179, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 90 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 8} - VerticalPad - 0 - - - - Bounds - {{165, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 89 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 7} - VerticalPad - 0 - - - - Bounds - {{151, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 88 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 6} - VerticalPad - 0 - - - - Bounds - {{137, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 87 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 5} - VerticalPad - 0 - - - - Bounds - {{123, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 86 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 4} - VerticalPad - 0 - - - - Bounds - {{109, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 85 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 3} - VerticalPad - 0 - - - - Bounds - {{95, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 84 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 2} - VerticalPad - 0 - - - - Bounds - {{81, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 83 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 1} - VerticalPad - 0 - - - - Bounds - {{67, 152.9680093688965}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 82 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 0} - VerticalPad - 0 - - - - Bounds - {{179, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 80 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Pattern - 1 - - - Text - - VerticalPad - 0 - - - - Bounds - {{165, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 79 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{151, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 78 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{137, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 77 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{123, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 76 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{109, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 75 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{95, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 74 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{81, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 73 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{67, 132.47600936889648}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 72 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{12, 93.238006011962895}, {50, 13}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica-Light - Size - 11 - - ID - 71 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs22 \cf0 partition 1} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{165, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 68 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 7} - VerticalPad - 0 - - - - Bounds - {{151, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 67 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 6} - VerticalPad - 0 - - - - Bounds - {{137, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 66 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 5} - VerticalPad - 0 - - - - Bounds - {{123, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 65 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 4} - VerticalPad - 0 - - - - Bounds - {{109, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 64 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 3} - VerticalPad - 0 - - - - Bounds - {{95, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 63 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 2} - VerticalPad - 0 - - - - Bounds - {{81, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 62 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 1} - VerticalPad - 0 - - - - Bounds - {{67, 106.98400439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 61 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 0} - VerticalPad - 0 - - - - Bounds - {{165, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 58 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Pattern - 1 - - - Text - - VerticalPad - 0 - - - - Bounds - {{151, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 57 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{137, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 56 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{123, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 55 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{109, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 54 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{95, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 53 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{81, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 52 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{67, 86.49200439453125}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 51 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{12, 47.254001617431641}, {50, 13}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica-Light - Size - 11 - - ID - 50 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Pad - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc - -\f0\fs22 \cf0 partition 0} - VerticalPad - 0 - - Wrap - NO - - - Bounds - {{193, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 44 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 9} - VerticalPad - 0 - - - - Bounds - {{179, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 43 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 8} - VerticalPad - 0 - - - - Bounds - {{165, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 42 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 7} - VerticalPad - 0 - - - - Bounds - {{151, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 41 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 6} - VerticalPad - 0 - - - - Bounds - {{137, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 40 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 5} - VerticalPad - 0 - - - - Bounds - {{123, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 39 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 4} - VerticalPad - 0 - - - - Bounds - {{109, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 38 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 3} - VerticalPad - 0 - - - - Bounds - {{95, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 37 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 2} - VerticalPad - 0 - - - - Bounds - {{81, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 36 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 1} - VerticalPad - 0 - - - - Bounds - {{67, 61}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 35 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Width - 0.0 - - - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs20 \cf0 0} - VerticalPad - 0 - - - - Bounds - {{193, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 29 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - stroke - - Pattern - 1 - - - Text - - VerticalPad - 0 - - - - Bounds - {{179, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 28 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{165, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 27 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{151, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 26 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{137, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 25 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{123, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 24 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{109, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 23 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{95, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 22 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{81, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 21 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - Bounds - {{67, 40.507999999999996}, {14, 25.492000579833984}} - Class - ShapedGraphic - ID - 19 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - - Shape - Rectangle - Style - - shadow - - Draws - NO - - - Text - - VerticalPad - 0 - - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 1 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2013-07-28 22:33:38 +0000 - Modifier - Jay Kreps - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - PageBreaks - YES - PrintInfo - - NSBottomMargin - - float - 41 - - NSHorizonalPagination - - coded - BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {612.00002479553223, 792} - - NSPrintReverseOrientation - - int - 0 - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - - name - Canvas 1 - - - Frame - {{575, -38}, {711, 872}} - ListView - - OutlineWidth - 142 - RightSidebar - - ShowRuler - - Sidebar - - SidebarWidth - 120 - VisibleRegion - {{0, 0}, {576, 733}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 1 - 1 - - - - - diff --git a/docs/img/0.7.0/learn/documentation/introduction/stream.png b/docs/img/0.7.0/learn/documentation/introduction/stream.png deleted file mode 100644 index e190041441208d5c1801410e904fd64560f7a72f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19806 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 diff --git a/docs/img/0.7.0/learn/documentation/motivation/data-processing-spectrum-3.png b/docs/img/0.7.0/learn/documentation/motivation/data-processing-spectrum-3.png deleted file mode 100644 index 3c9ff05323cb56c56e83d4f3b31d050594415cc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29389 zcmZU)V_+pg*EJeVY?~81nIse2nb@{%+jcUsZQC{`wr%^KdHjAiKTh|l(^b1__pXh# zDq*tHqHxgI&_F;yaN=S@@<2dfK7e~aND#p1VwPVu5D+G=nV_JoxS$}Rti6q~nWYgB zkSbKAnu#i^Wc}su$)0!z5&J1M`ziMDv3TYd!$d;jc+^-z=ui;iQ2)5^ApW7m@!u(+ z^KyLi^nt#Q;{9}=dda%l^l`~DG2X27Zf|QVD>f-Z2YOs9sHq`LMfcr~g{-TLqpPlu zpr*G*=JSO^1Y(XQcMA?VQPoHf__|ZY5?mg+k+K(E`VxQJ!a45f=;sFZt%x&5sJ5Nf z1=|7#TG+=Di3S3y&zB+OAhv`!B20~o#0=dY!#jV&uwL!O_u1*viten$@B0l7BqK~5 z=LJkiM{K`IA)_ONz=8&(`ie;Zg;;hA*Kyf(@ugLw!J-rml33k6ytMp^MOGY z$Mv}=PWcrMTngY&?>Qb)ykUKH3A{ zTLH;)aAc+bsiBRAo@?=@v3W|Mryrv$63D!ZVRn9vGc5|vaZH$s5@!P*oOW@I#M@gz zgrBSoStMHHYtn+h`<7X&TlkaLqj(F~f!@Xo6pW-C(wQt|^>gPfNOa{RZg}wJMD242 zB38;}_gB<4vzQ^+#VRO<8wA!xWIIHh4qQadX03xs#b+$x_?Cm8iPuOlX9nI&o6Ga1 zr;FuX#C1KJ$bRS~#VTao2Ry`YlJNQAtr@W1P%8>7-ntutR%g|j%QTVKyz|kxCQffe zzM2@9(Eexymwhbl?;m(u#60{-K!SWAhTCvle2}U@9X+_mz#m&G+CupLBV7CxkOI<7 z^pn}>6CM+YhqT71%u#MPqQUp?lc1kHFugt}uPQ!5))2crh!+@EV?f(#L^ zJx>UNMastf#&$~@E*611#ceR8Y=+r@Pn0F0+FsI>(<)I?BgT@QIq7O|3Q;{eszY?TOM$pyouaFMwBIw++ojDcdKi1wXp+q zz2WR46O;<^85iddBpV0nEAT|1Mp4Il1|2)RbI!{|w9js!@NK)O(&Rh)DZSTmCJwkP z5cYnlF6g>1K`0@99H;~zo+&7(E_8)2w=FP4EXz5BKTU%&?i_iS#NmkW74o>7A>A zt^iH%eZ2Nw#^3=P?xnn@Y=NW;sqTZj_Iifmf|ltg*fB!olgmq$^P~_@gqA=s3bGe| z$r&jDQv@$VREjPWY$UX}!7|5g3{@92n1wafZupKYZqNX_isA*C={qHmEvS-@GlMWQ zJ!3N?d8~s;9E?H|E!Ur_o59$XYAQulgs2eI8gL?#b>xzYMuR>ci8e$D zvM*WxtQK#X=p5D=E2O`6XTT2oCp9hU3ypsIm zB3I#?%=mbFghHx9xI$hdWFw>lr!mn)8;Yfpx5z#U7$h0!|AM(_l6`FBNl2LliG zOy>-5kJ?7&#^or6A)|07fFzJ8z$!4#a~GKzqt+wVLpdNi zu-^STWIS|2r$fg>w@G$P=1A5{R#Jvnwoyzt+>w=5G^|z~&Yk+HnE5SA0jomHQo$#&J{@KymGD*j>O0jt&-=@J=DQ>a7YI6tD46*-GB7BADt~W(6EF`jm7u_&j6i8f7U)Tsdgye> zVW=hOZe*fx(=c3QN(?Nd!SJ$B@bKht`0!r+aD8w6L4DBOnwI#MZr9T1STGR*C1RmG zO?}OH33*W_i8|%mDAfAIR>eBS{68jUz-B5ZnkV=tI!xhA{7gwq^hPH}zl;)$Gz_~( z!$#f4(8i-iP!8Y@P!7`fyQxB{U8yrvT&qTMOmkfYY8C7x#nr+p6pI^jXmZZ0H1oKs z`bzXG;|p)a(DKX5(@Iv$+KP$_&~u#?E+X0r+;d*h9$q^8JUXA0FEeMC^ZDmmN*F6g z%TKD@_#M70LOI%BD=Tu(awf@ivsWSvp-i;k^>O;=F^s zyMa6X0(#j4DEqmCyMh~oB}KwTLZUb#8HbFAT8H+?G|95aSjZ%c#)@u=5GG0{&L^gR zcd}qGlczVU_MjJ`yP;Rpe4`bl!Kw633RB8jC}^yCAUbPjRmHJL*H3?Hs%sLp^f<>n zhhNpI)u>%+oNn?tA>2hgnK=>LJ3dt1YdI~ra$GfARa<4>dU}@=IQFD|y?D)Y!F`m!E!*#VPKqgdk$W0gF= zTsSW8rLu&z1$k_|MLuKv1HQ$;ph1sM$!3IcF>4uW|8Z2_wwzj-bnreBiExTIll&<; zC#fviDG@SlkzGx_M>S5P(Y@`n^CFxd0e2v95QMfIUK0M46rIGKqDZ%(SgT^BY^4R? z%B5wc@sT6aT673~lyt7%!dmCNQ?|CyYw^02cKZE{ZjpJ(L>pp>q}r!t$J^k%Xk~Ir zgR1$|8fKHOwcnOJAJ{z9O4a<{BE#C=4BMR5>e5oqrqw~^^zuNtYjM{@>ZxvxVpV>% zX>D&cg|m+X{pxKq`-E%xrEa{{V&88v;M2PPQWOD>!1>|$zJYhn_0Oy7g`GpSgv}mG zAvv5^xR*;76;J1U^`9+<9IlxkB^=944K5{Csus_m%pWEQqEaGRk?PU#QS6c21THw) z-j@%apTaW{)hKc(IP?kHdfG-(bJFP2cG5}R=w4d9l|Q_$qCV5Rnw@QQrd+2yGvKl} zJX3D7p1W+LO{$Ewt-G9hZS}7EyAZB;g1y#Nr9On7O84tWj@EPSUpxJb3h2r7A2=jB zDcv(V^O_l6OW8L$>Spt0Lxj$NH%I6~w5Rz)Kk*t1{hJM!;FDCJrjE9ZgM*%oh?QdM zpk@>)%Jl%OP-x+MX1?*L^l*m)aWsLHbZ3EUN3pAE~*JAuwe=2aLC|!J(Rh2nah3#W8n}~d*eR{cz|%u22{`wsyHOH zDx4}XSIbD3%lLRIJT5wevncSMF|BM*%ygXieJjTQt&4nY>MH?@*Hy1QDyX;LPXoY~v+LyT9!$~18Vio(P ze1}wkRJhEICn}R$n{k~Zn@O5&W~5=5Wh$?URh?h9u9vZsw;y%5+7sXH99il*BK@i( zEJTc{$qNlDX;-aq%^H9kDlW5G@ID_jw>2FzS2Kk; zF+9^=!uj)M7|OQGl+4V?;KXqE1EDswR;q@>*lV3^fpwCupJ$w?pK*|Kabj2ZM9%$W}v@n5(O2E)Rh zQ+TTH$yUfQiqmwmQ=Pp@UeLcDKcto{Puc~q8jng2MGmRak$Ine?$z(#P~X|lC70!w zRc@P0u4;MnQa)57mCclGK7KsE7*0A}%)f4vEi4XLzYq3;j=;LZd*s)YST_802SN!+ z8lu~#+xdW;3uFn`9%Cvq&7*C^g=3k7zJO_if5i^w8geDmG1fqbQ{wcC}iV1zfnEZ(m0 z#5hWhqFo4xlU%{vFCX%5)2_SD9Y$0JUFNGdcq#cf5y70n@Zc6<_(L2+@Db*r-rP!( z&;2{is6)l+<8pYS4O7BWbXS8Ky#-XHIIHrBx_jh=?MZDO3;|OXqnVZ_3HbR|F zuFFiJR_M%em#fum6DWwkLe@arFbX#pfP<@x|54SZ!zt%d`ML5inNHlSX_MW>{AXl& ze@=6bX*0Z)eAW2Rz-f=?Z9RooNDHDmxzcFQTWM~8V z01=E~6lAKSqX}FXBGcov!_1(hgLuN74ngQ+L$L)T7huuL?DO9x9;7NHHDWq0suNha1R zUOvV!Ml;Hj)J~jTwOwpl21vRJIx26)og}POJ6&v=hd?LsE4?qEGTk=NymWnqAK5z? zHv@GgjD}37OmcP2%+T~RZRXA2rm~K6wvTsFuRMDX{LV6P4!nPZMnlB3sKmc=d%Huq zuD#$sSv_bV%)oHrG@$Qdad?izu4CsSsu9p)IgnUi?esp+2u&5#?!Tkn?NO88&XY2= z)py7+8g);3rLn2iXbpHsHx9hN_rla3U{I0MNiJ%(P${r^?d@KGMkP)<0icmVPPaBV zf}|%oxKP;2$o=Su4or8a&xha5{Z|_pi#)SFt*>zJv1)Q!8`|TlHmjH`9qmdt)Rr1< zE?>UR7V!7JppZn3;Iz8H>#?f>AS2(BavEqZJhzJUZWup~=H~UOgF8Cw%0lPba{Dnq81RgfQ+ot|x(xu3_LbDlAqYn(ruePUW>lp_9p z!lA%gk9miZELbs70cXi-d9`A|9*Uckv6@k@*}7iD^@l5=qxo6-;^t@xO&9H%!c~Ss zbXinLMNu|V8<*ZMZa`8_a(;Yfbk}HU|L|ZK%^mHEdPC(>$*uJDSEhS)WN=hbw{jq> z+OW)$+O(L?0$;D};K;~xj=2Aca6SGVsU$o#=o#OBX0naTP*)Gp){VbH`<;r)pqIF{ z41z5|q%Fbq_S5|h)pgh2{1xX}Gg1#O1%V*}E}A`E1Ian)Z_;%JVyavFKSHop6~da2 zJ4ZJHP&Z-BqFynxMfXJ_1$y%`hI#dK(sqU}2V_U=7{{4%yye;z+GXlw?nqjnHB4pU zd$*m~G3rI-2~HbJ5Y}{CaaLS&?*&Okzq$j~)gE+nMW1dac~(B-dq;N&NOXn|v!>rZ$zLCB;P5ZXR`VBZBQvL^fH0wx@W z-cw9}R(qAFtowQwYNuD04_0^xnzJFITLlXkV&v$Ju8?*7w`PIDd%|@iWDys|;G?#q z&%>i5A2{CGbD1a~k5zAtp*?Z4B|HRpXt}(;&l6efD5^&*UPg2@fIRe73$q--C(0&j z(R%@2$?Zta5*)%#$idB9r^m6pS9^w$QO|K7ah1o1yO4uN^ak|pCYLyz~*6;f* z2s%!04DZMcycxeuBXA%v^Wfl5;D>)bk1zSZ{q35ZINrZahf-* z_jE8A_dZ*t|3iPIqtcvf6>>q%d4up2CwiJR0xWkzd@x*kad9O8v@H!bcTdJCOWykbjROWaMCAZ)WRgW@AnGcU(Pv8z)C@ zV&cDo{`2?Gc^bKz{a2E;!@rgVSRno1U+5X>80h~qHlQol-&PJ;Ggl)^RUtDgBWnkM z3?4>C7Dldrbol@M^k0$x(^c(%x-zlM+Ze^&HQb^W6ipf4V1F8crI zo(KA4gkb;(h!03yh+oka_#zX+S5bIw*kr}G2ZU?@2n0N~B*%YeN`b51WQzUlw}Uc6 zhI{bc#1j@&5pyO~Kjmp@4q;Y!I7G>JQY^7}R`2f1w9*SN6ld1D^F;^Cvi9=ww~sBU ztMaPT(~R5O+f=P!Um{&dOpyP3d5GkTa8I_`g##AsL1X}f{XZ96kRq>@r~iLDtY0u+ zPeXMu-^%O%+vV>74fJpD|F0Z?)EPv`)W-!x3Jrq)JB5FIOMNuj`aiP&H4|(QzmDMJ zfmbmB-OmoU{4F<=iBv|1!-?N)HrmbB8?O&%OYJUKmmBRiO)JLY=Z#dUJO)GQHXTI7 ztgEK^UQZh;gWPZD_1&MZ<%S49b-$wVmX@eU{xP^L*x^*>+ngl5I4e2%(Ey6f#Psx% zI_cqL`rB@VU6XVs$3^`#kNSdGsNr2au9eJ!W3Z<_+gDr@Kiu9q*TeG^O1H8J<})!>i6Gd=~RWWfo-O4bRl7 zjyTx0V7-67#u-CIhBcJ{p0Vn#*V7S_nD3J_XE5{~*Qe#x@HninQ?QoGMt~=s{P~(q zx?e71vnuV+gj5}n><7_QaJ`>*FfY=_;nuvc|C$6Mp{yiAk;|r=Nnaq8!Ep2-*j&3y z_2q`gHswsNAjAog(Z!t6_(Tk)D@Zw;*{VuEclS!Yi4C_dpPZdt!8l-v8XI2)WhEuY zCHc|*UwIL9;S3s!0E;?B_hX+&Z}Pb<4-$Q}&P-8gj!$oD04TN{DXl4u_0ZV`AiZV` zN$jL|Km-|2H3?q|L&x(5&t*OLoxb~>>3&Jahjvw^ZS^;^NtWFZ)*Li%kuApPFSd;W zZ>i@WD|E<%O|!^{w)3_zhkq1g;FRc{-D*4hHXp|6yAu-=rLwqQ(k!Z=L>*2FQ*I4l zBu_Jj25+{)$~|H(o#?i}utB15{o?23MO3-onw@358yi|G;$oWQ;1CE70rRMpgDYhX zSaCnAL~+>Zt_GOVYG_>(V8%0wNIfoQJ-)zLtTDEGt_)5ma|flxSrSlv*E{`!3zBYa zPshNSt;)ZnR5y?SZwZvUcNpJ;X5H55c9cB-rNMGVzHNGPl5`W?=hkJ-s<}4+B0o}2 zTUpt8CkTV*Y2D$0Z2-@CIrlR#-B2(mj>Pv=Y1e8N;{M`u_lbFp_u-+B#2pPi6+ypg zItq=nsDjmM)o?8b>8|#4qVvZt@ahb}#C6d~WXbWRcFMO8(`}|W-T-=Nbv&8t(0nQ; zcetSH@;U3eL}a)qzpR;{IB7ehLRVPQw5asBY!y|iuGzTq`FiVqKcG+1a{i6V^Ywmr z)%A8s*M3gC@^;m&2cK=6oGzO^8wF!(J&7Tfr|(|A;tT= z9dLIvjghq{^E20>SXyAIE*~%od`baSw)FFPcXqClKE#%By4B;l!}LTzt-4^29})#U zb^myZ^wK1KiydEg`4?yH1}`}+&pK+2Wp@8G@7F}ytj^c#k|oZ7zNP*1Quil|ULQGu z*F7UWZs75>_jzkneaZqdnM?=S(_AEuOV%6F?60N=wJ)-{ z41I{EQ;^?17;fl>VVf4!Es~OxnH0D`pZD0-Z36@Xjh&8jL##V)hSWhAEf#4eZ|jED zJB-UK;MfJz!lF+UB>-DUsOV3&3}#A>Z+Y?@x}w;EZT zeFHu8iyn14atOc*b_XLGp$5*XyQ>M5(i8o>k2; zL@+_h(Sa?;$5ZH!II-H@&MCjN?Wf5P*rF+;Hty7>Lc=7LlPgwhS^744Kc5XUsfh;$ z!cd%g_J(7Y)b;VrTM>ERuR+xlm?-38v!^8#0@doU9=r4%aCkoxY8Eb-|^r_?F$3gim70Z8}apVeoXKkl=^%)8g+cG>(|HA-7OU?4h^!f z>#|dxecuzE-neYKUUayl-pWu6-=K<6H=M{Hb`XQ1XgH%_57K`7T#aUHuMwh@VpzfIilkL6U}(972344X}Va&hJUPU?EzjTo_a8Zl@fn$d-1 z;LP_8OR3HuH@JXS*W}IFYBUBeKgH5D5RG~Le7g#Yi`w3azH_Xs)nsG|t7Yu#4_4ij zvu*)|2kI*?BWkxXIOMsEpfdgd@H)7Bm1=DyKSMReMXO^&jYjKEhrTev-|XYa=?L{; zW6Q99MIn5&+^MSQ-2kue7xY`U*9~A%E7lUpjZ`=6QfiW5=KwdQs6mQyIGh+MZa{DL z4y})ZNo2Bj{Nx)TQQkqaDUg^Qgm|z-s#-c2a0Bq$-X8aBn3-#hHr2mWU7%77nJQ8g z&ECqCMR(fa;TR{8lmk)JeV*F4PL`)Quedt#06|146eyawqiZ^o6Jl*?)P}Ch!t-To zI3)p|1xB^37gM1T>sBwUl~5#0Qs^!3ad|I#fxwBMAK0UZLaNv+ zXmvFh$2xGc{I(zJw4#1$&K?*0M1ZU_L7GE+oJiGau1bdMMyN8}RL2#IMy)PzwN#GX$1X21)o&(SCPEU0ZMkp2S zb=9K!VyQYixjx;$6D3Wn!8C5J@q695>E(K>rCUmu?JfI3qC$gClOJ5GbEvUsG;V1F zQgBb1u3yOWYDULumSyh3j0w2rZ1- zQ^_Dm44TvBl16B3H5!kz=$!OTprdG|Jbp?K`l}*|TBYmjcK*?xUYdF6#D0vUYR2{F zrmGERR5do)JaKpVOKK)~m2m8hGmwB-M=To*ayaE0da&P;SZ<{qLEU`rF@L0^jym8t zZPXc!Cl~IRd5{}|&#@DTqDTPz@dYsV` z7#9ke6ehR3BW9x8OWgrc{hY?LWWAH{vZtzwSQ@UNE{ni+aklr|EK?&zX7uq~W4ZE; z{t&*wF7fWTC{Y~iy^_`OOm4;xij2UHDcSNlbHVqc&L_hK@1@@MIxXcrv;6ehm=rhF zz-+I_l~ovTsp3rMG{admmu0&UJAxPzk0mXaodq5A!7Cw#>|U{s1b^$3$R%P~tusN8{f}hv)Tb&Zwt~t^`J*=aENxkDWNhL^D8; ziAgCb95|^eeed1u2aGhj(!g(hs0=Y;fMIpcAC+wcKgC2N6<3evp->XZ-b?33g@oSp z5ne}-NV0r(zNzs_AIf0qp*1l$s@j)hrvS8Ia9oi~RP#zK>w!>|IDQNVB_`3%jTB=D zd&;0xNPq$?PyppErK07eB)BP{a5~O~fU|2R;=kbe;WWr(J9hbC6}-yh^;)nG^^^$% zszEPrzgWjG9(})FL)E?~6-nh5*^6i@2DYpk27>M_VL-Rmlrw0g@kps-N*8LD4NgX1 zX~54G$xv{Bh-BcZik2&gKro@1Zq;_uC>R`Ah5^&C0}dWt79$o*gWi;Q&`8tpQj-j% z?jWe^B$UI$m5PlSlIZM#7r-GEM18V599ZtJeK=eYx)2Y@)o6hy%G{cJKvTg1x#tFT zbw_;F!Lf@-$ZE=}Kgs)!A97q-+a$n8xvEl`P><`)P>RME_9R+W&LEZ`fMpyJy>;2^ zr*??72HK+6yst~XJ+wOIsrAT%#t^`?gE%7aVYU-n&baMGnM`I-k`Az+W49axTFzKL z#UmH>@_ydLsC&Gg6gwnxbpidnmMuK8Dwyv&HDjR~KN&w1^s)s6`CmYOuh+Wfx~db_ zTRpxems1VZ6VHEs(en5`?{DXk>}q>GC@ng=Y&b0$o{$z6rf7PGCD(@$YaT4ziiibX zc3W<7y=0Us1@lROg?9QK5t(Div31;{k&oCnQjc^N*krGDy^lTm778JRBo7C} zy_tQ!CpOA27rWRjbiF>FwLfXwZ6(3}`dJ}h5jJE82+iioBo4Ci(r*&1@@9A7gqA#( zK(UoDf;qj2VvoA3fX&Qwk6)Ere5X4$)4@{~Up$Z~sdzZ7NU%*l{^NogE5V&|M>b8b zKe*J&1yBeXd>LUTBx*y6xep+TdOoh0aQFif)8erijoaq79Cm%f5-+5CpX=>jDU6TT$BUKnC7!o)5*w&|ktlh;IIO*Z zr>!L_c6yC^iGql)T-XN*z%Ho1PP6@+wU!_t6oGert6yVd*#6zld_m33Pm^n) zxS?N}d7Ovq5dAH32_79M^x$D1Mdlb@jDrmN4p1_vn~;>4@L#Mpw!eo{12RXElOsS9 z<$W`VLF$Y}{!Qy@ItHKF7`BndOmwsG)XkJ^6R`vYn81!F*Qs#FDk0lLFMHGH?exr9 zMn>IJsJhSp&sx-6gZ1uUMt8^8=Ud2P*$AA$`;izHh>zUo{k%*)DBuu=n7QPZU4r#IwZg1F~eFSf#xmM^J%XOKRkL$PNPKN+d zR0z+}dHq5|)B}vTTP3L#+AiEH%%FymxAPwVN#19hUPmfruouGSss@| zT5acmDrF1-=@JQHT!r20ZimVTj1@>Q2Og;>fYNcHKY-F6jM;0a_dX=kS^XDxDj0R` z8Vs$s6jAUqV=bcd6#J2`^vL0RK~3c>5di%NGX29DRU46D-p8_$sFek%j}ypctiN~l zQHrM4#oqa-_HEja(>6W=YW3etMs>!uhow((=-7aq!5&P)e!Z*ux<8t}u0TS}O3!<< z)yw@iNb>uLDkGdzv0*TgU@)K>$yD#M?FH$G8^k6H`e|@gJB&Z(8@$-*fiO9h^+A%g zT;~Qm49txZdB^Vkej{pR!4)_e5_P1uEC%bhNb!0z%G#yhY+^$-^=rV? zNJ-00nI3@*t7-Y-0sY!wjyZN928z50P@_FXGEZ&)L^NW~YXg8WN?HTvq^g5HpLf~aUmsTwj;<5cX6h-qj^!@DlHPjl^>EjHC=}FJA zMF0vy4;(_wiD;|2PtU=jM1d;!8baWWc++M4^bOcxqi6+1TJ{h_+m-)B1Q2eQOYlSB zh7e0gL4Iuph+i|dd(n22ul$(i_nHo#c0GjxKL3;9BMf^m2>@YO7FyrqoV4% zIumEVxU)n^1yQ2ae~rYNFaBk~-l}jkWkH&WM-Z;w;mR0MJwe{-{-9q5Tdqv9df2~k zthXWy=LZY9-RH1wH*5!{435v0daWq+A|IlGB1$5m!TJs;l@@a|U>j{ZZotQ%`e6M? zl32eNtQ=+g(5=|*4b=_`nt~k2WO68(z7y3BnxQ~?LK?C0{5bmr)Y1uyQ>lyrl^r|$ z5$fOka2IDS8My}v+8Ts6O6c^RCbm{|oM;;CLP?O-4`VB$3{qL41$`5eI_-s1!O`Kyt!`%Y-xsoL^o{9xuJRzwMNqEEQ8XebQ;wnMILH?H3ZID@R2QANCJD3R!Xm z^GzZmB9Otedjia5$m`v%6oKq}Ug|>Anl<9EL13EHq`O*U<$$%%f|AOPg>QQ@JUA~I z7p)zq;dm7~wj3zf#G?}EOhp&~Dyw*e3~Z|2aDP~~pM0d%XE)U=Sl3W9V*Yr1a|u^abF2MgP=0@ugsj|Qq3gaF=N5QE{0Iw8 z)GD0DJJ~i8cl2p{8&xdH9=Km6kVrg_Awk51IFfopo9)_ajrviLG{{$!I6tG*o9UwZ z(I6%(CE4L7jDiRsQW#qPtn}KC4Z>h!+&L~^?*@G{ud!8{08uhg+PPh zuzqPovg+#Un)0~glNXE1{P z*K<|}rV7B7{HFDrJTWo4Di$R=cQmFukuU@*Xhkn{VH_{`xE9SJHDEDGsjqv&$m`py zrL>;+C8LJr&GXl%30){WO8dXSVZenD3Rn$7hN=k!pp_Cb5a|ahIyx%4A}z|b@bzM@ zxHb&8x`N9+wC^dmeV6qGS$x&@S09&qu3o2sE#s07H$;SDAEJ=*!!)Jj8L@`=TMTp| zRhg>1;N%-;Xk8e^y35bpWGube4n5JAwLyT5b67pR{BK409s2v4=}aDouX!!9fk>P2 z15=a2W-V1y70Xi?#P(x}Z-gkvligFR$iJYNOXT7Th}y=zVj>&G6Hnf}q5AufK76CY zAqb#G|EQ67NmMp9>ZR?$wK)lDZ({Y1feeMdjR%ngM2)x&k5mw{tsnpU0)znQJ0e^@ zoL?FV;cCj-Q&8Tnm8NPe;Xw4h_T+~JM6VK5$k9n1CVh7#k^V_%o08X1X`54f|?nGpX`F(stpBIJj>;3ASgGqnN|uC zkIVIWRr5%eYz~^x;sh+;p#lhGz;f0dM)AK`-C9E&uRhlkDVrcBe41$)|Go2IfkS*( zy3RdxA^(tq1mt?S;Y2W7v}Wo^``rcl?75J}2VFl>r-)e6 z2cG9+mBwtOkWf~3l;=u*=q{FDi@)?pX2KWH?q*P zSA|ZY&J%=A+)D&Y=L9#d=`gIId|8jyNKB=HKSXKIwX;BH16F^t1n&c{|2cn{-p%Ax zrq=VEy!scG2l%)yjgZ`84p z3QmTS;bbVbhUgJENk6UbZl6{i>zBHjzfF9B)BMMb(x^cW-Ig`8J2qTCNPHIugvUY@ zdcHdi`@K|rEhR~!gRqFpi~c;I@jk6JK(wNsMP%jq2`f<+n5ZJ5MFGF0`Mo5=5+Dbm z&+1)mcbb2~!@91tmGHGXlJsBiE|`y57~p~@?|av*mZ(AU_I2m_ie+Fm=xp_(BMe3g zu_Ge+>qZak=26h{+?AAjb_b=!?@|zXNbm;V9x4Ypl9i(gQm@B-#WOu|d_Xi1LJW6f zrg!$fs?k4#UcR+k)tzW;`7Ax2h)YHvE2+lfV3>dX$8Li8?*4Lchc_7)bU5gK&#l^* zibloIv#o%bv4f?#(~@DKAI%9()2DE8%S1mMGE;J`+%{c^oCT#b3kFanjPr)!{A`hL>;JyKdO<+UO5Y%9#<2zhyI$D~z$P_YPeg5w z-v&FTm>YpGmWW^Lt0KV6DI~hOLzI@3K$OQHvujIg*IU+fi5Cb(l;>d(qtdb{Q$myu zlp*TC#o@L6gZS0g@!q?^8ug*>|Lwe)xY3Iv_ToSL5P+^m@qwD@001kGqfD0~nd~g& zNdSx_4@gzFiYgif1a%t)frNu%sMryAARdA%sMsZPkoh?$NA4s~*|i+>*{}I43Xon_ z!2|+BRZl__V_4;g<>(rt1ImQV0T3Mv&=bQV=_iG*&v8>2rEd9#%o@1mzqjQdWIyn^ zt}a0Nq~)^lkp1;u44bmlE{gBA56ChT&okH^O7Ixx(4)Y|EW^?#^>G1?n*tI1~CJ~lm|FEHMVF`%Al z9Hn2LrPM97%4YpWbA#64^WO*&#g`x2R;xW69mD(SnlQ9tUFAkZILjhb7?=1qoQNvg zOAvn$V7G00{A4BmOBEmJu;8Et2vfdDs7L;{6#4vkFZy9i03t4`n5$rTX7auOGY39S zHz+hNmo;=dvV1ymCH$ul|9Y-ub1idGt}iWnUb8U2lwUF0Kk~%C9&LrF#&9&g)?gUG z*E;R=1*KcJod60<@%|!%p~&A1dVMzCAB*{-G5mln+NwZq9uW~y3tQRwxZ3@;aV22v zEDT_XPM$a~{?z4c11#&3SC=ouY3T#NY4LpA&jXOm%Z7Prq@9Kj06Kr{zxnof(GDn> zkQQiADI68w^nY0Pt^(M>mC}dXaeAB9gJhrQeuCS(yP&tur_DD&+e*Y#BgMkB^PDkXq-sTx}*gNW!4gJns>FJp;_lHiVRvRF^+S zaWai1f-x2zlRx>}=_%&JiY=!l!H0V8reuOE`A z$@pA}R`X|Xpf=elB3$5%EJby6fHkCZ4oXy>YIJzU?@VZPOL> zz!bpa1IWa$Oqb0U0DX|tVHS95lI0eRA4ITV2H+jBc)j1TEh_xX6%-YJ=$--Z4Mk0l zM`h8WJaE0=3=_mnjl4cx`2diTD?o8l!Ut(&fqsf8K;Qm;n{LzP7Q_9B*|3oVARMKK zhv97MM#)TtQnZ~{W{3n^5++&K&UZoxl)*_UI!=nxM>f6RF76-ZWq2pEc?kquf;N1< zJ^+a9D&Pf$(C=cIWY{gLndE{oegD%}rPYq_^L_(>Hqlo1f16~LGL_?I*)O8?l6V5R zTg)9l2z<<4S(V#gQ|3{==S#biAVeuo>+=-wQy-C(eh6jB064(yKrvN(gRIu|w6Xaa zy{-iJRj6VQ)ju(YAW||Z_LgCRN@n?aWBx{L=%#}FeeK`?;h2X1=fpR=#?OwbhU$38IkTux^dZa}sF^>N>gzzvCH~EQDNYnWY~uvrf6($#R{tE&=EseE zyaSA%0HCL*Eg4QgpOY*yrOld02s=Pk8I8>Xy$dj+qm3Geqba@0nfan$?bm%UjCl6U zsUxy_E11sP{19*ij3D0}FW1>q@9{jivgA$<;aNXM&xK^YkDYgo=EtYIuPu+CLj zB?ti>{on~iPC?BZFcE*TtpTX``&i*(vvBKed&lyMaAiTXSg3yvLlzak-mAS8-G&+V z*dIOW9WXMEBr*<5Qse{H&$KR$O5I=f95w0xibGQbYFv#h#FIW zQNuxW4ML10sC*=75FW>4^+c)POhKpy@_uxgYObD&S4{<-KKd!k^mt{D?TEM|9~uoK<@!#$FQ$eILL=7ZOkfB` z!ic>V-4&E0E{RS`>R6>fKHQol1;JBJdh8&P{_`o0;rn-R$^)_d%n{U`0?j$fQj4>o z1cBm%9ek`{3vBX?zN5>Hp(_S6vG=w81MAt+wJ+})Ze4h{e;40r*dPZ7CEO~ScHfjU zaI8C!e7c*g))p7I>wKWs{#aCZ0zmuhunEAy6uuG8DS(3x;BW*0WE;oT>*%!6KX1iE zh~>z2`w#B{_Kq|IT#wevEL(C3AW&^BU8#cA9$n(l*!c3)`D|+Z6lBUek7@?;>bC*SZzwRM~Q@CkwcE^gWA$3WV z_fI)p%hPtHS4dMhc6W3+DjT`YPN6@SKQ`4Vx4c0nA7M+>35XQ6wG%+*jdx`iE?;Wg ztF85tKC+|`x!7D~@z!mP>DeK?5$@`nrOOGR5UrA+U+q6DXp#JMGBc~-O3ClkESxWr z@Pxi-V1oF4J+QnT)=sEWbwqSvua1?LYjdWmbZ{#ZE((M|#W6ifdCK|;b{Xb_1Nqg| zstugZ(|A#7qa**LN=e$xx=O=rk9sc|{5{`J(OHPq@z|*lRTEVCK0_n(f{Y`k7l$(10r-IuLmGp(i|#K`gJI+ggkP}p@Tcf@ zOand4uGiZvOX_EFq6GYJea6DnG*YYR{-sP4!Hxhzf8~H$IXLL#_|Ixe=nO0Jhru6< ze2$7WewZM{n!45{eN|xRajh2x2*#Kg1cLAcXtTx?%ucu z2?R)h;I6@fI|K;s?(XjH5HyX;S$z9^+5djdJ~v#@PrB$@)m5{`c*jgbXlRP~m9$t= z0^PGyUUNu^n!b7f>vim)+-Zsis#dgzf6my8dU{`q|4_;sDp4ygl}rMcFHO?4u$)Zl zHfx>oasoA`znh>j=$)EuTpvu97PfK56HCHNbtM=*XPn2tB@r@1_V=g03i zgF)TFDa1BEa;*y_`_{74H@Jgae@9}GE86>CSlaSn&Ulx9& ze5wb|_zYp{>u$CSfj{M^EvJoNx>|a}^KctmWcTV_F7S!mDfrC$Q-?RCw#iDk%5u`2 zFX%A+Fo{7igYg3EqU#!IG0gd}6oJBj1jND4t+z8CEIDO&FfCh6rLgd-1U~+o!tFIX z{XeEnZFd!fEtZjge+IcY9=tmxPBlOZd83<3<8Y6XE*FZ5Rh#p^&qu(imq)imA)V*u z?bQoR04CK!PVFTD3jWYX^}M_o>c`StvwwE{_!=?IOcLuo>)a?0xfoyYiNDA-O>5xP4(DyiFAM9OmY_pHaET~31D_3LN;o|4r(%(yKm~o_@r{rEP zliDl16qZey@}dD->igT~;uerSWdI>26&f+Q2Iqh#Zwvmw$OKe3Nf?`VGE_jz)(|}o zlXi^nVsQ#NBvk!*edG%Wp>Uq3wgB4a)4;v;ssXq^H$5@ezBw;M&oEeFo5D107?G?1)^hO5fK+~Acm@d=pq{5k)+i`l@41QbBQiZ|7 z<#HVn_2HfpnVndjx=z%M;NDr|RUN5U<3%1-gnehrV*90s_GNw*hYB8DAaovPy-YPb ziG=c^9$}LdDX<{}of$WluK!F&>=~0XikWFz&VMypSf!{Ijm(T({|vfO2x^kcqcph-k2sHw)U+dWnm$5~tYg4^> z!JC!t({g{W8nMINFE^*^+00lw`@pSXO~>`*hn4#vWzs99L<38m;Z7DDTKU%guF5=( zIgL+9h^#? z-D`sB_i>Q97%wvX74|YMT&|$$QvIdt-}1NA4fec#?y1qPw7urX&xDc8*@?u}4G3imEVp$XzwD16%ke z*7+ejUDm`{8r}sC#7ZcaMuI?;m^&AX#h*Oiy0A^jMifi)*-0QIV-qUd3B+@ytM7nZ zxow&kZ{k1h($Dk-d0ly@q2>Lz$K!iv2|)OA`6>LkkAuT_3zD>p%&C9qT`KRy*Afzf zY)b7FhLZc&^YNV}fM5+D6g&Y+#RG$*ciImGromXJ;Q@yIBVteu60BP-bgtJMo zAXszJM<6%RCEdQ2)z7O3;=O# zu?}E>J80V*xQ(0gel0juD)3A7A2WXd$^~AK79($;9jrPI#Nv(Xc%e&>ynda|{wN#A z&61jaIqjZEhjv7K2}zbAus_GH1uj{#2ZVA=tCT=#DS&SBOPV@1ChBe0EUa27&#*vSeu+tb95j z7Io{Y+q&053@QIfg&28Dtnb@*Ig|2fJeALViNAi!NmXRDa}b~(m=Zz~C7KneFdb`x zbD9ymhXrs;IH8VEeJR)acCS6rss^XC9gVc9GJIQfTx2s_jF=gjheroV19kA>QP2|~ z(oM@&J`&5FP`Zffx_dJVJJejp3LGpY1e$(pO#Yp@HVew1@1y_=L`@HVRuNIH0bg#1 zexh@>d#vsE@sPRLT4b;E?A2hdDdV!|(agZ(T+|WxiYiI)uklfW1DTw6e!QK$-N$tT zhe6c>p3^&PyIG^o{MrRm;z?v!TU+i)6bZ)-l>!5~h6gOX#k`)E@+q(EwFbJv-vgbf zo&w?m+BxMK#H3r!esu{$>Ai@)hP%!J7af7(^yBo={S3g5yHWy#wkVHh7IP~L2unkk z-cX1yf@8z=7sD>{2Mw-~FJV)0yVXuS3}wo#@CbVKPQ^*?#6zZ)GykSxtRP`GFa~B} zKSGTQ<$S96xDCMcdo({iiL$MY!0_d89}8eH@3^nApH~=Fl}RkJ$N6d{Lv}7vODDcC zPL$9M4t}=uN%%fBVXMXzc%9+P6ex*Y7PLk5j-4_t2&%cgC`Qm&JmaR@B_#=UaQn~h zsoMtJS$L@-*R$QZk)djpGqPrR(b238(!OJn)GkdifPejUAG}CdfU+6LVVI_n7l?Tc zpqQszW95KqNR_!^L(;blVO+ir{m zK2Mv`M;b!orG}>^4oQDUD}4r@NsUp}kKFF}y1re}m8;^@dq|&6mXPuzl$X)zLeUhJ+E|la z-cwQ$-5H5|Q z8@1ReO9zHMMZW7+F-Msp{uZs-t!sJ!$uRfVGC|O`^1lpXH1f5~S{~Y6>VaD%*hAQo z`Gn|A(WdA}cJFN<^kJg;PY101qaQpUU9q)(D%K}`38ZsoI@-ul%km_h*2m8i=zlGT zJ5u8%t*bA4ZvEiMH_Mef3ah*@ms`YV%%@S>jh}IKVfA*MlQ1|L6hma>VDE-GvSyMMs`5t-qgD$&Nr;-t6JOn*o4Ab%af``PUV?ElS* z%LzPa*&|B%lO6{FzIDGxR%I9+U$@s$TwGr{D^$a==a(fMK??pfByza|Df#B&K}du2 zvrI&1Bppc1U)>kDD{H%c^YQqp(@N*X&S?7Y2FjuI`rtCgS5KQV&``0YW(X!rA?^FY zMDxDr0T#!e`efR@^k`bGs!nRjPK{^KDkacx`gZFA4kui{J%{dG_F zf?olGvmeVu+_;e0bDJDL0+!!%Q5J^YImIXNj)uk4&zN=9b%_j7BFU^u&|TAJmPqF* z^TE1{@_uj{A>s{kOTzU>91KON5t`4AY`?$F^?bU_1wM0Is^njTWRw7ahf{8@>YK}{ zp(gZJuzIi}Y}gE4FBz~>l54{1!9&qWsxsT6`Na#=*j75(k6GGKJ=4ltneZmJrTGd*LWDui#t0pnp&ORY+RFEx@dCx$Xc{?E_L`!vsv1A- zH#(BX9AJc#^0L#UaZ-L!wBJRx=k=&FKQRFW|KB|`4482EK(ru{RZ)$}5rU9TPtZuRvpA&E60MW18X!y6M50^`@v_OwU$**81*uWrvxqn`>-n-bxp~y&F ziTf15;Ir$_PeGgXeOv87mgm-)5E&=OGohu{{I%YIU#_uM(_Uy&IM%eS85$q|IGGcO zWBK<%01Bw<3^Ups9PLLJzQ{A%uGw~GQMT``-(fjoA=rMF7ZY`EgZyh^fk(joQ3 ztje2FXNKrg{rCF~%u}$4Vq=?3o@u2s@XG;6->t1Jb3ilKZP}R*MDPJ@-5fxJnnHi@ zF!x=dGX-65FFj1pRdUWp*UFcB1-^|~YDU+^E1u8cwE)9svn~DiI*fY_*s)P*n!wIL zL6jOcB<}9-);Z`X8%|Y`)Js@f(=y+1#+ut7;X!yX7gvkf(3> z(db-z{y0j2;3)YI_ZbSV)8Q?w~3cPppZsy#LQdf5Iw z_`i|HpaEZMwl33zAQ4wo5eRy#MRWvh>*2(f^=b8~qXCw+AdzqTU1cpfSoB_&;ZJCm zP+W*xe2I5R26_7Na@c$;HyWDwdIIy;o*sz*!QJ@29;@{9$wx78!8PR#ZO@)tKnM~L za)Iob_sjFstNST2o{`S)THGCVBt8QWj6x18JmP>L@AOO8949eLkz+7{kH+UW207yO+n)ZXW z260Q(#Il4?jrG>Tc87784O=Ed4lBE&D*ZU=z&XnuG#Zfzx^_mp=A$~`6n0BwdT9)5 zMYAWXXC-0qx=l&j(>?ffm+4wi({J)WW?C5!AZ9fBa)n%!gupYCQbd%3H8!iB#}IFo zYZ96C_*{o(03SZ(65v%gfn-eAO3ffu>dd}~d>v4$^yuE=CY*ld`V6|-!YI^0)1xFoF``?vvkVpuyZIR-G zrN=V__0*ZaP6b8dIxS=ehqCe1G zRzbH9xStJcp2y}Jr3$mjtfuE5M7j4 zz2v$x5Zeyeg#-W}3mD%mKx`U7l|KhqCYXIbpQk%q;^TzE$A{oxVv-T_OAe+n&eLv9 zUam=G}<_Y=3LOT>I>J7q0MWT;OU103-a60iB?p)t=C?10q!R;h!&} z?<}#eO0Fd9nG*q!!X7F0x`4k)YJY@QoGU+8dhi6#YB@CSmj5wXnm@W-B`d8mK=SPf zP!i53i1GyzTdk_s!S7~(Ky>~Q;91KIng+fq;LNZamLXFKr(#L!oF8Wqsvm*Z;Lux? z1i&+D*+&wj?8|6UgctY6<-^k-lrXyfV^0hrF|I3zB>^YELNHtc-JR=RdjZ(5HgV>x z!YP}Z_fRS=j?OLHxtw>tE3ci?wKG&2WC0?O(S1=8v4BT=c8}ut@^q-=({)GP^$1`p zui4fGV}B$?p}U=%b)Of&ku_&t%=+N32#~};o_9TsWw@;>7oC5C%-+ajH-WkB7E_NS~mO;fOr)K=ozra&l3YIfrQv`Su<1j8URte+BvYPX8YrrF93SbL=v{$ z|EqRS7w{MXCBiNoTDbC}Ks6U2bY8g$K&~M+loy9NYuE5uNpk}vR_~{KjjiekQe|pb zxQ)-x02*|_$32BQ7H-ASfz;At_ z(Kt{q;>ejjuL?1Wp$Pzqbvag>KEGyy060KG;&JD@5-RjK5aB?dY-@;>V{YZJQ*1{O zx+Rgk(=zhnG)d}5^;rM~ZzkkDTE$K9pS4_t#FCR|Ur+AV5%D-)Gb}D81e^?s85WGC&4LIjaYw?LTj{*z~wR+k&XWMJ~NgbB{0qH3%d#C?cvyrx<39$ zd3QkO4$!{^kARFgQ3d!7tvD&1#H#ytWc*c7XEOp+InM8;`e1h;_}Y>yjlpFdpb+2< z{CWA;z`l|g_xiY1MSJdIUVv5l-FdBM0Tiv>l?57!>jG$<3@wgb%OcgWV>CX3YwjHW z9Bx_C?o=So%EqkU;0V}FIX0uUb4`F54wB?q1v2^?w`YLYYtGe$TEq&8>#KuILa2DM z$6DF06uQdK4&FbtuGH)AJ;i&NdoX=|SbtIcA@F1U(k~D}vsBwR0RN_qkE^F`^kWR> zL@~cN73&|GJ2>jX6TLU%%2e%M3(2Yg_tNha5=*7s<>7XVW;`CPURl!ZRGEB~@pT7PK!-5k-beYcN6>OqTmmFQ2vsb`mS&D@we176mo);v@uSX_ z1%226a5XA2ms|929!EjP<(3Lb+@Xl34O?Nu`LjUq1h1;HsZ_K4oJh2W+1gJPis07* z)A%r%rC{!?vcyiba{L5Yq=bXDC`k4x1v0FdLtV`x-rC|YC1ja;K$*w%#CK`pu6lJ*$m$$pkMxAWab~V9*gNfKV;q%`| z@c|&W_g_{jzh-@2_PPNgJ`Vu$6fDVZaz{0@`w9H6-Jz+E{sCAwT`kPc+D|%dUmM*F z{IhNJUK@90!I3L#E#b(Gi0hD#fFa%yR{%W5#;?&!)b9k6&z}xJYx`it{v4nriM9SN zgE%&_gj23s>clQs)fXTKc|~m~akwMrk*IKxuDmc(Qj@~{naPE@+z|*Sn~@{hUhpWH zpZ3~7ziuOcQqO@kwnaeh116{CFQ|~Zs264<@n-4r0OD?v#REB1p*nT|Wi+8X+va#Z zElT-GOhA}`F+k)kCg)+C9Mj}w{1VQGd~<1@E1E*o0ZdZ=cPNSIhIPgkAMOF{DVpWG z7X=#pWp1=k+!BC3ggDN=sl~#;KGQoWu`xC5|$&dvZjqKY! zDV%o6k^z-27DOIt)pmdLsQTb3$5;Q!(GWQ_oj+9jKr)4)v$2%$Im)w~)g(akb@Jap;S*zD-4Tq@AlEOH)@VcuEq8X{mu+4$t^c zvhJF+W)k|cEV<@faK)%V5+0vKS>~Z>J9WWe+T^o>Qr@)bXK$Q`5?;cBj)c}ETJqfr z#2)>g_3a(5%WKrh^7u$swYx#~daG<3qim4A&3nN3+3W}F-UZ&SzdTcGoJ+$E532f& zy99VFR+$HkSzAQQ{)=iAn1VM}pG1G_ zmWXZz>r`t)7E+|6MeC_~uORDKkv5<59TyM^Xh2_SxX+Hv8PSbcBavec!ZF?!U z=8F==&)}|hSnYN@9f^r_<%Z{)aLuxjl9N=V)FX?fysN(SK%v_#|5|0($f|?7tGn>S zKu%qGmzJv6zBoK`w%>tVHV8abidu_jBOY%K9Qj!?WF3(8ik!3`QP*4IcdOWmwcLX9}8+-59N)?|6djdDi?8>9{myWkvg{?r@Lge%4^yRENT9RCi z7q#%^4pFf+*!Z)crJx*^g8O1F4m=#;w{AZ=S58||dc&y(V((kf#mAgHAZGdrfDwP; zy?LAQXO#O$o2k2^1|4z`{zpP7I+S}tEEtg(<;$omV#9AuPvb-Org?pPqkwnHyriAZ zAt9sz-{OylWqU{x?H;;nDD8EE;LHp1CNHL<>s1vRA|hSO)Cv_7ioHb+!{<~*R7I>wUpq>3yNR0Xu@qAwVlseVr zq%jrU{AyXV_Y8=o+XF1g^zlafV#PcK5l9yd?tviRcy>yaU1hbpDpBAnZe;>n^qW5I zm~9#~gH#|3LN-XpA|vaRWjq$w9iZjM+_JB6zc69MgnUwHo-0-guhr)5GYAOZd}Lw1Ub*&X>@TdbZtD8QE|Re(|yDs zEb5)#uo;GA<3^@!vLDHcwIVAXyQhpVrRL@VM528@mGFR)n`@JfxOv z2I@7c@OsolF9{xO2QrPZyIl$dTC-V`a52(`osw}BKjBhy4rf~C)BIGsc0_uE1 z_8`i&3c9zWjW&li>`JstVYJ8w2woBBU8CDOBfU`4sK`-*6pukoC|2K7kTg;WUbQ6! zT!@y^<$}zlh6?~vG{y-d>5w0cTaO0%BUL=#$I?|De?(>0Z!`&F#k*JBrV=t(VVT6dZnGmNWm$jy>@J#o4zBBU( z-G!27AaYNxZ8*(ktLKN`Y{K>{gj=I`qzhODLIPj2%R%`FeY1>1?cGPeO-p{R8 zc$x;DgOhF)p&r4M>8Xj`3Ea@eXdU4{Bw;nRrKHOCP(x4F!$pR@?aAFBzCVt<7QL9k zt?`J29f5*rt83^9!H1MHZDV}L41}TGK_jB>m@YgIz-=%H&blNJPL0B zZPl_sN)#$yk(D)GYEo zXZG=aLkuNb!t6j&@XbXV2G?X;*5Y196)AGtV~*RpDT?~fctl!+N}^C=Fo4Prq3Q9w z3nE}utILV$CAhOUjfguZKpO*yn#~=T&On?hC_m2fZqMV+H|)M@x?Y`)gD_&1H<2C4%s-L7ZRUY{f+!v2AuMB2>Tx|e zB-|Nn0o~Mhs<+56w>}KeL6KW?qXblo9hv3(#duZpe(aJgB$C*9^6;;X4VFWnNDy<< zwW+lT)iBpEq>-v*hkj$&p2Qp$n7pE--*+rs%0BA&XAu?zcl^O)U-(Hm`72beXP9`7 zF|oqqg)}O#Z1Onrvv#@v1U{xhNx()eooW@Bi)pJyGA3#!juJf;^XOg+DJ3KTarjBC zfTvscW|SL8QBI8v5RYWFkJ@64aHs`HaPkAEMJIpqFhsjpIQn-M_4cs<5y<0O{1JYh zz603v>$`qoVv^x7l@(Kzw{U?jR|6VOZ%W|EkS@3G2qOMI29hA;146s!sNY^2Dd0RI zS<|F-m9Itbr+G!SA*x8sAR*ON-mHB=s0I!mMl?q>97leA`WxZpomY8z1cA9h#AXq4 zY^*5W?F@LTmm%a)s9fGBq6cs+o8vnCevz~)RlU8FUPnWkra8lX1Q_J8zcG&L3B$-# zVRiH=&2jpRiEMaSUgeIgP*N6?TNb!T$qDPaUUW@j6v1>C4pg+%&YeDfd(7xZdBo^= zWs0Pm(^UdR!E2Vr1P9zrGs~a9K44%C>lICrvbr8&R%zpRiRR|QQUrgfiSraSzW;Lw z^jpI8dXsQlu2QAU55N`OpbtHzM<3`7ht}KW9!Ahfx zD9m+eP_rUlH1T*Cl7%hiskRO|B356{MF^OH&+}B71K#m?rHY4xdu_yy1)B3Hjf5s&dhzFwWgDIwu z%bSs5tVJJDuM37cq6AO1X-gNC$xSOt0d*Fj&N;ROkOO{vRG#bd#YHlFq&!oiqHF^U~*`Li_N4@^9wkksrLs`3t?vj z*-p48eeq%=MDoR|zL)&U8$;VD;-B@{u_U2=n5;yuydW`%#{K#I#vBB_wGb@*{iK!| zSuSDC11%Ib){gIYxGr`(uO{bAE^43x^KPtu%kX7*B$T>1NUUV$Cfo5%iQ7l~>_EWwcW=*6?PmPFknn{ZSe+kw08^5A(+NBMU#5+8XCOdZ`p+!PkyD zAQ(rFtE|SlS>f~A`L>urLJ5{`=|7l;$}F+j0k(yr>Ys~Z_Ywie-Ipp{z#ej*|xuFdJMLtY(^KKA87j*(2uj(-nXFA3aKsA^j(OUvmGRU)NhkC+Tq;)6f;JC$c2X6VLtm|zQqi3UGT zY?2O0BXbv{E~V6-!TPwS7G38%=$|0L38vzTIOAxde*g?kSdxEc!Xn@eJTCLDKI))F zj0IG{YVm&o7$TmpBa$Y2^#*urKqLCa2%qp%7L(Q<$%jy@@W9)II%3ytO(2h%XlDM7 z(Xql#R`O@36>L-U&j_RN z5I^3!k}Fp?eQwqP=Igbp2@-#!h4A&o`w6Udo#jBN-OU#5t9ioL$(_MtcBuF!T-w-0 zs557OEWNoChG64x)UXs*%$X~dD$O~7OiFL1i_%%Jb)$8>)v-ynN}gUO6sV$UL6xsJ zp#Ry#wn&6T=b^ZWoz50Y*KE`};=f(DzdamqAvvXhNlG!b{2P}4kLI-l#K42D>L23y zSC;;d*NS){Jvcww{J;M!%Y!5)GgFD=%jvAB#_XQ2-c00DmZkmw@)iTw5LW^t*tFa1 ze?7Cm17vZ%wsj%+Q~K+_9@PJ6`Mdafgw{#pW&SU()xJLT|Nnr%=aCq?{TIReI~?G7 dBSF5PR9DWgcK!aE_S#)qMnX}%Ow`!#{{U=$rtkm& diff --git a/docs/img/0.7.0/learn/documentation/yarn/samza-am-dashboard.png b/docs/img/0.7.0/learn/documentation/yarn/samza-am-dashboard.png deleted file mode 100644 index 949a2f0c70b95247255e705e9d910f77de610db2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55603 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 Lv1SSE4)Xs2QFNC> literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/comparisons/mupd8.png b/docs/img/versioned/learn/documentation/comparisons/mupd8.png new file mode 100644 index 0000000000000000000000000000000000000000..ca7998269004d1aae0f328da16df8149536d16c4 GIT binary patch literal 7308 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 f=KoJgFWftF*ruh#`fYb* literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/container/checkpointing.svg b/docs/img/versioned/learn/documentation/container/checkpointing.svg new file mode 100644 index 0000000..676cd7c --- /dev/null +++ b/docs/img/versioned/learn/documentation/container/checkpointing.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/img/versioned/learn/documentation/container/stateful_job.png b/docs/img/versioned/learn/documentation/container/stateful_job.png new file mode 100644 index 0000000000000000000000000000000000000000..e48607949b40a424293ecae0c297a0835d261079 GIT binary patch literal 26142 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 + + + diff --git a/docs/img/versioned/learn/documentation/introduction/dag.graffle b/docs/img/versioned/learn/documentation/introduction/dag.graffle new file mode 100644 index 0000000..d743ea4 --- /dev/null +++ b/docs/img/versioned/learn/documentation/introduction/dag.graffle @@ -0,0 +1,1009 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro.MacAppStore + 139.18 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {576.00002479553223, 733}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-07-28 22:58:14 +0000 + Creator + Jay Kreps + DisplayScale + 1 0/72 in = 1 0/72 in + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{43.000001907348633, 12}, {208, 22}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 39 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs36 \cf0 A Multjob Dataflow Graph} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + Head + + ID + 37 + Info + 2 + + ID + 38 + Points + + {236.00000190734863, 144} + {231.00000190734863, 224} + {147.00000190734863, 292} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 23 + Info + 1 + + + + Bounds + {{113.00000190734863, 292}, {68, 27}} + Class + ShapedGraphic + ID + 37 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Stream F} + VerticalPad + 0 + + + + Class + LineGraphic + Head + + ID + 37 + Info + 2 + + ID + 36 + Points + + {147.00000190734863, 268} + {147.00000190734863, 292} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 6 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 6 + + ID + 35 + Points + + {147.00000190734863, 204} + {147.00000190734863, 232} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 27 + + + + Class + LineGraphic + Head + + ID + 6 + Info + 2 + + ID + 34 + Points + + {60.000001907348633, 204} + {147.00000190734863, 232} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 31 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 31 + + ID + 33 + Points + + {60.000001907348633, 144} + {60.000001907348633, 177} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 28 + + + + Bounds + {{26.000001907348633, 177}, {68, 27}} + Class + ShapedGraphic + ID + 31 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Stream D} + VerticalPad + 0 + + + + Bounds + {{113.00000190734863, 177}, {68, 27}} + Class + ShapedGraphic + ID + 27 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Stream E} + VerticalPad + 0 + + + + Class + LineGraphic + Head + + ID + 27 + Info + 2 + + ID + 29 + Points + + {236.00000190734863, 144} + {147.00000190734863, 177} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 23 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 27 + Info + 2 + + ID + 28 + Points + + {60.000001907348633, 144} + {147.00000190734863, 177} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + Head + + ID + 23 + + ID + 26 + Points + + {236.00000190734863, 72} + {236.00000190734863, 108} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 22 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 23 + Info + 2 + + ID + 25 + Points + + {151.00000190734863, 72} + {236.00000190734863, 108} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 21 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 5 + Info + 2 + + ID + 24 + Points + + {151.00000190734863, 72} + {60.000003814697266, 108} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 21 + Info + 1 + + + + Bounds + {{191.00000190734863, 108}, {90, 36}} + Class + ShapedGraphic + ID + 23 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Diamond + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Job 2} + VerticalPad + 0 + + + + Bounds + {{202.00000190734863, 45}, {68, 27}} + Class + ShapedGraphic + ID + 22 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Stream C} + VerticalPad + 0 + + + + Bounds + {{117.00000190734863, 45}, {68, 27}} + Class + ShapedGraphic + ID + 21 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Stream B} + VerticalPad + 0 + + + + Class + LineGraphic + Head + + ID + 5 + + ID + 20 + Points + + {60.000001907348633, 72} + {60.000003814697266, 108} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 19 + Info + 1 + + + + Bounds + {{26.000001907348633, 45}, {68, 27}} + Class + ShapedGraphic + ID + 19 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Stream A} + VerticalPad + 0 + + + + Bounds + {{102.00000190734863, 232}, {90, 36}} + Class + ShapedGraphic + ID + 6 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Diamond + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Job B} + VerticalPad + 0 + + + + Bounds + {{15.000003814697266, 108}, {90, 36}} + Class + ShapedGraphic + ID + 5 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Diamond + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs22 \cf0 Job 1} + VerticalPad + 0 + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-07-28 23:08:05 +0000 + Modifier + Jay Kreps + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {612.00002479553223, 792} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{424, 6}, {711, 872}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 0}, {576, 733}} + Zoom + 1 + ZoomValues + + + Canvas 1 + 1 + 1 + + + + + diff --git a/docs/img/versioned/learn/documentation/introduction/dag.png b/docs/img/versioned/learn/documentation/introduction/dag.png new file mode 100644 index 0000000000000000000000000000000000000000..d0df7e3a66df2e254bc9c9e6fc7eff606ef27f82 GIT binary patch literal 34869 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 JFK-g`e*ojPzQ6zg literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/introduction/group-by-example.png b/docs/img/versioned/learn/documentation/introduction/group-by-example.png new file mode 100644 index 0000000000000000000000000000000000000000..8584600b6c532ce1c455ee609188b0e08d1cd422 GIT binary patch literal 17509 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 E0L9QI=Kufz literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/introduction/job.graffle b/docs/img/versioned/learn/documentation/introduction/job.graffle new file mode 100644 index 0000000..2c5a994 --- /dev/null +++ b/docs/img/versioned/learn/documentation/introduction/job.graffle @@ -0,0 +1,512 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro.MacAppStore + 139.18 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {576.00002479553223, 733}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-07-28 22:09:17 +0000 + Creator + Jay Kreps + DisplayScale + 1 0/72 in = 1 0/72 in + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{41, 144}, {81, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 36 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Ouput Streams} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{47, 21}, {75, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 35 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Input Streams} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 34 + Points + + {100.76664679221969, 109} + {100.76665277122837, 143} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + ID + 32 + Points + + {59.5, 108} + {59.500005979008677, 142} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + Head + + ID + 19 + Info + 3 + + ID + 23 + Points + + {99.5, 38} + {100.00000220537189, 71} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + Head + + ID + 19 + Info + 2 + + ID + 22 + Points + + {81.5, 37} + {81.500001470248037, 71} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + Head + + ID + 19 + Info + 1 + + ID + 21 + Points + + {63.5, 37} + {63.000000275671482, 71} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Bounds + {{44.5, 71}, {74, 37}} + Class + ShapedGraphic + ID + 19 + Magnets + + {-0.59628479784302701, -1.1925696134567261} + {1.9868216701487083e-08, -1.3333333730697632} + {0.59628487781105233, -1.1925696134567261} + {1.1925696134567272, -0.59628480672836304} + {1.3333333730697643, 1.5894572413799324e-07} + {1.1925696134567272, 0.59628473564567486} + {0.59628465308492307, 1.1925697326660156} + {1.1842379282265398e-15, 1.3333333730697632} + {-0.5962849488937394, 1.1925696134567261} + {-1.1925697326660152, 0.5962844398368361} + {-1.3333333730697625, -6.3578289655197295e-07} + {-1.1925696134567256, -0.59628480672836304} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs28 \cf0 Samza \ +Job} + VerticalPad + 0 + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-07-28 22:21:28 +0000 + Modifier + Jay Kreps + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {612.00002479553223, 792} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{364, 6}, {711, 872}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 0}, {576, 733}} + Zoom + 1 + ZoomValues + + + Canvas 1 + 1 + 1 + + + + + diff --git a/docs/img/versioned/learn/documentation/introduction/job.png b/docs/img/versioned/learn/documentation/introduction/job.png new file mode 100644 index 0000000000000000000000000000000000000000..4a90b8c60b9a42f958535471ab04968ab367c7f6 GIT binary patch literal 8954 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 literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/introduction/job_detail.graffle b/docs/img/versioned/learn/documentation/introduction/job_detail.graffle new file mode 100644 index 0000000..1583d55 --- /dev/null +++ b/docs/img/versioned/learn/documentation/introduction/job_detail.graffle @@ -0,0 +1,1320 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro.MacAppStore + 139.18 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {576.00002479553223, 733}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-07-28 22:34:27 +0000 + Creator + Jay Kreps + DisplayScale + 1 0/72 in = 1 0/72 in + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{59.583091735839844, 17}, {71, 17}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 59 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs28 \cf0 Samza Job} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{101.5, 113.67618703842163}, {53, 34}} + Class + ShapedGraphic + ID + 38 + Magnets + + {-0.59628479784302701, -1.1925696134567261} + {1.9868216701487083e-08, -1.3333333730697632} + {0.59628487781105233, -1.1925696134567261} + {1.1925696134567272, -0.59628480672836304} + {1.3333333730697643, 1.5894572413799324e-07} + {1.1925696134567272, 0.59628473564567486} + {0.59628465308492307, 1.1925697326660156} + {1.1842379282265398e-15, 1.3333333730697632} + {-0.5962849488937394, 1.1925696134567261} + {-1.1925697326660152, 0.5962844398368361} + {-1.3333333730697625, -6.3578289655197295e-07} + {-1.1925696134567256, -0.59628480672836304} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 Task 2} + VerticalPad + 0 + + + + Bounds + {{126.51412229515523, 156.70258726469865}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 53 + Line + + ID + 51 + Position + 0.37774357199668884 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1} + VerticalPad + 1 + + Wrap + NO + + + Bounds + {{102.02543265311756, 155.54622220993042}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 52 + Line + + ID + 50 + Position + 0.30659866333007812 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 0} + VerticalPad + 1 + + Wrap + NO + + + Class + LineGraphic + ID + 51 + Points + + {142.95187377929688, 143.38228750228882} + {110.02543265311758, 197.17618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + ID + 50 + Points + + {114.74999684095383, 147.67618703842163} + {86.294020898085591, 196.17618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 38 + Info + 9 + + + + Bounds + {{83.310078640505097, 156.09778326749802}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 49 + Line + + ID + 47 + Position + 0.31154739856719971 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1} + VerticalPad + 1 + + Wrap + NO + + + Bounds + {{59.583090066240111, 154.42674145102501}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 48 + Line + + ID + 32 + Position + 0.28351658582687378 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 0} + VerticalPad + 1 + + Wrap + NO + + + Class + LineGraphic + ID + 47 + Points + + {78.249995261430769, 147.67618703842163} + {107.33091014225297, 197.17618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 37 + Info + 7 + + + + Bounds + {{74.999992370605469, 197.17618703842163}, {46, 26}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 46 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs22 \cf0 Output \ +Stream C} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{137.96903325656112, 78.093316394752037}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 45 + Line + + ID + 42 + Position + 0.4247739315032959 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1} + VerticalPad + 1 + + Wrap + NO + + + Bounds + {{106.55560185205636, 77.46781401806038}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 44 + Line + + ID + 41 + Position + 0.41218578815460205 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 0} + VerticalPad + 1 + + Wrap + NO + + + Bounds + {{115.5, 41.796580791473389}, {46, 26}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 43 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs22 \cf0 Input \ +Stream B} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + Head + + ID + 38 + Info + 3 + + ID + 42 + Points + + {142.5, 63.986382961273193} + {141.25000157952311, 113.67618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + Head + + ID + 37 + Info + 2 + + ID + 41 + Points + + {142.5, 63.986382961273193} + {65.000001053015481, 113.67618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 42 + + + + Bounds + {{72.487797844925495, 76.103014686803647}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 40 + Line + + ID + 22 + Position + 0.39506399631500244 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 1} + VerticalPad + 1 + + Wrap + NO + + + Bounds + {{47.596244023754139, 75.593161679834566}, {8, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica-Light + Size + 10 + + ID + 39 + Line + + ID + 21 + Position + 0.38497579097747803 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 0} + VerticalPad + 1 + + Wrap + NO + + + Bounds + {{38.5, 113.67618703842163}, {53, 34}} + Class + ShapedGraphic + ID + 37 + Magnets + + {-0.59628479784302701, -1.1925696134567261} + {1.9868216701487083e-08, -1.3333333730697632} + {0.59628487781105233, -1.1925696134567261} + {1.1925696134567272, -0.59628480672836304} + {1.3333333730697643, 1.5894572413799324e-07} + {1.1925696134567272, 0.59628473564567486} + {0.59628465308492307, 1.1925697326660156} + {1.1842379282265398e-15, 1.3333333730697632} + {-0.5962849488937394, 1.1925696134567261} + {-1.1925697326660152, 0.5962844398368361} + {-1.3333333730697625, -6.3578289655197295e-07} + {-1.1925696134567256, -0.59628480672836304} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 Task 1} + VerticalPad + 0 + + + + Bounds + {{28.596244812011719, 41.796580791473389}, {46, 26}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 35 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs22 \cf0 Input \ +Stream A} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + Head + + ID + 50 + Info + 1 + + ID + 32 + Points + + {54.596244812011719, 147.67618703842163} + {86.294020898085591, 196.17618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + Head + + ID + 38 + + ID + 22 + Points + + {51.5, 63.136671841144562} + {114.75000019744039, 113.67618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 21 + + + + Class + LineGraphic + Head + + ID + 37 + Info + 1 + + ID + 21 + Points + + {51.5, 63.136671841144562} + {51.750000197440386, 113.67618703842163} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Bounds + {{25, 96.176187038421631}, {136.5, 67}} + Class + ShapedGraphic + ID + 19 + Magnets + + {-0.59628479784302701, -1.1925696134567261} + {1.9868216701487083e-08, -1.3333333730697632} + {0.59628487781105233, -1.1925696134567261} + {1.1925696134567272, -0.59628480672836304} + {1.3333333730697643, 1.5894572413799324e-07} + {1.1925696134567272, 0.59628473564567486} + {0.59628465308492307, 1.1925697326660156} + {1.1842379282265398e-15, 1.3333333730697632} + {-0.5962849488937394, 1.1925696134567261} + {-1.1925697326660152, 0.5962844398368361} + {-1.3333333730697625, -6.3578289655197295e-07} + {-1.1925696134567256, -0.59628480672836304} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Pattern + 1 + + + Text + + VerticalPad + 0 + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-07-28 22:49:23 +0000 + Modifier + Jay Kreps + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {612.00002479553223, 792} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{706, 6}, {711, 872}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 0}, {576, 733}} + Zoom + 1 + ZoomValues + + + Canvas 1 + 1 + 1 + + + + + diff --git a/docs/img/versioned/learn/documentation/introduction/job_detail.png b/docs/img/versioned/learn/documentation/introduction/job_detail.png new file mode 100644 index 0000000000000000000000000000000000000000..31f67070c2737880f38514b90587226c72a536bb GIT binary patch literal 18176 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 literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/introduction/samza-ecosystem.png b/docs/img/versioned/learn/documentation/introduction/samza-ecosystem.png new file mode 100644 index 0000000000000000000000000000000000000000..4eb9f334271e5d3d712b3797946d5ed2000479c0 GIT binary patch literal 2473 zcmZ`*dpy)x8z0kX)6H$m+l(~XdsjgVVv8n>9(xd=1ZU%T(SpMBqV-}A?Fp7WgV^PK1Tob!A?C(Yk) z`--LLr3eIK1xO+WA`n_2tW%dPh9y7fJ%m8$`~(s`g6KW6ymdhsU!#=mL^G^jYHI2d zqBb%y)m@sql<29A3`o4?9u#Dz2b(>$3*n_ZtS?1jk+6c*)7M{uLh9=$zPPU_h?`&D zp3|C=HF368ksGZW9vfSUq2|BL%PVex&-~ZW+$SG;g zzEJI{bP9TDK70ElQ!}08>6~8m!qxd>rTc|-AiXZW^&sc@53Bd=Jy9`IN--mF@@zsL z)ep523w$Z!^vvY3kz4g1*I*>qehZ=VEafO94H1p-t;yeo##$ZE(g&rai)JHF=X!aJGY?p*;MqO(K;~tg@RPSH;N3 z$^?0z>jKp0B$deyEK+}bsI$SHT$jLtYg09s>ECb8=kA>Q?%gcDcE0So(!?wDJP48H zcUHi0E%jUSg=F&4e~=U%+=YT5Zjz;qKjCf@&)?LT5Z@m*prM|fiE<;2=@=G*Oe z8mlLa9!$lk<|I`V&mPUufh;B2zN%axD_{Zeg$?qGpqaLd6Uxljt1~U0);y2X0aF}3 z&^n0(tt#wra96~yof_8#LcxQ~Npj$WK;}B9V#=6>XydAF3T5#MID-E{K3ZS3-h4>t zwYSmW<5}DVe<&{*=+!pg+hG}Zo#wzRrp*zzngF8bfK+{p=1f-8P1khSMr%q3=B8PC z4seXghN$RsR=KZ5N_xP}&3Gf{&#`6)zO6q4$Rbo^aaES(V^d-D%#EXrFn`E-XjE8g zdcP;un9$g26&ePl0q--~J4Wy^mBod2a`L51G_Ux1-z$&SHElC2z?^VOOi>i4Ynyjp z4j(q?Vq!QFk^xJ)TtdB?3xvO?W{xjDK6`g!H}OIOwy8QNUQtw1;S}S`fQ~VWqL;?4 zbpC=Kw<`(kD7W3R;e%&K_K`;$KR7oJY|*m8PuWY**GgK#^6}uFZ*@x^)CbD;H;&9sYI_q!P%&cX(TvW&x>6V0#4_D`vEq$*RN=wg%%(V$eyW-~CEDm^_{8Kx^xd7?dsjwh_F9$N zv%=>G=F6%F!UMSS2UCk`#s=S3g%coaEpUD+?TBD><3=o3EOAIbPehjEYibSp$$n45 zwtKNBD&MpoyzW}24`u>K;PbvK*nC7M&U47J2!%WcI!2sz0#7%s z2{vo$X7dcC!I@?eu?7cYrQYK!p_NmDNS$sbg zXeqdUy1QQL^6;Od7`r-;wD{|dEn=4Ru!@jMs=&@PG*bZr20D=>+%Sq^eE+dM+jyt) zF{L;5_2IB~SE_waz{3>icBDElTf7Q5+#|wMxa>wOxh7E}qoewV0njb8dH#o|H%e248uHbDZQR$GOu&bI4i%OehtBj2J;=zMlGV zWVX`YaF^ZFBwyuYp4gfVnDwiEw z_E}!7oG3@;y9_Kv8JY6plPB z%%+!)cp11l;6|Hg+mX=4EB&O3K1jGEc^V%eM}sHc1>-`3x7AyjGY(4doA__5*^3Q~ z4s9{I1hA!-!;MQd6r!XLA7TNvnXaW8vBJNLUEf6WvHMz_2ksxDK%0;c_!2 zu3f&)Qq~{zI`kL6nhYS}gZIsv*C7*ct~CnldZ{Oz?007G=K-VXDlJgN0W#Lu`qrsv zzkpPmk+H1eRabZ|k2bl?52{8Zd21?C05(q?=*Jkx4KdByK%X;YDBp<1v+dM}atR<> z@GOQglEq@`7N7I0m($T8TA_C1{WLRjY5$&=bQ41m+q7`+xIFt{@?7;Y@3spn3pU59 znk{|lU2&u#IwS0g8(gA*UalK(YSB^alEs9ly{ OjG(6<@y^!$NxuQvb9#vY literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/introduction/samza-hadoop.png b/docs/img/versioned/learn/documentation/introduction/samza-hadoop.png new file mode 100644 index 0000000000000000000000000000000000000000..2142f949356da03d4c4f160f0a47a8f4e8aad1f6 GIT binary patch literal 2542 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 literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/introduction/samza-yarn-integration.png b/docs/img/versioned/learn/documentation/introduction/samza-yarn-integration.png new file mode 100644 index 0000000000000000000000000000000000000000..2748713274151a0af04b8131732566670f15e27b GIT binary patch literal 9400 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 + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro.MacAppStore + 139.18 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {576.00002479553223, 733}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-07-24 20:59:23 +0000 + Creator + Jay Kreps + DisplayScale + 1 0/72 in = 1 0/72 in + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{354.00000274926424, 96.386200297623873}, {56, 16}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 50 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 2 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 DB Queries} + VerticalPad + 2 + + Wrap + NO + + + Class + LineGraphic + Head + + ID + 32 + Info + 2 + + ID + 47 + Points + + {375.94502185497402, 143.5769404965329} + {400.50000206194818, 131} + {428.74999985404742, 131} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 27 + + + + Class + LineGraphic + Head + + ID + 32 + Info + 2 + + ID + 46 + Points + + {317.00000015459955, 138} + {351.50000206194818, 118} + {384.50000206194818, 118} + {429.25000015459955, 131} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 29 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 32 + Info + 2 + + ID + 45 + Points + + {274.95482065734831, 134.82683104667493} + {320.50000206194818, 106} + {382.50000206194818, 108} + {429.25000015459955, 131} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 28 + Position + 0.96286928653717041 + + + + Bounds + {{282.7798816413071, 176.46626249661199}, {70, 16}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 44 + Line + + ID + 41 + Position + 0.41301777958869934 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 2 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 Output Stream} + VerticalPad + 2 + + Wrap + NO + + + Bounds + {{265.50000206194818, 145.99999260902405}, {104, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 43 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 Stateless Samza Tasks} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 42 + Points + + {361.63447776995599, 166} + {362.63447776995599, 211} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + ID + 41 + Points + + {317.62499995563974, 166.49998140404247} + {318, 210} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 26 + + + + Class + LineGraphic + ID + 40 + Points + + {277.25000206194818, 166} + {278.25000206194818, 210} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Bounds + {{408.75000015459955, 131}, {41, 35}} + Class + ShapedGraphic + ID + 32 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Cylinder + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 DB} + VerticalPad + 0 + + + + Bounds + {{241.50000274926424, 49.500000346451998}, {62, 16}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 31 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 2 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 Input Stream} + VerticalPad + 2 + + Wrap + NO + + + Class + LineGraphic + ID + 30 + Points + + {281.09627582033107, 65.500000346451998} + {359.00000015459955, 138} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 31 + + + + Class + LineGraphic + ID + 29 + Points + + {276.92236275888934, 65.500000346451998} + {317.00000015459955, 138} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 31 + + + + Class + LineGraphic + Head + + ID + 25 + + ID + 28 + Points + + {272.75397078450942, 65.500000346451984} + {275.03969108280035, 137.50025175082229} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 31 + + + + Bounds + {{343.50000015459955, 138}, {32, 28}} + Class + ShapedGraphic + ID + 27 + Shape + Rectangle + Style + + shadow + + Draws + NO + + + + + Bounds + {{301.50000015459955, 138}, {32, 28}} + Class + ShapedGraphic + ID + 26 + Shape + Rectangle + Style + + shadow + + Draws + NO + + + + + Bounds + {{259.50000015459955, 138}, {32, 28}} + Class + ShapedGraphic + ID + 25 + Shape + Rectangle + Style + + shadow + + Draws + NO + + + + + Bounds + {{59.223656370973515, 185.64922458224424}, {70, 16}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 24 + Line + + ID + 22 + Position + 0.36017578840255737 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 2 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 Output Stream} + VerticalPad + 2 + + Wrap + NO + + + Bounds + {{46.00000206194818, 167.9414598941803}, {96, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 17 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 Stateful Samza Tasks} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 23 + Points + + {134.13447776995599, 171} + {135.13447776995599, 216} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Class + LineGraphic + ID + 22 + Points + + {94.068093287685457, 179.9414598941803} + {94.50000206194818, 218} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 17 + + + + Class + LineGraphic + ID + 21 + Points + + {49.75000206194818, 171} + {49.75000206194818, 221} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + + + Bounds + {{130.75000206194818, 151}, {11.5, 12}} + Class + ShapedGraphic + ID + 20 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Cylinder + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{88.75000206194818, 151}, {11.5, 12}} + Class + ShapedGraphic + ID + 48 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Cylinder + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{49.75000206194818, 151}, {11.5, 12}} + Class + ShapedGraphic + ID + 49 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Cylinder + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{110.13448295556009, 98.386206388473497}, {49, 14}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 16 + Line + + ID + 15 + Position + 0.37310343980789185 + RotationType + 0 + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 1 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 changelog} + VerticalPad + 1 + + Wrap + NO + + + Class + LineGraphic + Head + + ID + 10 + Info + 1 + + ID + 15 + Points + + {136.50000015459955, 82.999999999999986} + {131.50000015459955, 143} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 12 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 9 + Info + 1 + + ID + 14 + Points + + {136.19166917030824, 83.393614022499548} + {89.500000154599547, 143} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 12 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 5 + + ID + 13 + Points + + {136.11642027561359, 83.320733458135152} + {64.383577368540188, 143.30073769681798} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 12 + Info + 1 + + + + Bounds + {{116.00000015459955, 48}, {41, 35}} + Class + ShapedGraphic + ID + 12 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Cylinder + Style + + shadow + + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 DB} + VerticalPad + 0 + + + + Bounds + {{14.00000274926424, 54.500000346451998}, {62, 16}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + w + 0 + + Font + Helvetica + Size + 10 + + ID + 11 + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 2 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 Input Stream} + VerticalPad + 2 + + Wrap + NO + + + Class + LineGraphic + ID + 10 + Points + + {53.596275820331059, 70.500000346451998} + {131.50000015459955, 143} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 11 + + + + Class + LineGraphic + ID + 9 + Points + + {49.422362758889307, 70.500000346451998} + {89.500000154599547, 143} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 11 + + + + Class + LineGraphic + Head + + ID + 5 + + ID + 8 + Points + + {45.253970784509427, 70.500000346451984} + {47.53969108280036, 142.50025175082229} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 11 + + + + Bounds + {{116.00000015459955, 143}, {32, 28}} + Class + ShapedGraphic + ID + 7 + Shape + Rectangle + Style + + shadow + + Draws + NO + + + + + Bounds + {{74.000000154599547, 143}, {32, 28}} + Class + ShapedGraphic + ID + 6 + Shape + Rectangle + Style + + shadow + + Draws + NO + + + + + Bounds + {{32.000000154599547, 143}, {32, 28}} + Class + ShapedGraphic + ID + 5 + Shape + Rectangle + Style + + shadow + + Draws + NO + + + + + Bounds + {{288.00001239776611, 12}, {111, 22}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 4 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs36 \cf0 Remote State} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{39.223648071289062, 12}, {91, 22}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 3 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs36 \cf0 Local State} + VerticalPad + 0 + + Wrap + NO + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-07-24 21:26:31 +0000 + Modifier + Jay Kreps + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {612.00002479553223, 792} + + NSPrintReverseOrientation + + int + 0 + + NSPrinter + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAlOU1ByaW50ZXIAhIQITlNPYmplY3QAhZKEhIQITlNTdHJpbmcBlIQBKxdEZWxsIExhc2VyIFByaW50ZXIgMTcxMIaG + + NSPrinterName + + string + Dell Laser Printer 1710 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{364, 6}, {711, 872}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 0}, {576, 733}} + Zoom + 1 + ZoomValues + + + Canvas 1 + 1 + 1 + + + + + diff --git a/docs/img/versioned/learn/documentation/introduction/samza_state.png b/docs/img/versioned/learn/documentation/introduction/samza_state.png new file mode 100644 index 0000000000000000000000000000000000000000..80a2df667066ce1d64ed54858ac352aefc4e5b63 GIT binary patch literal 40635 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 + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro.MacAppStore + 139.18 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {576.00002479553223, 733}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2013-07-28 22:22:56 +0000 + Creator + Jay Kreps + DisplayScale + 1 0/72 in = 1 0/72 in + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{61, 10}, {138, 18}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 99 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs30 \cf0 A Partitioned Stream} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{241.5, 93.238006591796875}, {57, 12}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica + Size + 12 + + ID + 98 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 next append} + VerticalPad + 0 + + Wrap + NO + + + Class + LineGraphic + ID + 97 + Points + + {236, 99} + {199, 143.73800659179688} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + Width + 0.5 + + + Tail + + ID + 96 + + + + Class + LineGraphic + ID + 96 + Points + + {236, 99} + {186, 99} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + Width + 0.5 + + + + + Class + LineGraphic + ID + 95 + Points + + {236, 99} + {212, 55} + + Style + + stroke + + HeadArrow + StickArrow + Legacy + + LineType + 1 + TailArrow + 0 + Width + 0.5 + + + Tail + + ID + 96 + + + + Bounds + {{12, 138.72201098632814}, {50, 13}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica-Light + Size + 11 + + ID + 92 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs22 \cf0 partition 2} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{179, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 90 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 8} + VerticalPad + 0 + + + + Bounds + {{165, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 89 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 7} + VerticalPad + 0 + + + + Bounds + {{151, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 88 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 6} + VerticalPad + 0 + + + + Bounds + {{137, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 87 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 5} + VerticalPad + 0 + + + + Bounds + {{123, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 86 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 4} + VerticalPad + 0 + + + + Bounds + {{109, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 85 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 3} + VerticalPad + 0 + + + + Bounds + {{95, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 84 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 2} + VerticalPad + 0 + + + + Bounds + {{81, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 83 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 1} + VerticalPad + 0 + + + + Bounds + {{67, 152.9680093688965}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 82 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 0} + VerticalPad + 0 + + + + Bounds + {{179, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 80 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Pattern + 1 + + + Text + + VerticalPad + 0 + + + + Bounds + {{165, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 79 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{151, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 78 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{137, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 77 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{123, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 76 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{109, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 75 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{95, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 74 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{81, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 73 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{67, 132.47600936889648}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 72 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{12, 93.238006011962895}, {50, 13}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica-Light + Size + 11 + + ID + 71 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs22 \cf0 partition 1} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{165, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 68 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 7} + VerticalPad + 0 + + + + Bounds + {{151, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 67 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 6} + VerticalPad + 0 + + + + Bounds + {{137, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 66 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 5} + VerticalPad + 0 + + + + Bounds + {{123, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 65 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 4} + VerticalPad + 0 + + + + Bounds + {{109, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 64 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 3} + VerticalPad + 0 + + + + Bounds + {{95, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 63 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 2} + VerticalPad + 0 + + + + Bounds + {{81, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 62 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 1} + VerticalPad + 0 + + + + Bounds + {{67, 106.98400439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 61 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 0} + VerticalPad + 0 + + + + Bounds + {{165, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 58 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Pattern + 1 + + + Text + + VerticalPad + 0 + + + + Bounds + {{151, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 57 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{137, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 56 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{123, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 55 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{109, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 54 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{95, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 53 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{81, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 52 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{67, 86.49200439453125}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 51 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{12, 47.254001617431641}, {50, 13}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Font + Helvetica-Light + Size + 11 + + ID + 50 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs22 \cf0 partition 0} + VerticalPad + 0 + + Wrap + NO + + + Bounds + {{193, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 44 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 9} + VerticalPad + 0 + + + + Bounds + {{179, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 43 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 8} + VerticalPad + 0 + + + + Bounds + {{165, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 42 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 7} + VerticalPad + 0 + + + + Bounds + {{151, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 41 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 6} + VerticalPad + 0 + + + + Bounds + {{137, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 40 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 5} + VerticalPad + 0 + + + + Bounds + {{123, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 39 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 4} + VerticalPad + 0 + + + + Bounds + {{109, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 38 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 3} + VerticalPad + 0 + + + + Bounds + {{95, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 37 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 2} + VerticalPad + 0 + + + + Bounds + {{81, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 36 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 1} + VerticalPad + 0 + + + + Bounds + {{67, 61}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 35 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Width + 0.0 + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 0} + VerticalPad + 0 + + + + Bounds + {{193, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 29 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + stroke + + Pattern + 1 + + + Text + + VerticalPad + 0 + + + + Bounds + {{179, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 28 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{165, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 27 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{151, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 26 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{137, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 25 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{123, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 24 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{109, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 23 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{95, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 22 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{81, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 21 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + Bounds + {{67, 40.507999999999996}, {14, 25.492000579833984}} + Class + ShapedGraphic + ID + 19 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Draws + NO + + + Text + + VerticalPad + 0 + + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2013-07-28 22:33:38 +0000 + Modifier + Jay Kreps + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {612.00002479553223, 792} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{575, -38}, {711, 872}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{0, 0}, {576, 733}} + Zoom + 1 + ZoomValues + + + Canvas 1 + 1 + 1 + + + + + diff --git a/docs/img/versioned/learn/documentation/introduction/stream.png b/docs/img/versioned/learn/documentation/introduction/stream.png new file mode 100644 index 0000000000000000000000000000000000000000..e190041441208d5c1801410e904fd64560f7a72f GIT binary patch literal 19806 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 literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/motivation/data-processing-spectrum-3.png b/docs/img/versioned/learn/documentation/motivation/data-processing-spectrum-3.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9ff05323cb56c56e83d4f3b31d050594415cc4 GIT binary patch literal 29389 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 literal 0 HcmV?d00001 diff --git a/docs/img/versioned/learn/documentation/yarn/samza-am-dashboard.png b/docs/img/versioned/learn/documentation/yarn/samza-am-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..949a2f0c70b95247255e705e9d910f77de610db2 GIT binary patch literal 55603 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 v!B6}7>FMe|rxp_bx2>m;*p%k1oF{Iw9(nizT@ - -When writing a stream processor for Samza, you must implement the [StreamTask](javadocs/org/apache/samza/task/StreamTask.html) interface: - -{% highlight java %} -package com.example.samza; - -public class MyTaskClass implements StreamTask { - - public void process(IncomingMessageEnvelope envelope, - MessageCollector collector, - TaskCoordinator coordinator) { - // process message - } -} -{% endhighlight %} - -When you run your job, Samza will create several instances of your class (potentially on multiple machines). These task instances process the messages in the input streams. - -In your job's configuration you can tell Samza which streams you want to consume. An incomplete example could look like this (see the [configuration documentation](../jobs/configuration.html) for more detail): - -{% highlight jproperties %} -# This is the class above, which Samza will instantiate when the job is run -task.class=com.example.samza.MyTaskClass - -# Define a system called "kafka" (you can give it any name, and you can define -# multiple systems if you want to process messages from different sources) -systems.kafka.samza.factory=org.apache.samza.system.kafka.KafkaSystemFactory - -# The job consumes a topic called "PageViewEvent" from the "kafka" system -task.inputs=kafka.PageViewEvent - -# Define a serializer/deserializer called "json" which parses JSON messages -serializers.registry.json.class=org.apache.samza.serializers.JsonSerdeFactory - -# Use the "json" serializer for messages in the "PageViewEvent" topic -systems.kafka.streams.PageViewEvent.samza.msg.serde=json -{% endhighlight %} - -For each message that Samza receives from the task's input streams, the *process* method is called. The [envelope](javadocs/org/apache/samza/system/IncomingMessageEnvelope.html) contains three things of importance: the message, the key, and the stream that the message came from. - -{% highlight java %} -/** Every message that is delivered to a StreamTask is wrapped - * in an IncomingMessageEnvelope, which contains metadata about - * the origin of the message. */ -public class IncomingMessageEnvelope { - /** A deserialized message. */ - Object getMessage() { ... } - - /** A deserialized key. */ - Object getKey() { ... } - - /** The stream and partition that this message came from. */ - SystemStreamPartition getSystemStreamPartition() { ... } -} -{% endhighlight %} - -The key and value are declared as Object, and need to be cast to the correct type. If you don't configure a [serializer/deserializer](../container/serialization.html), they are typically Java byte arrays. A deserializer can convert these bytes into any other type, for example the JSON deserializer mentioned above parses the byte array into java.util.Map, java.util.List and String objects. - -The `getSystemStreamPartition()` method returns a [SystemStreamPartition](javadocs/org/apache/samza/system/SystemStreamPartition.html) object, which tells you where the message came from. It consists of three parts: - -1. The *system*: the name of the system from which the message came, as defined in your job configuration. You can have multiple systems for input and/or output, each with a different name. -2. The *stream name*: the name of the stream (topic, queue) within the source system. This is also defined in the job configuration. -3. The [*partition*](javadocs/org/apache/samza/Partition.html): a stream is normally split into several partitions, and each partition is assigned to one StreamTask instance by Samza. - -The API looks like this: - -{% highlight java %} -/** A triple of system name, stream name and partition. */ -public class SystemStreamPartition extends SystemStream { - - /** The name of the system which provides this stream. It is - defined in the Samza job's configuration. */ - public String getSystem() { ... } - - /** The name of the stream/topic/queue within the system. */ - public String getStream() { ... } - - /** The partition within the stream. */ - public Partition getPartition() { ... } -} -{% endhighlight %} - -In the example job configuration above, the system name is "kafka", the stream name is "PageViewEvent". (The name "kafka" isn't special — you can give your system any name you want.) If you have several input streams feeding into your StreamTask, you can use the SystemStreamPartition to determine what kind of message you've received. - -What about sending messages? If you take a look at the process() method in StreamTask, you'll see that you get a [MessageCollector](javadocs/org/apache/samza/task/MessageCollector.html). - -{% highlight java %} -/** When a task wishes to send a message, it uses this interface. */ -public interface MessageCollector { - void send(OutgoingMessageEnvelope envelope); -} -{% endhighlight %} - -To send a message, you create an [OutgoingMessageEnvelope](javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html) object and pass it to the message collector. At a minimum, the envelope specifies the message you want to send, and the system and stream name to send it to. Optionally you can specify the partitioning key and other parameters. See the [javadoc](javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html) for details. - -**NOTE:** Please only use the MessageCollector object within the `process()` method. If you hold on to a MessageCollector instance and use it again later, your messages may not be sent correctly. - -For example, here's a simple task that splits each input message into words, and emits each word as a separate message: - -{% highlight java %} -public class SplitStringIntoWords implements StreamTask { - - // Send outgoing messages to a stream called "words" - // in the "kafka" system. - private final SystemStream OUTPUT_STREAM = - new SystemStream("kafka", "words"); - - public void process(IncomingMessageEnvelope envelope, - MessageCollector collector, - TaskCoordinator coordinator) { - String message = (String) envelope.getMessage(); - - for (String word : message.split(" ")) { - // Use the word as the key, and 1 as the value. - // A second task can add the 1's to get the word count. - collector.send(new OutgoingMessageEnvelope(OUTPUT_STREAM, word, 1)); - } - } -} -{% endhighlight %} - -## [SamzaContainer »](../container/samza-container.html) diff --git a/docs/learn/documentation/0.7.0/comparisons/introduction.md b/docs/learn/documentation/0.7.0/comparisons/introduction.md deleted file mode 100644 index e6b16d4..0000000 --- a/docs/learn/documentation/0.7.0/comparisons/introduction.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -layout: page -title: Comparison Introduction ---- - - -Here are a few of the high-level design decisions that we think make Samza a bit different from other stream processing projects. - -### The Stream Model - -Streams are the input and output to Samza jobs. Samza has a very strong model of a stream—it is more than just a simple message exchange mechanism. A stream in Samza is a partitioned, ordered-per-partition, replayable, multi-subscriber, lossless sequence of messages. Streams are not just inputs and outputs to the system, but also buffers that isolate processing stages from each other. - -This stronger model requires persistence, fault-tolerance, and buffering in the stream implementation, but it has several benefits. - -First, delays in a downstream processing stage cannot block an upstream stage. A Samza job can stop consuming for a few minutes, or even a few hours (perhaps because of a bad deploy, or a long-running computation) without having any effect on upstream jobs. This makes Samza suitable for large deployments, such as processing all data flows in a large company: isolation between jobs is essential when they are written, owned, and run by different teams in different code bases with varying SLAs. - -This is motivated by our experience building analogous offline processing pipelines in Hadoop. In Hadoop the processing stages are MapReduce jobs, and the output of a processing stage is a directory of files on HDFS. The input to the next processing stage is simply the files produced by the earlier stage. We have found that this strong isolation between stages makes it possible to have hundreds of loosely coupled jobs, maintained by different teams, that comprise an offline processing ecosystem. Our goal is to replicate this kind of rich ecosystem in a near-real-time setting. - -The second benefit of this stronger model is that all stages are multi-subscriber. In practical terms this means that if one person adds a set of processing flows that create output data streams, others can see the output, consume it, and build on it, without introducing any coupling of code between the jobs. As a happy side-effect, this makes debugging flows easy, as you can manually inspect the output of any stage. - -Finally, this strong stream model greatly simplifies the implementation of features in the Samza framework. Each job need only be concerned with its own inputs and outputs, and in the case of a fault, each job can be recovered and restarted independently. There is no need for central control over the entire dataflow graph. - -The tradeoff we need to make for this stronger stream model is that messages are written to disk. We are willing to make this tradeoff because MapReduce and HDFS have shown that durable storage can offer very high read and write throughput, and almost limitless disk space. This observation is the foundation of Kafka, which allows hundreds of MB/sec of replicated throughput, and many TB of disk space per node. When used this way, disk throughput often isn't the bottleneck. - -MapReduce is sometimes criticized for writing to disk more than necessary. However, this criticism applies less to stream processing: batch processing like MapReduce often is used for processing large historical collections of data in a short period of time (e.g. query a month of data in ten minutes), whereas stream processing mostly needs to keep up with the steady-state flow of data (process 10 minutes worth of data in 10 minutes). This means that the raw throughput requirements for stream processing are, generally, orders of magnitude lower than for batch processing. - -### State - -Only the very simplest stream processing problems are stateless (i.e. can process one message at a time, independently of all other messages). Many stream processing applications require a job to maintain some state. For example: - -* If you want to know how many events have been seen for a particular user ID, you need to keep a counter for each user ID. -* If you want to know how many distinct users visit your site per day, you need to keep a set of all user IDs for which you've seen at least one event today. -* If you want to join two streams (for example, if you want to determine the click-through rate of adverts by joining a stream of ad impression events with a stream of ad click events) you need to store the event from one stream until you receive the corresponding event from the other stream. -* If you want to augment events with some information from a database (for example, extending a page-view event with some information about the user who viewed the page), the job needs to access the current state of that database. - -Some kinds of state, such as counters, could be kept in-memory in the tasks, but then that state would be lost if the job is restarted. Alternatively, you can keep the state in a remote database, but performance can become unacceptable if you need to perform a database query for every message you process. Kafka can easily handle 100k-500k messages/sec per node (depending on message size), but throughput for queries against a remote key-value store tend to be closer to 1-5k requests per second — two orders of magnitude slower. - -In Samza, we have put particular effort into supporting high-performance, reliable state. The key is to keep state local to each node (so that queries don't need to go over the network), and to make it robust to machine failures by replicating state changes to another stream. - -This approach is especially interesting when combined with database *change capture*. Take the -example above, where you have a stream of page-view events including the ID of the user who viewed the page, and you want to augment the events with more information about that user. At first glance, it looks as though you have no choice but to query the user database to look up every user ID you see (perhaps with some caching). With Samza, we can do better. - -*Change capture* means that every time some data changes in your database, you get an event telling you what changed. If you have that stream of change events, going all the way back to when the database was created, you can reconstruct the entire contents of the database by replaying the stream. That *changelog* stream can also be used as input to a Samza job. - -Now you can write a Samza job that takes both the page-view event and the changelog as inputs. You make sure that they are partitioned on the same key (e.g. user ID). Every time a changelog event comes in, you write the updated user information to the task's local storage. Every time a page-view event comes in, you read the current information about that user from local storage. That way, you can keep all the state local to a task, and never need to query a remote database. - -Stateful Processing - -In effect, you now have a replica of the main database, broken into small partitions that are on the same machines as the Samza tasks. Database writes still need to go to the main database, but when you need to read from the database in order to process a message from the input stream, you can just consult the task's local state. - -This approach is not only much faster than querying a remote database, it is also much better for operations. If you are processing a high-volume stream with Samza, and making a remote query for every message, you can easily overwhelm the database with requests and affect other services using the same database. By contrast, when a task uses local state, it is isolated from everything else, so it cannot accidentally bring down other services. - -Partitioned local state is not always appropriate, and not required — nothing in Samza prevents calls to external databases. If you cannot produce a feed of changes from your database, or you need to rely on logic that exists only in a remote service, then it may be more convenient to call a remote service from your Samza job. But if you want to use local state, it works out of the box. - -### Execution Framework - -One final decision we made was to not build a custom distributed execution system in Samza. Instead, execution is pluggable, and currently completely handled by YARN. This has two benefits. - -The first benefit is practical: there is another team of smart people working on the execution framework. YARN is developing at a rapid pace, and already supports a rich set of features around resource quotas and security. This allows you to control what portion of the cluster is allocated to which users and groups, and also control the resource utilization on individual nodes (CPU, memory, etc) via cgroups. YARN is run at massive scale to support Hadoop and will likely become an ubiquitous layer. Since Samza runs entirely through YARN, there are no separate daemons or masters to run beyond the YARN cluster itself. In other words, if you already have Kafka and YARN, you don't need to install anything in order to run Samza jobs. - -Secondly, our integration with YARN is completely componentized. It exists in a separate package, and the main Samza framework does not depend on it at build time. This means that YARN can be replaced with other virtualization frameworks — in particular, we are interested in adding direct AWS integration. Many companies run in AWS which is itself a virtualization framework, which for Samza's purposes is equivalent to YARN: it allows you to create and destroy virtual "container" machines and guarantees fixed resources for these containers. Since stream processing jobs are long-running, it is a bit silly to run a YARN cluster inside AWS and then schedule individual jobs within this cluster. Instead, a more sensible approach would be to directly allocate a set of EC2 instances for your jobs. - -We think there will be a lot of innovation both in open source virtualization frameworks like Mesos and YARN and in commercial cloud providers like Amazon, so it makes sense to integrate with them. - -## [MUPD8 »](mupd8.html) diff --git a/docs/learn/documentation/0.7.0/comparisons/mupd8.md b/docs/learn/documentation/0.7.0/comparisons/mupd8.md deleted file mode 100644 index 53417f9..0000000 --- a/docs/learn/documentation/0.7.0/comparisons/mupd8.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -layout: page -title: MUPD8 ---- - - -*People generally want to know how similar systems compare. We've done our best to fairly contrast the feature sets of Samza with other systems. But we aren't experts in these frameworks, and we are, of course, totally biased. If we have goofed anything, please let us know and we will correct it.* - -### Durability - -MUPD8 makes no durability or delivery guarantees. Within MUPD8, stream processor tasks receive messages at most once. Samza uses Kafka for messaging, which guarantees message delivery. - -### Ordering - -As with durability, developers would ideally like their stream processors to receive messages in exactly the order that they were written. - -We don't entirely follow MUPD8's description of their ordering guarantees, but it seems to guarantee that all messages will be processed in the order in which they are written to MUPD8 queues, which is comparable to Kafka and Samza's guarantee. - -### Buffering - -A critical issue for handling large data flows is handling back pressure when one downstream processing stage gets slow. - -MUPD8 buffers messages in an in-memory queue when passing messages between two MUPD8 tasks. When a queue fills up, developers have the option to either drop the messages on the floor, log the messages to local disk, or block until the queue frees up. All of these options are sub-optimal. Dropping messages leads to incorrect results. Blocking your stream processor can have a cascading effect, where the slowest processor blocks all upstream processors, which in turn block their upstream processors, until the whole system grinds to a halt. Logging to local disk is the most reasonable, but when a fault occurs, those messages are lost on failover. - -By adopting Kafka's broker as a remote buffer, Samza solves all of these problems. It doesn't need to block because consumers and producers are decoupled using the Kafka brokers' disks as buffers. Messages are not dropped because Kafka brokers are highly available as of version 0.8. In the event of a failure, when a Samza job is restarted on another machine, its input and output are not lost, because they are stored remotely on replicated Kafka brokers. - -### State Management - -As described in the [introduction](introduction.html#state), stream processors often need to maintain some state as they process messages. Different frameworks have different approaches to handling such state, and what to do in case of a failure. - -MUPD8 uses a write back caching strategy to manage in-memory state that is periodically written back to Cassandra. - -Samza maintains state locally with the task. This allows state larger than will fit in memory. State is persisted to an output stream to enable recovery should the task fail. We believe this design enables stronger fault tolerance semantics, because the change log captures the evolution of state, allowing the state of a task to restored to a consistent point in time. - -### Deployment and execution - -MUPD8 includes a custom execution framework. The functionality that this framework supports in terms of users and resource limits isn't clear to us. - -Samza leverages YARN to deploy user code, and execute it in a distributed environment. - -### Fault Tolerance - -What should a stream processing system do when a machine or processor fails? - -MUPD8 uses its custom equivalent to YARN to manage fault tolerance. When a stream processor is unable to send a message to a downstream processor, it notifies MUPD8's coordinator, and all other machines are notified. The machines then send all messages to a new machine based on the key hash that's used. Messages and state can be lost when this happens. - -Samza uses YARN to manage fault tolerance. YARN detects when nodes or Samza tasks fail, and notifies Samza's [ApplicationMaster](../yarn/application-master.html). At that point, it's up to Samza to decide what to do. Generally, this means re-starting the task on another machine. Since messages are persisted to Kafka brokers remotely, and there are no in-memory queues, no messages should be lost (unless the processors are using async Kafka producers, which offer higher performance but don't wait for messages to be committed). - -### Workflow - -Sometimes more than one job or processing stage is needed to accomplish something. This is the case where you wish to re-partition a stream, for example. MUPD8 has a custom workflow system setup to define how to execute multiple jobs at once, and how to feed stream data from one into the other. - -Samza makes the individual jobs the level of granularity of execution. Jobs communicate via named input and output streams. This implicitly defines a data flow graph between all running jobs. We chose this model to enable data flow graphs with processing stages owned by different engineers on different teams, working in different code bases, without the need to wire everything together into a single topology. - -This was motivated by our experience with Hadoop, where the data flow between jobs is implicitly defined by their input and output directories. This decentralized model has proven itself to scale well to a large organization. - -### Memory - -MUPD8 executes all of its map/update processors inside a single JVM, using threads. This is memory-efficient, as the JVM memory overhead is shared across the threads. - -Samza uses a separate JVM for each [stream processor container](../container/samza-container.html). This has the disadvantage of using more memory compared to running multiple stream processing threads within a single JVM. However, the advantage is improved isolation between tasks, which can make them more reliable. - -### Isolation - -MUPD8 provides no resource isolation between stream processors. A single badly behaved stream processor can bring down all processors on the node. - -Samza uses process level isolation between stream processor tasks, similarly to Hadoop's approach. We can enforce strict per-process memory limits. In addition, Samza supports CPU limits when used with YARN cgroups. As the YARN support for cgroups develops further, it should also become possible to support disk and network cgroup limits. - -### Further Reading - -The MUPD8 team has published a very good [paper](http://vldb.org/pvldb/vol5/p1814_wanglam_vldb2012.pdf) on the design of their system. - -## [Storm »](storm.html) diff --git a/docs/learn/documentation/0.7.0/comparisons/spark-streaming.md b/docs/learn/documentation/0.7.0/comparisons/spark-streaming.md deleted file mode 100644 index b8a521f..0000000 --- a/docs/learn/documentation/0.7.0/comparisons/spark-streaming.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -layout: page -title: Spark Streaming ---- - - -*People generally want to know how similar systems compare. We've done our best to fairly contrast the feature sets of Samza with other systems. But we aren't experts in these frameworks, and we are, of course, totally biased. If we have goofed anything, please let us know and we will correct it.* - -[Spark Streaming](http://spark.apache.org/docs/latest/streaming-programming-guide.html) is a stream processing system that uses the core [Apache Spark](http://spark.apache.org/) API. Both Samza and Spark Streaming provide data consistency, fault tolerance, a programming API, etc. Spark's approach to streaming is different from Samza's. Samza processes messages as they are received, while Spark Streaming treats streaming as a series of deterministic batch operations. Spark Streaming groups the stream into batches of a fixed duration (such as 1 second). Each batch is represented as a Resilient Distributed Dataset ([RDD](http://www.cs.berkeley.edu/~matei/papers/2012/nsdi_spark.pdf)). A neverending sequence of these RDDs is called a Discretized Stream ([DStream](http://www.cs.berkeley.edu/~matei/papers/2012/hotcloud_spark_streaming.pdf)). - -### Overview of Spark Streaming - -Before going into the comparison, here is a brief overview of the Spark Streaming application. If you already are familiar with Spark Streaming, you may skip this part. There are two main parts of a Spark Streaming application: data receiving and data processing. - -* Data receiving is accomplished by a [receiver](https://spark.apache.org/docs/latest/streaming-custom-receivers.html) which receives data and stores data in Spark (though not in an RDD at this point). -* Data processing transfers the data stored in Spark into the DStream. You can then apply the two [operations](https://spark.apache.org/docs/latest/streaming-programming-guide.html#operations) -- transformations and output operations -- on the DStream. The operations for DStream are a little different from what you can use for the general Spark RDD because of the streaming environment. - -Here is an overview of the Spark Streaming's [deploy](https://spark.apache.org/docs/latest/cluster-overview.html). Spark has a SparkContext (in SparkStreaming, it’s called [StreamingContext](https://spark.apache.org/docs/1.0.0/api/scala/index.html#org.apache.spark.streaming.StreamingContext)) object in the driver program. The SparkContext talks with cluster manager (e.g. YARN, Mesos) which then allocates resources (that is, executors) for the Spark application. And executors will run tasks sent by the SparkContext ([read more](http://spark.apache.org/docs/latest/cluster-overview.html#compenents)). In YARN’s context, one executor is equivalent to one container. Tasks are what is running in the containers. The driver program runs in the client machine that submits job ([client mode](https://spark.apache.org/docs/latest/running-on-yarn.html#launching-spark-on-yarn)) or in the application manager ([cluster mode](https://spark.apache.org/docs/latest/running-on-yarn.html#launching-spark-on-yarn)). Both data receiving and data processing are tasks for executors. One receiver (receives one input stream) is a long-running task. Processing has a bunch of tasks. All the tasks are sent to the available executors. - -### Ordering and Guarantees - -Spark Streaming guarantees ordered processing of batches in a DStream. Since messages are processed in batches by side-effect-free operators, the exact ordering of messages is not important in Spark Streaming. Spark Streaming does not gurantee at-least-once or at-most-once messaging semantics because in some situations it may lose data when the driver program fails (see [fault-tolerance](#fault-tolerance)). In addition, because Spark Streaming requires transformation operations to be deterministic, it is unsuitable for nondeterministic processing, e.g. a randomized machine learning algorithm. - -Samza guarantees processing the messages as the order they appear in the partition of the stream. Samza also allows you to define a deterministic ordering of messages between partitions using a [MessageChooser](../container/streams.html). It provides an at-least-once message delivery guarantee. And it does not require operations to be deterministic. - -### State Management - -Spark Streaming provides a state DStream which keeps the state for each key and a transformation operation called [updateStateByKey](https://spark.apache.org/docs/latest/streaming-programming-guide.html#transformations) to mutate state. Everytime updateStateByKey is applied, you will get a new state DStream where all of the state is updated by applying the function passed to updateStateByKey. This transformation can serve as a basic key-value store, though it has a few drawbacks: - -* you can only apply the DStream operations to your state because essentially it's a DStream. -* does not provide any key-value access to the data. If you want to access a certain key-value, you need to iterate the whole DStream. -* it is inefficient when the state is large because every time a new batch is processed, Spark Streaming consumes the entire state DStream to update relevant keys and values. - -Spark Streaming periodically writes intermedia data of stateful operations (updateStateByKey and window-based operations) into the HDFS. In the case of updateStateByKey, the entire state RDD is written into the HDFS after every checkpointing interval. As we mentioned in the *[in memory state with checkpointing](../container/state-management.html#in-memory-state-with-checkpointing)*, writing the entire state to durable storage is very expensive when the state becomes large. - -Samza uses an embedded key-value store for [state management](../container/state-management.html#local-state-in-samza). This store is replicated as it's mutated, and supports both very high throughput writing and reading. And it gives you a lot of flexibility to decide what kind of state you want to maintain. What is more, you can also plug in other [storage engines](../container/state-management.html#other-storage-engines), which enables great flexibility in the stream processing algorithms you can use. A good comparison of different types of state manager approaches can be found [here](../container/state-management.html#approaches-to-managing-task-state). - -One of the common use cases in state management is [stream-stream join](../container/state-management.html#stream-stream-join). Though Spark Streaming has the [join](https://spark.apache.org/docs/latest/streaming-programming-guide.html#transformations) operation, this operation only joins two batches that are in the same time interval. It does not deal with the situation where events in two streams have mismatch. Spark Streaming's updateStateByKey approach to store mismatch events also has the limitation because if the number of mismatch events is large, there will be a large state, which causes the inefficience in Spark Streaming. While Samza does not have this limitation. - -### Partitioning and Parallelism - -Spark Streaming's Parallelism is achieved by splitting the job into small tasks and sending them to executors. There are two types of [parallelism in Spark Streaming](http://spark.apache.org/docs/latest/streaming-programming-guide.html#level-of-parallelism-in-data-receiving): parallelism in receiving the stream and parallelism in processing the stream. On the receiving side, one input DStream creates one receiver, and one receiver receives one input stream of data and runs as a long-running task. So in order to parallelize the receiving process, you can split one input stream into multiple input streams based on some criteria (e.g. if you are receiving a Kafka stream with some partitions, you may split this stream based on the partition). Then you can create multiple input DStreams (so multiple receivers) for these streams and the receivers will run as multiple tasks. Accordingly, you should provide enough resources by increasing the core number of the executors or bringing up more executors. Then you can combine all the input Dstreams into one DStream during the processing if necessary. On the processing side, since a DStream is a continuous sequence of RDDs, the parallelism is simply accomplished by normal RDD operations, such as map, reduceByKey, reduceByWindow (check [here] (https://spark.apache.org/docs/latest/tuning.html#level-of-parallelism)). - -Samza’s parallelism is achieved by splitting processing into independent [tasks](../api/overview.html) which can be parallelized. You can run multiple tasks in one container or only one task per container. That depends on your workload and latency requirement. For example, if you want to quickly [reprocess a stream](../jobs/reprocessing.html), you may increase the number of containers to one task per container. It is important to notice that one container only uses [one thread](../container/event-loop.html), which maps to exactly one CPU. This design attempts to simplify resource management and the isolation between jobs. - -### Buffering & Latency - -Spark streaming essentially is a sequence of small batch processes. With a fast execution engine, it can reach the latency as low as one second (from their [paper](http://www.cs.berkeley.edu/~matei/papers/2012/hotcloud_spark_streaming.pdf)). If the processing is slower than receiving, the data will be queued as DStreams in memory and the queue will keep increasing. In order to run a healthy Spark streaming application, the system should be [tuned](http://spark.apache.org/docs/latest/streaming-programming-guide.html#performance-tuning) until the speed of processing is as fast as receiving. - -Samza jobs can have latency in the low milliseconds when running with Apache Kafka. It has a different approach to buffering. The buffering mechanism is dependent on the input and output system. For example, when using [Kafka](http://kafka.apache.org/) as the input and output system, data is actually buffered to disk. This design decision, by sacrificing a little latency, allows the buffer to absorb a large backlog of messages when a job has fallen behind in its processing. - -### Fault-tolerance - -There are two kinds of failures in both Spark Streaming and Samza: worker node (running executors) failure in Spark Streaming (equivalent to container failure in Samza) and driver node (running driver program) failure (equivalent to application manager (AM) failure in Samza). - -When a worker node fails in Spark Streaming, it will be restarted by the cluster manager. When a container fails in Samza, the application manager will work with YARN to start a new container. - -When a driver node fails in Spark Streaming, Spark’s [standalone cluster mode](http://spark.apache.org/docs/latest/spark-standalone.html) will restart the driver node automatically. But it is currently not supported in YARN and Mesos. You will need other mechanisms to restart the driver node automatically. Spark Streaming can use the checkpoint in HDFS to recreate the StreamingContext. When the AM fails in Samza, YARN will handle restarting the AM. Samza will restart all the containers if the AM restarts. - -In terms of data lost, there is a difference between Spark Streaming and Samza. If the input stream is active streaming system, such as Flume, Kafka, Spark Streaming may lose data if the failure happens when the data is received but not yet replicated to other nodes (also see [SPARK-1647](https://issues.apache.org/jira/browse/SPARK-1647)). Samza will not lose data when the failure happens because it has the concept of [checkpointing](../container/checkpointing.html) that stores the offset of the latest processed message and always commits the checkpoint after processing the data. There is not data lost situation like Spark Streaming has. If a container fails, it reads from the latest checkpoint. When a Samza job recovers from a failure, it's possible that it will process some data more than once. This happens because the job restarts at the last checkpoint, and any messages that had been processed between that checkpoint and the failure are processed again. The amount of reprocessed data can be minimized by setting a small checkpoint interval period. - -### Deployment & Execution - -Spark has a SparkContext object to talk with cluster managers, which then allocate resources for the application. Currently Spark supports three types of cluster managers: [Spark standalone](http://spark.apache.org/docs/latest/spark-standalone.html), [Apache Mesos](http://mesos.apache.org/) and [Hadoop YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html). Besides these, Spark has a script for launching in [Amazon EC2](http://spark.apache.org/docs/latest/ec2-scripts.html). - -Samza only supports YARN and local execution currently. - -### Isolation - -Spark Streaming and Samza have the same isolation. Spark Streaming depends on cluster managers (e.g Mesos or YARN) and Samza depend on YARN to provide processor isolation. Different applications run in different JVMs. Data cannot be shared among different applications unless it is written to external storage. Since Samza provides out-of-box Kafka integration, it is very easy to reuse the output of other Samza jobs (see [here](../introduction/concepts.html#dataflow-graphs)). - -### Language Support - -Spark Streaming is written in Java and Scala and provides Scala, Java, and Python APIs. Samza is written in Java and Scala and has a Java API. - -### Workflow - -In Spark Streaming, you build an entire processing graph with a DSL API and deploy that entire graph as one unit. The communication between the nodes in that graph (in the form of DStreams) is provided by the framework. That is a similar to Storm. Samza is totally different -- each job is just a message-at-a-time processor, and there is no framework support for topologies. Output of a processing task always needs to go back to a message broker (e.g. Kafka). - -A positive consequence of Samza's design is that a job's output can be consumed by multiple unrelated jobs, potentially run by different teams, and those jobs are isolated from each other through Kafka's buffering. That is not the case with Storm's and Spark Streaming's framework-internal streams. - -Although a Storm/Spark Streaming job could in principle write its output to a message broker, the framework doesn't really make this easy. It seems that Storm/Spark aren't intended to used in a way where one topology's output is another topology's input. By contrast, in Samza, that mode of usage is standard. - -### Maturity - -Spark has an active user and developer community, and recently releases 1.0.0 version. It has a list of companies that use it on its [Powered by](https://cwiki.apache.org/confluence/display/SPARK/Powered+By+Spark) page. Since Spark contains Spark Streaming, Spark SQL, MLlib, GraphX and Bagel, it's tough to tell what portion of companies on the list are actually using Spark Streaming, and not just Spark. - -Samza is still young, but has just released version 0.7.0. It has a responsive community and is being developed actively. That said, it is built on solid systems such as YARN and Kafka. Samza is heavily used at LinkedIn and we hope others will find it useful as well. - -## [API Overview »](../api/overview.html) diff --git a/docs/learn/documentation/0.7.0/comparisons/storm.md b/docs/learn/documentation/0.7.0/comparisons/storm.md deleted file mode 100644 index 58cb508..0000000 --- a/docs/learn/documentation/0.7.0/comparisons/storm.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -layout: page -title: Storm ---- - - -*People generally want to know how similar systems compare. We've done our best to fairly contrast the feature sets of Samza with other systems. But we aren't experts in these frameworks, and we are, of course, totally biased. If we have goofed anything, please let us know and we will correct it.* - -[Storm](http://storm-project.net/) and Samza are fairly similar. Both systems provide many of the same high-level features: a partitioned stream model, a distributed execution environment, an API for stream processing, fault tolerance, Kafka integration, etc. - -Storm and Samza use different words for similar concepts: *spouts* in Storm are similar to stream consumers in Samza, *bolts* are similar to tasks, and *tuples* are similar to messages in Samza. Storm also has some additional building blocks which don't have direct equivalents in Samza. - -### Ordering and Guarantees - -Storm allows you to choose the level of guarantee with which you want your messages to be processed: - -* The simplest mode is *at-most-once delivery*, which drops messages if they are not processed correctly, or if the machine doing the processing fails. This mode requires no special logic, and processes messages in the order they were produced by the spout. -* There is also *at-least-once delivery*, which tracks whether each input tuple (and any downstream tuples it generated) was successfully processed within a configured timeout, by keeping an in-memory record of all emitted tuples. Any tuples that are not fully processed within the timeout are re-emitted by the spout. This implies that a bolt may see the same tuple more than once, and that messages can be processed out-of-order. This mechanism also requires some co-operation from the user code, which must maintain the ancestry of records in order to properly acknowledge its input. This is explained in depth on [Storm's wiki](https://github.com/nathanmarz/storm/wiki/Guaranteeing-message-processing). -* Finally, Storm offers *exactly-once semantics* using its [Trident](https://github.com/nathanmarz/storm/wiki/Trident-tutorial) abstraction. This mode uses the same failure detection mechanism as the at-least-once mode. Tuples are actually processed at least once, but Storm's state implementation allows duplicates to be detected and ignored. (The duplicate detection only applies to state managed by Storm. If your code has other side-effects, e.g. sending messages to a service outside of the topology, it will not have exactly-once semantics.) In this mode, the spout breaks the input stream into batches, and processes batches in strictly sequential order. - -Samza also offers guaranteed delivery — currently only at-least-once delivery, but support for exactly-once semantics is planned. Within each stream partition, Samza always processes messages in the order they appear in the partition, but there is no guarantee of ordering across different input streams or partitions. This model allows Samza to offer at-least-once delivery without the overhead of ancestry tracking. In Samza, there would be no performance advantage to using at-most-once delivery (i.e. dropping messages on failure), which is why we don't offer that mode — message delivery is always guaranteed. - -Moreover, because Samza never processes messages in a partition out-of-order, it is better suited for handling keyed data. For example, if you have a stream of database updates — where later updates may replace earlier updates — then reordering the messages may change the final result. Provided that all updates for the same key appear in the same stream partition, Samza is able to guarantee a consistent state. - -### State Management - -Storm's lower-level API of bolts does not offer any help for managing state in a stream process. A bolt can maintain in-memory state (which is lost if that bolt dies), or it can make calls to a remote database to read and write state. However, a topology can usually process messages at a much higher rate than calls to a remote database can be made, so making a remote call for each message quickly becomes a bottleneck. - -As part of its higher-level Trident API, Storm offers automatic [state management](https://github.com/nathanmarz/storm/wiki/Trident-state). It keeps state in memory, and periodically checkpoints it to a remote database (e.g. Cassandra) for durability, so the cost of the remote database call is amortized over several processed tuples. By maintaining metadata alongside the state, Trident is able to achieve exactly-once processing semantics — for example, if you are counting events, this mechanism allows the counters to be correct, even when machines fail and tuples are replayed. - -Storm's approach of caching and batching state changes works well if the amount of state in each bolt is fairly small — perhaps less than 100kB. That makes it suitable for keeping track of counters, minimum, maximum and average values of a metric, and the like. However, if you need to maintain a large amount of state, this approach essentially degrades to making a database call per processed tuple, with the associated performance cost. - -Samza takes a [completely different approach](../container/state-management.html) to state management. Rather than using a remote database for durable storage, each Samza task includes an embedded key-value store, located on the same machine. Reads and writes to this store are very fast, even when the contents of the store are larger than the available memory. Changes to this key-value store are replicated to other machines in the cluster, so that if one machine dies, the state of the tasks it was running can be restored on another machine. - -By co-locating storage and processing on the same machine, Samza is able to achieve very high throughput, even when there is a large amount of state. This is necessary if you want to perform stateful operations that are not just counters. For example, if you want to perform a window join of multiple streams, or join a stream with a database table (replicated to Samza through a changelog), or group several related messages into a bigger message, then you need to maintain so much state that it is much more efficient to keep the state local to the task. - -A limitation of Samza's state handling is that it currently does not support exactly-once semantics — only at-least-once is supported right now. But we're working on fixing that, so stay tuned for updates. - -### Partitioning and Parallelism - -Storm's [parallelism model](https://github.com/nathanmarz/storm/wiki/Understanding-the-parallelism-of-a-Storm-topology) is fairly similar to Samza's. Both frameworks split processing into independent *tasks* that can run in parallel. Resource allocation is independent of the number of tasks: a small job can keep all tasks in a single process on a single machine; a large job can spread the tasks over many processes on many machines. - -The biggest difference is that Storm uses one thread per task by default, whereas Samza uses single-threaded processes (containers). A Samza container may contain multiple tasks, but there is only one thread that invokes each of the tasks in turn. This means each container is mapped to exactly one CPU core, which makes the resource model much simpler and reduces interference from other tasks running on the same machine. Storm's multithreaded model has the advantage of taking better advantage of excess capacity on an idle machine, at the cost of a less predictable resource model. - -Storm supports *dynamic rebalancing*, which means adding more threads or processes to a topology without restarting the topology or cluster. This is a convenient feature, especially during development. We haven't added this to Samza: philosophically we feel that this kind of change should go through a normal configuration management process (i.e. version control, notification, etc.) as it impacts production performance. In other words, the code and configuration of the jobs should fully recreate the state of the cluster. - -When using a transactional spout with Trident (a requirement for achieving exactly-once semantics), parallelism is potentially reduced. Trident relies on a global ordering in its input streams — that is, ordering across all partitions of a stream, not just within one partion. This means that the topology's input stream has to go through a single spout instance, effectively ignoring the partitioning of the input stream. This spout may become a bottleneck on high-volume streams. In Samza, all stream processing is parallel — there are no such choke points. - -### Deployment & Execution - -A Storm cluster is composed of a set of nodes running a *Supervisor* daemon. The supervisor daemons talk to a single master node running a daemon called *Nimbus*. The Nimbus daemon is responsible for assigning work and managing resources in the cluster. See Storm's [Tutorial](https://github.com/nathanmarz/storm/wiki/Tutorial) page for details. This is quite similar to YARN; though YARN is a bit more fully featured and intended to be multi-framework, Nimbus is better integrated with Storm. - -Yahoo! has also released [Storm-YARN](https://github.com/yahoo/storm-yarn). As described in [this Yahoo! blog post](http://developer.yahoo.com/blogs/ydn/storm-yarn-released-open-source-143745133.html), Storm-YARN is a wrapper that starts a single Storm cluster (complete with Nimbus, and Supervisors) inside a YARN grid. - -There are a lot of similarities between Storm's Nimbus and YARN's ResourceManager, as well as between Storm's Supervisor and YARN's Node Managers. Rather than writing our own resource management framework, or running a second one inside of YARN, we decided that Samza should use YARN directly, as a first-class citizen in the YARN ecosystem. YARN is stable, well adopted, fully-featured, and inter-operable with Hadoop. It also provides a bunch of nice features like security (user authentication), cgroup process isolation, etc. - -The YARN support in Samza is pluggable, so you can swap it for a different execution framework if you wish. - -### Language Support - -Storm is written in Java and Clojure but has good support for non-JVM languages. It follows a model similar to MapReduce Streaming: the non-JVM task is launched in a separate process, data is sent to its stdin, and output is read from its stdout. - -Samza is written in Java and Scala. It is built with multi-language support in mind, but currently only supports JVM languages. - -### Workflow - -Storm provides modeling of *topologies* (a processing graph of multiple stages) [in code](https://github.com/nathanmarz/storm/wiki/Tutorial). Trident provides a further [higher-level API](https://github.com/nathanmarz/storm/wiki/Trident-tutorial) on top of this, including familiar relational-like operators such as filters, grouping, aggregation and joins. This means the entire topology is wired up in one place, which has the advantage that it is documented in code, but has the disadvantage that the entire topology needs to be developed and deployed as a whole. - -In Samza, each job is an independent entity. You can define multiple jobs in a single codebase, or you can have separate teams working on different jobs using different codebases. Each job is deployed, started and stopped independently. Jobs communicate only through named streams, and you can add jobs to the system without affecting any other jobs. This makes Samza well suited for handling the data flow in a large company. - -Samza's approach can be emulated in Storm by connecting two separate topologies via a broker, such as Kafka. However, Storm's implementation of exactly-once semantics only works within a single topology. - -### Maturity - -We can't speak to Storm's maturity, but it has an [impressive number of adopters](https://github.com/nathanmarz/storm/wiki/Powered-By), a strong feature set, and seems to be under active development. It integrates well with many common messaging systems (RabbitMQ, Kestrel, Kafka, etc). - -Samza is pretty immature, though it builds on solid components. YARN is fairly new, but is already being run on 3000+ node clusters at Yahoo!, and the project is under active development by both [Hortonworks](http://hortonworks.com/) and [Cloudera](http://www.cloudera.com/content/cloudera/en/home.html). Kafka has a strong [powered by](https://cwiki.apache.org/KAFKA/powered-by.html) page, and has seen increased adoption recently. It's also frequently used with Storm. Samza is a brand new project that is in use at LinkedIn. Our hope is that others will find it useful, and adopt it as well. - -### Buffering & Latency - -Storm uses [ZeroMQ](http://zeromq.org/) for non-durable communication between bolts, which enables extremely low latency transmission of tuples. Samza does not have an equivalent mechanism, and always writes task output to a stream. - -On the flip side, when a bolt is trying to send messages using ZeroMQ, and the consumer can't read them fast enough, the ZeroMQ buffer in the producer's process begins to fill up with messages. If this buffer grows too much, the topology's processing timeout may be reached, which causes messages to be re-emitted at the spout and makes the problem worse by adding even more messages to the buffer. In order to prevent such overflow, you can configure a maximum number of messages that can be in flight in the topology at any one time; when that threshold is reached, the spout blocks until some of the messages in flight are fully processed. This mechanism allows back pressure, but requires [topology.max.spout.pending](http://nathanmarz.github.io/storm/doc/backtype/storm/Config.html#TOPOLOGY_MAX_SPOUT_PENDING) to be carefully configured. If a single bolt in a topology starts running slow, the processing in the entire topology grinds to a halt. - -A lack of a broker between bolts also adds complexity when trying to deal with fault tolerance and messaging semantics. Storm has a [clever mechanism](https://github.com/nathanmarz/storm/wiki/Guaranteeing-message-processing) for detecting tuples that failed to be processed, but Samza doesn't need such a mechanism because every input and output stream is fault-tolerant and replicated. - -Samza takes a different approach to buffering. We buffer to disk at every hop between a StreamTask. This decision, and its trade-offs, are described in detail on the [Comparison Introduction](introduction.html) page. This design decision makes durability guarantees easy, and has the advantage of allowing the buffer to absorb a large backlog of messages if a job has fallen behind in its processing. However, it comes at the price of slightly higher latency. - -As described in the *workflow* section above, Samza's approach can be emulated in Storm, but comes with a loss in functionality. - -### Isolation - -Storm provides standard UNIX process-level isolation. Your topology can impact another topology's performance (or vice-versa) if too much CPU, disk, network, or memory is used. - -Samza relies on YARN to provide resource-level isolation. Currently, YARN provides explicit controls for memory and CPU limits (through [cgroups](../yarn/isolation.html)), and both have been used successfully with Samza. No isolation for disk or network is provided by YARN at this time. - -### Distributed RPC - -In Storm, you can write topologies which not only accept a stream of fixed events, but also allow clients to run distributed computations on demand. The query is sent into the topology as a tuple on a special spout, and when the topology has computed the answer, it is returned to the client (who was synchronously waiting for the answer). This facility is called [Distributed RPC](https://github.com/nathanmarz/storm/wiki/Distributed-RPC) (DRPC). - -Samza does not currently have an equivalent API to DRPC, but you can build it yourself using Samza's stream processing primitives. - -### Data Model - -Storm models all messages as *tuples* with a defined data model but pluggable serialization. - -Samza's serialization and data model are both pluggable. We are not terribly opinionated about which approach is best. - -## [Spark Streaming »](spark-streaming.html) diff --git a/docs/learn/documentation/0.7.0/container/checkpointing.md b/docs/learn/documentation/0.7.0/container/checkpointing.md deleted file mode 100644 index 4efcef8..0000000 --- a/docs/learn/documentation/0.7.0/container/checkpointing.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -layout: page -title: Checkpointing ---- - - -Samza provides fault-tolerant processing of streams: Samza guarantees that messages won't be lost, even if your job crashes, if a machine dies, if there is a network fault, or something else goes wrong. In order to provide this guarantee, Samza expects the [input system](streams.html) to meet the following requirements: - -* The stream may be sharded into one or more *partitions*. Each partition is independent from the others, and is replicated across multiple machines (the stream continues to be available, even if a machine fails). -* Each partition consists of a sequence of messages in a fixed order. Each message has an *offset*, which indicates its position in that sequence. Messages are always consumed sequentially within each partition. -* A Samza job can start consuming the sequence of messages from any starting offset. - -Kafka meets these requirements, but they can also be implemented with other message broker systems. - -As described in the [section on SamzaContainer](samza-container.html), each task instance of your job consumes one partition of an input stream. Each task has a *current offset* for each input stream: the offset of the next message to be read from that stream partition. Every time a message is read from the stream, the current offset moves forwards. - -If a Samza container fails, it needs to be restarted (potentially on another machine) and resume processing where the failed container left off. In order to enable this, a container periodically checkpoints the current offset for each task instance. - -Illustration of checkpointing - -When a Samza container starts up, it looks for the most recent checkpoint and starts consuming messages from the checkpointed offsets. If the previous container failed unexpectedly, the most recent checkpoint may be slightly behind the current offsets (i.e. the job may have consumed some more messages since the last checkpoint was written), but we can't know for sure. In that case, the job may process a few messages again. - -This guarantee is called *at-least-once processing*: Samza ensures that your job doesn't miss any messages, even if containers need to be restarted. However, it is possible for your job to see the same message more than once when a container is restarted. We are planning to address this in a future version of Samza, but for now it is just something to be aware of: for example, if you are counting page views, a forcefully killed container could cause events to be slightly over-counted. You can reduce duplication by checkpointing more frequently, at a slight performance cost. - -For checkpoints to be effective, they need to be written somewhere where they will survive faults. Samza allows you to write checkpoints to the file system (using FileSystemCheckpointManager), but that doesn't help if the machine fails and the container needs to be restarted on another machine. The most common configuration is to use Kafka for checkpointing. You can enable this with the following job configuration: - -{% highlight jproperties %} -# The name of your job determines the name under which checkpoints will be stored -job.name=example-job - -# Define a system called "kafka" for consuming and producing to a Kafka cluster -systems.kafka.samza.factory=org.apache.samza.system.kafka.KafkaSystemFactory - -# Declare that we want our job's checkpoints to be written to Kafka -task.checkpoint.factory=org.apache.samza.checkpoint.kafka.KafkaCheckpointManagerFactory -task.checkpoint.system=kafka - -# By default, a checkpoint is written every 60 seconds. You can change this if you like. -task.commit.ms=60000 -{% endhighlight %} - -In this configuration, Samza writes checkpoints to a separate Kafka topic called \_\_samza\_checkpoint\_<job-name>\_<job-id> (in the example configuration above, the topic would be called \_\_samza\_checkpoint\_example-job\_1). Once per minute, Samza automatically sends a message to this topic, in which the current offsets of the input streams are encoded. When a Samza container starts up, it looks for the most recent offset message in this topic, and loads that checkpoint. - -Sometimes it can be useful to use checkpoints only for some input streams, but not for others. In this case, you can tell Samza to ignore any checkpointed offsets for a particular stream name: - -{% highlight jproperties %} -# Ignore any checkpoints for the topic "my-special-topic" -systems.kafka.streams.my-special-topic.samza.reset.offset=true - -# Always start consuming "my-special-topic" at the oldest available offset -systems.kafka.streams.my-special-topic.samza.offset.default=oldest -{% endhighlight %} - -The following table explains the meaning of these configuration parameters: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter nameValueMeaning
systems.<system>.
streams.<stream>.
samza.reset.offset
false (default)When container starts up, resume processing from last checkpoint
trueIgnore checkpoint (pretend that no checkpoint is present)
systems.<system>.
streams.<stream>.
samza.offset.default
upcoming (default)When container starts and there is no checkpoint (or the checkpoint is ignored), only process messages that are published after the job is started, but no old messages
oldestWhen container starts and there is no checkpoint (or the checkpoint is ignored), jump back to the oldest available message in the system, and consume all messages from that point onwards (most likely this means repeated processing of messages already seen previously)
- -Note that the example configuration above causes your tasks to start consuming from the oldest offset *every time a container starts up*. This is useful in case you have some in-memory state in your tasks that you need to rebuild from source data in an input stream. If you are using streams in this way, you may also find [bootstrap streams](streams.html) useful. - -### Manipulating Checkpoints Manually - -If you want to make a one-off change to a job's consumer offsets, for example to force old messages to be [processed again](../jobs/reprocessing.html) with a new version of your code, you can use CheckpointTool to inspect and manipulate the job's checkpoint. The tool is included in Samza's [source repository](/contribute/code.html). - -To inspect a job's latest checkpoint, you need to specify your job's config file, so that the tool knows which job it is dealing with: - -{% highlight bash %} -samza-example/target/bin/checkpoint-tool.sh \ - --config-path=file:///path/to/job/config.properties -{% endhighlight %} - -This command prints out the latest checkpoint in a properties file format. You can save the output to a file, and edit it as you wish. For example, to jump back to the oldest possible point in time, you can set all the offsets to 0. Then you can feed that properties file back into checkpoint-tool.sh and save the modified checkpoint: - -{% highlight bash %} -samza-example/target/bin/checkpoint-tool.sh \ - --config-path=file:///path/to/job/config.properties \ - --new-offsets=file:///path/to/new/offsets.properties -{% endhighlight %} - -Note that Samza only reads checkpoints on container startup. In order for your checkpoint change to take effect, you need to first stop the job, then save the modified offsets, and then start the job again. If you write a checkpoint while the job is running, it will most likely have no effect. - -## [State Management »](state-management.html) diff --git a/docs/learn/documentation/0.7.0/container/event-loop.md b/docs/learn/documentation/0.7.0/container/event-loop.md deleted file mode 100644 index f0f21b0..0000000 --- a/docs/learn/documentation/0.7.0/container/event-loop.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -layout: page -title: Event Loop ---- - - -The event loop is the [container](samza-container.html)'s single thread that is in charge of [reading and writing messages](streams.html), [flushing metrics](metrics.html), [checkpointing](checkpointing.html), and [windowing](windowing.html). - -Samza uses a single thread because every container is designed to use a single CPU core; to get more parallelism, simply run more containers. This uses a bit more memory than multithreaded parallelism, because each JVM has some overhead, but it simplifies resource management and improves isolation between jobs. This helps Samza jobs run reliably on a multitenant cluster, where many different jobs written by different people are running at the same time. - -You are strongly discouraged from using threads in your job's code. Samza uses multiple threads internally for communicating with input and output streams, but all message processing and user code runs on a single-threaded event loop. In general, Samza is not thread-safe. - -### Event Loop Internals - -A container may have multiple [SystemConsumers](../api/javadocs/org/apache/samza/system/SystemConsumer.html) for consuming messages from different input systems. Each SystemConsumer reads messages on its own thread, but writes messages into a shared in-process message queue. The container uses this queue to funnel all of the messages into the event loop. - -The event loop works as follows: - -1. Take a message from the incoming message queue; -2. Give the message to the appropriate [task instance](samza-container.html) by calling process() on it; -3. Call window() on the task instance if it implements [WindowableTask](../api/javadocs/org/apache/samza/task/WindowableTask.html), and the window time has expired; -4. Send any output from the process() and window() calls to the appropriate [SystemProducers](../api/javadocs/org/apache/samza/system/SystemProducer.html); -5. Write checkpoints for any tasks whose [commit interval](checkpointing.html) has elapsed. - -The container does this, in a loop, until it is shut down. Note that although there can be multiple task instances within a container (depending on the number of input stream partitions), their process() and window() methods are all called on the same thread, never concurrently on different threads. - -### Lifecycle Listeners - -Sometimes, you need to run your own code at specific points in a task's lifecycle. For example, you might want to set up some context in the container whenever a new message arrives, or perform some operations on startup or shutdown. - -To receive notifications when such events happen, you can implement the [TaskLifecycleListenerFactory](../api/javadocs/org/apache/samza/task/TaskLifecycleListenerFactory.html) interface. It returns a [TaskLifecycleListener](../api/javadocs/org/apache/samza/task/TaskLifecycleListener.html), whose methods are called by Samza at the appropriate times. - -You can then tell Samza to use your lifecycle listener with the following properties in your job configuration: - -{% highlight jproperties %} -# Define a listener called "my-listener" by giving the factory class name -task.lifecycle.listener.my-listener.class=com.example.foo.MyListenerFactory - -# Enable it in this job (multiple listeners can be separated by commas) -task.lifecycle.listeners=my-listener -{% endhighlight %} - -The Samza container creates one instance of your [TaskLifecycleListener](../api/javadocs/org/apache/samza/task/TaskLifecycleListener.html). If the container has multiple task instances (processing different input stream partitions), the beforeInit, afterInit, beforeClose and afterClose methods are called for each task instance. The [TaskContext](../api/javadocs/org/apache/samza/task/TaskContext.html) argument of those methods gives you more information about the partitions. - -## [JMX »](jmx.html) diff --git a/docs/learn/documentation/0.7.0/container/jmx.md b/docs/learn/documentation/0.7.0/container/jmx.md deleted file mode 100644 index bdd5614..0000000 --- a/docs/learn/documentation/0.7.0/container/jmx.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -layout: page -title: JMX ---- - - -Samza's containers and YARN ApplicationMaster enable [JMX](http://docs.oracle.com/javase/tutorial/jmx/) by default. JMX can be used for managing the JVM; for example, you can connect to it using [jconsole](http://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html), which is included in the JDK. - -You can tell Samza to publish its internal [metrics](metrics.html), and any custom metrics you define, as JMX MBeans. To enable this, set the following properties in your job configuration: - -{% highlight jproperties %} -# Define a Samza metrics reporter called "jmx", which publishes to JMX -metrics.reporter.jmx.class=org.apache.samza.metrics.reporter.JmxReporterFactory - -# Use it (if you have multiple reporters defined, separate them with commas) -metrics.reporters=jmx -{% endhighlight %} - -JMX needs to be configured to use a specific port, but in a distributed environment, there is no way of knowing in advance which ports are available on the machines running your containers. Therefore Samza chooses the JMX port randomly. If you need to connect to it, you can find the port by looking in the container's logs, which report the JMX server details as follows: - - 2014-06-02 21:50:17 JmxServer [INFO] According to InetAddress.getLocalHost.getHostName we are samza-grid-1234.example.com - 2014-06-02 21:50:17 JmxServer [INFO] Started JmxServer registry port=50214 server port=50215 url=service:jmx:rmi://localhost:50215/jndi/rmi://localhost:50214/jmxrmi - 2014-06-02 21:50:17 JmxServer [INFO] If you are tunneling, you might want to try JmxServer registry port=50214 server port=50215 url=service:jmx:rmi://samza-grid-1234.example.com:50215/jndi/rmi://samza-grid-1234.example.com:50214/jmxrmi - -## [JobRunner »](../jobs/job-runner.html) diff --git a/docs/learn/documentation/0.7.0/container/metrics.md b/docs/learn/documentation/0.7.0/container/metrics.md deleted file mode 100644 index 8ec7740..0000000 --- a/docs/learn/documentation/0.7.0/container/metrics.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -layout: page -title: Metrics ---- - - -When you're running a stream process in production, it's important that you have good metrics to track the health of your job. In order to make this easy, Samza includes a metrics library. It is used by Samza itself to generate some standard metrics such as message throughput, but you can also use it in your task code to emit custom metrics. - -Metrics can be reported in various ways. You can expose them via [JMX](jmx.html), which is useful in development. In production, a common setup is for each Samza container to periodically publish its metrics to a "metrics" Kafka topic, in which the metrics from all Samza jobs are aggregated. You can then consume this stream in another Samza job, and send the metrics to your favorite graphing system such as [Graphite](http://graphite.wikidot.com/). - -To set up your job to publish metrics to Kafka, you can use the following configuration: - -{% highlight jproperties %} -# Define a metrics reporter called "snapshot", which publishes metrics -# every 60 seconds. -metrics.reporters=snapshot -metrics.reporter.snapshot.class=org.apache.samza.metrics.reporter.MetricsSnapshotReporterFactory - -# Tell the snapshot reporter to publish to a topic called "metrics" -# in the "kafka" system. -metrics.reporter.snapshot.stream=kafka.metrics - -# Encode metrics data as JSON. -serializers.registry.metrics.class=org.apache.samza.serializers.MetricsSnapshotSerdeFactory -systems.kafka.streams.metrics.samza.msg.serde=metrics -{% endhighlight %} - -With this configuration, the job automatically sends several JSON-encoded messages to the "metrics" topic in Kafka every 60 seconds. The messages look something like this: - -{% highlight json %} -{ - "header": { - "container-name": "samza-container-0", - "host": "samza-grid-1234.example.com", - "job-id": "1", - "job-name": "my-samza-job", - "reset-time": 1401729000347, - "samza-version": "0.0.1", - "source": "Partition-2", - "time": 1401729420566, - "version": "0.0.1" - }, - "metrics": { - "org.apache.samza.container.TaskInstanceMetrics": { - "commit-calls": 7, - "commit-skipped": 77948, - "kafka-input-topic-offset": "1606", - "messages-sent": 985, - "process-calls": 1093, - "send-calls": 985, - "send-skipped": 76970, - "window-calls": 0, - "window-skipped": 77955 - } - } -} -{% endhighlight %} - -There is a separate message for each task instance, and the header tells you the job name, job ID and partition of the task. The metrics allow you to see how many messages have been processed and sent, the current offset in the input stream partition, and other details. There are additional messages which give you metrics about the JVM (heap size, garbage collection information, threads etc.), internal metrics of the Kafka producers and consumers, and more. - -It's easy to generate custom metrics in your job, if there's some value you want to keep an eye on. You can use Samza's built-in metrics framework, which is similar in design to Coda Hale's [metrics](http://metrics.codahale.com/) library. - -You can register your custom metrics through a [MetricsRegistry](../api/javadocs/org/apache/samza/metrics/MetricsRegistry.html). Your stream task needs to implement [InitableTask](../api/javadocs/org/apache/samza/task/InitableTask.html), so that you can get the metrics registry from the [TaskContext](../api/javadocs/org/apache/samza/task/TaskContext.html). This simple example shows how to count the number of messages processed by your task: - -{% highlight java %} -public class MyJavaStreamTask implements StreamTask, InitableTask { - private Counter messageCount; - - public void init(Config config, TaskContext context) { - this.messageCount = context - .getMetricsRegistry() - .newCounter(getClass().getName(), "message-count"); - } - - public void process(IncomingMessageEnvelope envelope, - MessageCollector collector, - TaskCoordinator coordinator) { - messageCount.inc(); - } -} -{% endhighlight %} - -Samza currently supports two kind of metrics: [counters](../api/javadocs/org/apache/samza/metrics/Counter.html) and [gauges](../api/javadocs/org/apache/samza/metrics/Gauge.html). Use a counter when you want to track how often something occurs, and a gauge when you want to report the level of something, such as the size of a buffer. Each task instance (for each input stream partition) gets its own set of metrics. - -If you want to report metrics in some other way, e.g. directly to a graphing system (without going via Kafka), you can implement a [MetricsReporterFactory](../api/javadocs/org/apache/samza/metrics/MetricsReporterFactory.html) and reference it in your job configuration. - -## [Windowing »](windowing.html) diff --git a/docs/learn/documentation/0.7.0/container/samza-container.md b/docs/learn/documentation/0.7.0/container/samza-container.md deleted file mode 100644 index ab4f0e4..0000000 --- a/docs/learn/documentation/0.7.0/container/samza-container.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -layout: page -title: SamzaContainer ---- - - -The SamzaContainer is responsible for managing the startup, execution, and shutdown of one or more [StreamTask](../api/overview.html) instances. Each SamzaContainer typically runs as an indepentent Java virtual machine. A Samza job can consist of several SamzaContainers, potentially running on different machines. - -When a SamzaContainer starts up, it does the following: - -1. Get last checkpointed offset for each input stream partition that it consumes -2. Create a "reader" thread for every input stream partition that it consumes -3. Start metrics reporters to report metrics -4. Start a checkpoint timer to save your task's input stream offsets every so often -5. Start a window timer to trigger your task's [window method](../api/javadocs/org/apache/samza/task/WindowableTask.html), if it is defined -6. Instantiate and initialize your StreamTask once for each input stream partition -7. Start an event loop that takes messages from the input stream reader threads, and gives them to your StreamTasks -8. Notify lifecycle listeners during each one of these steps - -Let's start in the middle, with the instantiation of a StreamTask. The following sections of the documentation cover the other steps. - -### Tasks and Partitions - -When the container starts, it creates instances of the [task class](../api/overview.html) that you've written. If the task class implements the [InitableTask](../api/javadocs/org/apache/samza/task/InitableTask.html) interface, the SamzaContainer will also call the init() method. - -{% highlight java %} -/** Implement this if you want a callback when your task starts up. */ -public interface InitableTask { - void init(Config config, TaskContext context); -} -{% endhighlight %} - -By default, how many instances of your task class are created depends on the number of partitions in the job's input streams. If your Samza job has ten partitions, there will be ten instantiations of your task class: one for each partition. The first task instance will receive all messages for partition one, the second instance will receive all messages for partition two, and so on. - -Illustration of tasks consuming partitions - -The number of partitions in the input streams is determined by the systems from which you are consuming. For example, if your input system is Kafka, you can specify the number of partitions when you create a topic from the command line or using the num.partitions in Kafka's server properties file. - -If a Samza job has more than one input stream, the number of task instances for the Samza job is the maximum number of partitions across all input streams. For example, if a Samza job is reading from PageViewEvent (12 partitions), and ServiceMetricEvent (14 partitions), then the Samza job would have 14 task instances (numbered 0 through 13). Task instances 12 and 13 only receive events from ServiceMetricEvent, because there is no corresponding PageViewEvent partition. - -With this default approach to assigning input streams to task instances, Samza is effectively performing a group-by operation on the input streams with their partitions as the key. Other strategies for grouping input stream partitions are possible by implementing a new [SystemStreamPartitionGrouper](../api/javadocs/org/apache/samza/container/SystemStreamPartitionGrouper.html) and factory, and configuring the job to use it via the job.systemstreampartition.grouper.factory configuration value. - -Samza provides the above-discussed per-partition grouper as well as the [GroupBySystemStreamPartitionGrouper](../api/javadocs/org/apache/samza/container/systemstreampartition/groupers/GroupBySystemStreamPartition), which provides a separate task class instance for every input stream partition, effectively grouping by the input stream itself. This provides maximum scalability in terms of how many containers can be used to process those input streams and is appropriate for very high volume jobs that need no grouping of the input streams. - -Considering the above example of a PageViewEvent partitioned 12 ways and a ServiceMetricEvent partitioned 14 ways, the GroupBySystemStreamPartitionGrouper would create 12 + 14 = 26 task instances, which would then be distributed across the number of containers configured, as discussed below. - -Note that once a job has been started using a particular SystemStreamPartitionGrouper and that job is using state or checkpointing, it is not possible to change that grouping in subsequent job starts, as the previous checkpoints and state information would likely be incorrect under the new grouping approach. - -### Containers and resource allocation - -Although the number of task instances is fixed — determined by the number of input partitions — you can configure how many containers you want to use for your job. If you are [using YARN](../jobs/yarn-jobs.html), the number of containers determines what CPU and memory resources are allocated to your job. - -If the data volume on your input streams is small, it might be sufficient to use just one SamzaContainer. In that case, Samza still creates one task instance per input partition, but all those tasks run within the same container. At the other extreme, you can create as many containers as you have partitions, and Samza will assign one task instance to each container. - -Each SamzaContainer is designed to use one CPU core, so it uses a [single-threaded event loop](event-loop.html) for execution. It's not advisable to create your own threads within a SamzaContainer. If you need more parallelism, please configure your job to use more containers. - -Any [state](state-management.html) in your job belongs to a task instance, not to a container. This is a key design decision for Samza's scalability: as your job's resource requirements grow and shrink, you can simply increase or decrease the number of containers, but the number of task instances remains unchanged. As you scale up or down, the same state remains attached to each task instance. Task instances may be moved from one container to another, and any persistent state managed by Samza will be moved with it. This allows the job's processing semantics to remain unchanged, even as you change the job's parallelism. - -### Joining multiple input streams - -If your job has multiple input streams, Samza provides a simple but powerful mechanism for joining data from different streams: each task instance receives messages from one partition of *each* of the input streams. For example, say you have two input streams, A and B, each with four partitions. Samza creates four task instances to process them, and assigns the partitions as follows: - - - - - - - - - - - - - - - - - - - - - - -
Task instanceConsumes stream partitions
0stream A partition 0, stream B partition 0
1stream A partition 1, stream B partition 1
2stream A partition 2, stream B partition 2
3stream A partition 3, stream B partition 3
- -Thus, if you want two events in different streams to be processed by the same task instance, you need to ensure they are sent to the same partition number. You can achieve this by using the same partitioning key when [sending the messages](../api/overview.html). Joining streams is discussed in detail in the [state management](state-management.html) section. - -There is one caveat in all of this: Samza currently assumes that a stream's partition count will never change. Partition splitting or repartitioning is not supported. If an input stream has N partitions, it is expected that it has always had, and will always have N partitions. If you want to re-partition a stream, you can write a job that reads messages from the stream, and writes them out to a new stream with the required number of partitions. For example, you could read messages from PageViewEvent, and write them to PageViewEventRepartition. - -## [Streams »](streams.html) diff --git a/docs/learn/documentation/0.7.0/container/serialization.md b/docs/learn/documentation/0.7.0/container/serialization.md deleted file mode 100644 index ff7d8b9..0000000 --- a/docs/learn/documentation/0.7.0/container/serialization.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -layout: page -title: Serialization ---- - - -Every message that is read from or written to a [stream](streams.html) or a [persistent state store](state-management.html) needs to eventually be serialized to bytes (which are sent over the network or written to disk). There are various places where that serialization and deserialization can happen: - -1. In the client library: for example, the library for publishing to Kafka and consuming from Kafka supports pluggable serialization. -2. In the task implementation: your [process method](../api/overview.html) can use raw byte arrays as inputs and outputs, and do any parsing and serialization itself. -3. Between the two: Samza provides a layer of serializers and deserializers, or *serdes* for short. - -You can use whatever makes sense for your job; Samza doesn't impose any particular data model or serialization scheme on you. However, the cleanest solution is usually to use Samza's serde layer. The following configuration example shows how to use it. - -{% highlight jproperties %} -# Define a system called "kafka" -systems.kafka.samza.factory=org.apache.samza.system.kafka.KafkaSystemFactory - -# The job is going to consume a topic called "PageViewEvent" from the "kafka" system -task.inputs=kafka.PageViewEvent - -# Define a serde called "json" which parses/serializes JSON objects -serializers.registry.json.class=org.apache.samza.serializers.JsonSerdeFactory - -# Define a serde called "integer" which encodes an integer as 4 binary bytes (big-endian) -serializers.registry.integer.class=org.apache.samza.serializers.IntegerSerdeFactory - -# For messages in the "PageViewEvent" topic, the key (the ID of the user viewing the page) -# is encoded as a binary integer, and the message is encoded as JSON. -systems.kafka.streams.PageViewEvent.samza.key.serde=integer -systems.kafka.streams.PageViewEvent.samza.msg.serde=json - -# Define a key-value store which stores the most recent page view for each user ID. -# Again, the key is an integer user ID, and the value is JSON. -stores.LastPageViewPerUser.factory=org.apache.samza.storage.kv.KeyValueStorageEngineFactory -stores.LastPageViewPerUser.changelog=kafka.last-page-view-per-user -stores.LastPageViewPerUser.key.serde=integer -stores.LastPageViewPerUser.msg.serde=json -{% endhighlight %} - -Each serde is defined with a factory class. Samza comes with several builtin serdes for UTF-8 strings, binary-encoded integers, JSON (requires the samza-serializers dependency) and more. You can also create your own serializer by implementing the [SerdeFactory](../api/javadocs/org/apache/samza/serializers/SerdeFactory.html) interface. - -The name you give to a serde (such as "json" and "integer" in the example above) is only for convenience in your job configuration; you can choose whatever name you like. For each stream and each state store, you can use the serde name to declare how messages should be serialized and deserialized. - -If you don't declare a serde, Samza simply passes objects through between your task instance and the system stream. In that case your task needs to send and receive whatever type of object the underlying client library uses. - -All the Samza APIs for sending and receiving messages are typed as *Object*. This means that you have to cast messages to the correct type before you can use them. It's a little bit more code, but it has the advantage that Samza is not restricted to any particular data model. - -## [Checkpointing »](checkpointing.html) diff --git a/docs/learn/documentation/0.7.0/container/state-management.md b/docs/learn/documentation/0.7.0/container/state-management.md deleted file mode 100644 index e54739c..0000000 --- a/docs/learn/documentation/0.7.0/container/state-management.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -layout: page -title: State Management ---- - - -One of the more interesting features of Samza is stateful stream processing. Tasks can store and query data through APIs provided by Samza. That data is stored on the same machine as the stream task; compared to connecting over the network to a remote database, Samza's local state allows you to read and write large amounts of data with better performance. Samza replicates this state across multiple machines for fault-tolerance (described in detail below). - -Some stream processing jobs don't require state: if you only need to transform one message at a time, or filter out messages based on some condition, your job can be simple. Every call to your task's [process method](../api/overview.html) handles one incoming message, and each message is independent of all the other messages. - -However, being able to maintain state opens up many possibilities for sophisticated stream processing jobs: joining input streams, grouping messages and aggregating groups of messages. By analogy to SQL, the *select* and *where* clauses of a query are usually stateless, but *join*, *group by* and aggregation functions like *sum* and *count* require state. Samza doesn't yet provide a higher-level SQL-like language, but it does provide lower-level primitives that you can use to implement streaming aggregation and joins. - -### Common use cases for stateful processing - -First, let's look at some simple examples of stateful stream processing that might be seen in the backend of a consumer website. Later in this page we'll discuss how to implement these applications using Samza's built-in key-value storage capabilities. - -#### Windowed aggregation - -*Example: Counting the number of page views for each user per hour* - -In this case, your state typically consists of a number of counters which are incremented when a message is processed. The aggregation is typically limited to a time window (e.g. 1 minute, 1 hour, 1 day) so that you can observe changes of activity over time. This kind of windowed processing is common for ranking and relevance, detecting "trending topics", as well as real-time reporting and monitoring. - -The simplest implementation keeps this state in memory (e.g. a hash map in the task instances), and writes it to a database or output stream at the end of every time window. However, you need to consider what happens when a container fails and your in-memory state is lost. You might be able to restore it by processing all the messages in the current window again, but that might take a long time if the window covers a long period of time. Samza can speed up this recovery by making the state fault-tolerant rather than trying to recompute it. - -#### Table-table join - -*Example: Join a table of user profiles to a table of user settings by user\_id and emit the joined stream* - -You might wonder: does it make sense to join two tables in a stream processing system? It does if your database can supply a log of all the changes in the database. There is a [duality between a database and a changelog stream](http://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying): you can publish every data change to a stream, and if you consume the entire stream from beginning to end, you can reconstruct the entire contents of the database. Samza is designed for data processing jobs that follow this philosophy. - -If you have changelog streams for several database tables, you can write a stream processing job which keeps the latest state of each table in a local key-value store, where you can access it much faster than by making queries to the original database. Now, whenever data in one table changes, you can join it with the latest data for the same key in the other table, and output the joined result. - -There are several real-life examples of data normalization which essentially work in this way: - -* E-commerce companies like Amazon and EBay need to import feeds of merchandise from merchants, normalize them by product, and present products with all the associated merchants and pricing information. -* Web search requires building a crawler which creates essentially a [table of web page contents](http://labs.yahoo.com/files/YahooWebmap.pdf) and joins on all the relevance attributes such as click-through ratio or pagerank. -* Social networks take feeds of user-entered text and need to normalize out entities such as companies, schools, and skills. - -Each of these use cases is a massively complex data normalization problem that can be thought of as constructing a materialized view over many input tables. Samza can help implement such data processing pipelines robustly. - -#### Stream-table join - -*Example: Augment a stream of page view events with the user's ZIP code (perhaps to allow aggregation by zip code in a later stage)* - -Joining side-information to a real-time feed is a classic use for stream processing. It's particularly common in advertising, relevance ranking, fraud detection and other domains. Activity events such as page views generally only include a small number of attributes, such as the ID of the viewer and the viewed items, but not detailed attributes of the viewer and the viewed items, such as the ZIP code of the user. If you want to aggregate the stream by attributes of the viewer or the viewed items, you need to join with the users table or the items table respectively. - -In data warehouse terminology, you can think of the raw event stream as rows in the central fact table, which needs to be joined with dimension tables so that you can use attributes of the dimensions in your analysis. - -#### Stream-stream join - -*Example: Join a stream of ad clicks to a stream of ad impressions (to link the information on when the ad was shown to the information on when it was clicked)* - -A stream join is useful for "nearly aligned" streams, where you expect to receive related events on several input streams, and you want to combine them into a single output event. You cannot rely on the events arriving at the stream processor at the same time, but you can set a maximum period of time over which you allow the events to be spread out. - -In order to perform a join between streams, your job needs to buffer events for the time window over which you want to join. For short time windows, you can do this in memory (at the risk of losing events if the machine fails). You can also use Samza's state store to buffer events, which supports buffering more messages than you can fit in memory. - -#### More - -There are many variations of joins and aggregations, but most are essentially variations and combinations of the above patterns. - -### Approaches to managing task state - -So how do systems support this kind of stateful processing? We'll lead in by describing what we have seen in other stream processing systems, and then describe what Samza does. - -#### In-memory state with checkpointing - -A simple approach, common in academic stream processing systems, is to periodically save the task's entire in-memory data to durable storage. This approach works well if the in-memory state consists of only a few values. However, you have to store the complete task state on each checkpoint, which becomes increasingly expensive as task state grows. Unfortunately, many non-trivial use cases for joins and aggregation have large amounts of state — often many gigabytes. This makes full dumps of the state impractical. - -Some academic systems produce *diffs* in addition to full checkpoints, which are smaller if only some of the state has changed since the last checkpoint. [Storm's Trident abstraction](../comparisons/storm.html) similarly keeps an in-memory cache of state, and periodically writes any changes to a remote store such as Cassandra. However, this optimization only helps if most of the state remains unchanged. In some use cases, such as stream joins, it is normal to have a lot of churn in the state, so this technique essentially degrades to making a remote database request for every message (see below). - -#### Using an external store - -Another common pattern for stateful processing is to store the state in an external database or key-value store. Conventional database replication can be used to make that database fault-tolerant. The architecture looks something like this: - -![state-kv-store](/img/0.7.0/learn/documentation/container/stream_job_and_db.png) - -Samza allows this style of processing — there is nothing to stop you querying a remote database or service within your job. However, there are a few reasons why a remote database can be problematic for stateful stream processing: - -1. **Performance**: Making database queries over a network is slow and expensive. A Kafka stream can deliver hundreds of thousands or even millions of messages per second per CPU core to a stream processor, but if you need to make a remote request for every message you process, your throughput is likely to drop by 2-3 orders of magnitude. You can somewhat mitigate this with careful caching of reads and batching of writes, but then you're back to the problems of checkpointing, discussed above. -2. **Isolation**: If your database or service also serves requests to users, it can be dangerous to use the same database with a stream processor. A scalable stream processing system can run with very high throughput, and easily generates a huge amount of load (for example when catching up on a queue backlog). If you're not very careful, you may cause a denial-of-service attack on your own database, and cause problems for interactive requests from users. -3. **Query Capabilities**: Many scalable databases expose very limited query interfaces (e.g. only supporting simple key-value lookups), because the equivalent of a "full table scan" or rich traversal would be too expensive. Stream processes are often less latency-sensitive, so richer query capabilities would be more feasible. -4. **Correctness**: When a stream processor fails and needs to be restarted, how is the database state made consistent with the processing task? For this purpose, some frameworks such as [Storm](../comparisons/storm.html) attach metadata to database entries, but it needs to be handled carefully, otherwise the stream process generates incorrect output. -5. **Reprocessing**: Sometimes it can be useful to re-run a stream process on a large amount of historical data, e.g. after updating your processing task's code. However, the issues above make this impractical for jobs that make external queries. - -### Local state in Samza - -Samza allows tasks to maintain state in a way that is different from the approaches described above: - -* The state is stored on disk, so the job can maintain more state than would fit in memory. -* It is stored on the same machine as the processing task, to avoid the performance problems of making database queries over the network. -* Each job has its own datastore, to avoid the isolation problems of a shared database (if you make an expensive query, it affects only the current task, nobody else). -* Different storage engines can be plugged in, enabling rich query capabilities. -* The state is continuously replicated, enabling fault tolerance without the problems of checkpointing large amounts of state. - -Imagine you take a remote database, partition it to match the number of tasks in the stream processing job, and co-locate each partition with its task. The result looks like this: - -![state-local](/img/0.7.0/learn/documentation/container/stateful_job.png) - -If a machine fails, all the tasks running on that machine and their database partitions are lost. In order to make them highly available, all writes to the database partition are replicated to a durable changelog (typically Kafka). Now, when a machine fails, we can restart the tasks on another machine, and consume this changelog in order to restore the contents of the database partition. - -Note that each task only has access to its own database partition, not to any other task's partition. This is important: when you scale out your job by giving it more computing resources, Samza needs to move tasks from one machine to another. By giving each task its own state, tasks can be relocated without affecting the job's operation. If necessary, you can repartition your streams so that all messages for a particular database partition are routed to the same task instance. - -[Log compaction](http://kafka.apache.org/documentation.html#compaction) runs in the background on the changelog topic, and ensures that the changelog does not grow indefinitely. If you overwrite the same value in the store many times, log compaction keeps only the most recent value, and throws away any old values in the log. If you delete an item from the store, log compaction also removes it from the log. With the right tuning, the changelog is not much bigger than the database itself. - -With this architecture, Samza allows tasks to maintain large amounts of fault-tolerant state, at a performance that is almost as good as a pure in-memory implementation. There are just a few limitations: - -* If you have some data that you want to share between tasks (across partition boundaries), you need to go to some additional effort to repartition and distribute the data. Each task will need its own copy of the data, so this may use more space overall. -* When a container is restarted, it can take some time to restore the data in all of its state partitions. The time depends on the amount of data, the storage engine, your access patterns, and other factors. As a rule of thumb, 50 MB/sec is a reasonable restore time to expect. - -Nothing prevents you from using an external database if you want to, but for many use cases, Samza's local state is a powerful tool for enabling stateful stream processing. - -### Key-value storage - -Any storage engine can be plugged into Samza, as described below. Out of the box, Samza ships with a key-value store implementation that is built on [LevelDB](https://code.google.com/p/leveldb) using a [JNI API](https://github.com/fusesource/leveldbjni). - -LevelDB has several nice properties. Its memory allocation is outside of the Java heap, which makes it more memory-efficient and less prone to garbage collection pauses than a Java-based storage engine. It is very fast for small datasets that fit in memory; datasets larger than memory are slower but still possible. It is [log-structured](http://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/), allowing very fast writes. It also includes support for block compression, which helps to reduce I/O and memory usage. - -Samza includes an additional in-memory caching layer in front of LevelDB, which avoids the cost of deserialization for frequently-accessed objects and batches writes. If the same key is updated multiple times in quick succession, the batching coalesces those updates into a single write. The writes are flushed to the changelog when a task [commits](checkpointing.html). - -To use a key-value store in your job, add the following to your job config: - -{% highlight jproperties %} -# Use the key-value store implementation for a store called "my-store" -stores.my-store.factory=org.apache.samza.storage.kv.KeyValueStorageEngineFactory - -# Use the Kafka topic "my-store-changelog" as the changelog stream for this store. -# This enables automatic recovery of the store after a failure. If you don't -# configure this, no changelog stream will be generated. -stores.my-store.changelog=kafka.my-store-changelog - -# Encode keys and values in the store as UTF-8 strings. -serializers.registry.string.class=org.apache.samza.serializers.StringSerdeFactory -stores.my-store.key.serde=string -stores.my-store.msg.serde=string -{% endhighlight %} - -See the [serialization section](serialization.html) for more information on the *serde* options. - -Here is a simple example that writes every incoming message to the store: - -{% highlight java %} -public class MyStatefulTask implements StreamTask, InitableTask { - private KeyValueStore store; - - public void init(Config config, TaskContext context) { - this.store = (KeyValueStore) context.getStore("my-store"); - } - - public void process(IncomingMessageEnvelope envelope, - MessageCollector collector, - TaskCoordinator coordinator) { - store.put((String) envelope.getKey(), (String) envelope.getMessage()); - } -} -{% endhighlight %} - -Here is the complete key-value store API: - -{% highlight java %} -public interface KeyValueStore { - V get(K key); - void put(K key, V value); - void putAll(List> entries); - void delete(K key); - KeyValueIterator range(K from, K to); - KeyValueIterator all(); -} -{% endhighlight %} - -Additional configuration properties for the key-value store are documented in the [configuration reference](../jobs/configuration-table.html#keyvalue). - -### Implementing common use cases with the key-value store - -Earlier in this section we discussed some example use cases for stateful stream processing. Let's look at how each of these could be implemented using a key-value storage engine such as Samza's LevelDB. - -#### Windowed aggregation - -*Example: Counting the number of page views for each user per hour* - -Implementation: You need two processing stages. - -1. The first one re-partitions the input data by user ID, so that all the events for a particular user are routed to the same stream task. If the input stream is already partitioned by user ID, you can skip this. -2. The second stage does the counting, using a key-value store that maps a user ID to the running count. For each new event, the job reads the current count for the appropriate user from the store, increments it, and writes it back. When the window is complete (e.g. at the end of an hour), the job iterates over the contents of the store and emits the aggregates to an output stream. - -Note that this job effectively pauses at the hour mark to output its results. This is totally fine for Samza, as scanning over the contents of the key-value store is quite fast. The input stream is buffered while the job is doing this hourly work. - -#### Table-table join - -*Example: Join a table of user profiles to a table of user settings by user\_id and emit the joined stream* - -Implementation: The job subscribes to the change streams for the user profiles database and the user settings database, both partitioned by user\_id. The job keeps a key-value store keyed by user\_id, which contains the latest profile record and the latest settings record for each user\_id. When a new event comes in from either stream, the job looks up the current value in its store, updates the appropriate fields (depending on whether it was a profile update or a settings update), and writes back the new joined record to the store. The changelog of the store doubles as the output stream of the task. - -#### Table-stream join - -*Example: Augment a stream of page view events with the user's ZIP code (perhaps to allow aggregation by zip code in a later stage)* - -Implementation: The job subscribes to the stream of user profile updates and the stream of page view events. Both streams must be partitioned by user\_id. The job maintains a key-value store where the key is the user\_id and the value is the user's ZIP code. Every time the job receives a profile update, it extracts the user's new ZIP code from the profile update and writes it to the store. Every time it receives a page view event, it reads the zip code for that user from the store, and emits the page view event with an added ZIP code field. - -If the next stage needs to aggregate by ZIP code, the ZIP code can be used as the partitioning key of the job's output stream. That ensures that all the events for the same ZIP code are sent to the same stream partition. - -#### Stream-stream join - -*Example: Join a stream of ad clicks to a stream of ad impressions (to link the information on when the ad was shown to the information on when it was clicked)* - -In this example we assume that each impression of an ad has a unique identifier, e.g. a UUID, and that the same identifier is included in both the impression and the click events. This identifier is used as the join key. - -Implementation: Partition the ad click and ad impression streams by the impression ID or user ID (assuming that two events with the same impression ID always have the same user ID). The task keeps two stores, one containing click events and one containing impression events, using the impression ID as key for both stores. When the job receives a click event, it looks for the corresponding impression in the impression store, and vice versa. If a match is found, the joined pair is emitted and the entry is deleted. If no match is found, the event is written to the appropriate store. Periodically the job scans over both stores and deletes any old events that were not matched within the time window of the join. - -### Other storage engines - -Samza's fault-tolerance mechanism (sending a local store's writes to a replicated changelog) is completely decoupled from the storage engine's data structures and query APIs. While a key-value storage engine is good for general-purpose processing, you can easily add your own storage engines for other types of queries by implementing the [StorageEngine](../api/javadocs/org/apache/samza/storage/StorageEngine.html) interface. Samza's model is especially amenable to embedded storage engines, which run as a library in the same process as the stream task. - -Some ideas for other storage engines that could be useful: a persistent heap (for running top-N queries), [approximate algorithms](http://infolab.stanford.edu/~ullman/mmds/ch4.pdf) such as [bloom filters](http://en.wikipedia.org/wiki/Bloom_filter) and [hyperloglog](http://research.google.com/pubs/pub40671.html), or full-text indexes such as [Lucene](http://lucene.apache.org). (Patches accepted!) - -### Fault tolerance semantics with state - -As discussed in the section on [checkpointing](checkpointing.html), Samza currently only supports at-least-once delivery guarantees in the presence of failure (this is sometimes referred to as "guaranteed delivery"). This means that if a task fails, no messages are lost, but some messages may be redelivered. - -For many of the stateful processing use cases discussed above, this is not a problem: if the effect of a message on state is idempotent, it is safe for the same message to be processed more than once. For example, if the store contains the ZIP code for each user, then processing the same profile update twice has no effect, because the duplicate update does not change the ZIP code. - -However, for non-idempotent operations such as counting, at-least-once delivery guarantees can give incorrect results. If a Samza task fails and is restarted, it may double-count some messages that were processed shortly before the failure. We are planning to address this limitation in a future release of Samza. - -## [Metrics »](metrics.html) diff --git a/docs/learn/documentation/0.7.0/container/streams.md b/docs/learn/documentation/0.7.0/container/streams.md deleted file mode 100644 index 59e0855..0000000 --- a/docs/learn/documentation/0.7.0/container/streams.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -layout: page -title: Streams ---- - - -The [samza container](samza-container.html) reads and writes messages using the [SystemConsumer](../api/javadocs/org/apache/samza/system/SystemConsumer.html) and [SystemProducer](../api/javadocs/org/apache/samza/system/SystemProducer.html) interfaces. You can integrate any message broker with Samza by implementing these two interfaces. - -{% highlight java %} -public interface SystemConsumer { - void start(); - - void stop(); - - void register( - SystemStreamPartition systemStreamPartition, - String lastReadOffset); - - List poll( - Map systemStreamPartitions, - long timeout) - throws InterruptedException; -} - -public class IncomingMessageEnvelope { - public Object getMessage() { ... } - - public Object getKey() { ... } - - public SystemStreamPartition getSystemStreamPartition() { ... } -} - -public interface SystemProducer { - void start(); - - void stop(); - - void register(String source); - - void send(String source, OutgoingMessageEnvelope envelope); - - void flush(String source); -} - -public class OutgoingMessageEnvelope { - ... - public Object getKey() { ... } - - public Object getMessage() { ... } -} -{% endhighlight %} - -Out of the box, Samza supports Kafka (KafkaSystemConsumer and KafkaSystemProducer). However, any message bus system can be plugged in, as long as it can provide the semantics required by Samza, as described in the [javadoc](../api/javadocs/org/apache/samza/system/SystemConsumer.html). - -SystemConsumers and SystemProducers may read and write messages of any data type. It's ok if they only support byte arrays — Samza has a separate [serialization layer](serialization.html) which converts to and from objects that application code can use. Samza does not prescribe any particular data model or serialization format. - -The job configuration file can include properties that are specific to a particular consumer and producer implementation. For example, the configuration would typically indicate the hostname and port of the message broker to use, and perhaps connection options. - -### How streams are processed - -If a job is consuming messages from more than one input stream, and all input streams have messages available, messages are processed in a round robin fashion by default. For example, if a job is consuming AdImpressionEvent and AdClickEvent, the task instance's process() method is called with a message from AdImpressionEvent, then a message from AdClickEvent, then another message from AdImpressionEvent, ... and continues to alternate between the two. - -If one of the input streams has no new messages available (the most recent message has already been consumed), that stream is skipped, and the job continues to consume from the other inputs. It continues to check for new messages becoming available. - -#### MessageChooser - -When a Samza container has several incoming messages on different stream partitions, how does it decide which to process first? The behavior is determined by a [MessageChooser](../api/javadocs/org/apache/samza/system/chooser/MessageChooser.html). The default chooser is RoundRobinChooser, but you can override it by implementing a custom chooser. - -To plug in your own message chooser, you need to implement the [MessageChooserFactory](../api/javadocs/org/apache/samza/system/chooser/MessageChooserFactory.html) interface, and set the "task.chooser.class" configuration to the fully-qualified class name of your implementation: - -{% highlight jproperties %} -task.chooser.class=com.example.samza.YourMessageChooserFactory -{% endhighlight %} - -#### Prioritizing input streams - -There are certain times when messages from one stream should be processed with higher priority than messages from another stream. For example, some Samza jobs consume two streams: one stream is fed by a real-time system and the other stream is fed by a batch system. In this case, it's useful to prioritize the real-time stream over the batch stream, so that the real-time processing doesn't slow down if there is a sudden burst of data on the batch stream. - -Samza provides a mechanism to prioritize one stream over another by setting this configuration parameter: systems.<system>.streams.<stream>.samza.priority=<number>. For example: - -{% highlight jproperties %} -systems.kafka.streams.my-real-time-stream.samza.priority=2 -systems.kafka.streams.my-batch-stream.samza.priority=1 -{% endhighlight %} - -This declares that my-real-time-stream's messages should be processed with higher priority than my-batch-stream's messages. If my-real-time-stream has any messages available, they are processed first. Only if there are no messages currently waiting on my-real-time-stream, the Samza job continues processing my-batch-stream. - -Each priority level gets its own MessageChooser. It is valid to define two streams with the same priority. If messages are available from two streams at the same priority level, it's up to the MessageChooser for that priority level to decide which message should be processed first. - -It's also valid to only define priorities for some streams. All non-prioritized streams are treated as the lowest priority, and share a MessageChooser. - -#### Bootstrapping - -Sometimes, a Samza job needs to fully consume a stream (from offset 0 up to the most recent message) before it processes messages from any other stream. This is useful in situations where the stream contains some prerequisite data that the job needs, and it doesn't make sense to process messages from other streams until the job has loaded that prerequisite data. Samza supports this use case with *bootstrap streams*. - -A bootstrap stream seems similar to a stream with a high priority, but is subtly different. Before allowing any other stream to be processed, a bootstrap stream waits for the consumer to explicitly confirm that the stream has been fully consumed. Until then, the bootstrap stream is the exclusive input to the job: even if a network issue or some other factor causes the bootstrap stream consumer to slow down, other inputs can't sneak their messages in. - -Another difference between a bootstrap stream and a high-priority stream is that the bootstrap stream's special treatment is temporary: when it has been fully consumed (we say it has "caught up"), its priority drops to be the same as all the other input streams. - -To configure a stream called "my-bootstrap-stream" to be a fully-consumed bootstrap stream, use the following settings: - -{% highlight jproperties %} -systems.kafka.streams.my-bootstrap-stream.samza.bootstrap=true -systems.kafka.streams.my-bootstrap-stream.samza.reset.offset=true -systems.kafka.streams.my-bootstrap-stream.samza.offset.default=oldest -{% endhighlight %} - -The bootstrap=true parameter enables the bootstrap behavior (prioritization over other streams). The combination of reset.offset=true and offset.default=oldest tells Samza to always start reading the stream from the oldest offset, every time a container starts up (rather than starting to read from the most recent checkpoint). - -It is valid to define multiple bootstrap streams. In this case, the order in which they are bootstrapped is determined by the priority. - -#### Batching - -In some cases, you can improve performance by consuming several messages from the same stream partition in sequence. Samza supports this mode of operation, called *batching*. - -For example, if you want to read 100 messages in a row from each stream partition (regardless of the MessageChooser), you can use this configuration parameter: - -{% highlight jproperties %} -task.consumer.batch.size=100 -{% endhighlight %} - -With this setting, Samza tries to read a message from the most recently used [SystemStreamPartition](../api/javadocs/org/apache/samza/system/SystemStreamPartition.html). This behavior continues either until no more messages are available for that SystemStreamPartition, or until the batch size has been reached. When that happens, Samza defers to the MessageChooser to determine the next message to process. It then again tries to continue consume from the chosen message's SystemStreamPartition until the batch size is reached. - -## [Serialization »](serialization.html) diff --git a/docs/learn/documentation/0.7.0/container/windowing.md b/docs/learn/documentation/0.7.0/container/windowing.md deleted file mode 100644 index b10e5d4..0000000 --- a/docs/learn/documentation/0.7.0/container/windowing.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -layout: page -title: Windowing ---- - - -Sometimes a stream processing job needs to do something in regular time intervals, regardless of how many incoming messages the job is processing. For example, say you want to report the number of page views per minute. To do this, you increment a counter every time you see a page view event. Once per minute, you send the current counter value to an output stream and reset the counter to zero. - -Samza's *windowing* feature provides a way for tasks to do something in regular time intervals, for example once per minute. To enable windowing, you just need to set one property in your job configuration: - -{% highlight jproperties %} -# Call the window() method every 60 seconds -task.window.ms=60000 -{% endhighlight %} - -Next, your stream task needs to implement the [WindowableTask](../api/javadocs/org/apache/samza/task/WindowableTask.html) interface. This interface defines a window() method which is called by Samza in the regular interval that you configured. - -For example, this is how you would implement a basic per-minute event counter: - -{% highlight java %} -public class EventCounterTask implements StreamTask, WindowableTask { - - public static final SystemStream OUTPUT_STREAM = - new SystemStream("kafka", "events-per-minute"); - - private int eventsSeen = 0; - - public void process(IncomingMessageEnvelope envelope, - MessageCollector collector, - TaskCoordinator coordinator) { - eventsSeen++; - } - - public void window(MessageCollector collector, - TaskCoordinator coordinator) { - collector.send(new OutgoingMessageEnvelope(OUTPUT_STREAM, eventsSeen)); - eventsSeen = 0; - } -} -{% endhighlight %} - -If you need to send messages to output streams, you can use the [MessageCollector](../api/javadocs/org/apache/samza/task/MessageCollector.html) object passed to the window() method. Please only use that MessageCollector object for sending messages, and don't use it outside of the call to window(). - -Note that Samza uses [single-threaded execution](event-loop.html), so the window() call can never happen concurrently with a process() call. This has the advantage that you don't need to worry about thread safety in your code (no need to synchronize anything), but the downside that the window() call may be delayed if your process() method takes a long time to return. - -## [Event Loop »](event-loop.html) diff --git a/docs/learn/documentation/0.7.0/index.html b/docs/learn/documentation/0.7.0/index.html deleted file mode 100644 index 626631b..0000000 --- a/docs/learn/documentation/0.7.0/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -layout: page -title: Documentation ---- - - -

Introduction

- - - -

Comparisons

- - - -

API

- - - -

Container

- - - -

Jobs

- - - -

YARN

- - - -

Operations

- -
diff --git a/docs/learn/documentation/0.7.0/introduction/architecture.md b/docs/learn/documentation/0.7.0/introduction/architecture.md deleted file mode 100644 index 46987e5..0000000 --- a/docs/learn/documentation/0.7.0/introduction/architecture.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -layout: page -title: Architecture ---- - - -Samza is made up of three layers: - -1. A streaming layer. -2. An execution layer. -3. A processing layer. - -Samza provides out of the box support for all three layers. - -1. **Streaming:** [Kafka](http://kafka.apache.org/) -2. **Execution:** [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html) -3. **Processing:** [Samza API](../api/overview.html) - -These three pieces fit together to form Samza: - -![diagram-medium](/img/0.7.0/learn/documentation/introduction/samza-ecosystem.png) - -This architecture follows a similar pattern to Hadoop (which also uses YARN as execution layer, HDFS for storage, and MapReduce as processing API): - -![diagram-medium](/img/0.7.0/learn/documentation/introduction/samza-hadoop.png) - -Before going in-depth on each of these three layers, it should be noted that Samza's support is not limited to Kafka and YARN. Both Samza's execution and streaming layer are pluggable, and allow developers to implement alternatives if they prefer. - -### Kafka - -[Kafka](http://kafka.apache.org/) is a distributed pub/sub and message queueing system that provides at-least once messaging guarantees (i.e. the system guarantees that no messages are lost, but in certain fault scenarios, a consumer might receive the same message more than once), and highly available partitions (i.e. a stream's partitions continue to be available even if a machine goes down). - -In Kafka, each stream is called a *topic*. Each topic is partitioned and replicated across multiple machines called *brokers*. When a *producer* sends a message to a topic, it provides a key, which is used to determine which partition the message should be sent to. The Kafka brokers receive and store the messages that the producer sends. Kafka *consumers* can then read from a topic by subscribing to messages on all partitions of a topic. - -Kafka has some interesting properties: - -* All messages with the same key are guaranteed to be in the same topic partition. This means that if you wish to read all messages for a specific user ID, you only have to read the messages from the partition that contains the user ID, not the whole topic (assuming the user ID is used as key). -* A topic partition is a sequence of messages in order of arrival, so you can reference any message in the partition using a monotonically increasing *offset* (like an index into an array). This means that the broker doesn't need to keep track of which messages have been seen by a particular consumer — the consumer can keep track itself by storing the offset of the last message it has processed. It then knows that every message with a lower offset than the current offset has already been processed; every message with a higher offset has not yet been processed. - -For more details on Kafka, see Kafka's [documentation](http://kafka.apache.org/documentation.html) pages. - -### YARN - -[YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html) (Yet Another Resource Negotiator) is Hadoop's next-generation cluster scheduler. It allows you to allocate a number of *containers* (processes) in a cluster of machines, and execute arbitrary commands on them. - -When an application interacts with YARN, it looks something like this: - -1. **Application**: I want to run command X on two machines with 512MB memory. -2. **YARN**: Cool, where's your code? -3. **Application**: http://path.to.host/jobs/download/my.tgz -4. **YARN**: I'm running your job on node-1.grid and node-2.grid. - -Samza uses YARN to manage deployment, fault tolerance, logging, resource isolation, security, and locality. A brief overview of YARN is below; see [this page from Hortonworks](http://hortonworks.com/blog/apache-hadoop-yarn-background-and-an-overview/) for a much better overview. - -#### YARN Architecture - -YARN has three important pieces: a *ResourceManager*, a *NodeManager*, and an *ApplicationMaster*. In a YARN grid, every machine runs a NodeManager, which is responsible for launching processes on that machine. A ResourceManager talks to all of the NodeManagers to tell them what to run. Applications, in turn, talk to the ResourceManager when they wish to run something on the cluster. The third piece, the ApplicationMaster, is actually application-specific code that runs in the YARN cluster. It's responsible for managing the application's workload, asking for containers (usually UNIX processes), and handling notifications when one of its containers fails. - -#### Samza and YARN - -Samza provides a YARN ApplicationMaster and a YARN job runner out of the box. The integration between Samza and YARN is outlined in the following diagram (different colors indicate different host machines): - -![diagram-small](/img/0.7.0/learn/documentation/introduction/samza-yarn-integration.png) - -The Samza client talks to the YARN RM when it wants to start a new Samza job. The YARN RM talks to a YARN NM to allocate space on the cluster for Samza's ApplicationMaster. Once the NM allocates space, it starts the Samza AM. After the Samza AM starts, it asks the YARN RM for one or more YARN containers to run [SamzaContainers](../container/samza-container.html). Again, the RM works with NMs to allocate space for the containers. Once the space has been allocated, the NMs start the Samza containers. - -### Samza - -Samza uses YARN and Kafka to provide a framework for stage-wise stream processing and partitioning. Everything, put together, looks like this (different colors indicate different host machines): - -![diagram-small](/img/0.7.0/learn/documentation/introduction/samza-yarn-kafka-integration.png) - -The Samza client uses YARN to run a Samza job: YARN starts and supervises one or more [SamzaContainers](../container/samza-container.html), and your processing code (using the [StreamTask](../api/overview.html) API) runs inside those containers. The input and output for the Samza StreamTasks come from Kafka brokers that are (usually) co-located on the same machines as the YARN NMs. - -### Example - -Let's take a look at a real example: suppose we want to count the number of page views. In SQL, you would write something like: - -{% highlight sql %} -SELECT user_id, COUNT(*) FROM PageViewEvent GROUP BY user_id -{% endhighlight %} - -Although Samza doesn't support SQL right now, the idea is the same. Two jobs are required to calculate this query: one to group messages by user ID, and the other to do the counting. - -In the first job, the grouping is done by sending all messages with the same user ID to the same partition of an intermediate topic. You can do this by using the user ID as key of the messages that are emitted by the first job, and this key is mapped to one of the intermediate topic's partitions (usually by taking a hash of the key mod the number of partitions). The second job consumes the intermediate topic. Each task in the second job consumes one partition of the intermediate topic, i.e. all the messages for a subset of user IDs. The task has a counter for each user ID in its partition, and the appropriate counter is incremented every time the task receives a message with a particular user ID. - -Repartitioning for a GROUP BY - -If you are familiar with Hadoop, you may recognize this as a Map/Reduce operation, where each record is associated with a particular key in the mappers, records with the same key are grouped together by the framework, and then counted in the reduce step. The difference between Hadoop and Samza is that Hadoop operates on a fixed input, whereas Samza works with unbounded streams of data. - -Kafka takes the messages emitted by the first job and buffers them on disk, distributed across multiple machines. This helps make the system fault-tolerant: if one machine fails, no messages are lost, because they have been replicated to other machines. And if the second job goes slow or stops consuming messages for any reason, the first job is unaffected: the disk buffer can absorb the backlog of messages from the first job until the second job catches up again. - -By partitioning topics, and by breaking a stream process down into jobs and parallel tasks that run on multiple machines, Samza scales to streams with very high message throughput. By using YARN and Kafka, Samza achieves fault-tolerance: if a process or machine fails, it is automatically restarted on another machine and continues processing messages from the point where it left off. - -## [Comparison Introduction »](../comparisons/introduction.html) diff --git a/docs/learn/documentation/0.7.0/introduction/background.md b/docs/learn/documentation/0.7.0/introduction/background.md deleted file mode 100644 index e09497b..0000000 --- a/docs/learn/documentation/0.7.0/introduction/background.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -layout: page -title: Background ---- - - -This page provides some background about stream processing, describes what Samza is, and why it was built. - -### What is messaging? - -Messaging systems are a popular way of implementing near-realtime asynchronous computation. Messages can be added to a message queue (ActiveMQ, RabbitMQ), pub-sub system (Kestrel, Kafka), or log aggregation system (Flume, Scribe) when something happens. Downstream *consumers* read messages from these systems, and process them or take actions based on the message contents. - -Suppose you have a website, and every time someone loads a page, you send a "user viewed page" event to a messaging system. You might then have consumers which do any of the following: - -* Store the message in Hadoop for future analysis -* Count page views and update a dashboard -* Trigger an alert if a page view fails -* Send an email notification to another user -* Join the page view event with the user's profile, and send the message back to the messaging system - -A messaging system lets you decouple all of this work from the actual web page serving. - -### What is stream processing? - -A messaging system is a fairly low-level piece of infrastructure—it stores messages and waits for consumers to consume them. When you start writing code that produces or consumes messages, you quickly find that there are a lot of tricky problems that have to be solved in the processing layer. Samza aims to help with these problems. - -Consider the counting example, above (count page views and update a dashboard). What happens when the machine that your consumer is running on fails, and your current counter values are lost? How do you recover? Where should the processor be run when it restarts? What if the underlying messaging system sends you the same message twice, or loses a message? (Unless you are careful, your counts will be incorrect.) What if you want to count page views grouped by the page URL? How do you distribute the computation across multiple machines if it's too much for a single machine to handle? - -Stream processing is a higher level of abstraction on top of messaging systems, and it's meant to address precisely this category of problems. - -### Samza - -Samza is a stream processing framework with the following features: - -* **Simple API:** Unlike most low-level messaging system APIs, Samza provides a very simple callback-based "process message" API comparable to MapReduce. -* **Managed state:** Samza manages snapshotting and restoration of a stream processor's state. When the processor is restarted, Samza restores its state to a consistent snapshot. Samza is built to handle large amounts of state (many gigabytes per partition). -* **Fault tolerance:** Whenever a machine in the cluster fails, Samza works with YARN to transparently migrate your tasks to another machine. -* **Durability:** Samza uses Kafka to guarantee that messages are processed in the order they were written to a partition, and that no messages are ever lost. -* **Scalability:** Samza is partitioned and distributed at every level. Kafka provides ordered, partitioned, replayable, fault-tolerant streams. YARN provides a distributed environment for Samza containers to run in. -* **Pluggable:** Though Samza works out of the box with Kafka and YARN, Samza provides a pluggable API that lets you run Samza with other messaging systems and execution environments. -* **Processor isolation:** Samza works with Apache YARN, which supports Hadoop's security model, and resource isolation through Linux CGroups. - -### Alternatives - -The available open source stream processing systems are actually quite young, and no single system offers a complete solution. New problems in this area include: how a stream processor's state should be managed, whether or not a stream should be buffered remotely on disk, what to do when duplicate messages are received or messages are lost, and how to model underlying messaging systems. - -Samza's main differentiators are: - -* Samza supports fault-tolerant local state. State can be thought of as tables that are split up and co-located with the processing tasks. State is itself modeled as a stream. If the local state is lost due to machine failure, the state stream is replayed to restore it. -* Streams are ordered, partitioned, replayable, and fault tolerant. -* YARN is used for processor isolation, security, and fault tolerance. -* Jobs are decoupled: if one job goes slow and builds up a backlog of unprocessed messages, the rest of the system is not affected. - -For a more in-depth discussion on Samza, and how it relates to other stream processing systems, have a look at Samza's [Comparisons](../comparisons/introduction.html) documentation. - -## [Concepts »](concepts.html) diff --git a/docs/learn/documentation/0.7.0/introduction/concepts.md b/docs/learn/documentation/0.7.0/introduction/concepts.md deleted file mode 100644 index dacc6af..0000000 --- a/docs/learn/documentation/0.7.0/introduction/concepts.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -layout: page -title: Concepts ---- - - -This page gives an introduction to the high-level concepts in Samza. - -### Streams - -Samza processes *streams*. A stream is composed of immutable *messages* of a similar type or category. For example, a stream could be all the clicks on a website, or all the updates to a particular database table, or all the logs produced by a service, or any other type of event data. Messages can be appended to a stream or read from a stream. A stream can have any number of *consumers*, and reading from a stream doesn't delete the message (so each message is effectively broadcast to all consumers). Messages can optionally have an associated key which is used for partitioning, which we'll talk about in a second. - -Samza supports pluggable *systems* that implement the stream abstraction: in [Kafka](https://kafka.apache.org/) a stream is a topic, in a database we might read a stream by consuming updates from a table, in Hadoop we might tail a directory of files in HDFS. - -![job](/img/0.7.0/learn/documentation/introduction/job.png) - -### Jobs - -A Samza *job* is code that performs a logical transformation on a set of input streams to append output messages to set of output streams. - -If scalability were not a concern, streams and jobs would be all we need. However, in order to scale the throughput of the stream processor, we chop streams and jobs up into smaller units of parallelism: *partitions* and *tasks*. - -### Partitions - -Each stream is broken into one or more partitions. Each partition in the stream is a totally ordered sequence of messages. - -Each message in this sequence has an identifier called the *offset*, which is unique per partition. The offset can be a sequential integer, byte offset, or string depending on the underlying system implementation. - -When a message is appended to a stream, it is appended to only one of the stream's partitions. The assignment of the message to its partition is done with a key chosen by the writer. For example, if the user ID is used as the key, that ensures that all messages related to a particular user end up in the same partition. - -![stream](/img/0.7.0/learn/documentation/introduction/stream.png) - -### Tasks - -A job is scaled by breaking it into multiple *tasks*. The *task* is the unit of parallelism of the job, just as the partition is to the stream. Each task consumes data from one partition for each of the job's input streams. - -A task processes messages from each of its input partitions sequentially, in the order of message offset. There is no defined ordering across partitions. This allows each task to operate independently. The YARN scheduler assigns each task to a machine, so the job as a whole can be distributed across many machines. - -The number of tasks in a job is determined by the number of input partitions (there cannot be more tasks than input partitions, or there would be some tasks with no input). However, you can change the computational resources assigned to the job (the amount of memory, number of CPU cores, etc.) to satisfy the job's needs. See notes on *containers* below. - -The assignment of partitions to tasks never changes: if a task is on a machine that fails, the task is restarted elsewhere, still consuming the same stream partitions. - -![job-detail](/img/0.7.0/learn/documentation/introduction/job_detail.png) - -### Dataflow Graphs - -We can compose multiple jobs to create a dataflow graph, where the nodes are streams containing data, and the edges are jobs performing transformations. This composition is done purely through the streams the jobs take as input and output. The jobs are otherwise totally decoupled: they need not be implemented in the same code base, and adding, removing, or restarting a downstream job will not impact an upstream job. - -These graphs are often acyclic—that is, data usually doesn't flow from a job, through other jobs, back to itself. However, it is possible to create cyclic graphs if you need to. - -Directed acyclic job graph - -### Containers - -Partitions and tasks are both *logical* units of parallelism—they don't correspond to any particular assignment of computational resources (CPU, memory, disk space, etc). Containers are the unit of physical parallelism, and a container is essentially a Unix process (or Linux [cgroup](http://en.wikipedia.org/wiki/Cgroups)). Each container runs one or more tasks. The number of tasks is determined automatically from the number of partitions in the input and is fixed, but the number of containers (and the CPU and memory resources associated with them) is specified by the user at run time and can be changed at any time. - -## [Architecture »](architecture.html) diff --git a/docs/learn/documentation/0.7.0/jobs/configuration-table.html b/docs/learn/documentation/0.7.0/jobs/configuration-table.html deleted file mode 100644 index ea6b1ef..0000000 --- a/docs/learn/documentation/0.7.0/jobs/configuration-table.html +++ /dev/null @@ -1,1157 +0,0 @@ - - - - - - Samza Configuration Reference - - - - -

Samza Configuration Reference

-

The following table lists all the standard properties that can be included in a Samza job configuration file.

-

Words highlighted like this are placeholders for your own variable names.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameDefaultDescription
Samza job configuration
job.factory.class - Required: The job factory to use for running this job. - The value is a fully-qualified Java classname, which must implement - StreamJobFactory. - Samza ships with two implementations: -
-
org.apache.samza.job.local.ThreadJobFactory
-
Runs your job on your local machine using threads. This is intended only for - development, not for production deployments.
-
org.apache.samza.job.local.ProcessJobFactory
-
Runs your job on your local machine as a subprocess. An optional command builder - property can also be specified (see - task.command.class for details). This is intended only for development, - not for production deployments.
-
org.apache.samza.job.yarn.YarnJobFactory
-
Runs your job on a YARN grid. See below for YARN-specific configuration.
-
-
job.name - Required: The name of your job. This name appears on the Samza dashboard, and it - is used to tell apart this job's checkpoints from other jobs' checkpoints. -
job.id1 - If you run several instances of your job at the same time, you need to give each execution a - different job.id. This is important, since otherwise the jobs will overwrite each - others' checkpoints, and perhaps interfere with each other in other ways. -
job.config.rewriter.
rewriter-name.class
- You can optionally define configuration rewriters, which have the opportunity to dynamically - modify the job configuration before the job is started. For example, this can be useful for - pulling configuration from an external configuration management system, or for determining - the set of input streams dynamically at runtime. The value of this property is a - fully-qualified Java classname which must implement - ConfigRewriter. - Samza ships with one rewriter by default: -
-
org.apache.samza.config.RegExTopicGenerator
-
When consuming from Kafka, this allows you to consume all Kafka topics that match - some regular expression (rather than having to list each topic explicitly). - This rewriter has additional configuration.
-
-
job.config.rewriters - If you have defined configuration rewriters, you need to list them here, in the order in - which they should be applied. The value of this property is a comma-separated list of - rewriter-name tokens. -
Task configuration
task.class - Required: The fully-qualified name of the Java class which processes - incoming messages from input streams. The class must implement - StreamTask, and may optionally implement - InitableTask, - ClosableTask and/or - WindowableTask. - The class will be instantiated several times, once for every - input stream partition. -
task.inputs - Required: A comma-separated list of streams that are consumed by this job. - Each stream is given in the format - system-name.stream-name. - For example, if you have one input system called my-kafka, and want to consume two - Kafka topics called PageViewEvent and UserActivityEvent, then you would set - task.inputs=my-kafka.PageViewEvent, my-kafka.UserActivityEvent. -
task.window.ms-1 - If task.class implements - WindowableTask, it can - receive a windowing callback in regular intervals. - This property specifies the time between window() calls, in milliseconds. If the number is - negative (the default), window() is never called. Note that Samza is - single-threaded, so a window() call will never - occur concurrently with the processing of a message. If a message is being processed at the - time when a window() call is due, the window() call occurs after the processing of the current - message has completed. -
task.checkpoint.factory - To enable checkpointing, you must set - this property to the fully-qualified name of a Java class that implements - CheckpointManagerFactory. - This is not required, but recommended for most jobs. If you don't configure checkpointing, - and a job or container restarts, it does not remember which messages it has already processed. - Without checkpointing, consumer behavior is determined by the - ...samza.offset.default - setting, which by default skips any messages that were published while the container was - restarting. Checkpointing allows a job to start up where it previously left off. - Samza ships with two checkpoint managers by default: -
-
org.apache.samza.checkpoint.file.FileSystemCheckpointManagerFactory
-
Writes checkpoints to files on the local filesystem. You can configure the file path - with the task.checkpoint.path - property. This is a simple option if your job always runs on the same machine. - On a multi-machine cluster, this would require a network filesystem mount.
-
org.apache.samza.checkpoint.kafka.KafkaCheckpointManagerFactory
-
Writes checkpoints to a dedicated topic on a Kafka cluster. This is the recommended - option if you are already using Kafka for input or output streams. Use the - task.checkpoint.system - property to configure which Kafka cluster to use for checkpoints.
-
-
task.commit.ms60000 - If task.checkpoint.factory is - configured, this property determines how often a checkpoint is written. The value is - the time between checkpoints, in milliseconds. The frequency of checkpointing affects - failure recovery: if a container fails unexpectedly (e.g. due to crash or machine failure) - and is restarted, it resumes processing at the last checkpoint. Any messages processed - since the last checkpoint on the failed container are processed again. Checkpointing - more frequently reduces the number of messages that may be processed twice, but also - uses more resources. -
task.command.classorg.apache.samza.job.
ShellCommandBuilder
- The fully-qualified name of the Java class which determines the command line and environment - variables for a container. It must be a subclass of - CommandBuilder. - This defaults to task.command.class=org.apache.samza.job.ShellCommandBuilder. -
task.opts - Any JVM options to include in the command line when executing Samza containers. For example, - this can be used to set the JVM heap size, to tune the garbage collector, or to enable - remote debugging. Note - there are some issues with the current implementation of task.opts: -
    -
  • If you set this property, the log configuration is disrupted. Please see - SAMZA-109 for a workaround.
  • -
  • This cannot be used when running with ThreadJobFactory
  • -
-
task.executebin/run-container.sh - The command that starts a Samza container. The script must be included in the - job package. There is usually no need to customize this. -
task.chooser.classorg.apache.samza.
system.chooser.
RoundRobinChooserFactory
- This property can be optionally set to override the default - message chooser, which determines the - order in which messages from multiple input streams are processed. The value of this - property is the fully-qualified name of a Java class that implements - MessageChooserFactory. -
task.lifecycle.listener.
listener-name.class
- Use this property to register a - lifecycle listener, which can receive - a notification when a container starts up or shuts down, or when a message is processed. - The value is the fully-qualified name of a Java class that implements - TaskLifecycleListenerFactory. - You can define multiple lifecycle listeners, each with a different listener-name, - and reference them in task.lifecycle.listeners. -
task.lifecycle.listeners - If you have defined lifecycle listeners with - task.lifecycle.listener.*.class, - you need to list them here in order to enable them. The value of this property is a - comma-separated list of listener-name tokens. -
task.drop.deserialization.errors - This property is to define how the system deals with deserialization failure situation. If set to true, the system will - skip the error messages and keep running. If set to false, the system with throw exceptions and fail the container. Default - is false. -
task.drop.serialization.errors - This property is to define how the system deals with serialization failure situation. If set to true, the system will - drop the error messages and keep running. If set to false, the system with throw exceptions and fail the container. Default - is false. -
task.poll.interval.ms - Samza's container polls for more messages under two conditions. The first condition arises when there are simply no remaining - buffered messages to process for any input SystemStreamPartition. The second condition arises when some input - SystemStreamPartitions have empty buffers, but some do not. In the latter case, a polling interval is defined to determine how - often to refresh the empty SystemStreamPartition buffers. By default, this interval is 50ms, which means that any empty - SystemStreamPartition buffer will be refreshed at least every 50ms. A higher value here means that empty SystemStreamPartitions - will be refreshed less often, which means more latency is introduced, but less CPU and network will be used. Decreasing this - value means that empty SystemStreamPartitions are refreshed more frequently, thereby introducing less latency, but increasing - CPU and network utilization. -
Systems (input and output streams)
systems.system-name.
samza.factory
- Required: The fully-qualified name of a Java class which provides a - system. A system can provide input streams which you can consume in your Samza job, - or output streams to which you can write, or both. The requirements on a system are very - flexible — it may connect to a message broker, or read and write files, or use a database, - or anything else. The class must implement - SystemFactory. - Samza ships with the following implementations: -
-
org.apache.samza.system.kafka.KafkaSystemFactory
-
Connects to a cluster of Kafka brokers, allows - Kafka topics to be consumed as streams in Samza, allows messages to be published to - Kafka topics, and allows Kafka to be used for checkpointing (see - task.checkpoint.factory). - See also configuration of a Kafka system.
-
org.apache.samza.system.filereader.FileReaderSystemFactory
-
Reads data from a file on the local filesystem (the stream name is the path of the - file to read). The file is read as ASCII, and treated as a stream of messages separated - by newline (\n) characters. A task can consume each line of the file as - a java.lang.String object. This system does not provide output streams.
-
-
systems.system-name.
samza.key.serde
- The serde which will be used to deserialize the - key of messages on input streams, and to serialize the key of messages on - output streams. This property can be defined either for an individual stream, or for all - streams within a system (if both are defined, the stream-level definition takes precedence). - The value of this property must be a serde-name that is registered - with serializers.registry.*.class. - If this property is not set, messages are passed unmodified between the input stream consumer, - the task and the output stream producer. -
systems.system-name.
streams.stream-name.
samza.key.serde
systems.system-name.
samza.msg.serde
- The serde which will be used to deserialize the - value of messages on input streams, and to serialize the value of messages on - output streams. This property can be defined either for an individual stream, or for all - streams within a system (if both are defined, the stream-level definition takes precedence). - The value of this property must be a serde-name that is registered - with serializers.registry.*.class. - If this property is not set, messages are passed unmodified between the input stream consumer, - the task and the output stream producer. -
systems.system-name.
streams.stream-name.
samza.msg.serde
systems.system-name.
samza.offset.default
upcoming - If a container starts up without a checkpoint, - this property determines where in the input stream we should start consuming. The value must be an - OffsetType, - one of the following: -
-
upcoming
-
Start processing messages that are published after the job starts. Any messages published while - the job was not running are not processed.
-
oldest
-
Start processing at the oldest available message in the system, and - reprocess the entire available message history.
-
- This property can be defined either for an individual stream, or for all streams within a system - (if both are defined, the stream-level definition takes precedence). -
systems.system-name.
streams.stream-name.
samza.offset.default
systems.system-name.
streams.stream-name.
samza.reset.offset
false - If set to true, when a Samza container starts up, it ignores any - checkpointed offset for this particular input - stream. Its behavior is thus determined by the samza.offset.default setting. - Note that the reset takes effect every time a container is started, which may be - every time you restart your job, or more frequently if a container fails and is restarted - by the framework. -
systems.system-name.
streams.stream-name.
samza.priority
-1 - If one or more streams have a priority set (any positive integer), they will be processed - with higher priority than the other streams. - You can set several streams to the same priority, or define multiple priority levels by - assigning a higher number to the higher-priority streams. If a higher-priority stream has - any messages available, they will always be processed first; messages from lower-priority - streams are only processed when there are no new messages on higher-priority inputs. -
systems.system-name.
streams.stream-name.
samza.bootstrap
false - If set to true, this stream will be processed as a - bootstrap stream. This means that every time - a Samza container starts up, this stream will be fully consumed before messages from any - other stream are processed. -
task.consumer.batch.size1 - If set to a positive integer, the task will try to consume - batches with the given number of messages - from each input stream, rather than consuming round-robin from all the input streams on - each individual message. Setting this property can improve performance in some cases. -
Serializers/Deserializers (Serdes)
serializers.registry.
serde-name.class
- Use this property to register a serializer/deserializer, - which defines a way of encoding application objects as an array of bytes (used for messages - in streams, and for data in persistent storage). You can give a serde any - serde-name you want, and reference that name in properties like - systems.*.samza.key.serde, - systems.*.samza.msg.serde, - stores.*.key.serde and - stores.*.msg.serde. - The value of this property is the fully-qualified name of a Java class that implements - SerdeFactory. - Samza ships with several serdes: -
-
org.apache.samza.serializers.ByteSerdeFactory
-
A no-op serde which passes through the undecoded byte array.
-
org.apache.samza.serializers.IntegerSerdeFactory
-
Encodes java.lang.Integer objects as binary (4 bytes fixed-length big-endian encoding).
-
org.apache.samza.serializers.StringSerdeFactory
-
Encodes java.lang.String objects as UTF-8.
-
org.apache.samza.serializers.JsonSerdeFactory
-
Encodes nested structures of java.util.Map, java.util.List etc. as JSON.
-
org.apache.samza.serializers.MetricsSnapshotSerdeFactory
-
Encodes org.apache.samza.metrics.reporter.MetricsSnapshot objects (which are - used for reporting metrics) as JSON.
-
org.apache.samza.serializers.KafkaSerdeFactory
-
Adapter which allows existing kafka.serializer.Encoder and - kafka.serializer.Decoder implementations to be used as Samza serdes. - Set serializers.registry.serde-name.encoder and - serializers.registry.serde-name.decoder to the appropriate - class names.
-
-
- Using the filesystem for checkpoints
- - (This section applies if you have set - task.checkpoint.factory - = org.apache.samza.checkpoint.file.FileSystemCheckpointManagerFactory) - -
task.checkpoint.path - Required if you are using the filesystem for checkpoints. Set this to the path on your local filesystem - where checkpoint files should be stored. -
- Using Kafka for input streams, output streams and checkpoints
- - (This section applies if you have set - systems.*.samza.factory - = org.apache.samza.system.kafka.KafkaSystemFactory) - -
systems.system-name.
consumer.zookeeper.connect
- The hostname and port of one or more Zookeeper nodes where information about the - Kafka cluster can be found. This is given as a comma-separated list of - hostname:port pairs, such as - zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181. - If the cluster information is at some sub-path of the Zookeeper namespace, you need to - include the path at the end of the list of hostnames, for example: - zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181/clusters/my-kafka -
systems.system-name.
consumer.auto.offset.reset
largest - This setting determines what happens if a consumer attempts to read an offset that is - outside of the current valid range. This could happen if the topic does not exist, or - if a checkpoint is older than the maximum message history retained by the brokers. - This property is not to be confused with - systems.*.samza.offset.default, - which determines what happens if there is no checkpoint. The following are valid - values for auto.offset.reset: -
-
smallest
-
Start consuming at the smallest (oldest) offset available on the broker - (process as much message history as available).
-
largest
-
Start consuming at the largest (newest) offset available on the broker - (skip any messages published while the job was not running).
-
anything else
-
Throw an exception and refuse to start up the job.
-
-
systems.system-name.
consumer.*
- Any Kafka consumer configuration - can be included here. For example, to change the socket timeout, you can set - systems.system-name.consumer.socket.timeout.ms. - (There is no need to configure group.id or client.id, - as they are automatically configured by Samza. Also, there is no need to set - auto.commit.enable because Samza has its own checkpointing mechanism.) -
systems.system-name.
producer.metadata.broker.list
- A list of network endpoints where the Kafka brokers are running. This is given as - a comma-separated list of hostname:port pairs, for example - kafka1.example.com:9092,kafka2.example.com:9092,kafka3.example.com:9092. - It's not necessary to list every single Kafka node in the cluster: Samza uses this - property in order to discover which topics and partitions are hosted on which broker. - This property is needed even if you are only consuming from Kafka, and not writing - to it, because Samza uses it to discover metadata about streams being consumed. -
systems.system-name.
producer.producer.type
sync - Controls whether messages emitted from a stream processor should be buffered before - they are sent to Kafka. The options are: -
-
sync
-
Any messages sent to output streams are synchronously flushed to the Kafka brokers - before the next message from an input stream is processed.
-
async
-
Messages sent to output streams are buffered within the Samza container, and published - to the Kafka brokers as a batch. This setting can increase throughput, but - risks buffered messages being lost if a container abruptly fails. The maximum - number of messages to buffer is controlled with - systems.system-name.producer.batch.num.messages - and the maximum time (in milliseconds) to wait before flushing the buffer is set with - systems.system-name.producer.queue.buffering.max.ms.
-
-
systems.system-name.
producer.*
- Any Kafka producer configuration - can be included here. For example, to change the request timeout, you can set - systems.system-name.producer.request.timeout.ms. - (There is no need to configure client.id as it is automatically - configured by Samza.) -
systems.system-name.
samza.fetch.threshold
50000 - When consuming streams from Kafka, a Samza container maintains an in-memory buffer - for incoming messages in order to increase throughput (the stream task can continue - processing buffered messages while new messages are fetched from Kafka). This - parameter determines the number of messages we aim to buffer across all stream - partitions consumed by a container. For example, if a container consumes 50 partitions, - it will try to buffer 1000 messages per partition by default. When the number of - buffered messages falls below that threshold, Samza fetches more messages from the - Kafka broker to replenish the buffer. Increasing this parameter can increase a job's - processing throughput, but also increases the amount of memory used. -
task.checkpoint.system - This property is required if you are using Kafka for checkpoints - (task.checkpoint.factory - = org.apache.samza.checkpoint.kafka.KafkaCheckpointManagerFactory). - You must set it to the system-name of a Kafka system. The stream - name (topic name) within that system is automatically determined from the job name and ID: - __samza_checkpoint_${job.name}_${job.id} - (with underscores in the job name and ID replaced by hyphens). -
task.checkpoint.
replication.factor
3 - If you are using Kafka for checkpoints, this is the number of Kafka nodes to which you want the - checkpoint topic replicated for durability. -
- Consuming all Kafka topics matching a regular expression
- - (This section applies if you have set - job.config.rewriter.*.class - = org.apache.samza.config.RegExTopicGenerator) - -
job.config.rewriter.
rewriter-name.system
- Set this property to the system-name of the Kafka system - from which you want to consume all matching topics. -
job.config.rewriter.
rewriter-name.regex
- A regular expression specifying which topics you want to consume within the Kafka system - job.config.rewriter.*.system. - Any topics matched by this regular expression will be consumed in addition to any - topics you specify with task.inputs. -
job.config.rewriter.
rewriter-name.config.*
- Any properties specified within this namespace are applied to the configuration of streams - that match the regex in - job.config.rewriter.*.regex. - For example, you can set job.config.rewriter.*.config.samza.msg.serde to configure - the deserializer for messages in the matching streams, which is equivalent to setting - systems.*.streams.*.samza.msg.serde - for each topic that matches the regex. -
Storage and State Management
stores.store-name.factory - This property defines a store, Samza's mechanism for efficient - stateful stream processing. You can give a - store any store-name, and use that name to get a reference to the - store in your stream task (call - TaskContext.getStore() - in your task's - init() - method). The value of this property is the fully-qualified name of a Java class that implements - StorageEngineFactory. - Samza currently ships with one storage engine implementation: -
-
org.apache.samza.storage.kv.KeyValueStorageEngineFactory
-
An on-disk storage engine with a key-value interface, implemented using - LevelDB. It supports fast random-access - reads and writes, as well as range queries on keys. LevelDB can be configured with - various additional tuning parameters.
-
-
stores.store-name.key.serde - If the storage engine expects keys in the store to be simple byte arrays, this - serde allows the stream task to access the - store using another object type as key. The value of this property must be a - serde-name that is registered with - serializers.registry.*.class. - If this property is not set, keys are passed unmodified to the storage engine - (and the changelog stream, if appropriate). -
stores.store-name.msg.serde - If the storage engine expects values in the store to be simple byte arrays, this - serde allows the stream task to access the - store using another object type as value. The value of this property must be a - serde-name that is registered with - serializers.registry.*.class. - If this property is not set, values are passed unmodified to the storage engine - (and the changelog stream, if appropriate). -
stores.store-name.changelog - Samza stores are local to a container. If the container fails, the contents of the - store are lost. To prevent loss of data, you need to set this property to configure - a changelog stream: Samza then ensures that writes to the store are replicated to - this stream, and the store is restored from this stream after a failure. The value - of this property is given in the form - system-name.stream-name. - Any output stream can be used as changelog, but you must ensure that only one job - ever writes to a given changelog stream (each instance of a job and each store - needs its own changelog stream). -
- Using LevelDB for key-value storage
- - (This section applies if you have set - stores.*.factory - = org.apache.samza.storage.kv.KeyValueStorageEngineFactory) - -
stores.store-name.
write.batch.size
500 - For better write performance, the storage engine buffers writes and applies them - to the underlying store in a batch. If the same key is written multiple times - in quick succession, this buffer also deduplicates writes to the same key. This - property is set to the number of key/value pairs that should be kept in this - in-memory buffer, per task instance. The number cannot be greater than - stores.*.object.cache.size. -
stores.store-name.
object.cache.size
1000 - Samza maintains an additional cache in front of LevelDB for frequently-accessed - objects. This cache contains deserialized objects (avoiding the deserialization - overhead on cache hits), in contrast to the LevelDB block cache - (stores.*.container.cache.size.bytes), - which caches serialized objects. This property determines the number of objects - to keep in Samza's cache, per task instance. This same cache is also used for - write buffering (see stores.*.write.batch.size). - A value of 0 disables all caching and batching. -
stores.store-name.container.
cache.size.bytes
104857600 - The size of LevelDB's block cache in bytes, per container. If there are several - task instances within one container, each is given a proportional share of this cache. - Note that this is an off-heap memory allocation, so the container's total memory use - is the maximum JVM heap size plus the size of this cache. -
stores.store-name.container.
write.buffer.size.bytes
33554432 - The amount of memory (in bytes) that LevelDB uses for buffering writes before they are - written to disk, per container. If there are several task instances within one - container, each is given a proportional share of this buffer. This setting also - determines the size of LevelDB's segment files. -
stores.store-name.
compaction.delete.threshold
-1 - Setting this property forces a LevelDB compaction to be performed after a certain - number of keys have been deleted from the store. This is used to work around - performance issues - in certain workloads. -
stores.store-name.
leveldb.compression
snappy - This property controls whether LevelDB should compress data on disk and in the - block cache. The following values are valid: -
-
snappy
-
Compress data using the Snappy codec.
-
none
-
Do not compress data.
-
-
stores.store-name.
leveldb.block.size.bytes
4096 - If compression is enabled, LevelDB groups approximately this many uncompressed bytes - into one compressed block. You probably don't need to change this property. -
- Running your job on a YARN cluster
- - (This section applies if you have set - job.factory.class - = org.apache.samza.job.yarn.YarnJobFactory) - -
yarn.package.path - Required for YARN jobs: The URL from which the job package can - be downloaded, for example a http:// or hdfs:// URL. - The job package is a .tar.gz file with a - specific directory structure. -
yarn.container.count1 - The number of YARN containers to request for running your job. This is the main parameter - for controlling the scale (allocated computing resources) of your job: to increase the - parallelism of processing, you need to increase the number of containers. The minimum is one - container, and the maximum number of containers is the number of task instances (usually the - number of input stream partitions). - Task instances are evenly distributed across the number of containers that you specify. -
yarn.container.memory.mb1024 - How much memory, in megabytes, to request from YARN per container of your job. Along with - yarn.container.cpu.cores, this - property determines how many containers YARN will run on one machine. If the container - exceeds this limit, YARN will kill it, so it is important that the container's actual - memory use remains below the limit. The amount of memory used is normally the JVM heap - size (configured with task.opts), plus the - size of any off-heap memory allocation (for example - stores.*.container.cache.size.bytes), - plus a safety margin to allow for JVM overheads. -
yarn.container.cpu.cores1 - The number of CPU cores to request from YARN per container of your job. Each node in the - YARN cluster has a certain number of CPU cores available, so this number (along with - yarn.container.memory.mb) - determines how many containers can be run on one machine. Samza is - single-threaded and designed to run on one - CPU core, so you shouldn't normally need to change this property. -
yarn.container.
retry.count
8 - If a container fails, it is automatically restarted by YARN. However, if a container keeps - failing shortly after startup, that indicates a deeper problem, so we should kill the job - rather than retrying indefinitely. This property determines the maximum number of times we are - willing to restart a failed container in quick succession (the time period is configured with - yarn.container.retry.window.ms). - Each container in the job is counted separately. If this property is set to 0, any failed - container immediately causes the whole job to fail. If it is set to a negative number, there - is no limit on the number of retries. -
yarn.container.
retry.window.ms
300000 - This property determines how frequently a container is allowed to fail before we give up and - fail the job. If the same container has failed more than - yarn.container.retry.count - times, and the time between failures was less than this property - yarn.container.retry.window.ms (in milliseconds), then we fail the job. - There is no limit to the number of times we will restart a container if the time between - failures is greater than yarn.container.retry.window.ms. -
yarn.am.container.
memory.mb
1024 - Each Samza job has one special container, the - ApplicationMaster (AM), which manages the - execution of the job. This property determines how much memory, in megabytes, to request - from YARN for running the ApplicationMaster. -
yarn.am.opts - Any JVM options to include in the command line when executing the Samza - ApplicationMaster. For example, this can be - used to set the JVM heap size, to tune the garbage collector, or to enable remote debugging. -
yarn.am.poll.interval.ms1000 - THe Samza ApplicationMaster sends regular heartbeats to the YARN ResourceManager - to confirm that it is alive. This property determines the time (in milliseconds) - between heartbeats. -
yarn.am.jmx.enabledtrue - Determines whether a JMX server should be started on this job's YARN ApplicationMaster - (true or false). -
Metrics
metrics.reporter.
reporter-name.class
- Samza automatically tracks various metrics which are useful for monitoring the health - of a job, and you can also track your own metrics. - With this property, you can define any number of metrics reporters which send - the metrics to a system of your choice (for graphing, alerting etc). You give each reporter - an arbitrary reporter-name. To enable the reporter, you need - to reference the reporter-name in - metrics.reporters. - The value of this property is the fully-qualified name of a Java class that implements - MetricsReporterFactory. - Samza ships with these implementations by default: -
-
org.apache.samza.metrics.reporter.JmxReporterFactory
-
With this reporter, every container exposes its own metrics as JMX MBeans. The JMX - server is started on a random port to avoid - collisions between containers running on the same machine.
-
org.apache.samza.metrics.reporter.MetricsSnapshotReporterFactory
-
This reporter sends the latest values of all metrics as messages to an output - stream once per minute. The output stream is configured with - metrics.reporter.*.stream - and it can use any system supported by Samza.
-
-
metrics.reporters - If you have defined any metrics reporters with - metrics.reporter.*.class, you - need to list them here in order to enable them. The value of this property is a - comma-separated list of reporter-name tokens. -
metrics.reporter.
reporter-name.stream
- If you have registered the metrics reporter - metrics.reporter.*.class - = org.apache.samza.metrics.reporter.MetricsSnapshotReporterFactory, - you need to set this property to configure the output stream to which the metrics data - should be sent. The stream is given in the form - system-name.stream-name, - and the system must be defined in the job configuration. It's fine for many different jobs - to publish their metrics to the same metrics stream. Samza defines a simple - JSON encoding for metrics; in order to use this - encoding, you also need to configure a serde for the metrics stream: - -
- - diff --git a/docs/learn/documentation/0.7.0/jobs/configuration.md b/docs/learn/documentation/0.7.0/jobs/configuration.md deleted file mode 100644 index 8bcc433..0000000 --- a/docs/learn/documentation/0.7.0/jobs/configuration.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -layout: page -title: Configuration ---- - - -All Samza jobs have a configuration file that defines the job. A very basic configuration file looks like this: - -{% highlight jproperties %} -# Job -job.factory.class=samza.job.local.ThreadJobFactory -job.name=hello-world - -# Task -task.class=samza.task.example.MyJavaStreamerTask -task.inputs=example-system.example-stream - -# Serializers -serializers.registry.json.class=org.apache.samza.serializers.JsonSerdeFactory -serializers.registry.string.class=org.apache.samza.serializers.StringSerdeFactory - -# Systems -systems.example-system.samza.factory=samza.stream.example.ExampleConsumerFactory -systems.example-system.samza.key.serde=string -systems.example-system.samza.msg.serde=json -{% endhighlight %} - -There are four major sections to a configuration file: - -1. The job section defines things like the name of the job, and whether to use the YarnJobFactory or ProcessJobFactory/ThreadJobFactory. -2. The task section is where you specify the class name for your [StreamTask](../api/overview.html). It's also where you define what the [input streams](../container/streams.html) are for your task. -3. The serializers section defines the classes of the [serdes](../container/serialization.html) used for serialization and deserialization of specific objects that are received and sent along different streams. -4. The system section defines systems that your StreamTask can read from along with the types of serdes used for sending keys and messages from that system. Usually, you'll define a Kafka system, if you're reading from Kafka, although you can also specify your own self-implemented Samza-compatible systems. See the [hello-samza example project](/startup/hello-samza/0.7.0)'s Wikipedia system for a good example of a self-implemented system. - -### Required Configuration - -Configuration keys that absolutely must be defined for a Samza job are: - -* `job.factory.class` -* `job.name` -* `task.class` -* `task.inputs` - -### Configuration Keys - -A complete list of configuration keys can be found on the [Configuration Table](configuration-table.html) page. - -## [Packaging »](packaging.html) diff --git a/docs/learn/documentation/0.7.0/jobs/job-runner.md b/docs/learn/documentation/0.7.0/jobs/job-runner.md deleted file mode 100644 index c2f6b09..0000000 --- a/docs/learn/documentation/0.7.0/jobs/job-runner.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -layout: page -title: JobRunner ---- - - -Samza jobs are started using a script called run-job.sh. - -{% highlight bash %} -samza-example/target/bin/run-job.sh \ - --config-factory=samza.config.factories.PropertiesConfigFactory \ - --config-path=file://$PWD/config/hello-world.properties -{% endhighlight %} - -You provide two parameters to the run-job.sh script. One is the config location, and the other is a factory class that is used to read your configuration file. The run-job.sh script is actually executing a Samza class called JobRunner. The JobRunner uses your ConfigFactory to get a Config object from the config path. - -{% highlight java %} -public interface ConfigFactory { - Config getConfig(URI configUri); -} -{% endhighlight %} - -The Config object is just a wrapper around Map, with some nice helper methods. Out of the box, Samza ships with the PropertiesConfigFactory, but developers can implement any kind of ConfigFactory they wish. - -Once the JobRunner gets your configuration, it gives your configuration to the StreamJobFactory class defined by the "job.factory" property. Samza ships with three job factory implementations: ThreadJobFactory, ProcessJobFactory and YarnJobFactory. The StreamJobFactory's responsibility is to give the JobRunner a job that it can run. - -{% highlight java %} -public interface StreamJob { - StreamJob submit(); - - StreamJob kill(); - - ApplicationStatus waitForFinish(long timeoutMs); - - ApplicationStatus waitForStatus(ApplicationStatus status, long timeoutMs); - - ApplicationStatus getStatus(); -} -{% endhighlight %} - -Once the JobRunner gets a job, it calls submit() on the job. This method is what tells the StreamJob implementation to start the SamzaContainer. In the case of LocalJobRunner, it uses a run-container.sh script to execute the SamzaContainer in a separate process, which will start one SamzaContainer locally on the machine that you ran run-job.sh on. - -This flow differs slightly when you use YARN, but we'll get to that later. - -## [Configuration »](configuration.html) diff --git a/docs/learn/documentation/0.7.0/jobs/logging.md b/docs/learn/documentation/0.7.0/jobs/logging.md deleted file mode 100644 index 5b78d7f..0000000 --- a/docs/learn/documentation/0.7.0/jobs/logging.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -layout: page -title: Logging ---- - - -Samza uses [SLF4J](http://www.slf4j.org/) for all of its logging. By default, Samza only depends on slf4j-api, so you must add an SLF4J runtime dependency to your Samza packages for whichever underlying logging platform you wish to use. - -### Log4j - -The [hello-samza](/startup/hello-samza/0.7.0) project shows how to use [log4j](http://logging.apache.org/log4j/1.2/) with Samza. To turn on log4j logging, you just need to make sure slf4j-log4j12 is in your SamzaContainer's classpath. In Maven, this can be done by adding the following dependency to your Samza package project. - -{% highlight xml %} - - org.slf4j - slf4j-log4j12 - runtime - 1.6.2 - -{% endhighlight %} - -If you're not using Maven, just make sure that slf4j-log4j12 ends up in your Samza package's lib directory. - -#### Log4j configuration - -Samza's [run-class.sh](packaging.html) script will automatically set the following setting if log4j.xml exists in your [Samza package's](packaging.html) lib directory. - -{% highlight bash %} --Dlog4j.configuration=file:$base_dir/lib/log4j.xml -{% endhighlight %} - -The [run-class.sh](packaging.html) script will also set the following Java system properties: - -{% highlight bash %} --Dsamza.log.dir=$SAMZA_LOG_DIR -Dsamza.container.name=$SAMZA_CONTAINER_NAME= -{% endhighlight %} - -These settings are very useful if you're using a file-based appender. For example, you can use a daily rolling appender by configuring log4j.xml like this: - -{% highlight xml %} - - - - - - - -{% endhighlight %} - -Setting up a file-based appender is recommended as a better alternative to using standard out. Standard out log files (see below) don't roll, and can get quite large if used for logging. - -**NOTE:** If you use the `task.opts` configuration property, the log configuration is disrupted. This is a known bug; please see [SAMZA-109](https://issues.apache.org/jira/browse/SAMZA-109) for a workaround. - -### Log Directory - -Samza will look for the `SAMZA_LOG_DIR` environment variable when it executes. If this variable is defined, all logs will be written to this directory. If the environment variable is empty, or not defined, then Samza will use /tmp. This environment variable can also be referenced inside log4j.xml files (see above). - -### Garbage Collection Logging - -Samza's will automatically set the following garbage collection logging setting, and will output it to `$SAMZA_LOG_DIR/gc.log`. - -{% highlight bash %} --XX:+PrintGCDateStamps -Xloggc:$SAMZA_LOG_DIR/gc.log -{% endhighlight %} - -#### Rotation - -In older versions of Java, it is impossible to have GC logs roll over based on time or size without the use of a secondary tool. This means that your GC logs will never be deleted until a Samza job ceases to run. As of [Java 6 Update 34](http://www.oracle.com/technetwork/java/javase/2col/6u34-bugfixes-1733379.html), and [Java 7 Update 2](http://www.oracle.com/technetwork/java/javase/7u2-relnotes-1394228.html), [new GC command line switches](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6941923) have been added to support this functionality. If you are using a version of Java that supports GC log rotation, it's highly recommended that you turn it on. - -### YARN - -When a Samza job executes on a YARN grid, the `$SAMZA_LOG_DIR` environment variable will point to a directory that is secured such that only the user executing the Samza job can read and write to it, if YARN is [securely configured](http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/ClusterSetup.html). - -#### STDOUT - -Samza's [ApplicationMaster](../yarn/application-master.html) pipes all STDOUT and STDERR output to logs/stdout and logs/stderr, respectively. These files are never rotated. - -## [Reprocessing »](reprocessing.html) diff --git a/docs/learn/documentation/0.7.0/jobs/packaging.md b/docs/learn/documentation/0.7.0/jobs/packaging.md deleted file mode 100644 index 9e55f9a..0000000 --- a/docs/learn/documentation/0.7.0/jobs/packaging.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: page -title: Packaging ---- - - -The [JobRunner](job-runner.html) page talks about run-job.sh, and how it's used to start a job either locally (ProcessJobFactory/ThreadJobFactory) or with YARN (YarnJobFactory). In the diagram that shows the execution flow, it also shows a run-container.sh script. This script, along with a run-am.sh script, are what Samza actually calls to execute its code. - -``` -bin/run-am.sh -bin/run-container.sh -``` - -The run-container.sh script is responsible for starting the [SamzaContainer](../container/samza-container.html). The run-am.sh script is responsible for starting Samza's application master for YARN. Thus, the run-am.sh script is only used by the YarnJob, but both YarnJob and ProcessJob use run-container.sh. - -Typically, these two scripts are bundled into a tar.gz file that has a structure like this: - -``` -bin/run-am.sh -bin/run-class.sh -bin/run-job.sh -bin/run-container.sh -lib/*.jar -``` - -To run a Samza job, you un-zip its tar.gz file, and execute the run-job.sh script, as defined in the JobRunner section. There are a number of interesting implications from this packaging scheme. First, you'll notice that there is no configuration in the package. Second, you'll notice that the lib directory contains all JARs that you'll need to run your Samza job. - -The reason that configuration is decoupled from your Samza job packaging is that it allows configuration to be updated without having to re-build the entire Samza package. This makes life easier for everyone when you just need to tweak one parameter, and don't want to have to worry about which branch your package was built from, or whether trunk is in a stable state. It also has the added benefit of forcing configuration to be fully resolved at runtime. This means that that the configuration for a job is resolved at the time run-job.sh is called (using --config-path and --config-provider parameters), and from that point on, the configuration is immutable, and passed where it needs to be by Samza (and YARN, if you're using it). - -The second statement, that your Samza package contains all JARs that it needs to run, means that a Samza package is entirely self contained. This allows Samza jobs to run on independent Samza versions without conflicting with each other. This is in contrast to Hadoop, where JARs are pulled in from the local machine that the job is running on (using environment variables). With Samza, you might run your job on version 0.7.0, and someone else might run their job on version 0.8.0. There is no problem with this. - -## [YARN Jobs »](yarn-jobs.html) diff --git a/docs/learn/documentation/0.7.0/jobs/reprocessing.md b/docs/learn/documentation/0.7.0/jobs/reprocessing.md deleted file mode 100644 index 28d9925..0000000 --- a/docs/learn/documentation/0.7.0/jobs/reprocessing.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -layout: page -title: Reprocessing previously processed data ---- - - -From time to time you may want to deploy a new version of your Samza job that computes results differently. Perhaps you fixed a bug or introduced a new feature. For example, say you have a Samza job that classifies messages as spam or not-spam, using a machine learning model that you train offline. Periodically you want to deploy an updated version of your Samza job which includes the latest classification model. - -When you start up a new version of your job, a question arises: what do you want to do with messages that were previously processed with the old version of your job? The answer depends on the behavior you want: - -1. **No reprocessing:** By default, Samza assumes that messages processed by the old version don't need to be processed again. When the new version starts up, it will resume processing at the point where the old version left off (assuming you have [checkpointing](../container/checkpointing.html) enabled). If this is the behavior you want, there's nothing special you need to do. - -2. **Simple rewind:** Perhaps you want to go back and re-process old messages using the new version of your job. For example, maybe the old version of your classifier marked things as spam too aggressively, so you now want to revisit its previous spam/not-spam decisions using an improved classifier. You can do this by restarting the job at an older point in time in the stream, and running through all the messages since that time. Thus your job starts off reprocessing messages that it has already seen, but it then seamlessly continues with new messages when the reprocessing is done. - - This approach requires an input system such as Kafka, which allows you to jump back in time to a previous point in the stream. We discuss below how this works in practice. - -3. **Parallel rewind:** This approach avoids a downside of the *simple rewind* approach. With simple rewind, any new messages that appear while the job is reprocessing old data are queued up, and are processed when the reprocessing is done. The queueing delay needn't be long, because Samza can stream through historical data very quickly, but some latency-sensitive applications need to process messages faster. - - In the *parallel rewind* approach, you run two jobs in parallel: one job continues to handle live updates with low latency (the *real-time job*), while the other is started at an older point in the stream and reprocesses historical data (the *reprocessing job*). The two jobs consume the same input stream at different points in time, and eventually the reprocessing job catches up with the real-time job. - - There are a few details that you need to think through before deploying parallel rewind, which we discuss below. - -### Jumping Back in Time - -A common aspect of the *simple rewind* and *parallel rewind* approaches is: you have a job which jumps back to an old point in time in the input streams, and consumes all messages since that time. You achieve this by working with Samza's checkpoints. - -Normally, when a Samza job starts up, it reads the latest checkpoint to determine at which offset in the input streams it needs to resume processing. If you need to rewind to an earlier time, you do that in one of two ways: - -1. You can stop the job, manipulate its last checkpoint to point to an older offset, and start the job up again. Samza includes a command-line tool called [CheckpointTool](../container/checkpointing.html#toc_0) which you can use to manipulate checkpoints. -2. You can start a new job with a different *job.name* or *job.id* (e.g. increment *job.id* every time you need to jump back in time). This gives the job a new checkpoint stream, with none of the old checkpoint information. You also need to set [samza.offset.default=oldest](../container/checkpointing.html), so that when the job starts up without checkpoint, it starts consuming at the oldest offset available. - -With either of these approaches you can get Samza to reprocess the entire history of messages in the input system. Input systems such as Kafka can retain a large amount of history — see discussion below. In order to speed up the reprocessing of historical data, you can increase the container count (*yarn.container.count* if you're running Samza on YARN) to boost your job's computational resources. - -If your job maintains any [persistent state](../container/state-management.html), you need to be careful when jumping back in time: resetting a checkpoint does not automatically change persistent state, so you could end up reprocessing old messages while using state from a later point in time. In most cases, a job that jumps back in time should start with an empty state. You can reset the state by deleting the changelog topic, or by changing the name of the changelog topic in your job configuration. - -When you're jumping back in time, you're using Samza somewhat like a batch processing framework (e.g. MapReduce) — with the difference that your job doesn't stop when it has processed all the historical data, but instead continues running, incrementally processing the stream of new messages as they come in. This has the advantage that you don't need to write and maintain separate batch and streaming versions of your job: you can just use the same Samza API for processing both real-time and historical data. - -### Retention of history - -Samza doesn't maintain history itself — that is the responsibility of the input system, such as Kafka. How far back in time you can jump depends on the amount of history that is retained in that system. - -Kafka is designed to keep a fairly large amount of history: it is common for Kafka brokers to keep one or two weeks of message history accessible, even for high volume topics. The retention period is mostly determined by how much disk space you have available. Kafka's performance [remains high](http://engineering.linkedin.com/kafka/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines) even if you have terabytes of history. - -There are two different kinds of history which require different configuration: - -* **Activity events** are things like user tracking events, web server log events and the like. This kind of stream is typically configured with a time-based retention, e.g. a few weeks. Events older than the retention period are deleted (or archived in an offline system such as HDFS). -* **Database changes** are events that show inserts, updates and deletes in a database. In this kind of stream, each event typically has a primary key, and a newer event for a key overwrites any older events for the same key. If the same key is updated many times, you're only really interested in the most recent value. (The [changelog streams](../container/state-management.html) used by Samza's persistent state fall in this category.) - -In a database change stream, when you're reprocessing data, you typically want to reprocess the entire database. You don't want to miss a value just because it was last updated more than a few weeks ago. In other words, you don't want change events to be deleted just because they are older than some threshold. In this case, when you're jumping back in time, you need to rewind to the *beginning of time*, to the first change ever made to the database (known in Kafka as "offset 0"). - -Fortunately this can be done efficiently, using a Kafka feature called [log compaction](http://kafka.apache.org/documentation.html#compaction). - -For example, imagine your database contains counters: every time something happens, you increment the appropriate counters and update the database with the new counter values. Every update is sent to the changelog, and because there are many updates, the changelog stream will take up a lot of space. With log compaction turned on, Kafka deduplicates the stream in the background, keeping only the most recent counter value for each key, and deleting any old values for the same counter. This reduces the size of the stream so much that you can keep the most recent update for every key, even if it was last updated long ago. - -With log compaction enabled, the stream of database changes becomes a full copy of the entire database. By jumping back to offset 0, your Samza job can scan over the entire database and reprocess it. This is a very powerful way of building scalable applications. - -### Details of Parallel Rewind - -If you are taking the *parallel rewind* approach described above, running two jobs in parallel, you need to configure them carefully to avoid problems. In particular, some things to look out for: - -* Make sure that the two jobs don't interfere with each other. They need different *job.name* or *job.id* configuration properties, so that each job gets its own checkpoint stream. If the jobs maintain [persistent state](../container/state-management.html), each job needs its own changelog (two different jobs writing to the same changelog produces undefined results). -* What happens to job output? If the job sends its results to an output stream, or writes to a database, then the easiest solution is for each job to have a separate output stream or database table. If they write to the same output, you need to take care to ensure that newer data isn't overwritten with older data (due to race conditions between the two jobs). -* Do you need to support A/B testing between the old and the new version of your job, e.g. to test whether the new version improves your metrics? Parallel rewind is ideal for this: each job writes to a separate output, and clients or consumers of the output can read from either the old or the new version's output, depending on whether a user is in test group A or B. -* Reclaiming resources: you might want to keep the old version of your job running for a while, even when the new version has finished reprocessing historical data (especially if the old version's output is being used in an A/B test). However, eventually you'll want to shut it down, and delete the checkpoint and changelog streams belonging to the old version. - -Samza gives you a lot of flexibility for reprocessing historical data, and you don't need to program against a separate batch processing API to take advantage of it. If you're mindful of these issues, you can build a data system that is very robust, but still gives you lots of freedom to change your processing logic in future. - -## [Application Master »](../yarn/application-master.html) diff --git a/docs/learn/documentation/0.7.0/jobs/yarn-jobs.md b/docs/learn/documentation/0.7.0/jobs/yarn-jobs.md deleted file mode 100644 index 58ca50d..0000000 --- a/docs/learn/documentation/0.7.0/jobs/yarn-jobs.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: page -title: YARN Jobs ---- - - -When you define `job.factory.class=org.apache.samza.job.yarn.YarnJobFactory` in your job's configuration, Samza will use YARN to execute your job. The YarnJobFactory will use the YARN_HOME environment variable on the machine that run-job.sh is executed on to get the appropriate YARN configuration, which will define where the YARN resource manager is. The YarnJob will work with the resource manager to get your job started on the YARN cluster. - -If you want to use YARN to run your Samza job, you'll also need to define the location of your Samza job's package. For example, you might say: - -{% highlight jproperties %} -yarn.package.path=http://my.http.server/jobs/ingraphs-package-0.0.55.tgz -{% endhighlight %} - -This .tgz file follows the conventions outlined on the [Packaging](packaging.html) page (it has bin/run-am.sh and bin/run-container.sh). YARN NodeManagers will take responsibility for downloading this .tgz file on the appropriate machines, and untar'ing them. From there, YARN will execute run-am.sh or run-container.sh for the Samza Application Master, and SamzaContainer, respectively. - - - -## [Logging »](logging.html) diff --git a/docs/learn/documentation/0.7.0/operations/kafka.md b/docs/learn/documentation/0.7.0/operations/kafka.md deleted file mode 100644 index 29833e4..0000000 --- a/docs/learn/documentation/0.7.0/operations/kafka.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: page -title: Kafka ---- - - - - - - -Kafka has a great [operations wiki](http://kafka.apache.org/08/ops.html), which provides some detail on how to operate Kafka at scale. - -### Auto-Create Topics - -Kafka brokers should be configured to automatically create topics. Without this, it's going to be very cumbersome to run Samze jobs, since jobs will write to arbitrary (and sometimes new) topics. - -{% highlight jproperties %} -auto.create.topics.enable=true -{% endhighlight %} diff --git a/docs/learn/documentation/0.7.0/operations/security.md b/docs/learn/documentation/0.7.0/operations/security.md deleted file mode 100644 index b7ef24e..0000000 --- a/docs/learn/documentation/0.7.0/operations/security.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -layout: page -title: Security ---- - - -Samza provides no security. All security is implemented in the stream system, or in the environment that Samza containers run. - -### Securing Streaming Systems - -Samza does not provide any security at the stream system level. It is up to individual streaming systems to enforce their own security. If a stream system requires usernames and passwords in order to consume from specific streams, these values must be supplied via configuration, and used at the StreamConsumer/StreamConsumerFactory implementation. The same holds true if the streaming system uses SSL certificates or Kerberos. The environment in which Samza runs must provide the appropriate certificate or Kerberos ticket, and the StreamConsumer must be implemented to use these certificates or tickets. - -#### Securing Kafka - -Kafka provides no security for its topics, and therefore Samza doesn't provide any security when using Kafka topics. - -### Securing Samza's Environment - -The most important thing to keep in mind when securing an environment that Samza containers run in is that **Samza containers execute arbitrary user code**. They must considered an adversarial application, and the environment must be locked down accordingly. - -#### Configuration - -Samza reads all configuration at the time a Samza job is started using the run-job.sh script. If configuration contains sensitive information, then care must be taken to provide the JobRunner with the configuration. This means implementing a ConfigFactory that understands the configuration security model, and resolves configuration to Samza's Config object in a secure way. - -During the duration of a Samza job's execution, the configuration is kept in memory. The only time configuration is visible is: - -1. When configuration is resolved using a ConfigFactory. -2. The configuration is printed to STDOUT when run-job.sh is run. -3. The configuration is written to the logs when a Samza container starts. - -If configuration contains sensitive data, then these three points must be secured. - -#### Ports - -The only port that a Samza container opens by default is an un-secured JMX port that is randomly selected at start time. If this is not desired, JMX can be disabled through configuration. See the [Configuration](configuration.html) page for details. - -Users might open ports from inside a Samza container. If this is not desired, then the user that executes the Samza container must have the appropriate permissions revoked, usually using iptables. - -#### Logs - -Samza container logs contain configuration, and might contain arbitrary sensitive data logged by the user. A secure log directory must be provided to the Samza container. - -#### Starting a Samza Job - -If operators do not wish to allow Samza containers to be executed by arbitrary users, then the mechanism that Samza containers are deployed must secured. Usually, this means controlling execution of the run-job.sh script. The recommended pattern is to lock down the machines that Samza containers run on, and execute run-job.sh from either a blessed web service or special machine, and only allow access to the service or machine by specific users. - -#### Shell Scripts - -Please see the [Packaging](packaging.html) section for details on the the shell scripts that Samza uses. Samza containers allow users to execute arbitrary shell commands, so user permissions must be locked down to prevent users from damaging the environment or reading sensitive data. - -#### YARN - - - -Samza provides out-of-the-box YARN integration. Take a look at Samza's YARN Security page for details. - -## [Kafka »](kafka.html) diff --git a/docs/learn/documentation/0.7.0/yarn/application-master.md b/docs/learn/documentation/0.7.0/yarn/application-master.md deleted file mode 100644 index 6b81805..0000000 --- a/docs/learn/documentation/0.7.0/yarn/application-master.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -layout: page -title: Application Master ---- - - -YARN is Hadoop's next-generation cluster manager. It allows developers to deploy and execute arbitrary commands on a grid. If you're unfamiliar with YARN, or the concept of an ApplicationMaster (AM), please read Hadoop's [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html) page. - -### Integration - -Samza's main integration with YARN comes in the form of a Samza ApplicationMaster. This is the chunk of code responsible for managing a Samza job in a YARN grid. It decides what to do when a stream processor fails, which machines a Samza job's [containers](../container/samza-container.html) should run on, and so on. - -When the Samza ApplicationMaster starts up, it does the following: - -1. Receives configuration from YARN via the STREAMING_CONFIG environment variable. -2. Starts a JMX server on a random port. -3. Instantiates a metrics registry and reporters to keep track of relevant metrics. -4. Registers the AM with YARN's RM. -5. Get the total number of partitions for the Samza job using each input stream's PartitionManager (see the [Streams](../container/streams.html) page for details). -6. Read the total number of containers requested from the Samza job's configuration. -7. Assign each partition to a container (called a Task Group in Samza's AM dashboard). -8. Make a [ResourceRequest](http://hadoop.apache.org/docs/current/api/org/apache/hadoop/yarn/api/records/ResourceRequest.html) to YARN for each container. -9. Poll the YARN RM every second to check for allocated and released containers. - -From this point on, the ApplicationMaster just reacts to events from the RM. - -### Fault Tolerance - -Whenever a container is allocated, the AM will work with the YARN NM to start a SamzaContainer (with appropriate partitions assigned to it) in the container. If a container fails with a non-zero return code, the AM will request a new container, and restart the SamzaContainer. If a SamzaContainer fails too many times, too quickly, the ApplicationMaster will fail the whole Samza job with a non-zero return code. See the yarn.container.retry.count and yarn.container.retry.window.ms [configuration](../jobs/configuration.html) parameters for details. - -When the AM receives a reboot signal from YARN, it will throw a SamzaException. This will trigger a clean and successful shutdown of the AM (YARN won't think the AM failed). - -If the AM, itself, fails, YARN will handle restarting the AM. When the AM is restarted, all containers that were running will be killed, and the AM will start from scratch. The same list of operations, shown above, will be executed. The AM will request new containers for its SamzaContainers, and proceed as though it has just started for the first time. YARN has a yarn.resourcemanager.am.max-retries configuration parameter that's defined in [yarn-site.xml](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-common/yarn-default.xml). This configuration defaults to 1, which means that, by default, a single AM failure will cause your Samza job to stop running. - -### Dashboard - -Samza's ApplicationMaster comes with a dashboard to show useful information such as: - -1. Where containers are located. -2. Links to logs. -3. The Samza job's configuration. -4. Container failure count. - -You can find this dashboard by going to your YARN grid's ResourceManager page (usually something like [http://localhost:8088/cluster](http://localhost:8088/cluster)), and clicking on the "ApplicationMaster" link of a running Samza job. - -Screenshot of ApplicationMaster dashboard - -### Security - -The Samza dashboard's HTTP access is currently un-secured, even when using YARN in secure-mode. This means that users with access to a YARN grid could port-scan a Samza ApplicationMaster's HTTP server, and open the dashboard in a browser to view its contents. Sensitive configuration can be viewed by anyone, in this way, and care should be taken. There are plans to secure Samza's ApplicationMaster using [Hadoop's security](http://docs.hortonworks.com/HDPDocuments/HDP1/HDP-1.3.0/bk_installing_manually_book/content/rpm-chap14-2-3-1.html) features ([SPENAGO](http://en.wikipedia.org/wiki/SPNEGO)). - -See Samza's [security](../operations/security.html) page for more details. - -## [Isolation »](isolation.html) diff --git a/docs/learn/documentation/0.7.0/yarn/isolation.md b/docs/learn/documentation/0.7.0/yarn/isolation.md deleted file mode 100644 index 1eb3bf5..0000000 --- a/docs/learn/documentation/0.7.0/yarn/isolation.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: Isolation ---- - - -When running Samza jobs in a shared, distributed environment, the stream processors can have an impact on one another's performance. A stream processor that uses 100% of a machine's CPU will slow down all other stream processors on the machine. - -One of [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html)'s responsibilities is to manage resources so that this doesn't happen. Each of YARN's Node Managers (NM) has a chunk of "resources" dedicated to it. The YARN Resource Manager (RM) will only allow a container to be allocated on a NM if it has enough resources to satisfy the container's needs. - -YARN currently supports resource management for memory and CPU. - -### Memory - -YARN will automatically enforce memory limits for all containers that it executes. All containers must have a max-memory size defined when they're created. If the sum of all memory usage for processes associated with a single YARN container exceeds this maximum, YARN will kill the container. - -Samza supports memory limits using the yarn.container.memory.mb and yarn.am.container.memory.mb configuration parameters. Keep in mind that this is simply the amount of memory YARN will allow a [SamzaContainer](../container/samza-container.html) or [ApplicationMaster](application-master.html) to have. You'll still need to configure your heap settings appropriately using task.opts, when using Java (the default is -Xmx160M). See the [Configuration](../jobs/configuration.html) and [Packaging](../jobs/packaging.html) pages for details. - -### CPU - -YARN has the concept of a virtual core. Each NM is assigned a total number of virtual cores (32, by default). When a container request is made, it must specify how many virtual cores it needs. The YARN RM will only assign the container to a NM that has enough virtual cores to satisfy the request. - -#### CGroups - -Unlike memory, which YARN can enforce itself (by looking at the /proc folder), YARN can't enforce CPU isolation, since this must be done at the Linux kernel level. One of YARN's interesting new features is its support for Linux [CGroups](https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt). CGroups are a way to control process utilization at the kernel level in Linux. - -If YARN is setup to use CGroups, then YARN will guarantee that a container will get at least the amount of CPU that it requires. Currently, YARN will give you more CPU, if it's available. For details on enforcing "at most" CPU usage, see [YARN-810](https://issues.apache.org/jira/browse/YARN-810). - -See [this blog post](http://riccomini.name/posts/hadoop/2013-06-14-yarn-with-cgroups/) for details on setting up YARN with CGroups. - -## [Security »](../operations/security.html) diff --git a/docs/learn/documentation/versioned/api/javadocs/allclasses-frame.html b/docs/learn/documentation/versioned/api/javadocs/allclasses-frame.html new file mode 100644 index 0000000..5cf9145 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/allclasses-frame.html @@ -0,0 +1,79 @@ + + + + + +All Classes (samza-api 0.8.0-SNAPSHOT API) + + + + +

All Classes

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/allclasses-noframe.html b/docs/learn/documentation/versioned/api/javadocs/allclasses-noframe.html new file mode 100644 index 0000000..bee21ff --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/allclasses-noframe.html @@ -0,0 +1,79 @@ + + + + + +All Classes (samza-api 0.8.0-SNAPSHOT API) + + + + +

All Classes

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/constant-values.html b/docs/learn/documentation/versioned/api/javadocs/constant-values.html new file mode 100644 index 0000000..6f53ff9 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/constant-values.html @@ -0,0 +1,142 @@ + + + + + +Constant Field Values (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+ +
+
+ + +

org.apache.*

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/deprecated-list.html b/docs/learn/documentation/versioned/api/javadocs/deprecated-list.html new file mode 100644 index 0000000..4227cfe --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/deprecated-list.html @@ -0,0 +1,113 @@ + + + + + +Deprecated List (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/help-doc.html b/docs/learn/documentation/versioned/api/javadocs/help-doc.html new file mode 100644 index 0000000..ca44e9a --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/help-doc.html @@ -0,0 +1,214 @@ + + + + + +API Help (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Overview

    +

    The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

    +
  • +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/index-all.html b/docs/learn/documentation/versioned/api/javadocs/index-all.html new file mode 100644 index 0000000..ff624f8 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/index-all.html @@ -0,0 +1,1276 @@ + + + + + +Index (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
A B C D E F G H I K L M N O P R S T U V W  + + +

A

+
+
afterClose(Config, TaskContext) - Method in interface org.apache.samza.task.TaskLifecycleListener
+
+
Called after all tasks in TaskRunner are closed.
+
+
afterInit(Config, TaskContext) - Method in interface org.apache.samza.task.TaskLifecycleListener
+
+
Called after all tasks in TaskRunner are initialized.
+
+
afterProcess(IncomingMessageEnvelope, Config, TaskContext) - Method in interface org.apache.samza.task.TaskLifecycleListener
+
+
Called after a message is processed by a task.
+
+
ApplicationStatus - Enum in org.apache.samza.job
+
+
Status of a StreamJob during and after its run.
+
+
+ + + +

B

+
+
BaseMessageChooser - Class in org.apache.samza.system.chooser
+
+
An abstract MessageChooser that implements start/stop/register for choosers + that don't use them.
+
+
BaseMessageChooser() - Constructor for class org.apache.samza.system.chooser.BaseMessageChooser
+
 
+
beforeClose(Config, TaskContext) - Method in interface org.apache.samza.task.TaskLifecycleListener
+
+
Called before all tasks in TaskRunner are closed.
+
+
beforeInit(Config, TaskContext) - Method in interface org.apache.samza.task.TaskLifecycleListener
+
+
Called before all tasks in TaskRunner are initialized.
+
+
beforeProcess(IncomingMessageEnvelope, Config, TaskContext) - Method in interface org.apache.samza.task.TaskLifecycleListener
+
+
Called before a message is processed by a task.
+
+
BLOCK_ON_OUTSTANDING_MESSAGES - Static variable in interface org.apache.samza.system.SystemConsumer
+
+
A constant that can be used in the poll method's timeout parameter to + denote that the poll invocation should block until at least one message is + available for one of the SystemStreamPartitions supplied, or until all + SystemStreamPartitions supplied are at head (have no new messages available + since the last poll invocation was made for each SystemStreamPartition).
+
+
BlockingEnvelopeMap - Class in org.apache.samza.util
+
+
+ BlockingEnvelopeMap is a helper class for SystemConsumer implementations.
+
+
BlockingEnvelopeMap() - Constructor for class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
BlockingEnvelopeMap(Clock) - Constructor for class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
BlockingEnvelopeMap(MetricsRegistry) - Constructor for class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
BlockingEnvelopeMap(MetricsRegistry, Clock) - Constructor for class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
BlockingEnvelopeMap(MetricsRegistry, Clock, String) - Constructor for class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
BlockingEnvelopeMap.BlockingEnvelopeMapMetrics - Class in org.apache.samza.util
+
 
+
BlockingEnvelopeMap.BlockingEnvelopeMapMetrics(String, MetricsRegistry) - Constructor for class org.apache.samza.util.BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
+
 
+
BlockingEnvelopeMap.BufferGauge - Class in org.apache.samza.util
+
 
+
BlockingEnvelopeMap.BufferGauge(SystemStreamPartition, String) - Constructor for class org.apache.samza.util.BlockingEnvelopeMap.BufferGauge
+
 
+
buildCommand() - Method in class org.apache.samza.job.CommandBuilder
+
 
+
buildEnvironment() - Method in class org.apache.samza.job.CommandBuilder
+
 
+
+ + + +

C

+
+
Checkpoint - Class in org.apache.samza.checkpoint
+
+
A checkpoint is a mapping of all the streams a job is consuming and the most recent current offset for each.
+
+
Checkpoint(Map<SystemStreamPartition, String>) - Constructor for class org.apache.samza.checkpoint.Checkpoint
+
+
Constructs a new checkpoint based off a map of Samza stream offsets.
+
+
CheckpointManager - Interface in org.apache.samza.checkpoint
+
+
CheckpointManagers read and write Checkpoint to some + implementation-specific location.
+
+
CheckpointManagerFactory - Interface in org.apache.samza.checkpoint
+
+ +
+
choose() - Method in interface org.apache.samza.system.chooser.MessageChooser
+
+
The choose method is invoked when the SamzaContainer is ready to process a + new message.
+
+
clear() - Method in class org.apache.samza.config.Config
+
 
+
clear() - Method in class org.apache.samza.metrics.Counter
+
 
+
Clock - Interface in org.apache.samza.util
+
+
Mockable interface for tracking time.
+
+
ClosableTask - Interface in org.apache.samza.task
+
+
A ClosableTask augments StreamTask, allowing the method implementer to specify + code that will be called when the StreamTask is being shut down by the framework, providing to emit final metrics, + clean or close resources, etc.
+
+
close() - Method in interface org.apache.samza.task.ClosableTask
+
 
+
CommandBuilder - Class in org.apache.samza.job
+
+
CommandBuilders are used to customize the command necessary to launch a Samza Job for a particular framework, + such as YARN or the LocalJobRunner.
+
+
CommandBuilder() - Constructor for class org.apache.samza.job.CommandBuilder
+
 
+
commit(TaskCoordinator.RequestScope) - Method in interface org.apache.samza.task.TaskCoordinator
+
+
Requests that Samza should write out a checkpoint, from which a task can restart + after failure.
+
+
compareAndSet(T, T) - Method in class org.apache.samza.metrics.Gauge
+
 
+
compareTo(TaskName) - Method in class org.apache.samza.container.TaskName
+
 
+
compareTo(Partition) - Method in class org.apache.samza.Partition
+
 
+
compareTo(SystemStreamPartition) - Method in class org.apache.samza.system.SystemStreamPartition
+
 
+
Config - Class in org.apache.samza.config
+
+
Store and retrieve named, typed values as configuration for classes implementing this interface.
+
+
Config() - Constructor for class org.apache.samza.config.Config
+
 
+
config - Variable in class org.apache.samza.container.SamzaContainerContext
+
 
+
config - Variable in class org.apache.samza.job.CommandBuilder
+
 
+
ConfigException - Exception in org.apache.samza.config
+
+
Specific SamzaExceptions thrown from Config
+
+
ConfigException(Throwable) - Constructor for exception org.apache.samza.config.ConfigException
+
 
+
ConfigException(String) - Constructor for exception org.apache.samza.config.ConfigException
+
 
+
ConfigException(String, Throwable) - Constructor for exception org.apache.samza.config.ConfigException
+
 
+
ConfigFactory - Interface in org.apache.samza.config
+
+
Build a Config
+
+
ConfigRewriter - Interface in org.apache.samza.config
+
+
A ConfigRewriter receives the job's config during job startup and may re-write it to provide new configs, + remove existing configs or audit and verify the config is correct or permitted.
+
+
containsKey(Object) - Method in class org.apache.samza.config.MapConfig
+
 
+
containsValue(Object) - Method in class org.apache.samza.config.MapConfig
+
 
+
Counter - Class in org.apache.samza.metrics
+
+
A counter is a Metric that represents a cumulative value.
+
+
Counter(String) - Constructor for class org.apache.samza.metrics.Counter
+
 
+
counter(Counter) - Method in class org.apache.samza.metrics.MetricsVisitor
+
 
+
currentTimeMillis() - Method in interface org.apache.samza.util.Clock
+
 
+
+ + + +

D

+
+
dec() - Method in class org.apache.samza.metrics.Counter
+
 
+
dec(long) - Method in class org.apache.samza.metrics.Counter
+
 
+
Deserializer<T> - Interface in org.apache.samza.serializers
+
+
A standard interface for Samza compatible deserializers, used for deserializing serialized objects back to their + original form.
+
+
+ + + +

E

+
+
entrySet() - Method in class org.apache.samza.config.MapConfig
+
 
+
equals(Object) - Method in class org.apache.samza.checkpoint.Checkpoint
+
 
+
equals(Object) - Method in class org.apache.samza.config.MapConfig
+
 
+
equals(Object) - Method in class org.apache.samza.container.TaskName
+
 
+
equals(Object) - Method in class org.apache.samza.Partition
+
 
+
equals(Object) - Method in class org.apache.samza.system.IncomingMessageEnvelope
+
 
+
equals(Object) - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
equals(Object) - Method in class org.apache.samza.system.SystemStream
+
 
+
equals(Object) - Method in class org.apache.samza.system.SystemStreamMetadata
+
 
+
equals(Object) - Method in class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
equals(Object) - Method in class org.apache.samza.system.SystemStreamPartition
+
 
+
+ + + +

F

+
+
flush() - Method in interface org.apache.samza.storage.StorageEngine
+
+
Flush any cached messages
+
+
flush(String) - Method in interface org.apache.samza.system.SystemProducer
+
+
If the SystemProducer buffers messages before sending them to its underlying system, it should flush those + messages and leave no messages remaining to be sent.
+
+
fromBytes(byte[]) - Method in interface org.apache.samza.serializers.Deserializer
+
+
Deserializes given serialized object from an array of bytes to its original form.
+
+
+ + + +

G

+
+
Gauge<T> - Class in org.apache.samza.metrics
+
+
A Gauge is a Metric that wraps some instance of T in a thread-safe + reference and allows it to be set or retrieved.
+
+
Gauge(String, T) - Constructor for class org.apache.samza.metrics.Gauge
+
 
+
gauge(Gauge<T>) - Method in class org.apache.samza.metrics.MetricsVisitor
+
 
+
get(String, String) - Method in class org.apache.samza.config.Config
+
 
+
get(Object) - Method in class org.apache.samza.config.MapConfig
+
 
+
getAdmin(String, Config) - Method in interface org.apache.samza.system.SystemFactory
+
 
+
getBoolean(String, boolean) - Method in class org.apache.samza.config.Config
+
 
+
getBoolean(String) - Method in class org.apache.samza.config.Config
+
 
+
getCheckpointManager(Config, MetricsRegistry) - Method in interface org.apache.samza.checkpoint.CheckpointManagerFactory
+
 
+
getChooser(Config, MetricsRegistry) - Method in interface org.apache.samza.system.chooser.MessageChooserFactory
+
 
+
getClass(String) - Method in class org.apache.samza.config.Config
+
 
+
getConfig(URI) - Method in interface org.apache.samza.config.ConfigFactory
+
+
Build a specific Config.
+
+
getConsumer(String, Config, MetricsRegistry) - Method in interface org.apache.samza.system.SystemFactory
+
 
+
getCount() - Method in class org.apache.samza.metrics.Counter
+
 
+
getDate(String) - Method in class org.apache.samza.config.Config
+
 
+
getDate(String, String) - Method in class org.apache.samza.config.Config
+
 
+
getDate(String, SimpleDateFormat) - Method in class org.apache.samza.config.Config
+
 
+
getDate(String, Date) - Method in class org.apache.samza.config.Config
+
 
+
getDate(String, String, Date) - Method in class org.apache.samza.config.Config
+
 
+
getDate(String, SimpleDateFormat, Date) - Method in class org.apache.samza.config.Config
+
 
+
getDouble(String, double) - Method in class org.apache.samza.config.Config
+
 
+
getDouble(String) - Method in class org.apache.samza.config.Config
+
 
+
getGroup(String) - Method in interface org.apache.samza.metrics.ReadableMetricsRegistry
+
 
+
getGroups() - Method in interface org.apache.samza.metrics.ReadableMetricsRegistry
+
 
+
getInt(String, int) - Method in class org.apache.samza.config.Config
+
 
+
getInt(String) - Method in class org.apache.samza.config.Config
+
 
+
getJob(Config) - Method in interface org.apache.samza.job.StreamJobFactory
+
 
+
getKey() - Method in class org.apache.samza.system.IncomingMessageEnvelope
+
 
+
getKey() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
getKeySerializerName() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
getLifecyleListener(String, Config) - Method in interface org.apache.samza.task.TaskLifecycleListenerFactory
+
 
+
getList(String, List<String>) - Method in class org.apache.samza.config.Config
+
 
+
getList(String) - Method in class org.apache.samza.config.Config
+
 
+
getLong(String, long) - Method in class org.apache.samza.config.Config
+
 
+
getLong(String) - Method in class org.apache.samza.config.Config
+
 
+
getMessage() - Method in class org.apache.samza.system.IncomingMessageEnvelope
+
 
+
getMessage() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
getMessageSerializerName() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
getMetricsRegistry() - Method in interface org.apache.samza.task.TaskContext
+
 
+
getMetricsReporter(String, String, Config) - Method in interface org.apache.samza.metrics.MetricsReporterFactory
+
 
+
getName() - Method in class org.apache.samza.metrics.Counter
+
 
+
getName() - Method in class org.apache.samza.metrics.Gauge
+
 
+
getNewestOffset() - Method in class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
getNewInstance(String) - Method in class org.apache.samza.config.Config
+
 
+
getNumMessagesInQueue(SystemStreamPartition) - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
getOffset() - Method in class org.apache.samza.system.IncomingMessageEnvelope
+
 
+
getOffset(SystemStreamMetadata.OffsetType) - Method in class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
getOffsets() - Method in class org.apache.samza.checkpoint.Checkpoint
+
+
Gets a unmodifiable view of the current Samza stream offsets.
+
+
getOffsetsAfter(Map<SystemStreamPartition, String>) - Method in interface org.apache.samza.system.SystemAdmin
+
+
Fetches the offsets for the messages immediately after the supplied offsets + for a group of SystemStreamPartitions.
+
+
getOffsetsAfter(Map<SystemStreamPartition, String>) - Method in class org.apache.samza.util.SinglePartitionWithoutOffsetsSystemAdmin
+
 
+
getOldestOffset() - Method in class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
getPartition() - Method in class org.apache.samza.system.SystemStreamPartition
+
 
+
getPartitionId() - Method in class org.apache.samza.Partition
+
 
+
getPartitionKey() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
getProducer(String, Config, MetricsRegistry) - Method in interface org.apache.samza.system.SystemFactory
+
 
+
getSerde(String, Config) - Method in interface org.apache.samza.serializers.SerdeFactory
+
 
+
getShort(String, short) - Method in class org.apache.samza.config.Config
+
 
+
getShort(String) - Method in class org.apache.samza.config.Config
+
 
+
getStatus() - Method in interface org.apache.samza.job.StreamJob
+
+
Get current ApplicationStatus of the job
+
+
getStorageEngine(String, File, Serde<K>, Serde<V>, MessageCollector, MetricsRegistry, SystemStreamPartition, SamzaContainerContext) - Method in interface org.apache.samza.storage.StorageEngineFactory
+
+
Create an instance of the given storage engine.
+
+
getStore(String) - Method in interface org.apache.samza.task.TaskContext
+
 
+
getStream() - Method in class org.apache.samza.system.SystemStream
+
 
+
getStreamName() - Method in class org.apache.samza.system.SystemStreamMetadata
+
 
+
getSystem() - Method in class org.apache.samza.system.SystemStream
+
 
+
getSystemStream() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
getSystemStream() - Method in class org.apache.samza.system.SystemStreamPartition
+
 
+
getSystemStreamMetadata(Set<String>) - Method in interface org.apache.samza.system.SystemAdmin
+
+
Fetch metadata from a system for a set of streams.
+
+
getSystemStreamMetadata(Set<String>) - Method in class org.apache.samza.util.SinglePartitionWithoutOffsetsSystemAdmin
+
 
+
getSystemStreamPartition() - Method in class org.apache.samza.system.IncomingMessageEnvelope
+
 
+
getSystemStreamPartitionGrouper(Config) - Method in interface org.apache.samza.container.grouper.stream.SystemStreamPartitionGrouperFactory
+
 
+
getSystemStreamPartitionMetadata() - Method in class org.apache.samza.system.SystemStreamMetadata
+
 
+
getSystemStreamPartitions() - Method in interface org.apache.samza.task.TaskContext
+
 
+
getTaskName() - Method in class org.apache.samza.container.TaskName
+
 
+
getTaskName() - Method in interface org.apache.samza.task.TaskContext
+
 
+
getUpcomingOffset() - Method in class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
getValue() - Method in class org.apache.samza.metrics.Gauge
+
 
+
getValue() - Method in class org.apache.samza.util.BlockingEnvelopeMap.BufferGauge
+
 
+
group(Set<SystemStreamPartition>) - Method in interface org.apache.samza.container.grouper.stream.SystemStreamPartitionGrouper
+
 
+
+ + + +

H

+
+
hash - Variable in class org.apache.samza.system.SystemStreamPartition
+
 
+
hashCode() - Method in class org.apache.samza.checkpoint.Checkpoint
+
 
+
hashCode() - Method in class org.apache.samza.config.MapConfig
+
 
+
hashCode() - Method in class org.apache.samza.container.TaskName
+
 
+
hashCode() - Method in class org.apache.samza.Partition
+
 
+
hashCode() - Method in class org.apache.samza.system.IncomingMessageEnvelope
+
 
+
hashCode() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
hashCode() - Method in class org.apache.samza.system.SystemStream
+
 
+
hashCode() - Method in class org.apache.samza.system.SystemStreamMetadata
+
 
+
hashCode() - Method in class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
hashCode() - Method in class org.apache.samza.system.SystemStreamPartition
+
 
+
hasNext() - Method in class org.apache.samza.system.SystemStreamPartitionIterator
+
 
+
+ + + +

I

+
+
inc() - Method in class org.apache.samza.metrics.Counter
+
 
+
inc(long) - Method in class org.apache.samza.metrics.Counter
+
 
+
incBlockingPoll(SystemStreamPartition) - Method in class org.apache.samza.util.BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
+
 
+
incBlockingTimeoutPoll(SystemStreamPartition) - Method in class org.apache.samza.util.BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
+
 
+
IncomingMessageEnvelope - Class in org.apache.samza.system
+
+
This class represents a message envelope that is received by a StreamTask for each message that is received from a + partition of a specific input stream.
+
+
IncomingMessageEnvelope(SystemStreamPartition, String, Object, Object) - Constructor for class org.apache.samza.system.IncomingMessageEnvelope
+
+
Constructs a new IncomingMessageEnvelope from specified components.
+
+
incPoll() - Method in class org.apache.samza.util.BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
+
 
+
init(Config, TaskContext) - Method in interface org.apache.samza.task.InitableTask
+
+
Called by TaskRunner each time an implementing task is created.
+
+
InitableTask - Interface in org.apache.samza.task
+
+
Used as an interface for user processing StreamTasks that need to have specific functionality performed as their StreamTasks + are instantiated by TaskRunner.
+
+
initMetrics(SystemStreamPartition) - Method in class org.apache.samza.util.BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
+
 
+
isAtHead(SystemStreamPartition) - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
isEmpty() - Method in class org.apache.samza.config.MapConfig
+
 
+
+ + + +

K

+
+
keySet() - Method in class org.apache.samza.config.MapConfig
+
 
+
kill() - Method in interface org.apache.samza.job.StreamJob
+
+
Kill this job immediately.
+
+
+ + + +

L

+
+
listen(ReadableMetricsRegistryListener) - Method in interface org.apache.samza.metrics.ReadableMetricsRegistry
+
 
+
+ + + +

M

+
+
MapConfig - Class in org.apache.samza.config
+
+
A Config backed by a Java Map
+
+
MapConfig() - Constructor for class org.apache.samza.config.MapConfig
+
 
+
MapConfig(Map<String, String>) - Constructor for class org.apache.samza.config.MapConfig
+
 
+
MapConfig(List<Map<String, String>>) - Constructor for class org.apache.samza.config.MapConfig
+
 
+
MessageChooser - Interface in org.apache.samza.system.chooser
+
+
MessageChooser is an interface for programmatic fine-grain control over + stream consumption.
+
+
MessageChooserFactory - Interface in org.apache.samza.system.chooser
+
+
Build an instance of a MessageChooser
+
+
MessageCollector - Interface in org.apache.samza.task
+
+
Used as an interface for the means of sending message envelopes to an output stream.
+
+
Metric - Interface in org.apache.samza.metrics
+
+
Metric class that allows metric visitors to visit it to get its information.
+
+
MetricsRegistry - Interface in org.apache.samza.metrics
+
+
A MetricsRegistry allows its users to create new Metrics and + have those metrics wired to specific metrics systems, such as JMX, provided by MetricsReporters.
+
+
MetricsReporter - Interface in org.apache.samza.metrics
+
+
A MetricsReporter is the interface that different metrics sinks, such as JMX, implement to receive + metrics from the Samza framework and Samza jobs.
+
+
MetricsReporterFactory - Interface in org.apache.samza.metrics
+
+ +
+
MetricsVisitor - Class in org.apache.samza.metrics
+
+
A MetricsVisitor can be used to process each metric in a ReadableMetricsRegistry, + encapsulating the logic of what to be done with each metric in the counter and gauge methods.
+
+
MetricsVisitor() - Constructor for class org.apache.samza.metrics.MetricsVisitor
+
 
+
+ + + +

N

+
+
name - Variable in class org.apache.samza.container.SamzaContainerContext
+
 
+
name - Variable in class org.apache.samza.job.CommandBuilder
+
 
+
newBlockingQueue() - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
newCounter(String, String) - Method in interface org.apache.samza.metrics.MetricsRegistry
+
+
Create and register a new Counter
+
+
newCounter(String, Counter) - Method in interface org.apache.samza.metrics.MetricsRegistry
+
+
Register existing Counter with this registry
+
+
newCounter(String, String) - Method in class org.apache.samza.util.NoOpMetricsRegistry
+
 
+
newCounter(String, Counter) - Method in class org.apache.samza.util.NoOpMetricsRegistry
+
 
+
newGauge(String, String, T) - Method in interface org.apache.samza.metrics.MetricsRegistry
+
+
Create and register a new Gauge
+
+
newGauge(String, Gauge<T>) - Method in interface org.apache.samza.metrics.MetricsRegistry
+
+
Register an existing Gauge
+
+
newGauge(String, String, T) - Method in class org.apache.samza.util.NoOpMetricsRegistry
+
 
+
newGauge(String, Gauge<T>) - Method in class org.apache.samza.util.NoOpMetricsRegistry
+
 
+
next() - Method in class org.apache.samza.system.SystemStreamPartitionIterator
+
 
+
NoOpMetricsRegistry - Class in org.apache.samza.util
+
+
MetricsRegistry implementation for when no actual metrics need to be + recorded but a registry is still required.
+
+
NoOpMetricsRegistry() - Constructor for class org.apache.samza.util.NoOpMetricsRegistry
+
 
+
+ + + +

O

+
+
onCounter(String, Counter) - Method in interface org.apache.samza.metrics.ReadableMetricsRegistryListener
+
 
+
onGauge(String, Gauge<?>) - Method in interface org.apache.samza.metrics.ReadableMetricsRegistryListener
+
 
+
org.apache.samza - package org.apache.samza
+
 
+
org.apache.samza.checkpoint - package org.apache.samza.checkpoint
+
 
+
org.apache.samza.config - package org.apache.samza.config
+
 
+
org.apache.samza.container - package org.apache.samza.container
+
 
+
org.apache.samza.container.grouper.stream - package org.apache.samza.container.grouper.stream
+
 
+
org.apache.samza.job - package org.apache.samza.job
+
 
+
org.apache.samza.metrics - package org.apache.samza.metrics
+
 
+
org.apache.samza.serializers - package org.apache.samza.serializers
+
 
+
org.apache.samza.storage - package org.apache.samza.storage
+
 
+
org.apache.samza.system - package org.apache.samza.system
+
 
+
org.apache.samza.system.chooser - package org.apache.samza.system.chooser
+
 
+
org.apache.samza.task - package org.apache.samza.task
+
 
+
org.apache.samza.util - package org.apache.samza.util
+
 
+
OutgoingMessageEnvelope - Class in org.apache.samza.system
+
+
An OutgoingMessageEnvelope is sent to a specified SystemStream via the appropriate SystemProducer + from the user's StreamTask.
+
+
OutgoingMessageEnvelope(SystemStream, String, String, Object, Object, Object) - Constructor for class org.apache.samza.system.OutgoingMessageEnvelope
+
+
Constructs a new OutgoingMessageEnvelope from specified components.
+
+
OutgoingMessageEnvelope(SystemStream, Object, Object, Object) - Constructor for class org.apache.samza.system.OutgoingMessageEnvelope
+
+
Constructs a new OutgoingMessageEnvelope from specified components.
+
+
OutgoingMessageEnvelope(SystemStream, Object, Object) - Constructor for class org.apache.samza.system.OutgoingMessageEnvelope
+
+
Constructs a new OutgoingMessageEnvelope from specified components.
+
+
OutgoingMessageEnvelope(SystemStream, Object) - Constructor for class org.apache.samza.system.OutgoingMessageEnvelope
+
+
Constructs a new OutgoingMessageEnvelope from specified components.
+
+
+ + + +

P

+
+
Partition - Class in org.apache.samza
+
+
A numbered, ordered partition of a stream.
+
+
Partition(int) - Constructor for class org.apache.samza.Partition
+
+
Constructs a new Samza stream partition from a specified partition number.
+
+
partition - Variable in class org.apache.samza.system.SystemStreamPartition
+
 
+
poll(Set<SystemStreamPartition>, long) - Method in interface org.apache.samza.system.SystemConsumer
+
+
Poll the SystemConsumer to get any available messages from the underlying + system.
+
+
poll(Set<SystemStreamPartition>, long) - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
process(IncomingMessageEnvelope, MessageCollector, TaskCoordinator) - Method in interface org.apache.samza.task.StreamTask
+
+
Called once for each message that this StreamTask receives.
+
+
put(String, String) - Method in class org.apache.samza.config.Config
+
 
+
put(SystemStreamPartition, IncomingMessageEnvelope) - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
putAll(Map<? extends String, ? extends String>) - Method in class org.apache.samza.config.Config
+
 
+
putAll(SystemStreamPartition, List<IncomingMessageEnvelope>) - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
+ + + +

R

+
+
ReadableMetricsRegistry - Interface in org.apache.samza.metrics
+
+
A ReadableMetricsRegistry is a MetricsRegistry that also + allows read access to the metrics for which it is responsible.
+
+
ReadableMetricsRegistryListener - Interface in org.apache.samza.metrics
+
 
+
readChangeLogPartitionMapping() - Method in interface org.apache.samza.checkpoint.CheckpointManager
+
+
Read the taskName to partition mapping that is being maintained by this CheckpointManager
+
+
readLastCheckpoint(TaskName) - Method in interface org.apache.samza.checkpoint.CheckpointManager
+
+
Returns the last recorded checkpoint for a specified taskName.
+
+
register(TaskName) - Method in interface org.apache.samza.checkpoint.CheckpointManager
+
+
Registers this manager to write checkpoints of a specific Samza stream partition.
+
+
register(String, ReadableMetricsRegistry) - Method in interface org.apache.samza.metrics.MetricsReporter
+
 
+
register(SystemStreamPartition, String) - Method in class org.apache.samza.system.chooser.BaseMessageChooser
+
 
+
register(SystemStreamPartition, String) - Method in interface org.apache.samza.system.chooser.MessageChooser
+
+
Called before start, to let the chooser know that it will be handling + envelopes from the given SystemStreamPartition.
+
+
register(SystemStreamPartition, String) - Method in interface org.apache.samza.system.SystemConsumer
+
+
Register a SystemStreamPartition to this SystemConsumer.
+
+
register(String) - Method in interface org.apache.samza.system.SystemProducer
+
+
Registers this producer to send messages from a specified Samza source, such as a StreamTask.
+
+
register(SystemStreamPartition, String) - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
remove(Object) - Method in class org.apache.samza.config.Config
+
 
+
remove() - Method in class org.apache.samza.system.SystemStreamPartitionIterator
+
 
+
restore(Iterator<IncomingMessageEnvelope>) - Method in interface org.apache.samza.storage.StorageEngine
+
+
Restore the content of this StorageEngine from the changelog.
+
+
rewrite(String, Config) - Method in interface org.apache.samza.config.ConfigRewriter
+
 
+
+ + + +

S

+
+
SamzaContainerContext - Class in org.apache.samza.container
+
+
A SamzaContainerContext maintains per-container information for the tasks it executes.
+
+
SamzaContainerContext(String, Config, Collection<TaskName>) - Constructor for class org.apache.samza.container.SamzaContainerContext
+
+
An immutable context object that can passed to tasks to give them information + about the container in which they are executing.
+
+
SamzaException - Exception in org.apache.samza
+
+
Unchecked exception that Samza throws when something goes wrong.
+
+
SamzaException() - Constructor for exception org.apache.samza.SamzaException
+
 
+
SamzaException(String, Throwable) - Constructor for exception org.apache.samza.SamzaException
+
 
+
SamzaException(String) - Constructor for exception org.apache.samza.SamzaException
+
 
+
SamzaException(Throwable) - Constructor for exception org.apache.samza.SamzaException
+
 
+
send(String, OutgoingMessageEnvelope) - Method in interface org.apache.samza.system.SystemProducer
+
+
Sends a specified message envelope from a specified Samza source.
+
+
send(OutgoingMessageEnvelope) - Method in interface org.apache.samza.task.MessageCollector
+
+
Sends message envelope out onto specified stream.
+
+
Serde<T> - Interface in org.apache.samza.serializers
+
+
A Serde is a convenience type that implements both the Serializer and + Deserializer interfaces, allowing it to both read and write data + in its value type, T.
+
+
SerdeFactory<T> - Interface in org.apache.samza.serializers
+
+
Build an instance of Serde
+
+
Serializer<T> - Interface in org.apache.samza.serializers
+
+
A standard interface for Samza compatible serializers, used for serializing objects to bytes.
+
+
set(long) - Method in class org.apache.samza.metrics.Counter
+
 
+
set(T) - Method in class org.apache.samza.metrics.Gauge
+
 
+
setConfig(Config) - Method in class org.apache.samza.job.CommandBuilder
+
 
+
setIsAtHead(SystemStreamPartition, boolean) - Method in class org.apache.samza.util.BlockingEnvelopeMap
+
 
+
setName(String) - Method in class org.apache.samza.job.CommandBuilder
+
 
+
setNoMoreMessages(SystemStreamPartition, boolean) - Method in class org.apache.samza.util.BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
+
 
+
setTaskNameToChangeLogPartitionMapping(Map<TaskName, Integer>) - Method in class org.apache.samza.job.CommandBuilder
+
 
+
setTaskNameToSystemStreamPartitionsMapping(Map<TaskName, Set<SystemStreamPartition>>) - Method in class org.apache.samza.job.CommandBuilder
+
 
+
shutdown(TaskCoordinator.RequestScope) - Method in interface org.apache.samza.task.TaskCoordinator
+
+
Requests that the container should be shut down.
+
+
SinglePartitionWithoutOffsetsSystemAdmin - Class in org.apache.samza.util
+
+
A simple helper admin class that defines a single partition (partition 0) for + a given system.
+
+
SinglePartitionWithoutOffsetsSystemAdmin() - Constructor for class org.apache.samza.util.SinglePartitionWithoutOffsetsSystemAdmin
+
 
+
size() - Method in class org.apache.samza.config.MapConfig
+
 
+
start() - Method in interface org.apache.samza.checkpoint.CheckpointManager
+
 
+
start() - Method in interface org.apache.samza.metrics.MetricsReporter
+
 
+
start() - Method in class org.apache.samza.system.chooser.BaseMessageChooser
+
 
+
start() - Method in interface org.apache.samza.system.chooser.MessageChooser
+
+
Called after all SystemStreamPartitions have been registered.
+
+
start() - Method in interface org.apache.samza.system.SystemConsumer
+
+
Tells the SystemConsumer to connect to the underlying system, and prepare + to begin serving messages when poll is invoked.
+
+
start() - Method in interface org.apache.samza.system.SystemProducer
+
+
Start the SystemProducer.
+
+
stop() - Method in interface org.apache.samza.checkpoint.CheckpointManager
+
 
+
stop() - Method in interface org.apache.samza.metrics.MetricsReporter
+
 
+
stop() - Method in interface org.apache.samza.storage.StorageEngine
+
+
Close the storage engine
+
+
stop() - Method in class org.apache.samza.system.chooser.BaseMessageChooser
+
 
+
stop() - Method in interface org.apache.samza.system.chooser.MessageChooser
+
+
Called when the chooser is about to be discarded.
+
+
stop() - Method in interface org.apache.samza.system.SystemConsumer
+
+
Tells the SystemConsumer to close all connections, release all resource, + and shut down everything.
+
+
stop() - Method in interface org.apache.samza.system.SystemProducer
+
+
Stop the SystemProducer.
+
+
StorageEngine - Interface in org.apache.samza.storage
+
+
A storage engine for managing state maintained by a stream processor.
+
+
StorageEngineFactory<K,V> - Interface in org.apache.samza.storage
+
+
An object provided by the storage engine implementation to create instances + of the given storage engine type.
+
+
stream - Variable in class org.apache.samza.system.SystemStream
+
 
+
StreamJob - Interface in org.apache.samza.job
+
+
A StreamJob runs Samza StreamTasks in its specific environment.
+
+
StreamJobFactory - Interface in org.apache.samza.job
+
+
Build a StreamJob
+
+
StreamTask - Interface in org.apache.samza.task
+
+
A StreamTask is the basic class on which Samza jobs are implemented.
+
+
submit() - Method in interface org.apache.samza.job.StreamJob
+
+
Submit this job to be run.
+
+
subset(String) - Method in class org.apache.samza.config.Config
+
 
+
subset(String, boolean) - Method in class org.apache.samza.config.Config
+
 
+
system - Variable in class org.apache.samza.system.SystemStream
+
 
+
SystemAdmin - Interface in org.apache.samza.system
+
+
Helper interface attached to an underlying system to fetch + information about streams, partitions, offsets, etc.
+
+
SystemConsumer - Interface in org.apache.samza.system
+
+
+ SystemConsumer is the interface that must be implemented by any system that + wishes to integrate with Samza.
+
+
SystemFactory - Interface in org.apache.samza.system
+
+
Build the SystemConsumer and SystemProducer for + a particular system, as well as the accompanying SystemAdmin.
+
+
SystemProducer - Interface in org.apache.samza.system
+
+
SystemProducers are how Samza writes messages from StreamTasks to outside systems, + such as messaging systems like Kafka, or file systems.
+
+
SystemStream - Class in org.apache.samza.system
+
+
Streams in Samza consist of both the stream name and the system to which the stream belongs.
+
+
SystemStream(String, String) - Constructor for class org.apache.samza.system.SystemStream
+
+
Constructs a Samza stream object from specified components.
+
+
SystemStream(SystemStream) - Constructor for class org.apache.samza.system.SystemStream
+
+
Constructs a Samza stream object based upon an existing Samza stream.
+
+
SystemStreamMetadata - Class in org.apache.samza.system
+
+
SystemAdmins use this class to return useful metadata about a stream's offset + and partition information.
+
+
SystemStreamMetadata(String, Map<Partition, SystemStreamMetadata.SystemStreamPartitionMetadata>) - Constructor for class org.apache.samza.system.SystemStreamMetadata
+
 
+
SystemStreamMetadata.OffsetType - Enum in org.apache.samza.system
+
+
OffsetType is an enum used to define which offset should be used when + reading from a SystemStreamPartition for the first time.
+
+
SystemStreamMetadata.SystemStreamPartitionMetadata - Class in org.apache.samza.system
+
+
Provides offset information for a given SystemStreamPartition.
+
+
SystemStreamMetadata.SystemStreamPartitionMetadata(String, String, String) - Constructor for class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
SystemStreamPartition - Class in org.apache.samza.system
+
+
Aggregate object representing a both the SystemStream and Partition.
+
+
SystemStreamPartition(String, String, Partition) - Constructor for class org.apache.samza.system.SystemStreamPartition
+
+
Constructs a Samza stream partition object from specified components.
+
+
SystemStreamPartition(SystemStreamPartition) - Constructor for class org.apache.samza.system.SystemStreamPartition
+
+
Constructs a Samza stream partition object based upon an existing Samza stream partition.
+
+
SystemStreamPartition(SystemStream, Partition) - Constructor for class org.apache.samza.system.SystemStreamPartition
+
+
Constructs a Samza stream partition object based upon another Samza stream and a specified partition.
+
+
SystemStreamPartitionGrouper - Interface in org.apache.samza.container.grouper.stream
+
+
Group a set of SystemStreamPartitions into logical taskNames that share a common characteristic, defined + by the implementation.
+
+
SystemStreamPartitionGrouperFactory - Interface in org.apache.samza.container.grouper.stream
+
+
Return an instance a SystemStreamPartitionGrouper per the particular implementation
+
+
SystemStreamPartitionIterator - Class in org.apache.samza.system
+
+
Iterator that wraps a + SystemConsumer to iterate over the messages + the consumer provides for the specified + SystemStreamPartition.
+
+
SystemStreamPartitionIterator(SystemConsumer, SystemStreamPartition) - Constructor for class org.apache.samza.system.SystemStreamPartitionIterator
+
 
+
SystemStreamPartitionIterator(SystemConsumer, SystemStreamPartition, int) - Constructor for class org.apache.samza.system.SystemStreamPartitionIterator
+
 
+
+ + + +

T

+
+
TaskContext - Interface in org.apache.samza.task
+
+
A TaskContext provides resources about the StreamTask, particularly during + initialization in an InitableTask and during calls to TaskLifecycleListeners.
+
+
TaskCoordinator - Interface in org.apache.samza.task
+
+
TaskCoordinators are provided to the process methods of StreamTask implementations + to allow the user code to request actions from the Samza framework, including committing the current checkpoints + to configured CheckpointManagers or shutting down the task or all tasks within + a container.
+
+
TaskCoordinator.RequestScope - Enum in org.apache.samza.task
+
+
A task can make requests to the Samza framework while processing messages, such as + TaskCoordinator.commit(RequestScope) and + TaskCoordinator.shutdown(RequestScope).
+
+
TaskLifecycleListener - Interface in org.apache.samza.task
+
+
Used to get before/after notifications before initializing/closing all tasks + in a given container (JVM/process).
+
+
TaskLifecycleListenerFactory - Interface in org.apache.samza.task
+
+ +
+
TaskName - Class in org.apache.samza.container
+
+
A unique identifier of a set of a SystemStreamPartitions that have been grouped by + a SystemStreamPartitionGrouper.
+
+
TaskName(String) - Constructor for class org.apache.samza.container.TaskName
+
 
+
taskNames - Variable in class org.apache.samza.container.SamzaContainerContext
+
 
+
taskNameToChangeLogPartitionMapping - Variable in class org.apache.samza.job.CommandBuilder
+
 
+
taskNameToSystemStreamPartitionsMapping - Variable in class org.apache.samza.job.CommandBuilder
+
 
+
toBytes(T) - Method in interface org.apache.samza.serializers.Serializer
+
+
Serializes given object to an array of bytes.
+
+
toString() - Method in class org.apache.samza.checkpoint.Checkpoint
+
 
+
toString() - Method in class org.apache.samza.config.MapConfig
+
 
+
toString() - Method in class org.apache.samza.container.TaskName
+
 
+
toString() - Method in enum org.apache.samza.job.ApplicationStatus
+
 
+
toString() - Method in class org.apache.samza.metrics.Counter
+
 
+
toString() - Method in class org.apache.samza.metrics.Gauge
+
 
+
toString() - Method in class org.apache.samza.Partition
+
 
+
toString() - Method in class org.apache.samza.system.IncomingMessageEnvelope
+
 
+
toString() - Method in class org.apache.samza.system.OutgoingMessageEnvelope
+
 
+
toString() - Method in class org.apache.samza.system.SystemStream
+
 
+
toString() - Method in class org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
+
 
+
toString() - Method in class org.apache.samza.system.SystemStreamMetadata
+
 
+
toString() - Method in class org.apache.samza.system.SystemStreamPartition
+
 
+
+ + + +

U

+
+
unlisten(ReadableMetricsRegistryListener) - Method in interface org.apache.samza.metrics.ReadableMetricsRegistry
+
 
+
update(IncomingMessageEnvelope) - Method in interface org.apache.samza.system.chooser.MessageChooser
+
+
Notify the chooser that a new envelope is available for a processing.
+
+
+ + + +

V

+
+
valueOf(String) - Static method in enum org.apache.samza.job.ApplicationStatus
+
+
Returns the enum constant of this type with the specified name.
+
+
valueOf(String) - Static method in enum org.apache.samza.system.SystemStreamMetadata.OffsetType
+
+
Returns the enum constant of this type with the specified name.
+
+
valueOf(String) - Static method in enum org.apache.samza.task.TaskCoordinator.RequestScope
+
+
Returns the enum constant of this type with the specified name.
+
+
values() - Method in class org.apache.samza.config.MapConfig
+
 
+
values() - Static method in enum org.apache.samza.job.ApplicationStatus
+
+
Returns an array containing the constants of this enum type, in +the order they are declared.
+
+
values() - Static method in enum org.apache.samza.system.SystemStreamMetadata.OffsetType
+
+
Returns an array containing the constants of this enum type, in +the order they are declared.
+
+
values() - Static method in enum org.apache.samza.task.TaskCoordinator.RequestScope
+
+
Returns an array containing the constants of this enum type, in +the order they are declared.
+
+
visit(MetricsVisitor) - Method in class org.apache.samza.metrics.Counter
+
 
+
visit(MetricsVisitor) - Method in class org.apache.samza.metrics.Gauge
+
 
+
visit(MetricsVisitor) - Method in interface org.apache.samza.metrics.Metric
+
 
+
visit(Metric) - Method in class org.apache.samza.metrics.MetricsVisitor
+
 
+
+ + + +

W

+
+
waitForFinish(long) - Method in interface org.apache.samza.job.StreamJob
+
+
Block on this job until either it finishes or reaches its timeout value
+
+
waitForStatus(ApplicationStatus, long) - Method in interface org.apache.samza.job.StreamJob
+
+
Block on this job until either it transitions to the specified status or reaches it timeout value
+
+
window(MessageCollector, TaskCoordinator) - Method in interface org.apache.samza.task.WindowableTask
+
+
Called by TaskRunner for each implementing task at the end of every specified window.
+
+
WindowableTask - Interface in org.apache.samza.task
+
+
Add-on interface to StreamTask implementations to add code which will be run on + a specified time interval (via configuration).
+
+
writeChangeLogPartitionMapping(Map<TaskName, Integer>) - Method in interface org.apache.samza.checkpoint.CheckpointManager
+
+
Write the taskName to partition mapping that is being maintained by this CheckpointManager
+
+
writeCheckpoint(TaskName, Checkpoint) - Method in interface org.apache.samza.checkpoint.CheckpointManager
+
+
Writes a checkpoint based on the current state of a Samza stream partition.
+
+
+A B C D E F G H I K L M N O P R S T U V W 
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/index.html b/docs/learn/documentation/versioned/api/javadocs/index.html new file mode 100644 index 0000000..0164466 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/index.html @@ -0,0 +1,74 @@ + + + + + +samza-api 0.8.0-SNAPSHOT API + + + + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="overview-summary.html">Non-frame version</a>.</p> + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/Partition.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/Partition.html new file mode 100644 index 0000000..1c3c02a --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/Partition.html @@ -0,0 +1,332 @@ + + + + + +Partition (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza
+

Class Partition

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.Partition
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.lang.Comparable<Partition>
    +
    +
    +
    +
    public class Partition
    +extends java.lang.Object
    +implements java.lang.Comparable<Partition>
    +
    A numbered, ordered partition of a stream.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      Partition(int partition) +
      Constructs a new Samza stream partition from a specified partition number.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      intcompareTo(Partition that) 
      booleanequals(java.lang.Object obj) 
      intgetPartitionId() 
      inthashCode() 
      java.lang.StringtoString() 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, finalize, getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Partition

        +
        public Partition(int partition)
        +
        Constructs a new Samza stream partition from a specified partition number.
        +
        Parameters:
        partition - An integer identifying the partition in a Samza stream.
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getPartitionId

        +
        public int getPartitionId()
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object obj)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(Partition that)
        +
        +
        Specified by:
        +
        compareTo in interface java.lang.Comparable<Partition>
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/SamzaException.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/SamzaException.html new file mode 100644 index 0000000..7efe8a3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/SamzaException.html @@ -0,0 +1,296 @@ + + + + + +SamzaException (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza
+

Class SamzaException

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • java.lang.Throwable
    • +
    • +
        +
      • java.lang.Exception
      • +
      • +
          +
        • java.lang.RuntimeException
        • +
        • +
            +
          • org.apache.samza.SamzaException
          • +
          +
        • +
        +
      • +
      +
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.io.Serializable
    +
    +
    +
    Direct Known Subclasses:
    +
    ConfigException
    +
    +
    +
    +
    public class SamzaException
    +extends java.lang.RuntimeException
    +
    Unchecked exception that Samza throws when something goes wrong.
    +
    See Also:
    Serialized Form
    +
  • +
+
+
+
    +
  • + + + +
      +
    • + + +

      Method Summary

      +
        +
      • + + +

        Methods inherited from class java.lang.Throwable

        +addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
      • +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        SamzaException

        +
        public SamzaException()
        +
      • +
      + + + +
        +
      • +

        SamzaException

        +
        public SamzaException(java.lang.String s,
        +              java.lang.Throwable t)
        +
      • +
      + + + +
        +
      • +

        SamzaException

        +
        public SamzaException(java.lang.String s)
        +
      • +
      + + + +
        +
      • +

        SamzaException

        +
        public SamzaException(java.lang.Throwable t)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/Checkpoint.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/Checkpoint.html new file mode 100644 index 0000000..6a6b0ba --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/Checkpoint.html @@ -0,0 +1,316 @@ + + + + + +Checkpoint (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.checkpoint
+

Class Checkpoint

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.checkpoint.Checkpoint
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class Checkpoint
    +extends java.lang.Object
    +
    A checkpoint is a mapping of all the streams a job is consuming and the most recent current offset for each. + It is used to restore a StreamTask, either as part of a job restart or as part + of restarting a failed container within a running job.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      Checkpoint(java.util.Map<SystemStreamPartition,java.lang.String> offsets) +
      Constructs a new checkpoint based off a map of Samza stream offsets.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      booleanequals(java.lang.Object o) 
      java.util.Map<SystemStreamPartition,java.lang.String>getOffsets() +
      Gets a unmodifiable view of the current Samza stream offsets.
      +
      inthashCode() 
      java.lang.StringtoString() 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, finalize, getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Checkpoint

        +
        public Checkpoint(java.util.Map<SystemStreamPartition,java.lang.String> offsets)
        +
        Constructs a new checkpoint based off a map of Samza stream offsets.
        +
        Parameters:
        offsets - Map of Samza streams to their current offset.
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getOffsets

        +
        public java.util.Map<SystemStreamPartition,java.lang.String> getOffsets()
        +
        Gets a unmodifiable view of the current Samza stream offsets.
        +
        Returns:
        A unmodifiable view of a Map of Samza streams to their recorded offsets.
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object o)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/CheckpointManager.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/CheckpointManager.html new file mode 100644 index 0000000..5f9409f --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/CheckpointManager.html @@ -0,0 +1,307 @@ + + + + + +CheckpointManager (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.checkpoint
+

Interface CheckpointManager

+
+
+
+
    +
  • +
    +
    +
    public interface CheckpointManager
    +
    CheckpointManagers read and write Checkpoint to some + implementation-specific location.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      java.util.Map<TaskName,java.lang.Integer>readChangeLogPartitionMapping() +
      Read the taskName to partition mapping that is being maintained by this CheckpointManager
      +
      CheckpointreadLastCheckpoint(TaskName taskName) +
      Returns the last recorded checkpoint for a specified taskName.
      +
      voidregister(TaskName taskName) +
      Registers this manager to write checkpoints of a specific Samza stream partition.
      +
      voidstart() 
      voidstop() 
      voidwriteChangeLogPartitionMapping(java.util.Map<TaskName,java.lang.Integer> mapping) +
      Write the taskName to partition mapping that is being maintained by this CheckpointManager
      +
      voidwriteCheckpoint(TaskName taskName, + Checkpoint checkpoint) +
      Writes a checkpoint based on the current state of a Samza stream partition.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        start

        +
        void start()
        +
      • +
      + + + +
        +
      • +

        register

        +
        void register(TaskName taskName)
        +
        Registers this manager to write checkpoints of a specific Samza stream partition.
        +
        Parameters:
        taskName - Specific Samza taskName of which to write checkpoints for.
        +
      • +
      + + + +
        +
      • +

        writeCheckpoint

        +
        void writeCheckpoint(TaskName taskName,
        +                   Checkpoint checkpoint)
        +
        Writes a checkpoint based on the current state of a Samza stream partition.
        +
        Parameters:
        taskName - Specific Samza taskName of which to write a checkpoint of.
        checkpoint - Reference to a Checkpoint object to store offset data in.
        +
      • +
      + + + +
        +
      • +

        readLastCheckpoint

        +
        Checkpoint readLastCheckpoint(TaskName taskName)
        +
        Returns the last recorded checkpoint for a specified taskName.
        +
        Parameters:
        taskName - Specific Samza taskName for which to get the last checkpoint of.
        +
        Returns:
        A Checkpoint object with the recorded offset data of the specified partition.
        +
      • +
      + + + +
        +
      • +

        readChangeLogPartitionMapping

        +
        java.util.Map<TaskName,java.lang.Integer> readChangeLogPartitionMapping()
        +
        Read the taskName to partition mapping that is being maintained by this CheckpointManager
        +
        Returns:
        TaskName to task log partition mapping, or an empty map if there were no messages.
        +
      • +
      + + + +
        +
      • +

        writeChangeLogPartitionMapping

        +
        void writeChangeLogPartitionMapping(java.util.Map<TaskName,java.lang.Integer> mapping)
        +
        Write the taskName to partition mapping that is being maintained by this CheckpointManager
        +
        Parameters:
        mapping - Each TaskName's partition within the changelog
        +
      • +
      + + + +
        +
      • +

        stop

        +
        void stop()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/CheckpointManagerFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/CheckpointManagerFactory.html new file mode 100644 index 0000000..d7e0905 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/CheckpointManagerFactory.html @@ -0,0 +1,207 @@ + + + + + +CheckpointManagerFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.checkpoint
+

Interface CheckpointManagerFactory

+
+
+
+ +
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-frame.html new file mode 100644 index 0000000..b742bba --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-frame.html @@ -0,0 +1,24 @@ + + + + + +org.apache.samza.checkpoint (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.checkpoint

+
+

Interfaces

+ +

Classes

+ +
+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-summary.html new file mode 100644 index 0000000..3d80d9d --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-summary.html @@ -0,0 +1,157 @@ + + + + + +org.apache.samza.checkpoint (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.checkpoint

+
+
+
    +
  • + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    CheckpointManager +
    CheckpointManagers read and write Checkpoint to some + implementation-specific location.
    +
    CheckpointManagerFactory + +
    +
  • +
  • + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    Checkpoint +
    A checkpoint is a mapping of all the streams a job is consuming and the most recent current offset for each.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-tree.html new file mode 100644 index 0000000..db70935 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/checkpoint/package-tree.html @@ -0,0 +1,131 @@ + + + + + +org.apache.samza.checkpoint Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.checkpoint

+Package Hierarchies: + +
+
+

Class Hierarchy

+
    +
  • java.lang.Object + +
  • +
+

Interface Hierarchy

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/Config.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/Config.html new file mode 100644 index 0000000..c72c170 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/Config.html @@ -0,0 +1,672 @@ + + + + + +Config (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.config
+

Class Config

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.config.Config
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.util.Map<java.lang.String,java.lang.String>
    +
    +
    +
    Direct Known Subclasses:
    +
    MapConfig
    +
    +
    +
    +
    public abstract class Config
    +extends java.lang.Object
    +implements java.util.Map<java.lang.String,java.lang.String>
    +
    Store and retrieve named, typed values as configuration for classes implementing this interface.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Nested Class Summary

      +
        +
      • + + +

        Nested classes/interfaces inherited from interface java.util.Map

        +java.util.Map.Entry<K,V>
      • +
      +
    • +
    + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      Config() 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidclear() 
      java.lang.Stringget(java.lang.String k, + java.lang.String defaultString) 
      booleangetBoolean(java.lang.String k) 
      booleangetBoolean(java.lang.String k, + boolean defaultValue) 
      <T> java.lang.Class<T>getClass(java.lang.String k) 
      java.util.DategetDate(java.lang.String k) 
      java.util.DategetDate(java.lang.String k, + java.util.Date defaultValue) 
      java.util.DategetDate(java.lang.String k, + java.text.SimpleDateFormat format) 
      java.util.DategetDate(java.lang.String k, + java.text.SimpleDateFormat format, + java.util.Date defaultValue) 
      java.util.DategetDate(java.lang.String k, + java.lang.String format) 
      java.util.DategetDate(java.lang.String k, + java.lang.String format, + java.util.Date defaultValue) 
      doublegetDouble(java.lang.String k) 
      doublegetDouble(java.lang.String k, + double defaultValue) 
      intgetInt(java.lang.String k) 
      intgetInt(java.lang.String k, + int defaultValue) 
      java.util.List<java.lang.String>getList(java.lang.String k) 
      java.util.List<java.lang.String>getList(java.lang.String k, + java.util.List<java.lang.String> defaultValue) 
      longgetLong(java.lang.String k) 
      longgetLong(java.lang.String k, + long defaultValue) 
      <T> TgetNewInstance(java.lang.String k) 
      shortgetShort(java.lang.String k) 
      shortgetShort(java.lang.String k, + short defaultValue) 
      java.lang.Stringput(java.lang.String key, + java.lang.String value) 
      voidputAll(java.util.Map<? extends java.lang.String,? extends java.lang.String> m) 
      java.lang.Stringremove(java.lang.Object s) 
      Configsubset(java.lang.String prefix) 
      Configsubset(java.lang.String prefix, + boolean stripPrefix) 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
        +
      • + + +

        Methods inherited from interface java.util.Map

        +containsKey, containsValue, entrySet, equals, get, hashCode, isEmpty, keySet, size, values
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Config

        +
        public Config()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        subset

        +
        public Config subset(java.lang.String prefix)
        +
      • +
      + + + +
        +
      • +

        subset

        +
        public Config subset(java.lang.String prefix,
        +            boolean stripPrefix)
        +
      • +
      + + + +
        +
      • +

        get

        +
        public java.lang.String get(java.lang.String k,
        +                   java.lang.String defaultString)
        +
      • +
      + + + +
        +
      • +

        getBoolean

        +
        public boolean getBoolean(java.lang.String k,
        +                 boolean defaultValue)
        +
      • +
      + + + +
        +
      • +

        getBoolean

        +
        public boolean getBoolean(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getShort

        +
        public short getShort(java.lang.String k,
        +             short defaultValue)
        +
      • +
      + + + +
        +
      • +

        getShort

        +
        public short getShort(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getLong

        +
        public long getLong(java.lang.String k,
        +           long defaultValue)
        +
      • +
      + + + +
        +
      • +

        getLong

        +
        public long getLong(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getInt

        +
        public int getInt(java.lang.String k,
        +         int defaultValue)
        +
      • +
      + + + +
        +
      • +

        getInt

        +
        public int getInt(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getDouble

        +
        public double getDouble(java.lang.String k,
        +               double defaultValue)
        +
      • +
      + + + +
        +
      • +

        getDouble

        +
        public double getDouble(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getList

        +
        public java.util.List<java.lang.String> getList(java.lang.String k,
        +                                       java.util.List<java.lang.String> defaultValue)
        +
      • +
      + + + +
        +
      • +

        getList

        +
        public java.util.List<java.lang.String> getList(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getClass

        +
        public <T> java.lang.Class<T> getClass(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getNewInstance

        +
        public <T> T getNewInstance(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getDate

        +
        public java.util.Date getDate(java.lang.String k)
        +
      • +
      + + + +
        +
      • +

        getDate

        +
        public java.util.Date getDate(java.lang.String k,
        +                     java.lang.String format)
        +
      • +
      + + + +
        +
      • +

        getDate

        +
        public java.util.Date getDate(java.lang.String k,
        +                     java.text.SimpleDateFormat format)
        +
      • +
      + + + +
        +
      • +

        getDate

        +
        public java.util.Date getDate(java.lang.String k,
        +                     java.util.Date defaultValue)
        +
      • +
      + + + +
        +
      • +

        getDate

        +
        public java.util.Date getDate(java.lang.String k,
        +                     java.lang.String format,
        +                     java.util.Date defaultValue)
        +
      • +
      + + + +
        +
      • +

        getDate

        +
        public java.util.Date getDate(java.lang.String k,
        +                     java.text.SimpleDateFormat format,
        +                     java.util.Date defaultValue)
        +
      • +
      + + + +
        +
      • +

        clear

        +
        public void clear()
        +
        +
        Specified by:
        +
        clear in interface java.util.Map<java.lang.String,java.lang.String>
        +
        +
      • +
      + + + +
        +
      • +

        put

        +
        public java.lang.String put(java.lang.String key,
        +                   java.lang.String value)
        +
        +
        Specified by:
        +
        put in interface java.util.Map<java.lang.String,java.lang.String>
        +
        +
      • +
      + + + +
        +
      • +

        putAll

        +
        public void putAll(java.util.Map<? extends java.lang.String,? extends java.lang.String> m)
        +
        +
        Specified by:
        +
        putAll in interface java.util.Map<java.lang.String,java.lang.String>
        +
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public java.lang.String remove(java.lang.Object s)
        +
        +
        Specified by:
        +
        remove in interface java.util.Map<java.lang.String,java.lang.String>
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigException.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigException.html new file mode 100644 index 0000000..5da86de --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigException.html @@ -0,0 +1,285 @@ + + + + + +ConfigException (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.config
+

Class ConfigException

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • java.lang.Throwable
    • +
    • + +
    • +
    +
  • +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + + + + + + + +
      Constructors 
      Constructor and Description
      ConfigException(java.lang.String msg) 
      ConfigException(java.lang.String msg, + java.lang.Throwable e) 
      ConfigException(java.lang.Throwable e) 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      +
        +
      • + + +

        Methods inherited from class java.lang.Throwable

        +addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
      • +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        ConfigException

        +
        public ConfigException(java.lang.Throwable e)
        +
      • +
      + + + +
        +
      • +

        ConfigException

        +
        public ConfigException(java.lang.String msg)
        +
      • +
      + + + +
        +
      • +

        ConfigException

        +
        public ConfigException(java.lang.String msg,
        +               java.lang.Throwable e)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigFactory.html new file mode 100644 index 0000000..4e5b1ee --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigFactory.html @@ -0,0 +1,210 @@ + + + + + +ConfigFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.config
+

Interface ConfigFactory

+
+
+
+
    +
  • +
    +
    +
    public interface ConfigFactory
    +
    Build a Config
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      ConfiggetConfig(java.net.URI configUri) +
      Build a specific Config.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getConfig

        +
        Config getConfig(java.net.URI configUri)
        +
        Build a specific Config.
        +
        Parameters:
        configUri - Resource containing information necessary for this Config.
        +
        Returns:
        Newly constructed Config.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigRewriter.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigRewriter.html new file mode 100644 index 0000000..3922257 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/ConfigRewriter.html @@ -0,0 +1,208 @@ + + + + + +ConfigRewriter (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.config
+

Interface ConfigRewriter

+
+
+
+
    +
  • +
    +
    +
    public interface ConfigRewriter
    +
    A ConfigRewriter receives the job's config during job startup and may re-write it to provide new configs, + remove existing configs or audit and verify the config is correct or permitted.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      Configrewrite(java.lang.String name, + Config config) 
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        rewrite

        +
        Config rewrite(java.lang.String name,
        +             Config config)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/MapConfig.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/MapConfig.html new file mode 100644 index 0000000..bf3f3bd --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/MapConfig.html @@ -0,0 +1,456 @@ + + + + + +MapConfig (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.config
+

Class MapConfig

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.util.Map<java.lang.String,java.lang.String>
    +
    +
    +
    +
    public class MapConfig
    +extends Config
    +
    A Config backed by a Java Map
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        MapConfig

        +
        public MapConfig()
        +
      • +
      + + + +
        +
      • +

        MapConfig

        +
        public MapConfig(java.util.Map<java.lang.String,java.lang.String> map)
        +
      • +
      + + + +
        +
      • +

        MapConfig

        +
        public MapConfig(java.util.List<java.util.Map<java.lang.String,java.lang.String>> maps)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        get

        +
        public java.lang.String get(java.lang.Object k)
        +
      • +
      + + + +
        +
      • +

        containsKey

        +
        public boolean containsKey(java.lang.Object k)
        +
      • +
      + + + +
        +
      • +

        entrySet

        +
        public java.util.Set<java.util.Map.Entry<java.lang.String,java.lang.String>> entrySet()
        +
      • +
      + + + +
        +
      • +

        isEmpty

        +
        public boolean isEmpty()
        +
      • +
      + + + +
        +
      • +

        keySet

        +
        public java.util.Set<java.lang.String> keySet()
        +
      • +
      + + + +
        +
      • +

        size

        +
        public int size()
        +
      • +
      + + + +
        +
      • +

        values

        +
        public java.util.Collection<java.lang.String> values()
        +
      • +
      + + + +
        +
      • +

        containsValue

        +
        public boolean containsValue(java.lang.Object v)
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Specified by:
        +
        hashCode in interface java.util.Map<java.lang.String,java.lang.String>
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object obj)
        +
        +
        Specified by:
        +
        equals in interface java.util.Map<java.lang.String,java.lang.String>
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-frame.html new file mode 100644 index 0000000..3340277 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-frame.html @@ -0,0 +1,29 @@ + + + + + +org.apache.samza.config (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.config

+
+

Interfaces

+ +

Classes

+ +

Exceptions

+ +
+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-summary.html new file mode 100644 index 0000000..b5c7782 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-summary.html @@ -0,0 +1,180 @@ + + + + + +org.apache.samza.config (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.config

+
+
+
    +
  • + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    ConfigFactory +
    Build a Config
    +
    ConfigRewriter +
    A ConfigRewriter receives the job's config during job startup and may re-write it to provide new configs, + remove existing configs or audit and verify the config is correct or permitted.
    +
    +
  • +
  • + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    Config +
    Store and retrieve named, typed values as configuration for classes implementing this interface.
    +
    MapConfig +
    A Config backed by a Java Map
    +
    +
  • +
  • + + + + + + + + + + + + +
    Exception Summary 
    ExceptionDescription
    ConfigException +
    Specific SamzaExceptions thrown from Config
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-tree.html new file mode 100644 index 0000000..f2471c8 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/config/package-tree.html @@ -0,0 +1,152 @@ + + + + + +org.apache.samza.config Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.config

+Package Hierarchies: + +
+
+

Class Hierarchy

+
    +
  • java.lang.Object +
      +
    • org.apache.samza.config.Config (implements java.util.Map<K,V>) + +
    • +
    • java.lang.Throwable (implements java.io.Serializable) + +
    • +
    +
  • +
+

Interface Hierarchy

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/SamzaContainerContext.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/SamzaContainerContext.html new file mode 100644 index 0000000..e73734f --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/SamzaContainerContext.html @@ -0,0 +1,299 @@ + + + + + +SamzaContainerContext (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.container
+

Class SamzaContainerContext

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.container.SamzaContainerContext
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class SamzaContainerContext
    +extends java.lang.Object
    +
    A SamzaContainerContext maintains per-container information for the tasks it executes.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Field Summary

      + + + + + + + + + + + + + + + + + + +
      Fields 
      Modifier and TypeField and Description
      Configconfig 
      java.lang.Stringname 
      java.util.Collection<TaskName>taskNames 
      +
    • +
    + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      SamzaContainerContext(java.lang.String name, + Config config, + java.util.Collection<TaskName> taskNames) +
      An immutable context object that can passed to tasks to give them information + about the container in which they are executing.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        name

        +
        public final java.lang.String name
        +
      • +
      + + + +
        +
      • +

        config

        +
        public final Config config
        +
      • +
      + + + +
        +
      • +

        taskNames

        +
        public final java.util.Collection<TaskName> taskNames
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        SamzaContainerContext

        +
        public SamzaContainerContext(java.lang.String name,
        +                     Config config,
        +                     java.util.Collection<TaskName> taskNames)
        +
        An immutable context object that can passed to tasks to give them information + about the container in which they are executing.
        +
        Parameters:
        name - The name of the container (either a YARN AM or SamzaContainer).
        config - The job configuration.
        taskNames - The set of taskName keys for which this container is responsible.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/TaskName.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/TaskName.html new file mode 100644 index 0000000..28bacf2 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/TaskName.html @@ -0,0 +1,330 @@ + + + + + +TaskName (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.container
+

Class TaskName

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.container.TaskName
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.lang.Comparable<TaskName>
    +
    +
    +
    +
    public class TaskName
    +extends java.lang.Object
    +implements java.lang.Comparable<TaskName>
    +
    A unique identifier of a set of a SystemStreamPartitions that have been grouped by + a SystemStreamPartitionGrouper. The + SystemStreamPartitionGrouper determines the TaskName for each set it creates.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      TaskName(java.lang.String taskName) 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      intcompareTo(TaskName that) 
      booleanequals(java.lang.Object o) 
      java.lang.StringgetTaskName() 
      inthashCode() 
      java.lang.StringtoString() 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, finalize, getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        TaskName

        +
        public TaskName(java.lang.String taskName)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getTaskName

        +
        public java.lang.String getTaskName()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object o)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(TaskName that)
        +
        +
        Specified by:
        +
        compareTo in interface java.lang.Comparable<TaskName>
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/SystemStreamPartitionGrouper.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/SystemStreamPartitionGrouper.html new file mode 100644 index 0000000..fa4249a --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/SystemStreamPartitionGrouper.html @@ -0,0 +1,214 @@ + + + + + +SystemStreamPartitionGrouper (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.container.grouper.stream
+

Interface SystemStreamPartitionGrouper

+
+
+
+
    +
  • +
    +
    +
    public interface SystemStreamPartitionGrouper
    +
    Group a set of SystemStreamPartitions into logical taskNames that share a common characteristic, defined + by the implementation. Each taskName has a key that uniquely describes what sets may be in it, but does + not generally enumerate the elements of those sets. For example, a SystemStreamPartitionGrouper that + groups SystemStreamPartitions (each with 4 partitions) by their partition, would end up generating + four TaskNames: 0, 1, 2, 3. These TaskNames describe the partitions but do not list all of the + SystemStreamPartitions, which allows new SystemStreamPartitions to be added later without changing + the definition of the TaskNames, assuming these new SystemStreamPartitions do not have more than + four partitions. On the other hand, a SystemStreamPartitionGrouper that wanted each SystemStreamPartition + to be its own, unique group would use the SystemStreamPartition's entire description to generate + the TaskNames.
    +
  • +
+
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/SystemStreamPartitionGrouperFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/SystemStreamPartitionGrouperFactory.html new file mode 100644 index 0000000..c19d50f --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/SystemStreamPartitionGrouperFactory.html @@ -0,0 +1,205 @@ + + + + + +SystemStreamPartitionGrouperFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.container.grouper.stream
+

Interface SystemStreamPartitionGrouperFactory

+
+
+
+
    +
  • +
    +
    +
    public interface SystemStreamPartitionGrouperFactory
    +
    Return an instance a SystemStreamPartitionGrouper per the particular implementation
    +
  • +
+
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-frame.html new file mode 100644 index 0000000..8b7e4d2 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-frame.html @@ -0,0 +1,20 @@ + + + + + +org.apache.samza.container.grouper.stream (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.container.grouper.stream

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-summary.html new file mode 100644 index 0000000..ce2f5a0 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-summary.html @@ -0,0 +1,140 @@ + + + + + +org.apache.samza.container.grouper.stream (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.container.grouper.stream

+
+
+
    +
  • + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    SystemStreamPartitionGrouper +
    Group a set of SystemStreamPartitions into logical taskNames that share a common characteristic, defined + by the implementation.
    +
    SystemStreamPartitionGrouperFactory +
    Return an instance a SystemStreamPartitionGrouper per the particular implementation
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-tree.html new file mode 100644 index 0000000..0387a1e --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/grouper/stream/package-tree.html @@ -0,0 +1,123 @@ + + + + + +org.apache.samza.container.grouper.stream Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.container.grouper.stream

+Package Hierarchies: + +
+
+

Interface Hierarchy

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-frame.html new file mode 100644 index 0000000..f32687a --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-frame.html @@ -0,0 +1,20 @@ + + + + + +org.apache.samza.container (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.container

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-summary.html new file mode 100644 index 0000000..827233e --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-summary.html @@ -0,0 +1,140 @@ + + + + + +org.apache.samza.container (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.container

+
+
+
    +
  • + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    SamzaContainerContext +
    A SamzaContainerContext maintains per-container information for the tasks it executes.
    +
    TaskName +
    A unique identifier of a set of a SystemStreamPartitions that have been grouped by + a SystemStreamPartitionGrouper.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-tree.html new file mode 100644 index 0000000..6782780 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/container/package-tree.html @@ -0,0 +1,127 @@ + + + + + +org.apache.samza.container Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.container

+Package Hierarchies: + +
+
+

Class Hierarchy

+
    +
  • java.lang.Object + +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/ApplicationStatus.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/ApplicationStatus.html new file mode 100644 index 0000000..0eaa87d --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/ApplicationStatus.html @@ -0,0 +1,359 @@ + + + + + +ApplicationStatus (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.job
+

Enum ApplicationStatus

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • java.lang.Enum<ApplicationStatus>
    • +
    • +
        +
      • org.apache.samza.job.ApplicationStatus
      • +
      +
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.io.Serializable, java.lang.Comparable<ApplicationStatus>
    +
    +
    +
    +
    public enum ApplicationStatus
    +extends java.lang.Enum<ApplicationStatus>
    +
    Status of a StreamJob during and after its run.
    +
  • +
+
+
+
    +
  • + + + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      java.lang.StringtoString() 
      static ApplicationStatusvalueOf(java.lang.String name) +
      Returns the enum constant of this type with the specified name.
      +
      static ApplicationStatus[]values() +
      Returns an array containing the constants of this enum type, in +the order they are declared.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Enum

        +clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, valueOf
      • +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        values

        +
        public static ApplicationStatus[] values()
        +
        Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
        +for (ApplicationStatus c : ApplicationStatus.values())
        +    System.out.println(c);
        +
        +
        Returns:
        an array containing the constants of this enum type, in the order they are declared
        +
      • +
      + + + +
        +
      • +

        valueOf

        +
        public static ApplicationStatus valueOf(java.lang.String name)
        +
        Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
        +
        Parameters:
        name - the name of the enum constant to be returned.
        +
        Returns:
        the enum constant with the specified name
        +
        Throws:
        +
        java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
        +
        java.lang.NullPointerException - if the argument is null
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Enum<ApplicationStatus>
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/CommandBuilder.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/CommandBuilder.html new file mode 100644 index 0000000..5415ea3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/CommandBuilder.html @@ -0,0 +1,398 @@ + + + + + +CommandBuilder (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.job
+

Class CommandBuilder

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.job.CommandBuilder
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public abstract class CommandBuilder
    +extends java.lang.Object
    +
    CommandBuilders are used to customize the command necessary to launch a Samza Job for a particular framework, + such as YARN or the LocalJobRunner.
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        taskNameToSystemStreamPartitionsMapping

        +
        protected java.util.Map<TaskName,java.util.Set<SystemStreamPartition>> taskNameToSystemStreamPartitionsMapping
        +
      • +
      + + + +
        +
      • +

        taskNameToChangeLogPartitionMapping

        +
        protected java.util.Map<TaskName,java.lang.Integer> taskNameToChangeLogPartitionMapping
        +
      • +
      + + + +
        +
      • +

        name

        +
        protected java.lang.String name
        +
      • +
      + + + +
        +
      • +

        config

        +
        protected Config config
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        CommandBuilder

        +
        public CommandBuilder()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        setName

        +
        public CommandBuilder setName(java.lang.String name)
        +
        Parameters:
        name - associated with a specific instantiation of a TaskRunner.
        +
        Returns:
        self to support a builder style of use.
        +
      • +
      + + + + + + + +
        +
      • +

        setTaskNameToChangeLogPartitionMapping

        +
        public CommandBuilder setTaskNameToChangeLogPartitionMapping(java.util.Map<TaskName,java.lang.Integer> mapping)
        +
      • +
      + + + +
        +
      • +

        buildCommand

        +
        public abstract java.lang.String buildCommand()
        +
      • +
      + + + +
        +
      • +

        buildEnvironment

        +
        public abstract java.util.Map<java.lang.String,java.lang.String> buildEnvironment()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/StreamJob.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/StreamJob.html new file mode 100644 index 0000000..27b1dc3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/StreamJob.html @@ -0,0 +1,284 @@ + + + + + +StreamJob (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.job
+

Interface StreamJob

+
+
+
+
    +
  • +
    +
    +
    public interface StreamJob
    +
    A StreamJob runs Samza StreamTasks in its specific environment. + Users generally do not need to implement a StreamJob themselves, rather it is a framework-level + interface meant for those extending Samza itself. This class, and its accompanying factory, + allow Samza to run on other service providers besides YARN and LocalJob, such as Mesos or Sun Grid Engine.
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        submit

        +
        StreamJob submit()
        +
        Submit this job to be run.
        +
        Returns:
        An instance of this job after it has been submitted.
        +
      • +
      + + + +
        +
      • +

        kill

        +
        StreamJob kill()
        +
        Kill this job immediately.
        +
        Returns:
        An instance of this job after it has been killed.
        +
      • +
      + + + +
        +
      • +

        waitForFinish

        +
        ApplicationStatus waitForFinish(long timeoutMs)
        +
        Block on this job until either it finishes or reaches its timeout value
        +
        Parameters:
        timeoutMs - How many milliseconds to wait before returning, assuming the job has not yet finished
        +
        Returns:
        ApplicationStatus of the job after finishing or timing out
        +
      • +
      + + + +
        +
      • +

        waitForStatus

        +
        ApplicationStatus waitForStatus(ApplicationStatus status,
        +                              long timeoutMs)
        +
        Block on this job until either it transitions to the specified status or reaches it timeout value
        +
        Parameters:
        status - Target ApplicationStatus to wait upon
        timeoutMs - How many milliseconds to wait before returning, assuming the job has not transitioned to the specified value
        +
        Returns:
        ApplicationStatus of the job after finishing or reaching target state
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/StreamJobFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/StreamJobFactory.html new file mode 100644 index 0000000..78c972e --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/StreamJobFactory.html @@ -0,0 +1,205 @@ + + + + + +StreamJobFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.job
+

Interface StreamJobFactory

+
+
+
+
    +
  • +
    +
    +
    public interface StreamJobFactory
    +
    Build a StreamJob
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      StreamJobgetJob(Config config) 
      +
    • +
    +
  • +
+
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-frame.html new file mode 100644 index 0000000..8a0aaf5 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-frame.html @@ -0,0 +1,28 @@ + + + + + +org.apache.samza.job (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.job

+
+

Interfaces

+ +

Classes

+ +

Enums

+ +
+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-summary.html new file mode 100644 index 0000000..e379064 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-summary.html @@ -0,0 +1,174 @@ + + + + + +org.apache.samza.job (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.job

+
+
+
    +
  • + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    StreamJob +
    A StreamJob runs Samza StreamTasks in its specific environment.
    +
    StreamJobFactory +
    Build a StreamJob
    +
    +
  • +
  • + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    CommandBuilder +
    CommandBuilders are used to customize the command necessary to launch a Samza Job for a particular framework, + such as YARN or the LocalJobRunner.
    +
    +
  • +
  • + + + + + + + + + + + + +
    Enum Summary 
    EnumDescription
    ApplicationStatus +
    Status of a StreamJob during and after its run.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-tree.html new file mode 100644 index 0000000..6f04e2e --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/job/package-tree.html @@ -0,0 +1,143 @@ + + + + + +org.apache.samza.job Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.job

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +

Interface Hierarchy

+ +

Enum Hierarchy

+
    +
  • java.lang.Object +
      +
    • java.lang.Enum<E> (implements java.lang.Comparable<T>, java.io.Serializable) + +
    • +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Clock.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Clock.html new file mode 100644 index 0000000..b870d91 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Clock.html @@ -0,0 +1,254 @@ + + + + + +Clock (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Class Clock

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.metrics.Clock
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class Clock
    +extends java.lang.Object
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      Clock() 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      longgetCurrentTimeMs() 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Clock

        +
        public Clock()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getCurrentTimeMs

        +
        public long getCurrentTimeMs()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Counter.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Counter.html new file mode 100644 index 0000000..6adf9d1 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Counter.html @@ -0,0 +1,386 @@ + + + + + +Counter (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Class Counter

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.metrics.Counter
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Metric
    +
    +
    +
    +
    public class Counter
    +extends java.lang.Object
    +implements Metric
    +
    A counter is a Metric that represents a cumulative value. + For example, the number of messages processed since the container was started.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      Counter(java.lang.String name) 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidclear() 
      longdec() 
      longdec(long n) 
      longgetCount() 
      java.lang.StringgetName() 
      longinc() 
      longinc(long n) 
      voidset(long n) 
      java.lang.StringtoString() 
      voidvisit(MetricsVisitor visitor) 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Counter

        +
        public Counter(java.lang.String name)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        inc

        +
        public long inc()
        +
      • +
      + + + +
        +
      • +

        inc

        +
        public long inc(long n)
        +
      • +
      + + + +
        +
      • +

        dec

        +
        public long dec()
        +
      • +
      + + + +
        +
      • +

        dec

        +
        public long dec(long n)
        +
      • +
      + + + +
        +
      • +

        set

        +
        public void set(long n)
        +
      • +
      + + + +
        +
      • +

        clear

        +
        public void clear()
        +
      • +
      + + + +
        +
      • +

        getCount

        +
        public long getCount()
        +
      • +
      + + + +
        +
      • +

        getName

        +
        public java.lang.String getName()
        +
      • +
      + + + + + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Gauge.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Gauge.html new file mode 100644 index 0000000..8bca739 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Gauge.html @@ -0,0 +1,350 @@ + + + + + +Gauge (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Class Gauge<T>

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.metrics.Gauge<T>
    • +
    +
  • +
+
+
    +
  • +
    Type Parameters:
    T - Instance to be wrapped in the gauge for metering.
    +
    +
    All Implemented Interfaces:
    +
    Metric
    +
    +
    +
    Direct Known Subclasses:
    +
    BlockingEnvelopeMap.BufferGauge
    +
    +
    +
    +
    public class Gauge<T>
    +extends java.lang.Object
    +implements Metric
    +
    A Gauge is a Metric that wraps some instance of T in a thread-safe + reference and allows it to be set or retrieved. Gauages record specific values over time. + For example, the current length of a queue or the size of a buffer.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      Gauge(java.lang.String name, + T value) 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      booleancompareAndSet(T expected, + T n) 
      java.lang.StringgetName() 
      TgetValue() 
      Tset(T n) 
      java.lang.StringtoString() 
      voidvisit(MetricsVisitor visitor) 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + + + +
        +
      • +

        Gauge

        +
        public Gauge(java.lang.String name,
        +     T value)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + + + +
        +
      • +

        compareAndSet

        +
        public boolean compareAndSet(T expected,
        +                    T n)
        +
      • +
      + + + + + +
        +
      • +

        set

        +
        public T set(T n)
        +
      • +
      + + + +
        +
      • +

        getValue

        +
        public T getValue()
        +
      • +
      + + + +
        +
      • +

        getName

        +
        public java.lang.String getName()
        +
      • +
      + + + + + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Metric.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Metric.html new file mode 100644 index 0000000..a04459c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Metric.html @@ -0,0 +1,209 @@ + + + + + +Metric (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Interface Metric

+
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidvisit(MetricsVisitor visitor) 
      +
    • +
    +
  • +
+
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsRegistry.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsRegistry.html new file mode 100644 index 0000000..ab736b7 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsRegistry.html @@ -0,0 +1,290 @@ + + + + + +MetricsRegistry (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Interface MetricsRegistry

+
+
+
+
    +
  • +
    +
    All Known Subinterfaces:
    +
    ReadableMetricsRegistry
    +
    +
    +
    All Known Implementing Classes:
    +
    NoOpMetricsRegistry
    +
    +
    +
    +
    public interface MetricsRegistry
    +
    A MetricsRegistry allows its users to create new Metrics and + have those metrics wired to specific metrics systems, such as JMX, provided by MetricsReporters. + Those implementing Samza jobs use the MetricsRegistry to register metrics, which then handle + the details of getting those metrics to each defined MetricsReporter. + + Users are free to define their metrics into groups as needed for their jobs. MetricsReporters + will likely use the group field to group the user-defined metrics together.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      CounternewCounter(java.lang.String group, + Counter counter) +
      Register existing Counter with this registry
      +
      CounternewCounter(java.lang.String group, + java.lang.String name) +
      Create and register a new Counter
      +
      <T> Gauge<T>newGauge(java.lang.String group, + Gauge<T> value) +
      Register an existing Gauge
      +
      <T> Gauge<T>newGauge(java.lang.String group, + java.lang.String name, + T value) +
      Create and register a new Gauge
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        newCounter

        +
        Counter newCounter(java.lang.String group,
        +                 java.lang.String name)
        +
        Create and register a new Counter
        +
        Parameters:
        group - Group for this Counter
        name - Name of to-be-created Counter
        +
        Returns:
        New Counter instance
        +
      • +
      + + + +
        +
      • +

        newCounter

        +
        Counter newCounter(java.lang.String group,
        +                 Counter counter)
        +
        Register existing Counter with this registry
        +
        Parameters:
        group - Group for this Counter
        counter - Existing Counter to register
        +
        Returns:
        Counter that was registered
        +
      • +
      + + + + + +
        +
      • +

        newGauge

        +
        <T> Gauge<T> newGauge(java.lang.String group,
        +                    java.lang.String name,
        +                    T value)
        +
        Create and register a new Gauge
        +
        Type Parameters:
        T - Type the Gauge will be wrapping
        Parameters:
        group - Group for this Gauge
        name - Name of to-be-created Gauge
        value - Initial value for the Gauge
        +
        Returns:
        Gauge was created and registered
        +
      • +
      + + + +
        +
      • +

        newGauge

        +
        <T> Gauge<T> newGauge(java.lang.String group,
        +                    Gauge<T> value)
        +
        Register an existing Gauge
        +
        Type Parameters:
        T - Type the Gauge will be wrapping
        Parameters:
        group - Group for this Gauge
        value - Initial value for the Gauge
        +
        Returns:
        Gauge was registered
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsReporter.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsReporter.html new file mode 100644 index 0000000..fe87acc --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsReporter.html @@ -0,0 +1,234 @@ + + + + + +MetricsReporter (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Interface MetricsReporter

+
+
+
+
    +
  • +
    +
    +
    public interface MetricsReporter
    +
    A MetricsReporter is the interface that different metrics sinks, such as JMX, implement to receive + metrics from the Samza framework and Samza jobs.
    +
  • +
+
+
+
    +
  • + + +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        start

        +
        void start()
        +
      • +
      + + + + + + + +
        +
      • +

        stop

        +
        void stop()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsReporterFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsReporterFactory.html new file mode 100644 index 0000000..e30495c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsReporterFactory.html @@ -0,0 +1,209 @@ + + + + + +MetricsReporterFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Interface MetricsReporterFactory

+
+
+
+
    +
  • +
    +
    +
    public interface MetricsReporterFactory
    + +
  • +
+
+
+
    +
  • + + +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getMetricsReporter

        +
        MetricsReporter getMetricsReporter(java.lang.String name,
        +                                 java.lang.String containerName,
        +                                 Config config)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsVisitor.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsVisitor.html new file mode 100644 index 0000000..cf005c3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/MetricsVisitor.html @@ -0,0 +1,283 @@ + + + + + +MetricsVisitor (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Class MetricsVisitor

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.metrics.MetricsVisitor
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public abstract class MetricsVisitor
    +extends java.lang.Object
    +
    A MetricsVisitor can be used to process each metric in a ReadableMetricsRegistry, + encapsulating the logic of what to be done with each metric in the counter and gauge methods. This makes it easy + to quickly process all of the metrics in a registry.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      MetricsVisitor() 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      abstract voidcounter(Counter counter) 
      abstract <T> voidgauge(Gauge<T> gauge) 
      voidvisit(Metric metric) 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        MetricsVisitor

        +
        public MetricsVisitor()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        counter

        +
        public abstract void counter(Counter counter)
        +
      • +
      + + + +
        +
      • +

        gauge

        +
        public abstract <T> void gauge(Gauge<T> gauge)
        +
      • +
      + + + +
        +
      • +

        visit

        +
        public void visit(Metric metric)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/ReadableMetricsRegistry.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/ReadableMetricsRegistry.html new file mode 100644 index 0000000..e73acc8 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/ReadableMetricsRegistry.html @@ -0,0 +1,257 @@ + + + + + +ReadableMetricsRegistry (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Interface ReadableMetricsRegistry

+
+
+
+
    +
  • +
    +
    All Superinterfaces:
    +
    MetricsRegistry
    +
    +
    +
    +
    public interface ReadableMetricsRegistry
    +extends MetricsRegistry
    +
    A ReadableMetricsRegistry is a MetricsRegistry that also + allows read access to the metrics for which it is responsible.
    +
  • +
+
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/ReadableMetricsRegistryListener.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/ReadableMetricsRegistryListener.html new file mode 100644 index 0000000..bf7610b --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/ReadableMetricsRegistryListener.html @@ -0,0 +1,221 @@ + + + + + +ReadableMetricsRegistryListener (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Interface ReadableMetricsRegistryListener

+
+
+
+
    +
  • +
    +
    +
    public interface ReadableMetricsRegistryListener
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidonCounter(java.lang.String group, + Counter counter) 
      voidonGauge(java.lang.String group, + Gauge<?> gauge) 
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        onCounter

        +
        void onCounter(java.lang.String group,
        +             Counter counter)
        +
      • +
      + + + +
        +
      • +

        onGauge

        +
        void onGauge(java.lang.String group,
        +           Gauge<?> gauge)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Reservoir.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Reservoir.html new file mode 100644 index 0000000..d1cf13d --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Reservoir.html @@ -0,0 +1,247 @@ + + + + + +Reservoir (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Interface Reservoir

+
+
+
+
    +
  • +
    +
    All Known Implementing Classes:
    +
    SlidingTimeWindowReservoir
    +
    +
    +
    +
    public interface Reservoir
    +
    A reservoir interface to store, update and display values
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      SnapshotgetSnapshot() +
      Return a Snapshot of this reservoir
      +
      intsize() +
      Return the number of values in this reservoir
      +
      voidupdate(long value) +
      Update the reservoir with the new value
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        size

        +
        int size()
        +
        Return the number of values in this reservoir
        +
        Returns:
        the number of values;
        +
      • +
      + + + +
        +
      • +

        update

        +
        void update(long value)
        +
        Update the reservoir with the new value
        +
        Parameters:
        new - value
        +
      • +
      + + + +
        +
      • +

        getSnapshot

        +
        Snapshot getSnapshot()
        +
        Return a Snapshot of this reservoir
        +
        Returns:
        a statistical snapshot of this reservoir
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/SlidingTimeWindowReservoir.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/SlidingTimeWindowReservoir.html new file mode 100644 index 0000000..f1e27d3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/SlidingTimeWindowReservoir.html @@ -0,0 +1,328 @@ + + + + + +SlidingTimeWindowReservoir (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Class SlidingTimeWindowReservoir

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.metrics.SlidingTimeWindowReservoir
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Reservoir
    +
    +
    +
    +
    public class SlidingTimeWindowReservoir
    +extends java.lang.Object
    +implements Reservoir
    +
    An implemented Reservoir used to store values that appear in a + sliding time window
    +
  • +
+
+
+
    +
  • + + + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      SnapshotgetSnapshot() +
      Return a Snapshot of this reservoir
      +
      intsize() +
      Return the number of values in this reservoir
      +
      voidupdate(long value) +
      Update the reservoir with the new value
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        SlidingTimeWindowReservoir

        +
        public SlidingTimeWindowReservoir()
        +
        Default constructor using default window size
        +
      • +
      + + + +
        +
      • +

        SlidingTimeWindowReservoir

        +
        public SlidingTimeWindowReservoir(long windowMs,
        +                          Clock clock)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        size

        +
        public int size()
        +
        Description copied from interface: Reservoir
        +
        Return the number of values in this reservoir
        +
        +
        Specified by:
        +
        size in interface Reservoir
        +
        Returns:
        the number of values;
        +
      • +
      + + + +
        +
      • +

        update

        +
        public void update(long value)
        +
        Description copied from interface: Reservoir
        +
        Update the reservoir with the new value
        +
        +
        Specified by:
        +
        update in interface Reservoir
        +
        +
      • +
      + + + +
        +
      • +

        getSnapshot

        +
        public Snapshot getSnapshot()
        +
        Description copied from interface: Reservoir
        +
        Return a Snapshot of this reservoir
        +
        +
        Specified by:
        +
        getSnapshot in interface Reservoir
        +
        Returns:
        a statistical snapshot of this reservoir
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Snapshot.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Snapshot.html new file mode 100644 index 0000000..8ae5491 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Snapshot.html @@ -0,0 +1,327 @@ + + + + + +Snapshot (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Class Snapshot

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.metrics.Snapshot
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class Snapshot
    +extends java.lang.Object
    +
    A statistical snapshot of a collection of values
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      Snapshot(java.util.Collection<java.lang.Long> values) 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      doublegetAverage() +
      Get the average of the values in the collection
      +
      longgetMax() +
      Get the maximum value in the collection
      +
      longgetMin() +
      Get the minimum value in the collection
      +
      intgetSize() +
      Get the number of values in the collection
      +
      java.util.ArrayList<java.lang.Long>getValues() +
      Return the entire list of values
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Snapshot

        +
        public Snapshot(java.util.Collection<java.lang.Long> values)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getMax

        +
        public long getMax()
        +
        Get the maximum value in the collection
        +
        Returns:
        maximum value
        +
      • +
      + + + +
        +
      • +

        getMin

        +
        public long getMin()
        +
        Get the minimum value in the collection
        +
        Returns:
        minimum value
        +
      • +
      + + + +
        +
      • +

        getAverage

        +
        public double getAverage()
        +
        Get the average of the values in the collection
        +
        Returns:
        average value
        +
      • +
      + + + +
        +
      • +

        getSize

        +
        public int getSize()
        +
        Get the number of values in the collection
        +
        Returns:
        size of the collection
        +
      • +
      + + + +
        +
      • +

        getValues

        +
        public java.util.ArrayList<java.lang.Long> getValues()
        +
        Return the entire list of values
        +
        Returns:
        the list of values
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Timer.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Timer.html new file mode 100644 index 0000000..daf2883 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/Timer.html @@ -0,0 +1,359 @@ + + + + + +Timer (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.metrics
+

Class Timer

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.metrics.Timer
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Metric
    +
    +
    +
    +
    public class Timer
    +extends java.lang.Object
    +implements Metric
    +
    A timer metric that stores time duration and provides Snapshot of the + durations.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + + + + + + + +
      Constructors 
      Constructor and Description
      Timer(java.lang.String name) +
      Default constructor.
      +
      Timer(java.lang.String name, + long windowMs, + Clock clock) +
      Construct a Timer with given window size
      +
      Timer(java.lang.String name, + Reservoir reservoir) +
      Construct a Timer with given Reservoir
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      java.lang.StringgetName() +
      Get the name of the timer
      +
      SnapshotgetSnapshot() +
      Get the Snapshot
      +
      voidupdate(long duration) +
      Add the time duration
      +
      voidvisit(MetricsVisitor visitor) 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Timer

        +
        public Timer(java.lang.String name)
        +
        Default constructor. It uses SlidingTimeWindowReservoir as the + default reservoir.
        +
        Parameters:
        name - name of this timer
        +
      • +
      + + + +
        +
      • +

        Timer

        +
        public Timer(java.lang.String name,
        +     long windowMs,
        +     Clock clock)
        +
        Construct a Timer with given window size
        +
        Parameters:
        name - name of this timer
        windowMs - the window size. unit is millisecond
        clock - the clock for the reservoir
        +
      • +
      + + + +
        +
      • +

        Timer

        +
        public Timer(java.lang.String name,
        +     Reservoir reservoir)
        +
        Construct a Timer with given Reservoir
        +
        Parameters:
        name - name of this timer
        reservoir - the given reservoir
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        update

        +
        public void update(long duration)
        +
        Add the time duration
        +
        Parameters:
        duration - time duration
        +
      • +
      + + + +
        +
      • +

        getSnapshot

        +
        public Snapshot getSnapshot()
        +
        Get the Snapshot
        +
        Returns:
        a statistical snapshot
        +
      • +
      + + + + + + + +
        +
      • +

        getName

        +
        public java.lang.String getName()
        +
        Get the name of the timer
        +
        Returns:
        name of the timer
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-frame.html new file mode 100644 index 0000000..f70c051 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-frame.html @@ -0,0 +1,30 @@ + + + + + +org.apache.samza.metrics (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.metrics

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-summary.html new file mode 100644 index 0000000..1ae811f --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-summary.html @@ -0,0 +1,195 @@ + + + + + +org.apache.samza.metrics (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.metrics

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    Metric +
    Metric class that allows metric visitors to visit it to get its information.
    +
    MetricsRegistry +
    A MetricsRegistry allows its users to create new Metrics and + have those metrics wired to specific metrics systems, such as JMX, provided by MetricsReporters.
    +
    MetricsReporter +
    A MetricsReporter is the interface that different metrics sinks, such as JMX, implement to receive + metrics from the Samza framework and Samza jobs.
    +
    MetricsReporterFactory + +
    ReadableMetricsRegistry +
    A ReadableMetricsRegistry is a MetricsRegistry that also + allows read access to the metrics for which it is responsible.
    +
    ReadableMetricsRegistryListener 
    +
  • +
  • + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    Counter +
    A counter is a Metric that represents a cumulative value.
    +
    Gauge<T> +
    A Gauge is a Metric that wraps some instance of T in a thread-safe + reference and allows it to be set or retrieved.
    +
    MetricsVisitor +
    A MetricsVisitor can be used to process each metric in a ReadableMetricsRegistry, + encapsulating the logic of what to be done with each metric in the counter and gauge methods.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-tree.html new file mode 100644 index 0000000..162dea5 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/metrics/package-tree.html @@ -0,0 +1,140 @@ + + + + + +org.apache.samza.metrics Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.metrics

+Package Hierarchies: + +
+
+

Class Hierarchy

+
    +
  • java.lang.Object +
      +
    • org.apache.samza.metrics.Counter (implements org.apache.samza.metrics.Metric)
    • +
    • org.apache.samza.metrics.Gauge<T> (implements org.apache.samza.metrics.Metric)
    • +
    • org.apache.samza.metrics.MetricsVisitor
    • +
    +
  • +
+

Interface Hierarchy

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-frame.html new file mode 100644 index 0000000..74ddaac --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-frame.html @@ -0,0 +1,23 @@ + + + + + +org.apache.samza (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza

+
+

Classes

+ +

Exceptions

+ +
+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-summary.html new file mode 100644 index 0000000..ab75a68 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-summary.html @@ -0,0 +1,150 @@ + + + + + +org.apache.samza (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza

+
+
+
    +
  • + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    Partition +
    A numbered, ordered partition of a stream.
    +
    +
  • +
  • + + + + + + + + + + + + +
    Exception Summary 
    ExceptionDescription
    SamzaException +
    Unchecked exception that Samza throws when something goes wrong.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-tree.html new file mode 100644 index 0000000..cfd8b45 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/package-tree.html @@ -0,0 +1,139 @@ + + + + + +org.apache.samza Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza

+Package Hierarchies: + +
+
+

Class Hierarchy

+
    +
  • java.lang.Object +
      +
    • org.apache.samza.Partition (implements java.lang.Comparable<T>)
    • +
    • java.lang.Throwable (implements java.io.Serializable) +
        +
      • java.lang.Exception + +
      • +
      +
    • +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Deserializer.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Deserializer.html new file mode 100644 index 0000000..97d986b --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Deserializer.html @@ -0,0 +1,216 @@ + + + + + +Deserializer (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.serializers
+

Interface Deserializer<T>

+
+
+
+
    +
  • +
    Type Parameters:
    T - The type of serialized object implementations can read
    +
    +
    All Known Subinterfaces:
    +
    Serde<T>
    +
    +
    +
    +
    public interface Deserializer<T>
    +
    A standard interface for Samza compatible deserializers, used for deserializing serialized objects back to their + original form.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      TfromBytes(byte[] bytes) +
      Deserializes given serialized object from an array of bytes to its original form.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromBytes

        +
        T fromBytes(byte[] bytes)
        +
        Deserializes given serialized object from an array of bytes to its original form.
        +
        Parameters:
        bytes - Array of bytes representing serialized object.
        +
        Returns:
        Original deserialized object.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Serde.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Serde.html new file mode 100644 index 0000000..6cd6962 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Serde.html @@ -0,0 +1,193 @@ + + + + + +Serde (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.serializers
+

Interface Serde<T>

+
+
+
+
    +
  • +
    Type Parameters:
    T - The type of serialized object implementations can both read and write
    +
    +
    All Superinterfaces:
    +
    Deserializer<T>, Serializer<T>
    +
    +
    +
    +
    public interface Serde<T>
    +extends Serializer<T>, Deserializer<T>
    +
    A Serde is a convenience type that implements both the Serializer and + Deserializer interfaces, allowing it to both read and write data + in its value type, T.
    +
  • +
+
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/SerdeFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/SerdeFactory.html new file mode 100644 index 0000000..6d27e10 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/SerdeFactory.html @@ -0,0 +1,208 @@ + + + + + +SerdeFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.serializers
+

Interface SerdeFactory<T>

+
+
+
+
    +
  • +
    Type Parameters:
    T - The type of serialized object this factory's output can both read and write
    +
    +
    +
    public interface SerdeFactory<T>
    +
    Build an instance of Serde
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      Serde<T>getSerde(java.lang.String name, + Config config) 
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getSerde

        +
        Serde<T> getSerde(java.lang.String name,
        +                Config config)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Serializer.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Serializer.html new file mode 100644 index 0000000..0ef9baa --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/Serializer.html @@ -0,0 +1,217 @@ + + + + + +Serializer (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.serializers
+

Interface Serializer<T>

+
+
+
+
    +
  • +
    Type Parameters:
    T - The type of serialized object implementations can write
    +
    +
    All Known Subinterfaces:
    +
    Serde<T>
    +
    +
    +
    +
    public interface Serializer<T>
    +
    A standard interface for Samza compatible serializers, used for serializing objects to bytes.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      byte[]toBytes(T object) +
      Serializes given object to an array of bytes.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + +
        +
      • +

        toBytes

        +
        byte[] toBytes(T object)
        +
        Serializes given object to an array of bytes.
        +
        Parameters:
        object - Object of specific type to serialize.
        +
        Returns:
        An array of bytes representing the object in serialized form.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-frame.html new file mode 100644 index 0000000..694fb75 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-frame.html @@ -0,0 +1,22 @@ + + + + + +org.apache.samza.serializers (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.serializers

+
+

Interfaces

+ +
+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-summary.html new file mode 100644 index 0000000..de0b194 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-summary.html @@ -0,0 +1,154 @@ + + + + + +org.apache.samza.serializers (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.serializers

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    Deserializer<T> +
    A standard interface for Samza compatible deserializers, used for deserializing serialized objects back to their + original form.
    +
    Serde<T> +
    A Serde is a convenience type that implements both the Serializer and + Deserializer interfaces, allowing it to both read and write data + in its value type, T.
    +
    SerdeFactory<T> +
    Build an instance of Serde
    +
    Serializer<T> +
    A standard interface for Samza compatible serializers, used for serializing objects to bytes.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-tree.html new file mode 100644 index 0000000..4b99298 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/serializers/package-tree.html @@ -0,0 +1,132 @@ + + + + + +org.apache.samza.serializers Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.serializers

+Package Hierarchies: + +
+
+

Interface Hierarchy

+
    +
  • org.apache.samza.serializers.Deserializer<T> +
      +
    • org.apache.samza.serializers.Serde<T> (also extends org.apache.samza.serializers.Serializer<T>)
    • +
    +
  • +
  • org.apache.samza.serializers.SerdeFactory<T>
  • +
  • org.apache.samza.serializers.Serializer<T> +
      +
    • org.apache.samza.serializers.Serde<T> (also extends org.apache.samza.serializers.Deserializer<T>)
    • +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/StorageEngine.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/StorageEngine.html new file mode 100644 index 0000000..7130a6b --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/StorageEngine.html @@ -0,0 +1,251 @@ + + + + + +StorageEngine (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.storage
+

Interface StorageEngine

+
+
+
+
    +
  • +
    +
    +
    public interface StorageEngine
    +
    A storage engine for managing state maintained by a stream processor. + +

    + This interface does not specify any query capabilities, which, of course, + would be query engine specific. Instead it just specifies the minimum + functionality required to reload a storage engine from its changelog as well + as basic lifecycle management. +

    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidflush() +
      Flush any cached messages
      +
      voidrestore(java.util.Iterator<IncomingMessageEnvelope> envelopes) +
      Restore the content of this StorageEngine from the changelog.
      +
      voidstop() +
      Close the storage engine
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        restore

        +
        void restore(java.util.Iterator<IncomingMessageEnvelope> envelopes)
        +
        Restore the content of this StorageEngine from the changelog. Messages are + provided in one Iterator and not deserialized for + efficiency, allowing the implementation to optimize replay, if possible.
        +
        Parameters:
        envelopes - An iterator of envelopes that the storage engine can read from to + restore its state on startup.
        +
      • +
      + + + +
        +
      • +

        flush

        +
        void flush()
        +
        Flush any cached messages
        +
      • +
      + + + +
        +
      • +

        stop

        +
        void stop()
        +
        Close the storage engine
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/StorageEngineFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/StorageEngineFactory.html new file mode 100644 index 0000000..f76c6e3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/StorageEngineFactory.html @@ -0,0 +1,225 @@ + + + + + +StorageEngineFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.storage
+

Interface StorageEngineFactory<K,V>

+
+
+
+
    +
  • +
    +
    +
    public interface StorageEngineFactory<K,V>
    +
    An object provided by the storage engine implementation to create instances + of the given storage engine type.
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getStorageEngine

        +
        StorageEngine getStorageEngine(java.lang.String storeName,
        +                             java.io.File storeDir,
        +                             Serde<K> keySerde,
        +                             Serde<V> msgSerde,
        +                             MessageCollector collector,
        +                             MetricsRegistry registry,
        +                             SystemStreamPartition changeLogSystemStreamPartition,
        +                             SamzaContainerContext containerContext)
        +
        Create an instance of the given storage engine.
        +
        Parameters:
        storeName - The name of the storage engine.
        storeDir - The directory of the storage engine.
        keySerde - The serializer to use for serializing keys when reading or writing to the store.
        msgSerde - The serializer to use for serializing messages when reading or writing to the store.
        collector - MessageCollector the storage engine uses to persist changes.
        registry - MetricsRegistry to which to publish storage-engine specific metrics.
        changeLogSystemStreamPartition - Samza stream partition from which to receive the changelog.
        containerContext - Information about the container in which the task is executing.
        +
        Returns:
        The storage engine instance.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-frame.html new file mode 100644 index 0000000..6613477 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-frame.html @@ -0,0 +1,20 @@ + + + + + +org.apache.samza.storage (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.storage

+
+

Interfaces

+ +
+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-summary.html new file mode 100644 index 0000000..701c91b --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-summary.html @@ -0,0 +1,140 @@ + + + + + +org.apache.samza.storage (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.storage

+
+
+
    +
  • + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    StorageEngine +
    A storage engine for managing state maintained by a stream processor.
    +
    StorageEngineFactory<K,V> +
    An object provided by the storage engine implementation to create instances + of the given storage engine type.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-tree.html new file mode 100644 index 0000000..52dbb1f --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/storage/package-tree.html @@ -0,0 +1,123 @@ + + + + + +org.apache.samza.storage Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.storage

+Package Hierarchies: + +
+
+

Interface Hierarchy

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/IncomingMessageEnvelope.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/IncomingMessageEnvelope.html new file mode 100644 index 0000000..5074ea4 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/IncomingMessageEnvelope.html @@ -0,0 +1,357 @@ + + + + + +IncomingMessageEnvelope (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Class IncomingMessageEnvelope

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.system.IncomingMessageEnvelope
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class IncomingMessageEnvelope
    +extends java.lang.Object
    +
    This class represents a message envelope that is received by a StreamTask for each message that is received from a + partition of a specific input stream.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      IncomingMessageEnvelope(SystemStreamPartition systemStreamPartition, + java.lang.String offset, + java.lang.Object key, + java.lang.Object message) +
      Constructs a new IncomingMessageEnvelope from specified components.
      +
      +
    • +
    + + +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IncomingMessageEnvelope

        +
        public IncomingMessageEnvelope(SystemStreamPartition systemStreamPartition,
        +                       java.lang.String offset,
        +                       java.lang.Object key,
        +                       java.lang.Object message)
        +
        Constructs a new IncomingMessageEnvelope from specified components.
        +
        Parameters:
        systemStreamPartition - The aggregate object representing the incoming stream name, the name of the cluster + from which the stream came, and the partition of the stream from which the message was received.
        offset - The offset in the partition that the message was received from.
        key - A deserialized key received from the partition offset.
        message - A deserialized message received from the partition offset.
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        getOffset

        +
        public java.lang.String getOffset()
        +
      • +
      + + + +
        +
      • +

        getKey

        +
        public java.lang.Object getKey()
        +
      • +
      + + + +
        +
      • +

        getMessage

        +
        public java.lang.Object getMessage()
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object obj)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html new file mode 100644 index 0000000..6b2092c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html @@ -0,0 +1,447 @@ + + + + + +OutgoingMessageEnvelope (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Class OutgoingMessageEnvelope

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.system.OutgoingMessageEnvelope
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class OutgoingMessageEnvelope
    +extends java.lang.Object
    +
    An OutgoingMessageEnvelope is sent to a specified SystemStream via the appropriate SystemProducer + from the user's StreamTask. StreamTasks consume from their input streams via their + process method and write to their output streams by sending OutgoingMessageEnvelopes via the provided MessageCollector
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + + + + + + + + + + +
      Constructors 
      Constructor and Description
      OutgoingMessageEnvelope(SystemStream systemStream, + java.lang.Object message) +
      Constructs a new OutgoingMessageEnvelope from specified components.
      +
      OutgoingMessageEnvelope(SystemStream systemStream, + java.lang.Object key, + java.lang.Object message) +
      Constructs a new OutgoingMessageEnvelope from specified components.
      +
      OutgoingMessageEnvelope(SystemStream systemStream, + java.lang.Object partitionKey, + java.lang.Object key, + java.lang.Object message) +
      Constructs a new OutgoingMessageEnvelope from specified components.
      +
      OutgoingMessageEnvelope(SystemStream systemStream, + java.lang.String keySerializerName, + java.lang.String messageSerializerName, + java.lang.Object partitionKey, + java.lang.Object key, + java.lang.Object message) +
      Constructs a new OutgoingMessageEnvelope from specified components.
      +
      +
    • +
    + + +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        OutgoingMessageEnvelope

        +
        public OutgoingMessageEnvelope(SystemStream systemStream,
        +                       java.lang.String keySerializerName,
        +                       java.lang.String messageSerializerName,
        +                       java.lang.Object partitionKey,
        +                       java.lang.Object key,
        +                       java.lang.Object message)
        +
        Constructs a new OutgoingMessageEnvelope from specified components.
        +
        Parameters:
        systemStream - Object representing the appropriate stream of which this envelope will be sent on.
        keySerializerName - String representing the serializer used for serializing this envelope's key.
        messageSerializerName - String representing the serializer used for serializing this envelope's message.
        partitionKey - A key representing which partition of the systemStream to send this envelope on.
        key - A deserialized key to be used for the message.
        message - A deserialized message to be sent in this envelope.
        +
      • +
      + + + +
        +
      • +

        OutgoingMessageEnvelope

        +
        public OutgoingMessageEnvelope(SystemStream systemStream,
        +                       java.lang.Object partitionKey,
        +                       java.lang.Object key,
        +                       java.lang.Object message)
        +
        Constructs a new OutgoingMessageEnvelope from specified components.
        +
        Parameters:
        systemStream - Object representing the appropriate stream of which this envelope will be sent on.
        partitionKey - A key representing which partition of the systemStream to send this envelope on.
        key - A deserialized key to be used for the message.
        message - A deserialized message to be sent in this envelope.
        +
      • +
      + + + +
        +
      • +

        OutgoingMessageEnvelope

        +
        public OutgoingMessageEnvelope(SystemStream systemStream,
        +                       java.lang.Object key,
        +                       java.lang.Object message)
        +
        Constructs a new OutgoingMessageEnvelope from specified components.
        +
        Parameters:
        systemStream - Object representing the appropriate stream of which this envelope will be sent on.
        key - A deserialized key to be used for the message.
        message - A deserialized message to be sent in this envelope.
        +
      • +
      + + + +
        +
      • +

        OutgoingMessageEnvelope

        +
        public OutgoingMessageEnvelope(SystemStream systemStream,
        +                       java.lang.Object message)
        +
        Constructs a new OutgoingMessageEnvelope from specified components.
        +
        Parameters:
        systemStream - Object representing the appropriate stream of which this envelope will be sent on.
        message - A deserialized message to be sent in this envelope.
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getSystemStream

        +
        public SystemStream getSystemStream()
        +
      • +
      + + + +
        +
      • +

        getKeySerializerName

        +
        public java.lang.String getKeySerializerName()
        +
      • +
      + + + +
        +
      • +

        getMessageSerializerName

        +
        public java.lang.String getMessageSerializerName()
        +
      • +
      + + + +
        +
      • +

        getPartitionKey

        +
        public java.lang.Object getPartitionKey()
        +
      • +
      + + + +
        +
      • +

        getKey

        +
        public java.lang.Object getKey()
        +
      • +
      + + + +
        +
      • +

        getMessage

        +
        public java.lang.Object getMessage()
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object obj)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemAdmin.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemAdmin.html new file mode 100644 index 0000000..00db100 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemAdmin.html @@ -0,0 +1,239 @@ + + + + + +SystemAdmin (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Interface SystemAdmin

+
+
+
+
    +
  • +
    +
    All Known Implementing Classes:
    +
    SinglePartitionWithoutOffsetsSystemAdmin
    +
    +
    +
    +
    public interface SystemAdmin
    +
    Helper interface attached to an underlying system to fetch + information about streams, partitions, offsets, etc. This interface is useful + for providing utility methods that Samza needs in order to interact with a + system.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      java.util.Map<SystemStreamPartition,java.lang.String>getOffsetsAfter(java.util.Map<SystemStreamPartition,java.lang.String> offsets) +
      Fetches the offsets for the messages immediately after the supplied offsets + for a group of SystemStreamPartitions.
      +
      java.util.Map<java.lang.String,SystemStreamMetadata>getSystemStreamMetadata(java.util.Set<java.lang.String> streamNames) +
      Fetch metadata from a system for a set of streams.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getOffsetsAfter

        +
        java.util.Map<SystemStreamPartition,java.lang.String> getOffsetsAfter(java.util.Map<SystemStreamPartition,java.lang.String> offsets)
        +
        Fetches the offsets for the messages immediately after the supplied offsets + for a group of SystemStreamPartitions.
        +
        Parameters:
        offsets - Map from SystemStreamPartition to current offsets.
        +
        Returns:
        Map from SystemStreamPartition to offsets immediately after the + current offsets.
        +
      • +
      + + + +
        +
      • +

        getSystemStreamMetadata

        +
        java.util.Map<java.lang.String,SystemStreamMetadata> getSystemStreamMetadata(java.util.Set<java.lang.String> streamNames)
        +
        Fetch metadata from a system for a set of streams.
        +
        Parameters:
        streamNames - The streams to to fetch metadata for.
        +
        Returns:
        A map from stream name to SystemStreamMetadata for each stream + requested in the parameter set.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemConsumer.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemConsumer.html new file mode 100644 index 0000000..eaab313 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemConsumer.html @@ -0,0 +1,428 @@ + + + + + +SystemConsumer (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Interface SystemConsumer

+
+
+
+
    +
  • +
    +
    All Known Implementing Classes:
    +
    BlockingEnvelopeMap
    +
    +
    +
    +
    public interface SystemConsumer
    +

    + SystemConsumer is the interface that must be implemented by any system that + wishes to integrate with Samza. Examples of systems that one might want to + integrate would be systems like Kafka, Hadoop, Kestrel, SQS, etc. +

    + +

    + SamzaContainer uses SystemConsumer to read messages from the underlying + system, and funnels the messages to the appropriate StreamTask instances. The + basic flow is for the SamzaContainer to poll for all SystemStreamPartitions, + feed all IncomingMessageEnvelopes to the appropriate StreamTask, and then + repeat. If no IncomingMessageEnvelopes are returned, the SamzaContainer polls + again, but with a timeout of 10ms. +

    + +

    + The SamzaContainer treats SystemConsumer in the following way: +

    + +
      +
    • Start will be called before stop.
    • +
    • Register will be called one or more times before start.
    • +
    • Register won't be called twice for the same SystemStreamPartition.
    • +
    • If timeout < 0, poll will block unless all SystemStreamPartition are at + "head" (the underlying system has been checked, and returned an empty set). + If at head, an empty list is returned.
    • +
    • If timeout >= 0, poll will return any messages that are currently + available for any of the SystemStreamPartitions specified. If no new messages + are available, it will wait up to timeout milliseconds for messages from any + SystemStreamPartition to become available. It will return an empty list if + the timeout is hit, and no new messages are available.
    • +
    • Nothing will be called after stop has been invoked.
    • +
    • Poll will only be called for registered SystemStreamPartition.
    • +
    • The SystemConsumer can't assume that a given SystemStreamPartition's + messages will ever be read. It shouldn't run out of memory or deadlock all + new message arrivals if one SystemStreamPartition is never read from.
    • +
    • Any exception thrown by the SystemConsumer means that the SamzaContainer + should halt.
    • +
    + +

    + There are generally three implementation styles to this interface: +

    + +
      +
    1. Thread-based
    2. +
    3. Selector-based
    4. +
    5. Synchronous
    6. +
    + +

    + Thread-based implementations typically use a series of threads to read from + an underlying system asynchronously, and put the resulting messages into a + queue, which is then read from whenever the poll method is invoked. The poll + method's parameters map very closely to Java's BlockingQueue interface. + BlockingEnvelopeMap is a helper class that makes it easy to implement + thread-based implementations of SystemConsumer. +

    + +

    + Selector-based implementations typically setup NIO-based non-blocking socket + that can be selected for new data when poll is called. +

    + +

    + Synchronous implementations simply fetch directly from the underlying system + whenever poll is invoked. Synchronous implementations must take great care to + adhere to the timeout rules defined in the poll method. +

    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Field Summary

      + + + + + + + + + + +
      Fields 
      Modifier and TypeField and Description
      static intBLOCK_ON_OUTSTANDING_MESSAGES +
      A constant that can be used in the poll method's timeout parameter to + denote that the poll invocation should block until at least one message is + available for one of the SystemStreamPartitions supplied, or until all + SystemStreamPartitions supplied are at head (have no new messages available + since the last poll invocation was made for each SystemStreamPartition).
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      java.util.Map<SystemStreamPartition,java.util.List<IncomingMessageEnvelope>>poll(java.util.Set<SystemStreamPartition> systemStreamPartitions, + long timeout) +
      Poll the SystemConsumer to get any available messages from the underlying + system.
      +
      voidregister(SystemStreamPartition systemStreamPartition, + java.lang.String offset) +
      Register a SystemStreamPartition to this SystemConsumer.
      +
      voidstart() +
      Tells the SystemConsumer to connect to the underlying system, and prepare + to begin serving messages when poll is invoked.
      +
      voidstop() +
      Tells the SystemConsumer to close all connections, release all resource, + and shut down everything.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        BLOCK_ON_OUTSTANDING_MESSAGES

        +
        static final int BLOCK_ON_OUTSTANDING_MESSAGES
        +
        A constant that can be used in the poll method's timeout parameter to + denote that the poll invocation should block until at least one message is + available for one of the SystemStreamPartitions supplied, or until all + SystemStreamPartitions supplied are at head (have no new messages available + since the last poll invocation was made for each SystemStreamPartition).
        +
        See Also:
        Constant Field Values
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        start

        +
        void start()
        +
        Tells the SystemConsumer to connect to the underlying system, and prepare + to begin serving messages when poll is invoked.
        +
      • +
      + + + +
        +
      • +

        stop

        +
        void stop()
        +
        Tells the SystemConsumer to close all connections, release all resource, + and shut down everything. The SystemConsumer will not be used again after + stop is called.
        +
      • +
      + + + +
        +
      • +

        register

        +
        void register(SystemStreamPartition systemStreamPartition,
        +            java.lang.String offset)
        +
        Register a SystemStreamPartition to this SystemConsumer. The SystemConsumer + should try and read messages from all SystemStreamPartitions that are + registered to it. SystemStreamPartitions should only be registered before + start is called.
        +
        Parameters:
        systemStreamPartition - The SystemStreamPartition object representing the Samza + SystemStreamPartition to receive messages from.
        offset - String representing the offset of the point in the stream to start + reading messages from. This is an inclusive parameter; if "7" were + specified, the first message for the system/stream/partition to be + consumed and returned would be a message whose offset is "7".
        +
      • +
      + + + +
        +
      • +

        poll

        +
        java.util.Map<SystemStreamPartition,java.util.List<IncomingMessageEnvelope>> poll(java.util.Set<SystemStreamPartition> systemStreamPartitions,
        +                                                                                long timeout)
        +                                                                                  throws java.lang.InterruptedException
        +
        Poll the SystemConsumer to get any available messages from the underlying + system. + +

        + If the underlying implementation does not take care to adhere to the + timeout parameter, the SamzaContainer's performance will suffer + drastically. Specifically, if poll blocks when it's not supposed to, it + will block the entire main thread in SamzaContainer, and no messages will + be processed while blocking is occurring. +

        +
        Parameters:
        systemStreamPartitions - A set of SystemStreamPartition to poll for new messages. If + SystemConsumer has messages available for other registered + SystemStreamPartitions, but they are not in the + systemStreamPartitions set in a given poll invocation, they can't + be returned. It is illegal to pass in SystemStreamPartitions that + have not been registered with the SystemConsumer first.
        timeout - If timeout < 0, poll will block unless all SystemStreamPartition + are at "head" (the underlying system has been checked, and + returned an empty set). If at head, an empty map is returned. If + timeout >= 0, poll will return any messages that are currently + available for any of the SystemStreamPartitions specified. If no + new messages are available, it will wait up to timeout + milliseconds for messages from any SystemStreamPartition to become + available. It will return an empty map if the timeout is hit, and + no new messages are available.
        +
        Returns:
        A map from SystemStreamPartitions to any available + IncomingMessageEnvelopes for the SystemStreamPartitions. If no + messages are available for a SystemStreamPartition that was + supplied in the polling set, the map will not contain a key for the + SystemStreamPartition. Will return an empty map, not null, if no + new messages are available for any SystemStreamPartitions in the + input set.
        +
        Throws:
        +
        java.lang.InterruptedException - Thrown when a blocking poll has been interrupted by another + thread.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemFactory.html new file mode 100644 index 0000000..2427879 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemFactory.html @@ -0,0 +1,242 @@ + + + + + +SystemFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Interface SystemFactory

+
+
+
+ +
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemProducer.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemProducer.html new file mode 100644 index 0000000..07dcbfe --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemProducer.html @@ -0,0 +1,282 @@ + + + + + +SystemProducer (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Interface SystemProducer

+
+
+
+
    +
  • +
    +
    +
    public interface SystemProducer
    +
    SystemProducers are how Samza writes messages from StreamTasks to outside systems, + such as messaging systems like Kafka, or file systems. Implementations are responsible for accepting messages + and writing them to their backing systems.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidflush(java.lang.String source) +
      If the SystemProducer buffers messages before sending them to its underlying system, it should flush those + messages and leave no messages remaining to be sent.
      +
      voidregister(java.lang.String source) +
      Registers this producer to send messages from a specified Samza source, such as a StreamTask.
      +
      voidsend(java.lang.String source, + OutgoingMessageEnvelope envelope) +
      Sends a specified message envelope from a specified Samza source.
      +
      voidstart() +
      Start the SystemProducer.
      +
      voidstop() +
      Stop the SystemProducer.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        start

        +
        void start()
        +
        Start the SystemProducer. After this method finishes it should be ready to accept messages received from the send method.
        +
      • +
      + + + +
        +
      • +

        stop

        +
        void stop()
        +
        Stop the SystemProducer. After this method finished, the system should have completed all necessary work, sent + any remaining messages and will not receive any new calls to the send method.
        +
      • +
      + + + +
        +
      • +

        register

        +
        void register(java.lang.String source)
        +
        Registers this producer to send messages from a specified Samza source, such as a StreamTask.
        +
        Parameters:
        source - String representing the source of the message.
        +
      • +
      + + + +
        +
      • +

        send

        +
        void send(java.lang.String source,
        +        OutgoingMessageEnvelope envelope)
        +
        Sends a specified message envelope from a specified Samza source.
        +
        Parameters:
        source - String representing the source of the message.
        envelope - Aggregate object representing the serialized message to send from the source.
        +
      • +
      + + + +
        +
      • +

        flush

        +
        void flush(java.lang.String source)
        +
        If the SystemProducer buffers messages before sending them to its underlying system, it should flush those + messages and leave no messages remaining to be sent.
        +
        Parameters:
        source - String representing the source of the message.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStream.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStream.html new file mode 100644 index 0000000..61f18e7 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStream.html @@ -0,0 +1,398 @@ + + + + + +SystemStream (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Class SystemStream

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.system.SystemStream
    • +
    +
  • +
+
+
    +
  • +
    +
    Direct Known Subclasses:
    +
    SystemStreamPartition
    +
    +
    +
    +
    public class SystemStream
    +extends java.lang.Object
    +
    Streams in Samza consist of both the stream name and the system to which the stream belongs. + Systems are defined through the job config and have corresponding serdes, producers and + consumers in order to deserialize, send to and retrieve from them. A stream name is dependent + on its system, and may be the topic, queue name, file name, etc. as makes sense for a + particular system.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Field Summary

      + + + + + + + + + + + + + + +
      Fields 
      Modifier and TypeField and Description
      protected java.lang.Stringstream 
      protected java.lang.Stringsystem 
      +
    • +
    + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + + + + +
      Constructors 
      Constructor and Description
      SystemStream(java.lang.String system, + java.lang.String stream) +
      Constructs a Samza stream object from specified components.
      +
      SystemStream(SystemStream other) +
      Constructs a Samza stream object based upon an existing Samza stream.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      booleanequals(java.lang.Object obj) 
      java.lang.StringgetStream() 
      java.lang.StringgetSystem() 
      inthashCode() 
      java.lang.StringtoString() 
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, finalize, getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        system

        +
        protected final java.lang.String system
        +
      • +
      + + + +
        +
      • +

        stream

        +
        protected final java.lang.String stream
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        SystemStream

        +
        public SystemStream(java.lang.String system,
        +            java.lang.String stream)
        +
        Constructs a Samza stream object from specified components.
        +
        Parameters:
        system - The name of the system of which this stream is associated with.
        stream - The name of the stream as specified in the stream configuration file.
        +
      • +
      + + + +
        +
      • +

        SystemStream

        +
        public SystemStream(SystemStream other)
        +
        Constructs a Samza stream object based upon an existing Samza stream.
        +
        Parameters:
        other - Reference to an already existing Samza stream.
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getSystem

        +
        public java.lang.String getSystem()
        +
      • +
      + + + +
        +
      • +

        getStream

        +
        public java.lang.String getStream()
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object obj)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.OffsetType.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.OffsetType.html new file mode 100644 index 0000000..8975b59 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.OffsetType.html @@ -0,0 +1,348 @@ + + + + + +SystemStreamMetadata.OffsetType (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Enum SystemStreamMetadata.OffsetType

+
+
+ +
+ +
+
+
    +
  • + +
      +
    • + + +

      Enum Constant Summary

      + + + + + + + + + + + + + + +
      Enum Constants 
      Enum Constant and Description
      NEWEST +
      Signals the offset of the newest message in a SystemStreamPartition.
      +
      OLDEST +
      Signals the offset of the oldest message in a SystemStreamPartition.
      +
      UPCOMING +
      Signals the offset of the next message to be written into a + SystemStreamPartition.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      static SystemStreamMetadata.OffsetTypevalueOf(java.lang.String name) +
      Returns the enum constant of this type with the specified name.
      +
      static SystemStreamMetadata.OffsetType[]values() +
      Returns an array containing the constants of this enum type, in +the order they are declared.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Enum

        +clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
      • +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Enum Constant Detail

      + + + + + + + + + + + +
        +
      • +

        UPCOMING

        +
        public static final SystemStreamMetadata.OffsetType UPCOMING
        +
        Signals the offset of the next message to be written into a + SystemStreamPartition. If the offset of the most recent message written + to a SystemStreamPartition is 7, then upcoming would signal offset 8 + (assuming the offsets were incremental).
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        values

        +
        public static SystemStreamMetadata.OffsetType[] values()
        +
        Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
        +for (SystemStreamMetadata.OffsetType c : SystemStreamMetadata.OffsetType.values())
        +    System.out.println(c);
        +
        +
        Returns:
        an array containing the constants of this enum type, in the order they are declared
        +
      • +
      + + + +
        +
      • +

        valueOf

        +
        public static SystemStreamMetadata.OffsetType valueOf(java.lang.String name)
        +
        Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
        +
        Parameters:
        name - the name of the enum constant to be returned.
        +
        Returns:
        the enum constant with the specified name
        +
        Throws:
        +
        java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
        +
        java.lang.NullPointerException - if the argument is null
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.SystemStreamPartitionMetadata.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.SystemStreamPartitionMetadata.html new file mode 100644 index 0000000..28463d0 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.SystemStreamPartitionMetadata.html @@ -0,0 +1,374 @@ + + + + + +SystemStreamMetadata.SystemStreamPartitionMetadata (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Class SystemStreamMetadata.SystemStreamPartitionMetadata

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.system.SystemStreamMetadata.SystemStreamPartitionMetadata
    • +
    +
  • +
+
+
    +
  • +
    +
    Enclosing class:
    +
    SystemStreamMetadata
    +
    +
    +
    +
    public static class SystemStreamMetadata.SystemStreamPartitionMetadata
    +extends java.lang.Object
    +
    Provides offset information for a given SystemStreamPartition. This + currently only includes offset information.
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        SystemStreamMetadata.SystemStreamPartitionMetadata

        +
        public SystemStreamMetadata.SystemStreamPartitionMetadata(java.lang.String oldestOffset,
        +                                                  java.lang.String newestOffset,
        +                                                  java.lang.String upcomingOffset)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getOldestOffset

        +
        public java.lang.String getOldestOffset()
        +
        Returns:
        The oldest offset that still exists in the stream for the + partition given. If a partition has two messages with offsets 0 + and 1, respectively, then this method would return 0 for the + oldest offset. This offset is useful when one wishes to read all + messages in a stream from the very beginning. A null value means + the stream is empty.
        +
      • +
      + + + +
        +
      • +

        getNewestOffset

        +
        public java.lang.String getNewestOffset()
        +
        Returns:
        The newest offset that exists in the stream for the partition + given. If a partition has two messages with offsets 0 and 1, + respectively, then this method would return 1 for the newest + offset. This offset is useful when one wishes to see if all + messages have been read from a stream (offset of last message + read == newest offset). A null value means the stream is empty.
        +
      • +
      + + + +
        +
      • +

        getUpcomingOffset

        +
        public java.lang.String getUpcomingOffset()
        +
        Returns:
        The offset that represents the next message to be written in the + stream for the partition given. If a partition has two messages + with offsets 0 and 1, respectively, then this method would return + 2 for the upcoming offset. This offset is useful when one wishes + to pick up reading at the very end of a stream. A null value + means the stream is empty.
        +
      • +
      + + + +
        +
      • +

        getOffset

        +
        public java.lang.String getOffset(SystemStreamMetadata.OffsetType offsetType)
        +
        Parameters:
        offsetType - The type of offset to get. Either oldest, newest, or upcoming.
        +
        Returns:
        The corresponding offset for the offset type requested.
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object obj)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.html new file mode 100644 index 0000000..b9838bc --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamMetadata.html @@ -0,0 +1,354 @@ + + + + + +SystemStreamMetadata (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Class SystemStreamMetadata

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.system.SystemStreamMetadata
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class SystemStreamMetadata
    +extends java.lang.Object
    +
    SystemAdmins use this class to return useful metadata about a stream's offset + and partition information.
    +
  • +
+
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getStreamName

        +
        public java.lang.String getStreamName()
        +
        Returns:
        The stream name that's associated with the metadata contained in an + instance of this class.
        +
      • +
      + + + + + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(java.lang.Object obj)
        +
        +
        Overrides:
        +
        equals in class java.lang.Object
        +
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public java.lang.String toString()
        +
        +
        Overrides:
        +
        toString in class java.lang.Object
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamPartition.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamPartition.html new file mode 100644 index 0000000..5097c9f --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamPartition.html @@ -0,0 +1,451 @@ + + + + + +SystemStreamPartition (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Class SystemStreamPartition

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        partition

        +
        protected final Partition partition
        +
      • +
      + + + +
        +
      • +

        hash

        +
        protected final int hash
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        SystemStreamPartition

        +
        public SystemStreamPartition(java.lang.String system,
        +                     java.lang.String stream,
        +                     Partition partition)
        +
        Constructs a Samza stream partition object from specified components.
        +
        Parameters:
        system - The name of the system of which this stream is associated with.
        stream - The name of the stream as specified in the stream configuration file.
        partition - The partition in the stream of which this object is associated with.
        +
      • +
      + + + +
        +
      • +

        SystemStreamPartition

        +
        public SystemStreamPartition(SystemStreamPartition other)
        +
        Constructs a Samza stream partition object based upon an existing Samza stream partition.
        +
        Parameters:
        other - Reference to an already existing Samza stream partition.
        +
      • +
      + + + +
        +
      • +

        SystemStreamPartition

        +
        public SystemStreamPartition(SystemStream other,
        +                     Partition partition)
        +
        Constructs a Samza stream partition object based upon another Samza stream and a specified partition.
        +
        Parameters:
        other - Reference to an already existing Samza stream.
        partition - Reference to an already existing Samza partition.
        +
      • +
      +
    • +
    + + +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamPartitionIterator.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamPartitionIterator.html new file mode 100644 index 0000000..2f251c2 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/SystemStreamPartitionIterator.html @@ -0,0 +1,319 @@ + + + + + +SystemStreamPartitionIterator (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system
+

Class SystemStreamPartitionIterator

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.system.SystemStreamPartitionIterator
    • +
    +
  • +
+
+ +
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/BaseMessageChooser.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/BaseMessageChooser.html new file mode 100644 index 0000000..c3ca4a5 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/BaseMessageChooser.html @@ -0,0 +1,329 @@ + + + + + +BaseMessageChooser (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system.chooser
+

Class BaseMessageChooser

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.system.chooser.BaseMessageChooser
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    MessageChooser
    +
    +
    +
    +
    public abstract class BaseMessageChooser
    +extends java.lang.Object
    +implements MessageChooser
    +
    An abstract MessageChooser that implements start/stop/register for choosers + that don't use them.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + +
      Constructors 
      Constructor and Description
      BaseMessageChooser() 
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidregister(SystemStreamPartition systemStreamPartition, + java.lang.String offset) +
      Called before start, to let the chooser know that it will be handling + envelopes from the given SystemStreamPartition.
      +
      voidstart() +
      Called after all SystemStreamPartitions have been registered.
      +
      voidstop() +
      Called when the chooser is about to be discarded.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      + +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        BaseMessageChooser

        +
        public BaseMessageChooser()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        start

        +
        public void start()
        +
        Description copied from interface: MessageChooser
        +
        Called after all SystemStreamPartitions have been registered. Start is used + to notify the chooser that it will start receiving update and choose calls.
        +
        +
        Specified by:
        +
        start in interface MessageChooser
        +
        +
      • +
      + + + +
        +
      • +

        stop

        +
        public void stop()
        +
        Description copied from interface: MessageChooser
        +
        Called when the chooser is about to be discarded. No more messages will be + given to the chooser after it is stopped.
        +
        +
        Specified by:
        +
        stop in interface MessageChooser
        +
        +
      • +
      + + + +
        +
      • +

        register

        +
        public void register(SystemStreamPartition systemStreamPartition,
        +            java.lang.String offset)
        +
        Description copied from interface: MessageChooser
        +
        Called before start, to let the chooser know that it will be handling + envelopes from the given SystemStreamPartition. Register will only be + called before start.
        +
        +
        Specified by:
        +
        register in interface MessageChooser
        +
        Parameters:
        systemStreamPartition - A SystemStreamPartition that envelopes will be coming from.
        offset - The offset of the first message expected for the + system/stream/partition that's being registered. If "7" were + supplied as the offset, then the MessageChooser can expect the + first message it is updated with for the system/stream/partition + will have an offset of "7".
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/MessageChooser.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/MessageChooser.html new file mode 100644 index 0000000..3c1aafa --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/MessageChooser.html @@ -0,0 +1,350 @@ + + + + + +MessageChooser (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system.chooser
+

Interface MessageChooser

+
+
+
+
    +
  • +
    +
    All Known Implementing Classes:
    +
    BaseMessageChooser
    +
    +
    +
    +
    public interface MessageChooser
    +
    MessageChooser is an interface for programmatic fine-grain control over + stream consumption. + +

    Consider the case of a Samza task consuming multiple streams, where some + streams may be from live systems that have stricter SLA requirements and must + always be prioritized over other streams that may be from batch systems. + MessageChooser allows developers to inject message prioritization logic into + the SamzaContainer. + +

    In general, the MessageChooser can be used to prioritize certain systems, + streams or partitions over others. It can also be used to throttle certain + partitions, by choosing not to return messages even though they are + available. The MessageChooser can also throttle the entire SamzaContainer by + performing a blocking operation, such as Thread.sleep. + +

    The manner in which MessageChooser is used is: + +

      +
    • SystemConsumers buffer messages from all SystemStreamPartitions as they + become available.
    • +
    • If MessageChooser has no messages for a given SystemStreamPartition, and + a SystemConsumer has a message in its buffer for the SystemStreamPartition, + the MessageChooser will be updated once with the next message in the buffer.
    • +
    • When SamzaContainer is ready to process another message, it calls + SystemConsumers.choose, which in turn calls choose().
    • +
    + +

    Since the MessageChooser only receives one message at a time per + SystemStreamPartition, it can be used to order messages between different + SystemStreamPartitions, but it can't be used to re-order messages within a + single SystemStreamPartition (a buffered sort). This must be done within a + StreamTask. + +

    The contract between the MessageChooser and the SystemConsumers is: + +

      +
    • update(IncomingMessageEnvelope) can be called multiple times + before choose() is called.
    • +
    • If choose() returns null, that means no envelopes should be + processed at the moment.
    • +
    • A MessageChooser may elect to return null when choose() is + called, even if unprocessed messages have been given by the update method.
    • +
    • A MessageChooser will not have any of its in-memory state restored in the + event of a failure.
    • +
    • Blocking operations (such as Thread.sleep) will block all processing in + the entire SamzaContainer.
    • +
    • A MessageChooser should never return the same envelope more than once.
    • +
    • Non-deterministic (e.g. time-based) MessageChoosers are allowed.
    • +
    • A MessageChooser does not need to be thread-safe.
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      IncomingMessageEnvelopechoose() +
      The choose method is invoked when the SamzaContainer is ready to process a + new message.
      +
      voidregister(SystemStreamPartition systemStreamPartition, + java.lang.String offset) +
      Called before start, to let the chooser know that it will be handling + envelopes from the given SystemStreamPartition.
      +
      voidstart() +
      Called after all SystemStreamPartitions have been registered.
      +
      voidstop() +
      Called when the chooser is about to be discarded.
      +
      voidupdate(IncomingMessageEnvelope envelope) +
      Notify the chooser that a new envelope is available for a processing.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        start

        +
        void start()
        +
        Called after all SystemStreamPartitions have been registered. Start is used + to notify the chooser that it will start receiving update and choose calls.
        +
      • +
      + + + +
        +
      • +

        stop

        +
        void stop()
        +
        Called when the chooser is about to be discarded. No more messages will be + given to the chooser after it is stopped.
        +
      • +
      + + + +
        +
      • +

        register

        +
        void register(SystemStreamPartition systemStreamPartition,
        +            java.lang.String offset)
        +
        Called before start, to let the chooser know that it will be handling + envelopes from the given SystemStreamPartition. Register will only be + called before start.
        +
        Parameters:
        systemStreamPartition - A SystemStreamPartition that envelopes will be coming from.
        offset - The offset of the first message expected for the + system/stream/partition that's being registered. If "7" were + supplied as the offset, then the MessageChooser can expect the + first message it is updated with for the system/stream/partition + will have an offset of "7".
        +
      • +
      + + + +
        +
      • +

        update

        +
        void update(IncomingMessageEnvelope envelope)
        +
        Notify the chooser that a new envelope is available for a processing. A + MessageChooser will receive, at most, one outstanding envelope per + system/stream/partition combination. For example, if update is called for + partition 7 of kafka.mystream, then update will not be called with an + envelope from partition 7 of kafka.mystream until the previous envelope has + been returned via the choose method. Update will only be invoked after the + chooser has been started.
        +
        Parameters:
        envelope - An unprocessed envelope.
        +
      • +
      + + + +
        +
      • +

        choose

        +
        IncomingMessageEnvelope choose()
        +
        The choose method is invoked when the SamzaContainer is ready to process a + new message. The chooser may elect to return any envelope that it's been + given via the update method, which hasn't yet been returned. Choose will + only be called after the chooser has been started.
        +
        Returns:
        The next envelope to process, or null if the chooser has no + messages or doesn't want to process any at the moment.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/MessageChooserFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/MessageChooserFactory.html new file mode 100644 index 0000000..2df5449 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/MessageChooserFactory.html @@ -0,0 +1,207 @@ + + + + + +MessageChooserFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.system.chooser
+

Interface MessageChooserFactory

+
+
+
+
    +
  • +
    +
    +
    public interface MessageChooserFactory
    +
    Build an instance of a MessageChooser
    +
  • +
+
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-frame.html new file mode 100644 index 0000000..91a30b9 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-frame.html @@ -0,0 +1,24 @@ + + + + + +org.apache.samza.system.chooser (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.system.chooser

+
+

Interfaces

+ +

Classes

+ +
+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-summary.html new file mode 100644 index 0000000..446a371 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-summary.html @@ -0,0 +1,158 @@ + + + + + +org.apache.samza.system.chooser (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.system.chooser

+
+
+
    +
  • + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    MessageChooser +
    MessageChooser is an interface for programmatic fine-grain control over + stream consumption.
    +
    MessageChooserFactory +
    Build an instance of a MessageChooser
    +
    +
  • +
  • + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    BaseMessageChooser +
    An abstract MessageChooser that implements start/stop/register for choosers + that don't use them.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-tree.html new file mode 100644 index 0000000..bb0a4f5 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/chooser/package-tree.html @@ -0,0 +1,131 @@ + + + + + +org.apache.samza.system.chooser Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.system.chooser

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +

Interface Hierarchy

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-frame.html new file mode 100644 index 0000000..71e77d6 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-frame.html @@ -0,0 +1,36 @@ + + + + + +org.apache.samza.system (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.system

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-summary.html new file mode 100644 index 0000000..1d7c2f6 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-summary.html @@ -0,0 +1,233 @@ + + + + + +org.apache.samza.system (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.system

+
+
+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-tree.html new file mode 100644 index 0000000..039da6c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/system/package-tree.html @@ -0,0 +1,154 @@ + + + + + +org.apache.samza.system Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.system

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +

Interface Hierarchy

+ +

Enum Hierarchy

+
    +
  • java.lang.Object + +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/ClosableTask.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/ClosableTask.html new file mode 100644 index 0000000..c8708aa --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/ClosableTask.html @@ -0,0 +1,211 @@ + + + + + +ClosableTask (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface ClosableTask

+
+
+
+
    +
  • +
    +
    +
    public interface ClosableTask
    +
    A ClosableTask augments StreamTask, allowing the method implementer to specify + code that will be called when the StreamTask is being shut down by the framework, providing to emit final metrics, + clean or close resources, etc. The close method is not guaranteed to be called in event of crash or hard kill + of the process.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidclose() 
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        close

        +
        void close()
        +           throws java.lang.Exception
        +
        Throws:
        +
        java.lang.Exception
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/InitableTask.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/InitableTask.html new file mode 100644 index 0000000..6fa7e8c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/InitableTask.html @@ -0,0 +1,215 @@ + + + + + +InitableTask (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface InitableTask

+
+
+
+
    +
  • +
    +
    +
    public interface InitableTask
    +
    Used as an interface for user processing StreamTasks that need to have specific functionality performed as their StreamTasks + are instantiated by TaskRunner.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidinit(Config config, + TaskContext context) +
      Called by TaskRunner each time an implementing task is created.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        init

        +
        void init(Config config,
        +        TaskContext context)
        +          throws java.lang.Exception
        +
        Called by TaskRunner each time an implementing task is created.
        +
        Parameters:
        config - Allows accessing of fields in the configuration files that this StreamTask is specified in.
        context - Allows accessing of contextual data of this StreamTask.
        +
        Throws:
        +
        java.lang.Exception - Any exception types encountered during the execution of the processing task.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/MessageCollector.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/MessageCollector.html new file mode 100644 index 0000000..f241b70 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/MessageCollector.html @@ -0,0 +1,213 @@ + + + + + +MessageCollector (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface MessageCollector

+
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidsend(OutgoingMessageEnvelope envelope) +
      Sends message envelope out onto specified stream.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        send

        +
        void send(OutgoingMessageEnvelope envelope)
        +
        Sends message envelope out onto specified stream.
        +
        Parameters:
        envelope - Self contained envelope containing message, key and specified stream to be sent to.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/StreamTask.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/StreamTask.html new file mode 100644 index 0000000..4e909b3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/StreamTask.html @@ -0,0 +1,229 @@ + + + + + +StreamTask (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface StreamTask

+
+
+
+
    +
  • +
    +
    +
    public interface StreamTask
    +
    A StreamTask is the basic class on which Samza jobs are implemented. Developers writing Samza jobs begin by + implementing this class, which processes messages from the job's input streams and writes messages out to + streams via the provided MessageCollector. A StreamTask may be augmented by + implementing other interfaces, such as InitableTask, WindowableTask, + or ClosableTask. +

    + The methods of StreamTasks and associated other tasks are guaranteed to be called in a single-threaded fashion; + no extra synchronization is necessary on the part of the class implementer. References to instances of + IncomingMessageEnvelopes,MessageCollectors, and + TaskCoordinator should not be held onto between calls; there is no guarantee that + these will not be invalidated or otherwise used by the framework.

    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        process

        +
        void process(IncomingMessageEnvelope envelope,
        +           MessageCollector collector,
        +           TaskCoordinator coordinator)
        +             throws java.lang.Exception
        +
        Called once for each message that this StreamTask receives.
        +
        Parameters:
        envelope - Contains the received deserialized message and key, and also information regarding the stream and + partition of which the message was received from.
        collector - Contains the means of sending message envelopes to the output stream. The collector must only + be used during the current call to the process method; you should not reuse the collector between invocations + of this method.
        coordinator - Manages execution of tasks.
        +
        Throws:
        +
        java.lang.Exception - Any exception types encountered during the execution of the processing task.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskContext.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskContext.html new file mode 100644 index 0000000..9d8c18f --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskContext.html @@ -0,0 +1,245 @@ + + + + + +TaskContext (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface TaskContext

+
+
+
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + + + + + +
        +
      • +

        getStore

        +
        java.lang.Object getStore(java.lang.String name)
        +
      • +
      + + + +
        +
      • +

        getTaskName

        +
        TaskName getTaskName()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskCoordinator.RequestScope.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskCoordinator.RequestScope.html new file mode 100644 index 0000000..aafd78a --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskCoordinator.RequestScope.html @@ -0,0 +1,332 @@ + + + + + +TaskCoordinator.RequestScope (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Enum TaskCoordinator.RequestScope

+
+
+ +
+ +
+
+
    +
  • + +
      +
    • + + +

      Enum Constant Summary

      + + + + + + + + + + + +
      Enum Constants 
      Enum Constant and Description
      ALL_TASKS_IN_CONTAINER +
      Indicates that a request applies to all tasks in the current container.
      +
      CURRENT_TASK +
      Indicates that a request applies only to the task making the call.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      static TaskCoordinator.RequestScopevalueOf(java.lang.String name) +
      Returns the enum constant of this type with the specified name.
      +
      static TaskCoordinator.RequestScope[]values() +
      Returns an array containing the constants of this enum type, in +the order they are declared.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Enum

        +clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
      • +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Enum Constant Detail

      + + + +
        +
      • +

        CURRENT_TASK

        +
        public static final TaskCoordinator.RequestScope CURRENT_TASK
        +
        Indicates that a request applies only to the task making the call.
        +
      • +
      + + + +
        +
      • +

        ALL_TASKS_IN_CONTAINER

        +
        public static final TaskCoordinator.RequestScope ALL_TASKS_IN_CONTAINER
        +
        Indicates that a request applies to all tasks in the current container.
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        values

        +
        public static TaskCoordinator.RequestScope[] values()
        +
        Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
        +for (TaskCoordinator.RequestScope c : TaskCoordinator.RequestScope.values())
        +    System.out.println(c);
        +
        +
        Returns:
        an array containing the constants of this enum type, in the order they are declared
        +
      • +
      + + + +
        +
      • +

        valueOf

        +
        public static TaskCoordinator.RequestScope valueOf(java.lang.String name)
        +
        Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
        +
        Parameters:
        name - the name of the enum constant to be returned.
        +
        Returns:
        the enum constant with the specified name
        +
        Throws:
        +
        java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
        +
        java.lang.NullPointerException - if the argument is null
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskCoordinator.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskCoordinator.html new file mode 100644 index 0000000..e246de3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskCoordinator.html @@ -0,0 +1,279 @@ + + + + + +TaskCoordinator (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface TaskCoordinator

+
+
+
+
    +
  • +
    +
    +
    public interface TaskCoordinator
    +
    TaskCoordinators are provided to the process methods of StreamTask implementations + to allow the user code to request actions from the Samza framework, including committing the current checkpoints + to configured CheckpointManagers or shutting down the task or all tasks within + a container. +

    + This interface may evolve over time. +

    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        commit

        +
        void commit(TaskCoordinator.RequestScope scope)
        +
        Requests that Samza should write out a checkpoint, from which a task can restart + after failure. + +

        If CURRENT_TASK is given, a checkpoint is only written for the + current task. If ALL_TASKS_IN_CONTAINER is given, a checkpoint is + written for all tasks in the current container. + +

        Note that if you also have also configured your job to commit in regular + intervals (using the task.commit.ms property), those time-based + commits are not affected by calling this method. Any commits you request explicitly + are in addition to timer-based commits. You can set task.commit.ms=-1 + if you don't want commits to happen automatically.

        +
        Parameters:
        scope - Which tasks are being asked to commit.
        +
      • +
      + + + +
        +
      • +

        shutdown

        +
        void shutdown(TaskCoordinator.RequestScope scope)
        +
        Requests that the container should be shut down. + +

        If CURRENT_TASK is given, that indicates a willingness of the current + task to shut down. All tasks in the container (including the one that requested + shutdown) will continue processing messages. Only when every task in the container + has called shutdown(CURRENT_TASK), the container is shut down. Once a + task has called shutdown(CURRENT_TASK), it cannot change its mind + (i.e. it cannot revoke its willingness to shut down). + +

        If ALL_TASKS_IN_CONTAINER is given, the container will shut down + immediately after it has finished processing the current message. Any buffers of + pending writes are flushed, but no further messages will be processed in this + container.

        +
        Parameters:
        scope - The approach we should use for shutting down the container.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskLifecycleListener.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskLifecycleListener.html new file mode 100644 index 0000000..0d69f8c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskLifecycleListener.html @@ -0,0 +1,311 @@ + + + + + +TaskLifecycleListener (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface TaskLifecycleListener

+
+
+
+
    +
  • +
    +
    +
    public interface TaskLifecycleListener
    +
    Used to get before/after notifications before initializing/closing all tasks + in a given container (JVM/process).
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        beforeInit

        +
        void beforeInit(Config config,
        +              TaskContext context)
        +
        Called before all tasks in TaskRunner are initialized.
        +
        Parameters:
        config - Config for the Samza job.
        context - TaskContext for the StreamTask that's being initialized.
        +
      • +
      + + + +
        +
      • +

        afterInit

        +
        void afterInit(Config config,
        +             TaskContext context)
        +
        Called after all tasks in TaskRunner are initialized.
        +
        Parameters:
        config - Config for the Samza job.
        context - TaskContext for the StreamTask that's being initialized.
        +
      • +
      + + + +
        +
      • +

        beforeProcess

        +
        void beforeProcess(IncomingMessageEnvelope envelope,
        +                 Config config,
        +                 TaskContext context)
        +
        Called before a message is processed by a task.
        +
        Parameters:
        envelope - The envelope to be processed by the StreamTask.
        config - Config for the Samza job.
        context - TaskContext for the StreamTask that's about to process a message.
        +
      • +
      + + + +
        +
      • +

        afterProcess

        +
        void afterProcess(IncomingMessageEnvelope envelope,
        +                Config config,
        +                TaskContext context)
        +
        Called after a message is processed by a task.
        +
        Parameters:
        envelope - The envelope that was processed by the StreamTask.
        config - Config for the Samza job.
        context - TaskContext for the StreamTask that just processed a message.
        +
      • +
      + + + +
        +
      • +

        beforeClose

        +
        void beforeClose(Config config,
        +               TaskContext context)
        +
        Called before all tasks in TaskRunner are closed.
        +
        Parameters:
        config - Config for the Samza job.
        context - TaskContext for the StreamTask that's about to be shutdown.
        +
      • +
      + + + +
        +
      • +

        afterClose

        +
        void afterClose(Config config,
        +              TaskContext context)
        +
        Called after all tasks in TaskRunner are closed.
        +
        Parameters:
        config - Config for the Samza job.
        context - TaskContext for the StreamTask that was just shutdown.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskLifecycleListenerFactory.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskLifecycleListenerFactory.html new file mode 100644 index 0000000..0d342e3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/TaskLifecycleListenerFactory.html @@ -0,0 +1,207 @@ + + + + + +TaskLifecycleListenerFactory (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface TaskLifecycleListenerFactory

+
+
+
+ +
+
+ +
+
+ +
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/WindowableTask.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/WindowableTask.html new file mode 100644 index 0000000..9339f1e --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/WindowableTask.html @@ -0,0 +1,219 @@ + + + + + +WindowableTask (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.task
+

Interface WindowableTask

+
+
+
+
    +
  • +
    +
    +
    public interface WindowableTask
    +
    Add-on interface to StreamTask implementations to add code which will be run on + a specified time interval (via configuration). This can be used to implement direct time-based windowing or, + with a frequent window interval, windowing based on some other condition which is checked during the call to + window. The window method will be called even if no messages are received for a particular StreamTask.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      voidwindow(MessageCollector collector, + TaskCoordinator coordinator) +
      Called by TaskRunner for each implementing task at the end of every specified window.
      +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        window

        +
        void window(MessageCollector collector,
        +          TaskCoordinator coordinator)
        +            throws java.lang.Exception
        +
        Called by TaskRunner for each implementing task at the end of every specified window.
        +
        Parameters:
        collector - Contains the means of sending message envelopes to the output stream. The collector must only + be used during the current call to the window method; you should not reuse the collector between invocations + of this method.
        coordinator - Manages execution of tasks.
        +
        Throws:
        +
        java.lang.Exception - Any exception types encountered during the execution of the processing task.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-frame.html new file mode 100644 index 0000000..57c04c9 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-frame.html @@ -0,0 +1,31 @@ + + + + + +org.apache.samza.task (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.task

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-summary.html new file mode 100644 index 0000000..7280581 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-summary.html @@ -0,0 +1,209 @@ + + + + + +org.apache.samza.task (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.task

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    ClosableTask +
    A ClosableTask augments StreamTask, allowing the method implementer to specify + code that will be called when the StreamTask is being shut down by the framework, providing to emit final metrics, + clean or close resources, etc.
    +
    InitableTask +
    Used as an interface for user processing StreamTasks that need to have specific functionality performed as their StreamTasks + are instantiated by TaskRunner.
    +
    MessageCollector +
    Used as an interface for the means of sending message envelopes to an output stream.
    +
    StreamTask +
    A StreamTask is the basic class on which Samza jobs are implemented.
    +
    TaskContext +
    A TaskContext provides resources about the StreamTask, particularly during + initialization in an InitableTask and during calls to TaskLifecycleListeners.
    +
    TaskCoordinator +
    TaskCoordinators are provided to the process methods of StreamTask implementations + to allow the user code to request actions from the Samza framework, including committing the current checkpoints + to configured CheckpointManagers or shutting down the task or all tasks within + a container.
    +
    TaskLifecycleListener +
    Used to get before/after notifications before initializing/closing all tasks + in a given container (JVM/process).
    +
    TaskLifecycleListenerFactory + +
    WindowableTask +
    Add-on interface to StreamTask implementations to add code which will be run on + a specified time interval (via configuration).
    +
    +
  • +
  • + + + + + + + + + + + + +
    Enum Summary 
    EnumDescription
    TaskCoordinator.RequestScope +
    A task can make requests to the Samza framework while processing messages, such as + TaskCoordinator.commit(RequestScope) and + TaskCoordinator.shutdown(RequestScope).
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-tree.html new file mode 100644 index 0000000..acdbedf --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/task/package-tree.html @@ -0,0 +1,142 @@ + + + + + +org.apache.samza.task Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.task

+Package Hierarchies: + +
+
+

Interface Hierarchy

+ +

Enum Hierarchy

+
    +
  • java.lang.Object + +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.BlockingEnvelopeMapMetrics.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.BlockingEnvelopeMapMetrics.html new file mode 100644 index 0000000..20f7f0b --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.BlockingEnvelopeMapMetrics.html @@ -0,0 +1,314 @@ + + + + + +BlockingEnvelopeMap.BlockingEnvelopeMapMetrics (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.util
+

Class BlockingEnvelopeMap.BlockingEnvelopeMapMetrics

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.util.BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
    • +
    +
  • +
+
+
    +
  • +
    +
    Enclosing class:
    +
    BlockingEnvelopeMap
    +
    +
    +
    +
    public class BlockingEnvelopeMap.BlockingEnvelopeMapMetrics
    +extends java.lang.Object
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        BlockingEnvelopeMap.BlockingEnvelopeMapMetrics

        +
        public BlockingEnvelopeMap.BlockingEnvelopeMapMetrics(java.lang.String group,
        +                                              MetricsRegistry metricsRegistry)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        setNoMoreMessages

        +
        public void setNoMoreMessages(SystemStreamPartition systemStreamPartition,
        +                     boolean noMoreMessages)
        +
      • +
      + + + + + + + +
        +
      • +

        incBlockingTimeoutPoll

        +
        public void incBlockingTimeoutPoll(SystemStreamPartition systemStreamPartition)
        +
      • +
      + + + +
        +
      • +

        incPoll

        +
        public void incPoll()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.BufferGauge.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.BufferGauge.html new file mode 100644 index 0000000..9efacf4 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.BufferGauge.html @@ -0,0 +1,280 @@ + + + + + +BlockingEnvelopeMap.BufferGauge (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.util
+

Class BlockingEnvelopeMap.BufferGauge

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Metric
    +
    +
    +
    Enclosing class:
    +
    BlockingEnvelopeMap
    +
    +
    +
    +
    public class BlockingEnvelopeMap.BufferGauge
    +extends Gauge<java.lang.Integer>
    +
  • +
+
+
+
    +
  • + + + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      java.lang.IntegergetValue() 
      + +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        BlockingEnvelopeMap.BufferGauge

        +
        public BlockingEnvelopeMap.BufferGauge(SystemStreamPartition systemStreamPartition,
        +                               java.lang.String name)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getValue

        +
        public java.lang.Integer getValue()
        +
        +
        Overrides:
        +
        getValue in class Gauge<java.lang.Integer>
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.html new file mode 100644 index 0000000..e149ead --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/BlockingEnvelopeMap.html @@ -0,0 +1,540 @@ + + + + + +BlockingEnvelopeMap (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.util
+

Class BlockingEnvelopeMap

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.util.BlockingEnvelopeMap
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    SystemConsumer
    +
    +
    +
    +
    public abstract class BlockingEnvelopeMap
    +extends java.lang.Object
    +implements SystemConsumer
    +

    + BlockingEnvelopeMap is a helper class for SystemConsumer implementations. + Samza's poll() requirements make implementing SystemConsumers somewhat + tricky. BlockingEnvelopeMap is provided to help other developers write + SystemConsumers. The intended audience is not those writing Samza jobs, but + rather those extending Samza to consume from new types of stream providers + and other systems. +

    + +

    + SystemConsumers that implement BlockingEnvelopeMap need to add messages using + add (or addAll), and update noMoreMessage using setIsAtHead. The + noMoreMessage variable is used to determine whether a SystemStreamPartition + is "caught up" (has read all possible messages from the underlying system). + For example, with a Kafka system, noMoreMessages would be set to true when + the last message offset returned is equal to the offset high watermark for a + given topic/partition. +

    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        BlockingEnvelopeMap

        +
        public BlockingEnvelopeMap()
        +
      • +
      + + + +
        +
      • +

        BlockingEnvelopeMap

        +
        public BlockingEnvelopeMap(Clock clock)
        +
      • +
      + + + +
        +
      • +

        BlockingEnvelopeMap

        +
        public BlockingEnvelopeMap(MetricsRegistry metricsRegistry)
        +
      • +
      + + + +
        +
      • +

        BlockingEnvelopeMap

        +
        public BlockingEnvelopeMap(MetricsRegistry metricsRegistry,
        +                   Clock clock)
        +
      • +
      + + + +
        +
      • +

        BlockingEnvelopeMap

        +
        public BlockingEnvelopeMap(MetricsRegistry metricsRegistry,
        +                   Clock clock,
        +                   java.lang.String metricsGroupName)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        register

        +
        public void register(SystemStreamPartition systemStreamPartition,
        +            java.lang.String offset)
        +
        Description copied from interface: SystemConsumer
        +
        Register a SystemStreamPartition to this SystemConsumer. The SystemConsumer + should try and read messages from all SystemStreamPartitions that are + registered to it. SystemStreamPartitions should only be registered before + start is called.
        +
        +
        Specified by:
        +
        register in interface SystemConsumer
        +
        Parameters:
        systemStreamPartition - The SystemStreamPartition object representing the Samza + SystemStreamPartition to receive messages from.
        offset - String representing the offset of the point in the stream to start + reading messages from. This is an inclusive parameter; if "7" were + specified, the first message for the system/stream/partition to be + consumed and returned would be a message whose offset is "7".
        +
      • +
      + + + +
        +
      • +

        newBlockingQueue

        +
        protected java.util.concurrent.BlockingQueue<IncomingMessageEnvelope> newBlockingQueue()
        +
      • +
      + + + +
        +
      • +

        poll

        +
        public java.util.Map<SystemStreamPartition,java.util.List<IncomingMessageEnvelope>> poll(java.util.Set<SystemStreamPartition> systemStreamPartitions,
        +                                                                                long timeout)
        +                                                                                  throws java.lang.InterruptedException
        +
        Description copied from interface: SystemConsumer
        +
        Poll the SystemConsumer to get any available messages from the underlying + system. + +

        + If the underlying implementation does not take care to adhere to the + timeout parameter, the SamzaContainer's performance will suffer + drastically. Specifically, if poll blocks when it's not supposed to, it + will block the entire main thread in SamzaContainer, and no messages will + be processed while blocking is occurring. +

        +
        +
        Specified by:
        +
        poll in interface SystemConsumer
        +
        Parameters:
        systemStreamPartitions - A set of SystemStreamPartition to poll for new messages. If + SystemConsumer has messages available for other registered + SystemStreamPartitions, but they are not in the + systemStreamPartitions set in a given poll invocation, they can't + be returned. It is illegal to pass in SystemStreamPartitions that + have not been registered with the SystemConsumer first.
        timeout - If timeout < 0, poll will block unless all SystemStreamPartition + are at "head" (the underlying system has been checked, and + returned an empty set). If at head, an empty map is returned. If + timeout >= 0, poll will return any messages that are currently + available for any of the SystemStreamPartitions specified. If no + new messages are available, it will wait up to timeout + milliseconds for messages from any SystemStreamPartition to become + available. It will return an empty map if the timeout is hit, and + no new messages are available.
        +
        Returns:
        A map from SystemStreamPartitions to any available + IncomingMessageEnvelopes for the SystemStreamPartitions. If no + messages are available for a SystemStreamPartition that was + supplied in the polling set, the map will not contain a key for the + SystemStreamPartition. Will return an empty map, not null, if no + new messages are available for any SystemStreamPartitions in the + input set.
        +
        Throws:
        +
        java.lang.InterruptedException - Thrown when a blocking poll has been interrupted by another + thread.
        +
      • +
      + + + + + + + +
        +
      • +

        putAll

        +
        protected void putAll(SystemStreamPartition systemStreamPartition,
        +          java.util.List<IncomingMessageEnvelope> envelopes)
        +               throws java.lang.InterruptedException
        +
        Throws:
        +
        java.lang.InterruptedException
        +
      • +
      + + + +
        +
      • +

        getNumMessagesInQueue

        +
        public int getNumMessagesInQueue(SystemStreamPartition systemStreamPartition)
        +
      • +
      + + + +
        +
      • +

        setIsAtHead

        +
        protected java.lang.Boolean setIsAtHead(SystemStreamPartition systemStreamPartition,
        +                            boolean isAtHead)
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/Clock.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/Clock.html new file mode 100644 index 0000000..0e0cdf3 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/Clock.html @@ -0,0 +1,205 @@ + + + + + +Clock (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.util
+

Interface Clock

+
+
+
+
    +
  • +
    +
    +
    public interface Clock
    +
    Mockable interface for tracking time.
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      longcurrentTimeMillis() 
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        currentTimeMillis

        +
        long currentTimeMillis()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/NoOpMetricsRegistry.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/NoOpMetricsRegistry.html new file mode 100644 index 0000000..de8240c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/NoOpMetricsRegistry.html @@ -0,0 +1,348 @@ + + + + + +NoOpMetricsRegistry (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.util
+

Class NoOpMetricsRegistry

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.util.NoOpMetricsRegistry
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    MetricsRegistry
    +
    +
    +
    +
    public class NoOpMetricsRegistry
    +extends java.lang.Object
    +implements MetricsRegistry
    +
    MetricsRegistry implementation for when no actual metrics need to be + recorded but a registry is still required.
    +
  • +
+
+
+
    +
  • + + + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      CounternewCounter(java.lang.String group, + Counter counter) +
      Register existing Counter with this registry
      +
      CounternewCounter(java.lang.String group, + java.lang.String name) +
      Create and register a new Counter
      +
      <T> Gauge<T>newGauge(java.lang.String group, + Gauge<T> gauge) +
      Register an existing Gauge
      +
      <T> Gauge<T>newGauge(java.lang.String group, + java.lang.String name, + T value) +
      Create and register a new Gauge
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        NoOpMetricsRegistry

        +
        public NoOpMetricsRegistry()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        newCounter

        +
        public Counter newCounter(java.lang.String group,
        +                 java.lang.String name)
        +
        Description copied from interface: MetricsRegistry
        +
        Create and register a new Counter
        +
        +
        Specified by:
        +
        newCounter in interface MetricsRegistry
        +
        Parameters:
        group - Group for this Counter
        name - Name of to-be-created Counter
        +
        Returns:
        New Counter instance
        +
      • +
      + + + +
        +
      • +

        newCounter

        +
        public Counter newCounter(java.lang.String group,
        +                 Counter counter)
        +
        Description copied from interface: MetricsRegistry
        +
        Register existing Counter with this registry
        +
        +
        Specified by:
        +
        newCounter in interface MetricsRegistry
        +
        Parameters:
        group - Group for this Counter
        counter - Existing Counter to register
        +
        Returns:
        Counter that was registered
        +
      • +
      + + + + + +
        +
      • +

        newGauge

        +
        public <T> Gauge<T> newGauge(java.lang.String group,
        +                    java.lang.String name,
        +                    T value)
        +
        Description copied from interface: MetricsRegistry
        +
        Create and register a new Gauge
        +
        +
        Specified by:
        +
        newGauge in interface MetricsRegistry
        +
        Type Parameters:
        T - Type the Gauge will be wrapping
        Parameters:
        group - Group for this Gauge
        name - Name of to-be-created Gauge
        value - Initial value for the Gauge
        +
        Returns:
        Gauge was created and registered
        +
      • +
      + + + +
        +
      • +

        newGauge

        +
        public <T> Gauge<T> newGauge(java.lang.String group,
        +                    Gauge<T> gauge)
        +
        Description copied from interface: MetricsRegistry
        +
        Register an existing Gauge
        +
        +
        Specified by:
        +
        newGauge in interface MetricsRegistry
        +
        Type Parameters:
        T - Type the Gauge will be wrapping
        Parameters:
        group - Group for this Gauge
        gauge - Initial value for the Gauge
        +
        Returns:
        Gauge was registered
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/SinglePartitionWithoutOffsetsSystemAdmin.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/SinglePartitionWithoutOffsetsSystemAdmin.html new file mode 100644 index 0000000..b35cf40 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/SinglePartitionWithoutOffsetsSystemAdmin.html @@ -0,0 +1,299 @@ + + + + + +SinglePartitionWithoutOffsetsSystemAdmin (samza-api 0.8.0-SNAPSHOT API) + + + + + + + + + + + +
+
org.apache.samza.util
+

Class SinglePartitionWithoutOffsetsSystemAdmin

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • org.apache.samza.util.SinglePartitionWithoutOffsetsSystemAdmin
    • +
    +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    SystemAdmin
    +
    +
    +
    +
    public class SinglePartitionWithoutOffsetsSystemAdmin
    +extends java.lang.Object
    +implements SystemAdmin
    +
    A simple helper admin class that defines a single partition (partition 0) for + a given system. The metadata uses null for all offsets, which means that the + stream doesn't support offsets, and will be treated as empty. This class + should be used when a system has no concept of partitioning or offsets, since + Samza needs at least one partition for an input stream, in order to read it.
    +
  • +
+
+
+
    +
  • + + + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + +
      Methods 
      Modifier and TypeMethod and Description
      java.util.Map<SystemStreamPartition,java.lang.String>getOffsetsAfter(java.util.Map<SystemStreamPartition,java.lang.String> offsets) +
      Fetches the offsets for the messages immediately after the supplied offsets + for a group of SystemStreamPartitions.
      +
      java.util.Map<java.lang.String,SystemStreamMetadata>getSystemStreamMetadata(java.util.Set<java.lang.String> streamNames) +
      Fetch metadata from a system for a set of streams.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        SinglePartitionWithoutOffsetsSystemAdmin

        +
        public SinglePartitionWithoutOffsetsSystemAdmin()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getSystemStreamMetadata

        +
        public java.util.Map<java.lang.String,SystemStreamMetadata> getSystemStreamMetadata(java.util.Set<java.lang.String> streamNames)
        +
        Description copied from interface: SystemAdmin
        +
        Fetch metadata from a system for a set of streams.
        +
        +
        Specified by:
        +
        getSystemStreamMetadata in interface SystemAdmin
        +
        Parameters:
        streamNames - The streams to to fetch metadata for.
        +
        Returns:
        A map from stream name to SystemStreamMetadata for each stream + requested in the parameter set.
        +
      • +
      + + + +
        +
      • +

        getOffsetsAfter

        +
        public java.util.Map<SystemStreamPartition,java.lang.String> getOffsetsAfter(java.util.Map<SystemStreamPartition,java.lang.String> offsets)
        +
        Description copied from interface: SystemAdmin
        +
        Fetches the offsets for the messages immediately after the supplied offsets + for a group of SystemStreamPartitions.
        +
        +
        Specified by:
        +
        getOffsetsAfter in interface SystemAdmin
        +
        Parameters:
        offsets - Map from SystemStreamPartition to current offsets.
        +
        Returns:
        Map from SystemStreamPartition to offsets immediately after the + current offsets.
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-frame.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-frame.html new file mode 100644 index 0000000..c4badfe --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-frame.html @@ -0,0 +1,25 @@ + + + + + +org.apache.samza.util (samza-api 0.8.0-SNAPSHOT API) + + + + +

org.apache.samza.util

+ + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-summary.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-summary.html new file mode 100644 index 0000000..9c90ba9 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-summary.html @@ -0,0 +1,165 @@ + + + + + +org.apache.samza.util (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package org.apache.samza.util

+
+
+
    +
  • + + + + + + + + + + + + +
    Interface Summary 
    InterfaceDescription
    Clock +
    Mockable interface for tracking time.
    +
    +
  • +
  • + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    BlockingEnvelopeMap +
    + BlockingEnvelopeMap is a helper class for SystemConsumer implementations.
    +
    NoOpMetricsRegistry +
    MetricsRegistry implementation for when no actual metrics need to be + recorded but a registry is still required.
    +
    SinglePartitionWithoutOffsetsSystemAdmin +
    A simple helper admin class that defines a single partition (partition 0) for + a given system.
    +
    +
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-tree.html b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-tree.html new file mode 100644 index 0000000..a13273b --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/org/apache/samza/util/package-tree.html @@ -0,0 +1,138 @@ + + + + + +org.apache.samza.util Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package org.apache.samza.util

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +

Interface Hierarchy

+
    +
  • org.apache.samza.util.Clock
  • +
+
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/overview-frame.html b/docs/learn/documentation/versioned/api/javadocs/overview-frame.html new file mode 100644 index 0000000..39decc9 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/overview-frame.html @@ -0,0 +1,32 @@ + + + + + +Overview List (samza-api 0.8.0-SNAPSHOT API) + + + + + + +

 

+ + diff --git a/docs/learn/documentation/versioned/api/javadocs/overview-summary.html b/docs/learn/documentation/versioned/api/javadocs/overview-summary.html new file mode 100644 index 0000000..84d9a6e --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/overview-summary.html @@ -0,0 +1,175 @@ + + + + + +Overview (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

samza-api 0.8.0-SNAPSHOT API

+
+ + +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/overview-tree.html b/docs/learn/documentation/versioned/api/javadocs/overview-tree.html new file mode 100644 index 0000000..abd7634 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/overview-tree.html @@ -0,0 +1,249 @@ + + + + + +Class Hierarchy (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + + +
+

Class Hierarchy

+ +

Interface Hierarchy

+ +

Enum Hierarchy

+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/package-list b/docs/learn/documentation/versioned/api/javadocs/package-list new file mode 100644 index 0000000..d504fbf --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/package-list @@ -0,0 +1,13 @@ +org.apache.samza +org.apache.samza.checkpoint +org.apache.samza.config +org.apache.samza.container +org.apache.samza.container.grouper.stream +org.apache.samza.job +org.apache.samza.metrics +org.apache.samza.serializers +org.apache.samza.storage +org.apache.samza.system +org.apache.samza.system.chooser +org.apache.samza.task +org.apache.samza.util diff --git a/docs/learn/documentation/versioned/api/javadocs/resources/background.gif b/docs/learn/documentation/versioned/api/javadocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/docs/learn/documentation/versioned/api/javadocs/serialized-form.html b/docs/learn/documentation/versioned/api/javadocs/serialized-form.html new file mode 100644 index 0000000..8cea96c --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/serialized-form.html @@ -0,0 +1,144 @@ + + + + + +Serialized Form (samza-api 0.8.0-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Serialized Form

+
+
+ +
+ +
+ + + + + +
+ + + + diff --git a/docs/learn/documentation/versioned/api/javadocs/stylesheet.css b/docs/learn/documentation/versioned/api/javadocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/docs/learn/documentation/versioned/api/javadocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/docs/learn/documentation/versioned/api/overview.md b/docs/learn/documentation/versioned/api/overview.md new file mode 100644 index 0000000..6712344 --- /dev/null +++ b/docs/learn/documentation/versioned/api/overview.md @@ -0,0 +1,142 @@ +--- +layout: page +title: API Overview +--- + + +When writing a stream processor for Samza, you must implement the [StreamTask](javadocs/org/apache/samza/task/StreamTask.html) interface: + +{% highlight java %} +package com.example.samza; + +public class MyTaskClass implements StreamTask { + + public void process(IncomingMessageEnvelope envelope, + MessageCollector collector, + TaskCoordinator coordinator) { + // process message + } +} +{% endhighlight %} + +When you run your job, Samza will create several instances of your class (potentially on multiple machines). These task instances process the messages in the input streams. + +In your job's configuration you can tell Samza which streams you want to consume. An incomplete example could look like this (see the [configuration documentation](../jobs/configuration.html) for more detail): + +{% highlight jproperties %} +# This is the class above, which Samza will instantiate when the job is run +task.class=com.example.samza.MyTaskClass + +# Define a system called "kafka" (you can give it any name, and you can define +# multiple systems if you want to process messages from different sources) +systems.kafka.samza.factory=org.apache.samza.system.kafka.KafkaSystemFactory + +# The job consumes a topic called "PageViewEvent" from the "kafka" system +task.inputs=kafka.PageViewEvent + +# Define a serializer/deserializer called "json" which parses JSON messages +serializers.registry.json.class=org.apache.samza.serializers.JsonSerdeFactory + +# Use the "json" serializer for messages in the "PageViewEvent" topic +systems.kafka.streams.PageViewEvent.samza.msg.serde=json +{% endhighlight %} + +For each message that Samza receives from the task's input streams, the *process* method is called. The [envelope](javadocs/org/apache/samza/system/IncomingMessageEnvelope.html) contains three things of importance: the message, the key, and the stream that the message came from. + +{% highlight java %} +/** Every message that is delivered to a StreamTask is wrapped + * in an IncomingMessageEnvelope, which contains metadata about + * the origin of the message. */ +public class IncomingMessageEnvelope { + /** A deserialized message. */ + Object getMessage() { ... } + + /** A deserialized key. */ + Object getKey() { ... } + + /** The stream and partition that this message came from. */ + SystemStreamPartition getSystemStreamPartition() { ... } +} +{% endhighlight %} + +The key and value are declared as Object, and need to be cast to the correct type. If you don't configure a [serializer/deserializer](../container/serialization.html), they are typically Java byte arrays. A deserializer can convert these bytes into any other type, for example the JSON deserializer mentioned above parses the byte array into java.util.Map, java.util.List and String objects. + +The `getSystemStreamPartition()` method returns a [SystemStreamPartition](javadocs/org/apache/samza/system/SystemStreamPartition.html) object, which tells you where the message came from. It consists of three parts: + +1. The *system*: the name of the system from which the message came, as defined in your job configuration. You can have multiple systems for input and/or output, each with a different name. +2. The *stream name*: the name of the stream (topic, queue) within the source system. This is also defined in the job configuration. +3. The [*partition*](javadocs/org/apache/samza/Partition.html): a stream is normally split into several partitions, and each partition is assigned to one StreamTask instance by Samza. + +The API looks like this: + +{% highlight java %} +/** A triple of system name, stream name and partition. */ +public class SystemStreamPartition extends SystemStream { + + /** The name of the system which provides this stream. It is + defined in the Samza job's configuration. */ + public String getSystem() { ... } + + /** The name of the stream/topic/queue within the system. */ + public String getStream() { ... } + + /** The partition within the stream. */ + public Partition getPartition() { ... } +} +{% endhighlight %} + +In the example job configuration above, the system name is "kafka", the stream name is "PageViewEvent". (The name "kafka" isn't special — you can give your system any name you want.) If you have several input streams feeding into your StreamTask, you can use the SystemStreamPartition to determine what kind of message you've received. + +What about sending messages? If you take a look at the process() method in StreamTask, you'll see that you get a [MessageCollector](javadocs/org/apache/samza/task/MessageCollector.html). + +{% highlight java %} +/** When a task wishes to send a message, it uses this interface. */ +public interface MessageCollector { + void send(OutgoingMessageEnvelope envelope); +} +{% endhighlight %} + +To send a message, you create an [OutgoingMessageEnvelope](javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html) object and pass it to the message collector. At a minimum, the envelope specifies the message you want to send, and the system and stream name to send it to. Optionally you can specify the partitioning key and other parameters. See the [javadoc](javadocs/org/apache/samza/system/OutgoingMessageEnvelope.html) for details. + +**NOTE:** Please only use the MessageCollector object within the `process()` method. If you hold on to a MessageCollector instance and use it again later, your messages may not be sent correctly. + +For example, here's a simple task that splits each input message into words, and emits each word as a separate message: + +{% highlight java %} +public class SplitStringIntoWords implements StreamTask { + + // Send outgoing messages to a stream called "words" + // in the "kafka" system. + private final SystemStream OUTPUT_STREAM = + new SystemStream("kafka", "words"); + + public void process(IncomingMessageEnvelope envelope, + MessageCollector collector, + TaskCoordinator coordinator) { + String message = (String) envelope.getMessage(); + + for (String word : message.split(" ")) { + // Use the word as the key, and 1 as the value. + // A second task can add the 1's to get the word count. + collector.send(new OutgoingMessageEnvelope(OUTPUT_STREAM, word, 1)); + } + } +} +{% endhighlight %} + +## [SamzaContainer »](../container/samza-container.html) diff --git a/docs/learn/documentation/versioned/comparisons/introduction.md b/docs/learn/documentation/versioned/comparisons/introduction.md new file mode 100644 index 0000000..88e17bb --- /dev/null +++ b/docs/learn/documentation/versioned/comparisons/introduction.md @@ -0,0 +1,80 @@ +--- +layout: page +title: Comparison Introduction +--- + + +Here are a few of the high-level design decisions that we think make Samza a bit different from other stream processing projects. + +### The Stream Model + +Streams are the input and output to Samza jobs. Samza has a very strong model of a stream—it is more than just a simple message exchange mechanism. A stream in Samza is a partitioned, ordered-per-partition, replayable, multi-subscriber, lossless sequence of messages. Streams are not just inputs and outputs to the system, but also buffers that isolate processing stages from each other. + +This stronger model requires persistence, fault-tolerance, and buffering in the stream implementation, but it has several benefits. + +First, delays in a downstream processing stage cannot block an upstream stage. A Samza job can stop consuming for a few minutes, or even a few hours (perhaps because of a bad deploy, or a long-running computation) without having any effect on upstream jobs. This makes Samza suitable for large deployments, such as processing all data flows in a large company: isolation between jobs is essential when they are written, owned, and run by different teams in different code bases with varying SLAs. + +This is motivated by our experience building analogous offline processing pipelines in Hadoop. In Hadoop the processing stages are MapReduce jobs, and the output of a processing stage is a directory of files on HDFS. The input to the next processing stage is simply the files produced by the earlier stage. We have found that this strong isolation between stages makes it possible to have hundreds of loosely coupled jobs, maintained by different teams, that comprise an offline processing ecosystem. Our goal is to replicate this kind of rich ecosystem in a near-real-time setting. + +The second benefit of this stronger model is that all stages are multi-subscriber. In practical terms this means that if one person adds a set of processing flows that create output data streams, others can see the output, consume it, and build on it, without introducing any coupling of code between the jobs. As a happy side-effect, this makes debugging flows easy, as you can manually inspect the output of any stage. + +Finally, this strong stream model greatly simplifies the implementation of features in the Samza framework. Each job need only be concerned with its own inputs and outputs, and in the case of a fault, each job can be recovered and restarted independently. There is no need for central control over the entire dataflow graph. + +The tradeoff we need to make for this stronger stream model is that messages are written to disk. We are willing to make this tradeoff because MapReduce and HDFS have shown that durable storage can offer very high read and write throughput, and almost limitless disk space. This observation is the foundation of Kafka, which allows hundreds of MB/sec of replicated throughput, and many TB of disk space per node. When used this way, disk throughput often isn't the bottleneck. + +MapReduce is sometimes criticized for writing to disk more than necessary. However, this criticism applies less to stream processing: batch processing like MapReduce often is used for processing large historical collections of data in a short period of time (e.g. query a month of data in ten minutes), whereas stream processing mostly needs to keep up with the steady-state flow of data (process 10 minutes worth of data in 10 minutes). This means that the raw throughput requirements for stream processing are, generally, orders of magnitude lower than for batch processing. + +### State + +Only the very simplest stream processing problems are stateless (i.e. can process one message at a time, independently of all other messages). Many stream processing applications require a job to maintain some state. For example: + +* If you want to know how many events have been seen for a particular user ID, you need to keep a counter for each user ID. +* If you want to know how many distinct users visit your site per day, you need to keep a set of all user IDs for which you've seen at least one event today. +* If you want to join two streams (for example, if you want to determine the click-through rate of adverts by joining a stream of ad impression events with a stream of ad click events) you need to store the event from one stream until you receive the corresponding event from the other stream. +* If you want to augment events with some information from a database (for example, extending a page-view event with some information about the user who viewed the page), the job needs to access the current state of that database. + +Some kinds of state, such as counters, could be kept in-memory in the tasks, but then that state would be lost if the job is restarted. Alternatively, you can keep the state in a remote database, but performance can become unacceptable if you need to perform a database query for every message you process. Kafka can easily handle 100k-500k messages/sec per node (depending on message size), but throughput for queries against a remote key-value store tend to be closer to 1-5k requests per second — two orders of magnitude slower. + +In Samza, we have put particular effort into supporting high-performance, reliable state. The key is to keep state local to each node (so that queries don't need to go over the network), and to make it robust to machine failures by replicating state changes to another stream. + +This approach is especially interesting when combined with database *change capture*. Take the +example above, where you have a stream of page-view events including the ID of the user who viewed the page, and you want to augment the events with more information about that user. At first glance, it looks as though you have no choice but to query the user database to look up every user ID you see (perhaps with some caching). With Samza, we can do better. + +*Change capture* means that every time some data changes in your database, you get an event telling you what changed. If you have that stream of change events, going all the way back to when the database was created, you can reconstruct the entire contents of the database by replaying the stream. That *changelog* stream can also be used as input to a Samza job. + +Now you can write a Samza job that takes both the page-view event and the changelog as inputs. You make sure that they are partitioned on the same key (e.g. user ID). Every time a changelog event comes in, you write the updated user information to the task's local storage. Every time a page-view event comes in, you read the current information about that user from local storage. That way, you can keep all the state local to a task, and never need to query a remote database. + +Stateful Processing + +In effect, you now have a replica of the main database, broken into small partitions that are on the same machines as the Samza tasks. Database writes still need to go to the main database, but when you need to read from the database in order to process a message from the input stream, you can just consult the task's local state. + +This approach is not only much faster than querying a remote database, it is also much better for operations. If you are processing a high-volume stream with Samza, and making a remote query for every message, you can easily overwhelm the database with requests and affect other services using the same database. By contrast, when a task uses local state, it is isolated from everything else, so it cannot accidentally bring down other services. + +Partitioned local state is not always appropriate, and not required — nothing in Samza prevents calls to external databases. If you cannot produce a feed of changes from your database, or you need to rely on logic that exists only in a remote service, then it may be more convenient to call a remote service from your Samza job. But if you want to use local state, it works out of the box. + +### Execution Framework + +One final decision we made was to not build a custom distributed execution system in Samza. Instead, execution is pluggable, and currently completely handled by YARN. This has two benefits. + +The first benefit is practical: there is another team of smart people working on the execution framework. YARN is developing at a rapid pace, and already supports a rich set of features around resource quotas and security. This allows you to control what portion of the cluster is allocated to which users and groups, and also control the resource utilization on individual nodes (CPU, memory, etc) via cgroups. YARN is run at massive scale to support Hadoop and will likely become an ubiquitous layer. Since Samza runs entirely through YARN, there are no separate daemons or masters to run beyond the YARN cluster itself. In other words, if you already have Kafka and YARN, you don't need to install anything in order to run Samza jobs. + +Secondly, our integration with YARN is completely componentized. It exists in a separate package, and the main Samza framework does not depend on it at build time. This means that YARN can be replaced with other virtualization frameworks — in particular, we are interested in adding direct AWS integration. Many companies run in AWS which is itself a virtualization framework, which for Samza's purposes is equivalent to YARN: it allows you to create and destroy virtual "container" machines and guarantees fixed resources for these containers. Since stream processing jobs are long-running, it is a bit silly to run a YARN cluster inside AWS and then schedule individual jobs within this cluster. Instead, a more sensible approach would be to directly allocate a set of EC2 instances for your jobs. + +We think there will be a lot of innovation both in open source virtualization frameworks like Mesos and YARN and in commercial cloud providers like Amazon, so it makes sense to integrate with them. + +## [MUPD8 »](mupd8.html) diff --git a/docs/learn/documentation/versioned/comparisons/mupd8.md b/docs/learn/documentation/versioned/comparisons/mupd8.md new file mode 100644 index 0000000..53417f9 --- /dev/null +++ b/docs/learn/documentation/versioned/comparisons/mupd8.md @@ -0,0 +1,88 @@ +--- +layout: page +title: MUPD8 +--- + + +*People generally want to know how similar systems compare. We've done our best to fairly contrast the feature sets of Samza with other systems. But we aren't experts in these frameworks, and we are, of course, totally biased. If we have goofed anything, please let us know and we will correct it.* + +### Durability + +MUPD8 makes no durability or delivery guarantees. Within MUPD8, stream processor tasks receive messages at most once. Samza uses Kafka for messaging, which guarantees message delivery. + +### Ordering + +As with durability, developers would ideally like their stream processors to receive messages in exactly the order that they were written. + +We don't entirely follow MUPD8's description of their ordering guarantees, but it seems to guarantee that all messages will be processed in the order in which they are written to MUPD8 queues, which is comparable to Kafka and Samza's guarantee. + +### Buffering + +A critical issue for handling large data flows is handling back pressure when one downstream processing stage gets slow. + +MUPD8 buffers messages in an in-memory queue when passing messages between two MUPD8 tasks. When a queue fills up, developers have the option to either drop the messages on the floor, log the messages to local disk, or block until the queue frees up. All of these options are sub-optimal. Dropping messages leads to incorrect results. Blocking your stream processor can have a cascading effect, where the slowest processor blocks all upstream processors, which in turn block their upstream processors, until the whole system grinds to a halt. Logging to local disk is the most reasonable, but when a fault occurs, those messages are lost on failover. + +By adopting Kafka's broker as a remote buffer, Samza solves all of these problems. It doesn't need to block because consumers and producers are decoupled using the Kafka brokers' disks as buffers. Messages are not dropped because Kafka brokers are highly available as of version 0.8. In the event of a failure, when a Samza job is restarted on another machine, its input and output are not lost, because they are stored remotely on replicated Kafka brokers. + +### State Management + +As described in the [introduction](introduction.html#state), stream processors often need to maintain some state as they process messages. Different frameworks have different approaches to handling such state, and what to do in case of a failure. + +MUPD8 uses a write back caching strategy to manage in-memory state that is periodically written back to Cassandra. + +Samza maintains state locally with the task. This allows state larger than will fit in memory. State is persisted to an output stream to enable recovery should the task fail. We believe this design enables stronger fault tolerance semantics, because the change log captures the evolution of state, allowing the state of a task to restored to a consistent point in time. + +### Deployment and execution + +MUPD8 includes a custom execution framework. The functionality that this framework supports in terms of users and resource limits isn't clear to us. + +Samza leverages YARN to deploy user code, and execute it in a distributed environment. + +### Fault Tolerance + +What should a stream processing system do when a machine or processor fails? + +MUPD8 uses its custom equivalent to YARN to manage fault tolerance. When a stream processor is unable to send a message to a downstream processor, it notifies MUPD8's coordinator, and all other machines are notified. The machines then send all messages to a new machine based on the key hash that's used. Messages and state can be lost when this happens. + +Samza uses YARN to manage fault tolerance. YARN detects when nodes or Samza tasks fail, and notifies Samza's [ApplicationMaster](../yarn/application-master.html). At that point, it's up to Samza to decide what to do. Generally, this means re-starting the task on another machine. Since messages are persisted to Kafka brokers remotely, and there are no in-memory queues, no messages should be lost (unless the processors are using async Kafka producers, which offer higher performance but don't wait for messages to be committed). + +### Workflow + +Sometimes more than one job or processing stage is needed to accomplish something. This is the case where you wish to re-partition a stream, for example. MUPD8 has a custom workflow system setup to define how to execute multiple jobs at once, and how to feed stream data from one into the other. + +Samza makes the individual jobs the level of granularity of execution. Jobs communicate via named input and output streams. This implicitly defines a data flow graph between all running jobs. We chose this model to enable data flow graphs with processing stages owned by different engineers on different teams, working in different code bases, without the need to wire everything together into a single topology. + +This was motivated by our experience with Hadoop, where the data flow between jobs is implicitly defined by their input and output directories. This decentralized model has proven itself to scale well to a large organization. + +### Memory + +MUPD8 executes all of its map/update processors inside a single JVM, using threads. This is memory-efficient, as the JVM memory overhead is shared across the threads. + +Samza uses a separate JVM for each [stream processor container](../container/samza-container.html). This has the disadvantage of using more memory compared to running multiple stream processing threads within a single JVM. However, the advantage is improved isolation between tasks, which can make them more reliable. + +### Isolation + +MUPD8 provides no resource isolation between stream processors. A single badly behaved stream processor can bring down all processors on the node. + +Samza uses process level isolation between stream processor tasks, similarly to Hadoop's approach. We can enforce strict per-process memory limits. In addition, Samza supports CPU limits when used with YARN cgroups. As the YARN support for cgroups develops further, it should also become possible to support disk and network cgroup limits. + +### Further Reading + +The MUPD8 team has published a very good [paper](http://vldb.org/pvldb/vol5/p1814_wanglam_vldb2012.pdf) on the design of their system. + +## [Storm »](storm.html) diff --git a/docs/learn/documentation/versioned/comparisons/spark-streaming.md b/docs/learn/documentation/versioned/comparisons/spark-streaming.md new file mode 100644 index 0000000..b8a521f --- /dev/null +++ b/docs/learn/documentation/versioned/comparisons/spark-streaming.md @@ -0,0 +1,105 @@ +--- +layout: page +title: Spark Streaming +--- + + +*People generally want to know how similar systems compare. We've done our best to fairly contrast the feature sets of Samza with other systems. But we aren't experts in these frameworks, and we are, of course, totally biased. If we have goofed anything, please let us know and we will correct it.* + +[Spark Streaming](http://spark.apache.org/docs/latest/streaming-programming-guide.html) is a stream processing system that uses the core [Apache Spark](http://spark.apache.org/) API. Both Samza and Spark Streaming provide data consistency, fault tolerance, a programming API, etc. Spark's approach to streaming is different from Samza's. Samza processes messages as they are received, while Spark Streaming treats streaming as a series of deterministic batch operations. Spark Streaming groups the stream into batches of a fixed duration (such as 1 second). Each batch is represented as a Resilient Distributed Dataset ([RDD](http://www.cs.berkeley.edu/~matei/papers/2012/nsdi_spark.pdf)). A neverending sequence of these RDDs is called a Discretized Stream ([DStream](http://www.cs.berkeley.edu/~matei/papers/2012/hotcloud_spark_streaming.pdf)). + +### Overview of Spark Streaming + +Before going into the comparison, here is a brief overview of the Spark Streaming application. If you already are familiar with Spark Streaming, you may skip this part. There are two main parts of a Spark Streaming application: data receiving and data processing. + +* Data receiving is accomplished by a [receiver](https://spark.apache.org/docs/latest/streaming-custom-receivers.html) which receives data and stores data in Spark (though not in an RDD at this point). +* Data processing transfers the data stored in Spark into the DStream. You can then apply the two [operations](https://spark.apache.org/docs/latest/streaming-programming-guide.html#operations) -- transformations and output operations -- on the DStream. The operations for DStream are a little different from what you can use for the general Spark RDD because of the streaming environment. + +Here is an overview of the Spark Streaming's [deploy](https://spark.apache.org/docs/latest/cluster-overview.html). Spark has a SparkContext (in SparkStreaming, it’s called [StreamingContext](https://spark.apache.org/docs/1.0.0/api/scala/index.html#org.apache.spark.streaming.StreamingContext)) object in the driver program. The SparkContext talks with cluster manager (e.g. YARN, Mesos) which then allocates resources (that is, executors) for the Spark application. And executors will run tasks sent by the SparkContext ([read more](http://spark.apache.org/docs/latest/cluster-overview.html#compenents)). In YARN’s context, one executor is equivalent to one container. Tasks are what is running in the containers. The driver program runs in the client machine that submits job ([client mode](https://spark.apache.org/docs/latest/running-on-yarn.html#launching-spark-on-yarn)) or in the application manager ([cluster mode](https://spark.apache.org/docs/latest/running-on-yarn.html#launching-spark-on-yarn)). Both data receiving and data processing are tasks for executors. One receiver (receives one input stream) is a long-running task. Processing has a bunch of tasks. All the tasks are sent to the available executors. + +### Ordering and Guarantees + +Spark Streaming guarantees ordered processing of batches in a DStream. Since messages are processed in batches by side-effect-free operators, the exact ordering of messages is not important in Spark Streaming. Spark Streaming does not gurantee at-least-once or at-most-once messaging semantics because in some situations it may lose data when the driver program fails (see [fault-tolerance](#fault-tolerance)). In addition, because Spark Streaming requires transformation operations to be deterministic, it is unsuitable for nondeterministic processing, e.g. a randomized machine learning algorithm. + +Samza guarantees processing the messages as the order they appear in the partition of the stream. Samza also allows you to define a deterministic ordering of messages between partitions using a [MessageChooser](../container/streams.html). It provides an at-least-once message delivery guarantee. And it does not require operations to be deterministic. + +### State Management + +Spark Streaming provides a state DStream which keeps the state for each key and a transformation operation called [updateStateByKey](https://spark.apache.org/docs/latest/streaming-programming-guide.html#transformations) to mutate state. Everytime updateStateByKey is applied, you will get a new state DStream where all of the state is updated by applying the function passed to updateStateByKey. This transformation can serve as a basic key-value store, though it has a few drawbacks: + +* you can only apply the DStream operations to your state because essentially it's a DStream. +* does not provide any key-value access to the data. If you want to access a certain key-value, you need to iterate the whole DStream. +* it is inefficient when the state is large because every time a new batch is processed, Spark Streaming consumes the entire state DStream to update relevant keys and values. + +Spark Streaming periodically writes intermedia data of stateful operations (updateStateByKey and window-based operations) into the HDFS. In the case of updateStateByKey, the entire state RDD is written into the HDFS after every checkpointing interval. As we mentioned in the *[in memory state with checkpointing](../container/state-management.html#in-memory-state-with-checkpointing)*, writing the entire state to durable storage is very expensive when the state becomes large. + +Samza uses an embedded key-value store for [state management](../container/state-management.html#local-state-in-samza). This store is replicated as it's mutated, and supports both very high throughput writing and reading. And it gives you a lot of flexibility to decide what kind of state you want to maintain. What is more, you can also plug in other [storage engines](../container/state-management.html#other-storage-engines), which enables great flexibility in the stream processing algorithms you can use. A good comparison of different types of state manager approaches can be found [here](../container/state-management.html#approaches-to-managing-task-state). + +One of the common use cases in state management is [stream-stream join](../container/state-management.html#stream-stream-join). Though Spark Streaming has the [join](https://spark.apache.org/docs/latest/streaming-programming-guide.html#transformations) operation, this operation only joins two batches that are in the same time interval. It does not deal with the situation where events in two streams have mismatch. Spark Streaming's updateStateByKey approach to store mismatch events also has the limitation because if the number of mismatch events is large, there will be a large state, which causes the inefficience in Spark Streaming. While Samza does not have this limitation. + +### Partitioning and Parallelism + +Spark Streaming's Parallelism is achieved by splitting the job into small tasks and sending them to executors. There are two types of [parallelism in Spark Streaming](http://spark.apache.org/docs/latest/streaming-programming-guide.html#level-of-parallelism-in-data-receiving): parallelism in receiving the stream and parallelism in processing the stream. On the receiving side, one input DStream creates one receiver, and one receiver receives one input stream of data and runs as a long-running task. So in order to parallelize the receiving process, you can split one input stream into multiple input streams based on some criteria (e.g. if you are receiving a Kafka stream with some partitions, you may split this stream based on the partition). Then you can create multiple input DStreams (so multiple receivers) for these streams and the receivers will run as multiple tasks. Accordingly, you should provide enough resources by increasing the core number of the executors or bringing up more executors. Then you can combine all the input Dstreams into one DStream during the processing if necessary. On the processing side, since a DStream is a continuous sequence of RDDs, the parallelism is simply accomplished by normal RDD operations, such as map, reduceByKey, reduceByWindow (check [here] (https://spark.apache.org/docs/latest/tuning.html#level-of-parallelism)). + +Samza’s parallelism is achieved by splitting processing into independent [tasks](../api/overview.html) which can be parallelized. You can run multiple tasks in one container or only one task per container. That depends on your workload and latency requirement. For example, if you want to quickly [reprocess a stream](../jobs/reprocessing.html), you may increase the number of containers to one task per container. It is important to notice that one container only uses [one thread](../container/event-loop.html), which maps to exactly one CPU. This design attempts to simplify resource management and the isolation between jobs. + +### Buffering & Latency + +Spark streaming essentially is a sequence of small batch processes. With a fast execution engine, it can reach the latency as low as one second (from their [paper](http://www.cs.berkeley.edu/~matei/papers/2012/hotcloud_spark_streaming.pdf)). If the processing is slower than receiving, the data will be queued as DStreams in memory and the queue will keep increasing. In order to run a healthy Spark streaming application, the system should be [tuned](http://spark.apache.org/docs/latest/streaming-programming-guide.html#performance-tuning) until the speed of processing is as fast as receiving. + +Samza jobs can have latency in the low milliseconds when running with Apache Kafka. It has a different approach to buffering. The buffering mechanism is dependent on the input and output system. For example, when using [Kafka](http://kafka.apache.org/) as the input and output system, data is actually buffered to disk. This design decision, by sacrificing a little latency, allows the buffer to absorb a large backlog of messages when a job has fallen behind in its processing. + +### Fault-tolerance + +There are two kinds of failures in both Spark Streaming and Samza: worker node (running executors) failure in Spark Streaming (equivalent to container failure in Samza) and driver node (running driver program) failure (equivalent to application manager (AM) failure in Samza). + +When a worker node fails in Spark Streaming, it will be restarted by the cluster manager. When a container fails in Samza, the application manager will work with YARN to start a new container. + +When a driver node fails in Spark Streaming, Spark’s [standalone cluster mode](http://spark.apache.org/docs/latest/spark-standalone.html) will restart the driver node automatically. But it is currently not supported in YARN and Mesos. You will need other mechanisms to restart the driver node automatically. Spark Streaming can use the checkpoint in HDFS to recreate the StreamingContext. When the AM fails in Samza, YARN will handle restarting the AM. Samza will restart all the containers if the AM restarts. + +In terms of data lost, there is a difference between Spark Streaming and Samza. If the input stream is active streaming system, such as Flume, Kafka, Spark Streaming may lose data if the failure happens when the data is received but not yet replicated to other nodes (also see [SPARK-1647](https://issues.apache.org/jira/browse/SPARK-1647)). Samza will not lose data when the failure happens because it has the concept of [checkpointing](../container/checkpointing.html) that stores the offset of the latest processed message and always commits the checkpoint after processing the data. There is not data lost situation like Spark Streaming has. If a container fails, it reads from the latest checkpoint. When a Samza job recovers from a failure, it's possible that it will process some data more than once. This happens because the job restarts at the last checkpoint, and any messages that had been processed between that checkpoint and the failure are processed again. The amount of reprocessed data can be minimized by setting a small checkpoint interval period. + +### Deployment & Execution + +Spark has a SparkContext object to talk with cluster managers, which then allocate resources for the application. Currently Spark supports three types of cluster managers: [Spark standalone](http://spark.apache.org/docs/latest/spark-standalone.html), [Apache Mesos](http://mesos.apache.org/) and [Hadoop YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html). Besides these, Spark has a script for launching in [Amazon EC2](http://spark.apache.org/docs/latest/ec2-scripts.html). + +Samza only supports YARN and local execution currently. + +### Isolation + +Spark Streaming and Samza have the same isolation. Spark Streaming depends on cluster managers (e.g Mesos or YARN) and Samza depend on YARN to provide processor isolation. Different applications run in different JVMs. Data cannot be shared among different applications unless it is written to external storage. Since Samza provides out-of-box Kafka integration, it is very easy to reuse the output of other Samza jobs (see [here](../introduction/concepts.html#dataflow-graphs)). + +### Language Support + +Spark Streaming is written in Java and Scala and provides Scala, Java, and Python APIs. Samza is written in Java and Scala and has a Java API. + +### Workflow + +In Spark Streaming, you build an entire processing graph with a DSL API and deploy that entire graph as one unit. The communication between the nodes in that graph (in the form of DStreams) is provided by the framework. That is a similar to Storm. Samza is totally different -- each job is just a message-at-a-time processor, and there is no framework support for topologies. Output of a processing task always needs to go back to a message broker (e.g. Kafka). + +A positive consequence of Samza's design is that a job's output can be consumed by multiple unrelated jobs, potentially run by different teams, and those jobs are isolated from each other through Kafka's buffering. That is not the case with Storm's and Spark Streaming's framework-internal streams. + +Although a Storm/Spark Streaming job could in principle write its output to a message broker, the framework doesn't really make this easy. It seems that Storm/Spark aren't intended to used in a way where one topology's output is another topology's input. By contrast, in Samza, that mode of usage is standard. + +### Maturity + +Spark has an active user and developer community, and recently releases 1.0.0 version. It has a list of companies that use it on its [Powered by](https://cwiki.apache.org/confluence/display/SPARK/Powered+By+Spark) page. Since Spark contains Spark Streaming, Spark SQL, MLlib, GraphX and Bagel, it's tough to tell what portion of companies on the list are actually using Spark Streaming, and not just Spark. + +Samza is still young, but has just released version 0.7.0. It has a responsive community and is being developed actively. That said, it is built on solid systems such as YARN and Kafka. Samza is heavily used at LinkedIn and we hope others will find it useful as well. + +## [API Overview »](../api/overview.html) diff --git a/docs/learn/documentation/versioned/comparisons/storm.md b/docs/learn/documentation/versioned/comparisons/storm.md new file mode 100644 index 0000000..58cb508 --- /dev/null +++ b/docs/learn/documentation/versioned/comparisons/storm.md @@ -0,0 +1,124 @@ +--- +layout: page +title: Storm +--- + + +*People generally want to know how similar systems compare. We've done our best to fairly contrast the feature sets of Samza with other systems. But we aren't experts in these frameworks, and we are, of course, totally biased. If we have goofed anything, please let us know and we will correct it.* + +[Storm](http://storm-project.net/) and Samza are fairly similar. Both systems provide many of the same high-level features: a partitioned stream model, a distributed execution environment, an API for stream processing, fault tolerance, Kafka integration, etc. + +Storm and Samza use different words for similar concepts: *spouts* in Storm are similar to stream consumers in Samza, *bolts* are similar to tasks, and *tuples* are similar to messages in Samza. Storm also has some additional building blocks which don't have direct equivalents in Samza. + +### Ordering and Guarantees + +Storm allows you to choose the level of guarantee with which you want your messages to be processed: + +* The simplest mode is *at-most-once delivery*, which drops messages if they are not processed correctly, or if the machine doing the processing fails. This mode requires no special logic, and processes messages in the order they were produced by the spout. +* There is also *at-least-once delivery*, which tracks whether each input tuple (and any downstream tuples it generated) was successfully processed within a configured timeout, by keeping an in-memory record of all emitted tuples. Any tuples that are not fully processed within the timeout are re-emitted by the spout. This implies that a bolt may see the same tuple more than once, and that messages can be processed out-of-order. This mechanism also requires some co-operation from the user code, which must maintain the ancestry of records in order to properly acknowledge its input. This is explained in depth on [Storm's wiki](https://github.com/nathanmarz/storm/wiki/Guaranteeing-message-processing). +* Finally, Storm offers *exactly-once semantics* using its [Trident](https://github.com/nathanmarz/storm/wiki/Trident-tutorial) abstraction. This mode uses the same failure detection mechanism as the at-least-once mode. Tuples are actually processed at least once, but Storm's state implementation allows duplicates to be detected and ignored. (The duplicate detection only applies to state managed by Storm. If your code has other side-effects, e.g. sending messages to a service outside of the topology, it will not have exactly-once semantics.) In this mode, the spout breaks the input stream into batches, and processes batches in strictly sequential order. + +Samza also offers guaranteed delivery — currently only at-least-once delivery, but support for exactly-once semantics is planned. Within each stream partition, Samza always processes messages in the order they appear in the partition, but there is no guarantee of ordering across different input streams or partitions. This model allows Samza to offer at-least-once delivery without the overhead of ancestry tracking. In Samza, there would be no performance advantage to using at-most-once delivery (i.e. dropping messages on failure), which is why we don't offer that mode — message delivery is always guaranteed. + +Moreover, because Samza never processes messages in a partition out-of-order, it is better suited for handling keyed data. For example, if you have a stream of database updates — where later updates may replace earlier updates — then reordering the messages may change the final result. Provided that all updates for the same key appear in the same stream partition, Samza is able to guarantee a consistent state. + +### State Management + +Storm's lower-level API of bolts does not offer any help for managing state in a stream process. A bolt can maintain in-memory state (which is lost if that bolt dies), or it can make calls to a remote database to read and write state. However, a topology can usually process messages at a much higher rate than calls to a remote database can be made, so making a remote call for each message quickly becomes a bottleneck. + +As part of its higher-level Trident API, Storm offers automatic [state management](https://github.com/nathanmarz/storm/wiki/Trident-state). It keeps state in memory, and periodically checkpoints it to a remote database (e.g. Cassandra) for durability, so the cost of the remote database call is amortized over several processed tuples. By maintaining metadata alongside the state, Trident is able to achieve exactly-once processing semantics — for example, if you are counting events, this mechanism allows the counters to be correct, even when machines fail and tuples are replayed. + +Storm's approach of caching and batching state changes works well if the amount of state in each bolt is fairly small — perhaps less than 100kB. That makes it suitable for keeping track of counters, minimum, maximum and average values of a metric, and the like. However, if you need to maintain a large amount of state, this approach essentially degrades to making a database call per processed tuple, with the associated performance cost. + +Samza takes a [completely different approach](../container/state-management.html) to state management. Rather than using a remote database for durable storage, each Samza task includes an embedded key-value store, located on the same machine. Reads and writes to this store are very fast, even when the contents of the store are larger than the available memory. Changes to this key-value store are replicated to other machines in the cluster, so that if one machine dies, the state of the tasks it was running can be restored on another machine. + +By co-locating storage and processing on the same machine, Samza is able to achieve very high throughput, even when there is a large amount of state. This is necessary if you want to perform stateful operations that are not just counters. For example, if you want to perform a window join of multiple streams, or join a stream with a database table (replicated to Samza through a changelog), or group several related messages into a bigger message, then you need to maintain so much state that it is much more efficient to keep the state local to the task. + +A limitation of Samza's state handling is that it currently does not support exactly-once semantics — only at-least-once is supported right now. But we're working on fixing that, so stay tuned for updates. + +### Partitioning and Parallelism + +Storm's [parallelism model](https://github.com/nathanmarz/storm/wiki/Understanding-the-parallelism-of-a-Storm-topology) is fairly similar to Samza's. Both frameworks split processing into independent *tasks* that can run in parallel. Resource allocation is independent of the number of tasks: a small job can keep all tasks in a single process on a single machine; a large job can spread the tasks over many processes on many machines. + +The biggest difference is that Storm uses one thread per task by default, whereas Samza uses single-threaded processes (containers). A Samza container may contain multiple tasks, but there is only one thread that invokes each of the tasks in turn. This means each container is mapped to exactly one CPU core, which makes the resource model much simpler and reduces interference from other tasks running on the same machine. Storm's multithreaded model has the advantage of taking better advantage of excess capacity on an idle machine, at the cost of a less predictable resource model. + +Storm supports *dynamic rebalancing*, which means adding more threads or processes to a topology without restarting the topology or cluster. This is a convenient feature, especially during development. We haven't added this to Samza: philosophically we feel that this kind of change should go through a normal configuration management process (i.e. version control, notification, etc.) as it impacts production performance. In other words, the code and configuration of the jobs should fully recreate the state of the cluster. + +When using a transactional spout with Trident (a requirement for achieving exactly-once semantics), parallelism is potentially reduced. Trident relies on a global ordering in its input streams — that is, ordering across all partitions of a stream, not just within one partion. This means that the topology's input stream has to go through a single spout instance, effectively ignoring the partitioning of the input stream. This spout may become a bottleneck on high-volume streams. In Samza, all stream processing is parallel — there are no such choke points. + +### Deployment & Execution + +A Storm cluster is composed of a set of nodes running a *Supervisor* daemon. The supervisor daemons talk to a single master node running a daemon called *Nimbus*. The Nimbus daemon is responsible for assigning work and managing resources in the cluster. See Storm's [Tutorial](https://github.com/nathanmarz/storm/wiki/Tutorial) page for details. This is quite similar to YARN; though YARN is a bit more fully featured and intended to be multi-framework, Nimbus is better integrated with Storm. + +Yahoo! has also released [Storm-YARN](https://github.com/yahoo/storm-yarn). As described in [this Yahoo! blog post](http://developer.yahoo.com/blogs/ydn/storm-yarn-released-open-source-143745133.html), Storm-YARN is a wrapper that starts a single Storm cluster (complete with Nimbus, and Supervisors) inside a YARN grid. + +There are a lot of similarities between Storm's Nimbus and YARN's ResourceManager, as well as between Storm's Supervisor and YARN's Node Managers. Rather than writing our own resource management framework, or running a second one inside of YARN, we decided that Samza should use YARN directly, as a first-class citizen in the YARN ecosystem. YARN is stable, well adopted, fully-featured, and inter-operable with Hadoop. It also provides a bunch of nice features like security (user authentication), cgroup process isolation, etc. + +The YARN support in Samza is pluggable, so you can swap it for a different execution framework if you wish. + +### Language Support + +Storm is written in Java and Clojure but has good support for non-JVM languages. It follows a model similar to MapReduce Streaming: the non-JVM task is launched in a separate process, data is sent to its stdin, and output is read from its stdout. + +Samza is written in Java and Scala. It is built with multi-language support in mind, but currently only supports JVM languages. + +### Workflow + +Storm provides modeling of *topologies* (a processing graph of multiple stages) [in code](https://github.com/nathanmarz/storm/wiki/Tutorial). Trident provides a further [higher-level API](https://github.com/nathanmarz/storm/wiki/Trident-tutorial) on top of this, including familiar relational-like operators such as filters, grouping, aggregation and joins. This means the entire topology is wired up in one place, which has the advantage that it is documented in code, but has the disadvantage that the entire topology needs to be developed and deployed as a whole. + +In Samza, each job is an independent entity. You can define multiple jobs in a single codebase, or you can have separate teams working on different jobs using different codebases. Each job is deployed, started and stopped independently. Jobs communicate only through named streams, and you can add jobs to the system without affecting any other jobs. This makes Samza well suited for handling the data flow in a large company. + +Samza's approach can be emulated in Storm by connecting two separate topologies via a broker, such as Kafka. However, Storm's implementation of exactly-once semantics only works within a single topology. + +### Maturity + +We can't speak to Storm's maturity, but it has an [impressive number of adopters](https://github.com/nathanmarz/storm/wiki/Powered-By), a strong feature set, and seems to be under active development. It integrates well with many common messaging systems (RabbitMQ, Kestrel, Kafka, etc). + +Samza is pretty immature, though it builds on solid components. YARN is fairly new, but is already being run on 3000+ node clusters at Yahoo!, and the project is under active development by both [Hortonworks](http://hortonworks.com/) and [Cloudera](http://www.cloudera.com/content/cloudera/en/home.html). Kafka has a strong [powered by](https://cwiki.apache.org/KAFKA/powered-by.html) page, and has seen increased adoption recently. It's also frequently used with Storm. Samza is a brand new project that is in use at LinkedIn. Our hope is that others will find it useful, and adopt it as well. + +### Buffering & Latency + +Storm uses [ZeroMQ](http://zeromq.org/) for non-durable communication between bolts, which enables extremely low latency transmission of tuples. Samza does not have an equivalent mechanism, and always writes task output to a stream. + +On the flip side, when a bolt is trying to send messages using ZeroMQ, and the consumer can't read them fast enough, the ZeroMQ buffer in the producer's process begins to fill up with messages. If this buffer grows too much, the topology's processing timeout may be reached, which causes messages to be re-emitted at the spout and makes the problem worse by adding even more messages to the buffer. In order to prevent such overflow, you can configure a maximum number of messages that can be in flight in the topology at any one time; when that threshold is reached, the spout blocks until some of the messages in flight are fully processed. This mechanism allows back pressure, but requires [topology.max.spout.pending](http://nathanmarz.github.io/storm/doc/backtype/storm/Config.html#TOPOLOGY_MAX_SPOUT_PENDING) to be carefully configured. If a single bolt in a topology starts running slow, the processing in the entire topology grinds to a halt. + +A lack of a broker between bolts also adds complexity when trying to deal with fault tolerance and messaging semantics. Storm has a [clever mechanism](https://github.com/nathanmarz/storm/wiki/Guaranteeing-message-processing) for detecting tuples that failed to be processed, but Samza doesn't need such a mechanism because every input and output stream is fault-tolerant and replicated. + +Samza takes a different approach to buffering. We buffer to disk at every hop between a StreamTask. This decision, and its trade-offs, are described in detail on the [Comparison Introduction](introduction.html) page. This design decision makes durability guarantees easy, and has the advantage of allowing the buffer to absorb a large backlog of messages if a job has fallen behind in its processing. However, it comes at the price of slightly higher latency. + +As described in the *workflow* section above, Samza's approach can be emulated in Storm, but comes with a loss in functionality. + +### Isolation + +Storm provides standard UNIX process-level isolation. Your topology can impact another topology's performance (or vice-versa) if too much CPU, disk, network, or memory is used. + +Samza relies on YARN to provide resource-level isolation. Currently, YARN provides explicit controls for memory and CPU limits (through [cgroups](../yarn/isolation.html)), and both have been used successfully with Samza. No isolation for disk or network is provided by YARN at this time. + +### Distributed RPC + +In Storm, you can write topologies which not only accept a stream of fixed events, but also allow clients to run distributed computations on demand. The query is sent into the topology as a tuple on a special spout, and when the topology has computed the answer, it is returned to the client (who was synchronously waiting for the answer). This facility is called [Distributed RPC](https://github.com/nathanmarz/storm/wiki/Distributed-RPC) (DRPC). + +Samza does not currently have an equivalent API to DRPC, but you can build it yourself using Samza's stream processing primitives. + +### Data Model + +Storm models all messages as *tuples* with a defined data model but pluggable serialization. + +Samza's serialization and data model are both pluggable. We are not terribly opinionated about which approach is best. + +## [Spark Streaming »](spark-streaming.html) diff --git a/docs/learn/documentation/versioned/container/checkpointing.md b/docs/learn/documentation/versioned/container/checkpointing.md new file mode 100644 index 0000000..6f8c6d6 --- /dev/null +++ b/docs/learn/documentation/versioned/container/checkpointing.md @@ -0,0 +1,124 @@ +--- +layout: page +title: Checkpointing +--- + + +Samza provides fault-tolerant processing of streams: Samza guarantees that messages won't be lost, even if your job crashes, if a machine dies, if there is a network fault, or something else goes wrong. In order to provide this guarantee, Samza expects the [input system](streams.html) to meet the following requirements: + +* The stream may be sharded into one or more *partitions*. Each partition is independent from the others, and is replicated across multiple machines (the stream continues to be available, even if a machine fails). +* Each partition consists of a sequence of messages in a fixed order. Each message has an *offset*, which indicates its position in that sequence. Messages are always consumed sequentially within each partition. +* A Samza job can start consuming the sequence of messages from any starting offset. + +Kafka meets these requirements, but they can also be implemented with other message broker systems. + +As described in the [section on SamzaContainer](samza-container.html), each task instance of your job consumes one partition of an input stream. Each task has a *current offset* for each input stream: the offset of the next message to be read from that stream partition. Every time a message is read from the stream, the current offset moves forwards. + +If a Samza container fails, it needs to be restarted (potentially on another machine) and resume processing where the failed container left off. In order to enable this, a container periodically checkpoints the current offset for each task instance. + +Illustration of checkpointing + +When a Samza container starts up, it looks for the most recent checkpoint and starts consuming messages from the checkpointed offsets. If the previous container failed unexpectedly, the most recent checkpoint may be slightly behind the current offsets (i.e. the job may have consumed some more messages since the last checkpoint was written), but we can't know for sure. In that case, the job may process a few messages again. + +This guarantee is called *at-least-once processing*: Samza ensures that your job doesn't miss any messages, even if containers need to be restarted. However, it is possible for your job to see the same message more than once when a container is restarted. We are planning to address this in a future version of Samza, but for now it is just something to be aware of: for example, if you are counting page views, a forcefully killed container could cause events to be slightly over-counted. You can reduce duplication by checkpointing more frequently, at a slight performance cost. + +For checkpoints to be effective, they need to be written somewhere where they will survive faults. Samza allows you to write checkpoints to the file system (using FileSystemCheckpointManager), but that doesn't help if the machine fails and the container needs to be restarted on another machine. The most common configuration is to use Kafka for checkpointing. You can enable this with the following job configuration: + +{% highlight jproperties %} +# The name of your job determines the name under which checkpoints will be stored +job.name=example-job + +# Define a system called "kafka" for consuming and producing to a Kafka cluster +systems.kafka.samza.factory=org.apache.samza.system.kafka.KafkaSystemFactory + +# Declare that we want our job's checkpoints to be written to Kafka +task.checkpoint.factory=org.apache.samza.checkpoint.kafka.KafkaCheckpointManagerFactory +task.checkpoint.system=kafka + +# By default, a checkpoint is written every 60 seconds. You can change this if you like. +task.commit.ms=60000 +{% endhighlight %} + +In this configuration, Samza writes checkpoints to a separate Kafka topic called \_\_samza\_checkpoint\_<job-name>\_<job-id> (in the example configuration above, the topic would be called \_\_samza\_checkpoint\_example-job\_1). Once per minute, Samza automatically sends a message to this topic, in which the current offsets of the input streams are encoded. When a Samza container starts up, it looks for the most recent offset message in this topic, and loads that checkpoint. + +Sometimes it can be useful to use checkpoints only for some input streams, but not for others. In this case, you can tell Samza to ignore any checkpointed offsets for a particular stream name: + +{% highlight jproperties %} +# Ignore any checkpoints for the topic "my-special-topic" +systems.kafka.streams.my-special-topic.samza.reset.offset=true + +# Always start consuming "my-special-topic" at the oldest available offset +systems.kafka.streams.my-special-topic.samza.offset.default=oldest +{% endhighlight %} + +The following table explains the meaning of these configuration parameters: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter nameValueMeaning
systems.<system>.
streams.<stream>.
samza.reset.offset
false (default)When container starts up, resume processing from last checkpoint
trueIgnore checkpoint (pretend that no checkpoint is present)
systems.<system>.
streams.<stream>.
samza.offset.default
upcoming (default)When container starts and there is no checkpoint (or the checkpoint is ignored), only process messages that are published after the job is started, but no old messages
oldestWhen container starts and there is no checkpoint (or the checkpoint is ignored), jump back to the oldest available message in the system, and consume all messages from that point onwards (most likely this means repeated processing of messages already seen previously)
+ +Note that the example configuration above causes your tasks to start consuming from the oldest offset *every time a container starts up*. This is useful in case you have some in-memory state in your tasks that you need to rebuild from source data in an input stream. If you are using streams in this way, you may also find [bootstrap streams](streams.html) useful. + +### Manipulating Checkpoints Manually + +If you want to make a one-off change to a job's consumer offsets, for example to force old messages to be [processed again](../jobs/reprocessing.html) with a new version of your code, you can use CheckpointTool to inspect and manipulate the job's checkpoint. The tool is included in Samza's [source repository](/contribute/code.html). + +To inspect a job's latest checkpoint, you need to specify your job's config file, so that the tool knows which job it is dealing with: + +{% highlight bash %} +samza-example/target/bin/checkpoint-tool.sh \ + --config-path=file:///path/to/job/config.properties +{% endhighlight %} + +This command prints out the latest checkpoint in a properties file format. You can save the output to a file, and edit it as you wish. For example, to jump back to the oldest possible point in time, you can set all the offsets to 0. Then you can feed that properties file back into checkpoint-tool.sh and save the modified checkpoint: + +{% highlight bash %} +samza-example/target/bin/checkpoint-tool.sh \ + --config-path=file:///path/to/job/config.properties \ + --new-offsets=file:///path/to/new/offsets.properties +{% endhighlight %} + +Note that Samza only reads checkpoints on container startup. In order for your checkpoint change to take effect, you need to first stop the job, then save the modified offsets, and then start the job again. If you write a checkpoint while the job is running, it will most likely have no effect. + +## [State Management »](state-management.html) diff --git a/docs/learn/documentation/versioned/container/event-loop.md b/docs/learn/documentation/versioned/container/event-loop.md new file mode 100644 index 0000000..f0f21b0 --- /dev/null +++ b/docs/learn/documentation/versioned/container/event-loop.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Event Loop +--- + + +The event loop is the [container](samza-container.html)'s single thread that is in charge of [reading and writing messages](streams.html), [flushing metrics](metrics.html), [checkpointing](checkpointing.html), and [windowing](windowing.html). + +Samza uses a single thread because every container is designed to use a single CPU core; to get more parallelism, simply run more containers. This uses a bit more memory than multithreaded parallelism, because each JVM has some overhead, but it simplifies resource management and improves isolation between jobs. This helps Samza jobs run reliably on a multitenant cluster, where many different jobs written by different people are running at the same time. + +You are strongly discouraged from using threads in your job's code. Samza uses multiple threads internally for communicating with input and output streams, but all message processing and user code runs on a single-threaded event loop. In general, Samza is not thread-safe. + +### Event Loop Internals + +A container may have multiple [SystemConsumers](../api/javadocs/org/apache/samza/system/SystemConsumer.html) for consuming messages from different input systems. Each SystemConsumer reads messages on its own thread, but writes messages into a shared in-process message queue. The container uses this queue to funnel all of the messages into the event loop. + +The event loop works as follows: + +1. Take a message from the incoming message queue; +2. Give the message to the appropriate [task instance](samza-container.html) by calling process() on it; +3. Call window() on the task instance if it implements [WindowableTask](../api/javadocs/org/apache/samza/task/WindowableTask.html), and the window time has expired; +4. Send any output from the process() and window() calls to the appropriate [SystemProducers](../api/javadocs/org/apache/samza/system/SystemProducer.html); +5. Write checkpoints for any tasks whose [commit interval](checkpointing.html) has elapsed. + +The container does this, in a loop, until it is shut down. Note that although there can be multiple task instances within a container (depending on the number of input stream partitions), their process() and window() methods are all called on the same thread, never concurrently on different threads. + +### Lifecycle Listeners + +Sometimes, you need to run your own code at specific points in a task's lifecycle. For example, you might want to set up some context in the container whenever a new message arrives, or perform some operations on startup or shutdown. + +To receive notifications when such events happen, you can implement the [TaskLifecycleListenerFactory](../api/javadocs/org/apache/samza/task/TaskLifecycleListenerFactory.html) interface. It returns a [TaskLifecycleListener](../api/javadocs/org/apache/samza/task/TaskLifecycleListener.html), whose methods are called by Samza at the appropriate times. + +You can then tell Samza to use your lifecycle listener with the following properties in your job configuration: + +{% highlight jproperties %} +# Define a listener called "my-listener" by giving the factory class name +task.lifecycle.listener.my-listener.class=com.example.foo.MyListenerFactory + +# Enable it in this job (multiple listeners can be separated by commas) +task.lifecycle.listeners=my-listener +{% endhighlight %} + +The Samza container creates one instance of your [TaskLifecycleListener](../api/javadocs/org/apache/samza/task/TaskLifecycleListener.html). If the container has multiple task instances (processing different input stream partitions), the beforeInit, afterInit, beforeClose and afterClose methods are called for each task instance. The [TaskContext](../api/javadocs/org/apache/samza/task/TaskContext.html) argument of those methods gives you more information about the partitions. + +## [JMX »](jmx.html) diff --git a/docs/learn/documentation/versioned/container/jmx.md b/docs/learn/documentation/versioned/container/jmx.md new file mode 100644 index 0000000..bdd5614 --- /dev/null +++ b/docs/learn/documentation/versioned/container/jmx.md @@ -0,0 +1,40 @@ +--- +layout: page +title: JMX +--- + + +Samza's containers and YARN ApplicationMaster enable [JMX](http://docs.oracle.com/javase/tutorial/jmx/) by default. JMX can be used for managing the JVM; for example, you can connect to it using [jconsole](http://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html), which is included in the JDK. + +You can tell Samza to publish its internal [metrics](metrics.html), and any custom metrics you define, as JMX MBeans. To enable this, set the following properties in your job configuration: + +{% highlight jproperties %} +# Define a Samza metrics reporter called "jmx", which publishes to JMX +metrics.reporter.jmx.class=org.apache.samza.metrics.reporter.JmxReporterFactory + +# Use it (if you have multiple reporters defined, separate them with commas) +metrics.reporters=jmx +{% endhighlight %} + +JMX needs to be configured to use a specific port, but in a distributed environment, there is no way of knowing in advance which ports are available on the machines running your containers. Therefore Samza chooses the JMX port randomly. If you need to connect to it, you can find the port by looking in the container's logs, which report the JMX server details as follows: + + 2014-06-02 21:50:17 JmxServer [INFO] According to InetAddress.getLocalHost.getHostName we are samza-grid-1234.example.com + 2014-06-02 21:50:17 JmxServer [INFO] Started JmxServer registry port=50214 server port=50215 url=service:jmx:rmi://localhost:50215/jndi/rmi://localhost:50214/jmxrmi + 2014-06-02 21:50:17 JmxServer [INFO] If you are tunneling, you might want to try JmxServer registry port=50214 server port=50215 url=service:jmx:rmi://samza-grid-1234.example.com:50215/jndi/rmi://samza-grid-1234.example.com:50214/jmxrmi + +## [JobRunner »](../jobs/job-runner.html) diff --git a/docs/learn/documentation/versioned/container/metrics.md b/docs/learn/documentation/versioned/container/metrics.md new file mode 100644 index 0000000..8ec7740 --- /dev/null +++ b/docs/learn/documentation/versioned/container/metrics.md @@ -0,0 +1,102 @@ +--- +layout: page +title: Metrics +--- + + +When you're running a stream process in production, it's important that you have good metrics to track the health of your job. In order to make this easy, Samza includes a metrics library. It is used by Samza itself to generate some standard metrics such as message throughput, but you can also use it in your task code to emit custom metrics. + +Metrics can be reported in various ways. You can expose them via [JMX](jmx.html), which is useful in development. In production, a common setup is for each Samza container to periodically publish its metrics to a "metrics" Kafka topic, in which the metrics from all Samza jobs are aggregated. You can then consume this stream in another Samza job, and send the metrics to your favorite graphing system such as [Graphite](http://graphite.wikidot.com/). + +To set up your job to publish metrics to Kafka, you can use the following configuration: + +{% highlight jproperties %} +# Define a metrics reporter called "snapshot", which publishes metrics +# every 60 seconds. +metrics.reporters=snapshot +metrics.reporter.snapshot.class=org.apache.samza.metrics.reporter.MetricsSnapshotReporterFactory + +# Tell the snapshot reporter to publish to a topic called "metrics" +# in the "kafka" system. +metrics.reporter.snapshot.stream=kafka.metrics + +# Encode metrics data as JSON. +serializers.registry.metrics.class=org.apache.samza.serializers.MetricsSnapshotSerdeFactory +systems.kafka.streams.metrics.samza.msg.serde=metrics +{% endhighlight %} + +With this configuration, the job automatically sends several JSON-encoded messages to the "metrics" topic in Kafka every 60 seconds. The messages look something like this: + +{% highlight json %} +{ + "header": { + "container-name": "samza-container-0", + "host": "samza-grid-1234.example.com", + "job-id": "1", + "job-name": "my-samza-job", + "reset-time": 1401729000347, + "samza-version": "0.0.1", + "source": "Partition-2", + "time": 1401729420566, + "version": "0.0.1" + }, + "metrics": { + "org.apache.samza.container.TaskInstanceMetrics": { + "commit-calls": 7, + "commit-skipped": 77948, + "kafka-input-topic-offset": "1606", + "messages-sent": 985, + "process-calls": 1093, + "send-calls": 985, + "send-skipped": 76970, + "window-calls": 0, + "window-skipped": 77955 + } + } +} +{% endhighlight %} + +There is a separate message for each task instance, and the header tells you the job name, job ID and partition of the task. The metrics allow you to see how many messages have been processed and sent, the current offset in the input stream partition, and other details. There are additional messages which give you metrics about the JVM (heap size, garbage collection information, threads etc.), internal metrics of the Kafka producers and consumers, and more. + +It's easy to generate custom metrics in your job, if there's some value you want to keep an eye on. You can use Samza's built-in metrics framework, which is similar in design to Coda Hale's [metrics](http://metrics.codahale.com/) library. + +You can register your custom metrics through a [MetricsRegistry](../api/javadocs/org/apache/samza/metrics/MetricsRegistry.html). Your stream task needs to implement [InitableTask](../api/javadocs/org/apache/samza/task/InitableTask.html), so that you can get the metrics registry from the [TaskContext](../api/javadocs/org/apache/samza/task/TaskContext.html). This simple example shows how to count the number of messages processed by your task: + +{% highlight java %} +public class MyJavaStreamTask implements StreamTask, InitableTask { + private Counter messageCount; + + public void init(Config config, TaskContext context) { + this.messageCount = context + .getMetricsRegistry() + .newCounter(getClass().getName(), "message-count"); + } + + public void process(IncomingMessageEnvelope envelope, + MessageCollector collector, + TaskCoordinator coordinator) { + messageCount.inc(); + } +} +{% endhighlight %} + +Samza currently supports two kind of metrics: [counters](../api/javadocs/org/apache/samza/metrics/Counter.html) and [gauges](../api/javadocs/org/apache/samza/metrics/Gauge.html). Use a counter when you want to track how often something occurs, and a gauge when you want to report the level of something, such as the size of a buffer. Each task instance (for each input stream partition) gets its own set of metrics. + +If you want to report metrics in some other way, e.g. directly to a graphing system (without going via Kafka), you can implement a [MetricsReporterFactory](../api/javadocs/org/apache/samza/metrics/MetricsReporterFactory.html) and reference it in your job configuration. + +## [Windowing »](windowing.html) diff --git a/docs/learn/documentation/versioned/container/samza-container.md b/docs/learn/documentation/versioned/container/samza-container.md new file mode 100644 index 0000000..9f46414 --- /dev/null +++ b/docs/learn/documentation/versioned/container/samza-container.md @@ -0,0 +1,105 @@ +--- +layout: page +title: SamzaContainer +--- + + +The SamzaContainer is responsible for managing the startup, execution, and shutdown of one or more [StreamTask](../api/overview.html) instances. Each SamzaContainer typically runs as an indepentent Java virtual machine. A Samza job can consist of several SamzaContainers, potentially running on different machines. + +When a SamzaContainer starts up, it does the following: + +1. Get last checkpointed offset for each input stream partition that it consumes +2. Create a "reader" thread for every input stream partition that it consumes +3. Start metrics reporters to report metrics +4. Start a checkpoint timer to save your task's input stream offsets every so often +5. Start a window timer to trigger your task's [window method](../api/javadocs/org/apache/samza/task/WindowableTask.html), if it is defined +6. Instantiate and initialize your StreamTask once for each input stream partition +7. Start an event loop that takes messages from the input stream reader threads, and gives them to your StreamTasks +8. Notify lifecycle listeners during each one of these steps + +Let's start in the middle, with the instantiation of a StreamTask. The following sections of the documentation cover the other steps. + +### Tasks and Partitions + +When the container starts, it creates instances of the [task class](../api/overview.html) that you've written. If the task class implements the [InitableTask](../api/javadocs/org/apache/samza/task/InitableTask.html) interface, the SamzaContainer will also call the init() method. + +{% highlight java %} +/** Implement this if you want a callback when your task starts up. */ +public interface InitableTask { + void init(Config config, TaskContext context); +} +{% endhighlight %} + +By default, how many instances of your task class are created depends on the number of partitions in the job's input streams. If your Samza job has ten partitions, there will be ten instantiations of your task class: one for each partition. The first task instance will receive all messages for partition one, the second instance will receive all messages for partition two, and so on. + +Illustration of tasks consuming partitions + +The number of partitions in the input streams is determined by the systems from which you are consuming. For example, if your input system is Kafka, you can specify the number of partitions when you create a topic from the command line or using the num.partitions in Kafka's server properties file. + +If a Samza job has more than one input stream, the number of task instances for the Samza job is the maximum number of partitions across all input streams. For example, if a Samza job is reading from PageViewEvent (12 partitions), and ServiceMetricEvent (14 partitions), then the Samza job would have 14 task instances (numbered 0 through 13). Task instances 12 and 13 only receive events from ServiceMetricEvent, because there is no corresponding PageViewEvent partition. + +With this default approach to assigning input streams to task instances, Samza is effectively performing a group-by operation on the input streams with their partitions as the key. Other strategies for grouping input stream partitions are possible by implementing a new [SystemStreamPartitionGrouper](../api/javadocs/org/apache/samza/container/SystemStreamPartitionGrouper.html) and factory, and configuring the job to use it via the job.systemstreampartition.grouper.factory configuration value. + +Samza provides the above-discussed per-partition grouper as well as the [GroupBySystemStreamPartitionGrouper](../api/javadocs/org/apache/samza/container/systemstreampartition/groupers/GroupBySystemStreamPartition), which provides a separate task class instance for every input stream partition, effectively grouping by the input stream itself. This provides maximum scalability in terms of how many containers can be used to process those input streams and is appropriate for very high volume jobs that need no grouping of the input streams. + +Considering the above example of a PageViewEvent partitioned 12 ways and a ServiceMetricEvent partitioned 14 ways, the GroupBySystemStreamPartitionGrouper would create 12 + 14 = 26 task instances, which would then be distributed across the number of containers configured, as discussed below. + +Note that once a job has been started using a particular SystemStreamPartitionGrouper and that job is using state or checkpointing, it is not possible to change that grouping in subsequent job starts, as the previous checkpoints and state information would likely be incorrect under the new grouping approach. + +### Containers and resource allocation + +Although the number of task instances is fixed — determined by the number of input partitions — you can configure how many containers you want to use for your job. If you are [using YARN](../jobs/yarn-jobs.html), the number of containers determines what CPU and memory resources are allocated to your job. + +If the data volume on your input streams is small, it might be sufficient to use just one SamzaContainer. In that case, Samza still creates one task instance per input partition, but all those tasks run within the same container. At the other extreme, you can create as many containers as you have partitions, and Samza will assign one task instance to each container. + +Each SamzaContainer is designed to use one CPU core, so it uses a [single-threaded event loop](event-loop.html) for execution. It's not advisable to create your own threads within a SamzaContainer. If you need more parallelism, please configure your job to use more containers. + +Any [state](state-management.html) in your job belongs to a task instance, not to a container. This is a key design decision for Samza's scalability: as your job's resource requirements grow and shrink, you can simply increase or decrease the number of containers, but the number of task instances remains unchanged. As you scale up or down, the same state remains attached to each task instance. Task instances may be moved from one container to another, and any persistent state managed by Samza will be moved with it. This allows the job's processing semantics to remain unchanged, even as you change the job's parallelism. + +### Joining multiple input streams + +If your job has multiple input streams, Samza provides a simple but powerful mechanism for joining data from different streams: each task instance receives messages from one partition of *each* of the input streams. For example, say you have two input streams, A and B, each with four partitions. Samza creates four task instances to process them, and assigns the partitions as follows: + + + + + + + + + + + + + + + + + + + + + + +
Task instanceConsumes stream partitions
0stream A partition 0, stream B partition 0
1stream A partition 1, stream B partition 1
2stream A partition 2, stream B partition 2
3stream A partition 3, stream B partition 3
+ +Thus, if you want two events in different streams to be processed by the same task instance, you need to ensure they are sent to the same partition number. You can achieve this by using the same partitioning key when [sending the messages](../api/overview.html). Joining streams is discussed in detail in the [state management](state-management.html) section. + +There is one caveat in all of this: Samza currently assumes that a stream's partition count will never change. Partition splitting or repartitioning is not supported. If an input stream has N partitions, it is expected that it has always had, and will always have N partitions. If you want to re-partition a stream, you can write a job that reads messages from the stream, and writes them out to a new stream with the required number of partitions. For example, you could read messages from PageViewEvent, and write them to PageViewEventRepartition. + +## [Streams »](streams.html) diff --git a/docs/learn/documentation/versioned/container/serialization.md b/docs/learn/documentation/versioned/container/serialization.md new file mode 100644 index 0000000..ff7d8b9 --- /dev/null +++ b/docs/learn/documentation/versioned/container/serialization.md @@ -0,0 +1,64 @@ +--- +layout: page +title: Serialization +--- + + +Every message that is read from or written to a [stream](streams.html) or a [persistent state store](state-management.html) needs to eventually be serialized to bytes (which are sent over the network or written to disk). There are various places where that serialization and deserialization can happen: + +1. In the client library: for example, the library for publishing to Kafka and consuming from Kafka supports pluggable serialization. +2. In the task implementation: your [process method](../api/overview.html) can use raw byte arrays as inputs and outputs, and do any parsing and serialization itself. +3. Between the two: Samza provides a layer of serializers and deserializers, or *serdes* for short. + +You can use whatever makes sense for your job; Samza doesn't impose any particular data model or serialization scheme on you. However, the cleanest solution is usually to use Samza's serde layer. The following configuration example shows how to use it. + +{% highlight jproperties %} +# Define a system called "kafka" +systems.kafka.samza.factory=org.apache.samza.system.kafka.KafkaSystemFactory + +# The job is going to consume a topic called "PageViewEvent" from the "kafka" system +task.inputs=kafka.PageViewEvent + +# Define a serde called "json" which parses/serializes JSON objects +serializers.registry.json.class=org.apache.samza.serializers.JsonSerdeFactory + +# Define a serde called "integer" which encodes an integer as 4 binary bytes (big-endian) +serializers.registry.integer.class=org.apache.samza.serializers.IntegerSerdeFactory + +# For messages in the "PageViewEvent" topic, the key (the ID of the user viewing the page) +# is encoded as a binary integer, and the message is encoded as JSON. +systems.kafka.streams.PageViewEvent.samza.key.serde=integer +systems.kafka.streams.PageViewEvent.samza.msg.serde=json + +# Define a key-value store which stores the most recent page view for each user ID. +# Again, the key is an integer user ID, and the value is JSON. +stores.LastPageViewPerUser.factory=org.apache.samza.storage.kv.KeyValueStorageEngineFactory +stores.LastPageViewPerUser.changelog=kafka.last-page-view-per-user +stores.LastPageViewPerUser.key.serde=integer +stores.LastPageViewPerUser.msg.serde=json +{% endhighlight %} + +Each serde is defined with a factory class. Samza comes with several builtin serdes for UTF-8 strings, binary-encoded integers, JSON (requires the samza-serializers dependency) and more. You can also create your own serializer by implementing the [SerdeFactory](../api/javadocs/org/apache/samza/serializers/SerdeFactory.html) interface. + +The name you give to a serde (such as "json" and "integer" in the example above) is only for convenience in your job configuration; you can choose whatever name you like. For each stream and each state store, you can use the serde name to declare how messages should be serialized and deserialized. + +If you don't declare a serde, Samza simply passes objects through between your task instance and the system stream. In that case your task needs to send and receive whatever type of object the underlying client library uses. + +All the Samza APIs for sending and receiving messages are typed as *Object*. This means that you have to cast messages to the correct type before you can use them. It's a little bit more code, but it has the advantage that Samza is not restricted to any particular data model. + +## [Checkpointing »](checkpointing.html) diff --git a/docs/learn/documentation/versioned/container/state-management.md b/docs/learn/documentation/versioned/container/state-management.md new file mode 100644 index 0000000..d71de0b --- /dev/null +++ b/docs/learn/documentation/versioned/container/state-management.md @@ -0,0 +1,238 @@ +--- +layout: page +title: State Management +--- + + +One of the more interesting features of Samza is stateful stream processing. Tasks can store and query data through APIs provided by Samza. That data is stored on the same machine as the stream task; compared to connecting over the network to a remote database, Samza's local state allows you to read and write large amounts of data with better performance. Samza replicates this state across multiple machines for fault-tolerance (described in detail below). + +Some stream processing jobs don't require state: if you only need to transform one message at a time, or filter out messages based on some condition, your job can be simple. Every call to your task's [process method](../api/overview.html) handles one incoming message, and each message is independent of all the other messages. + +However, being able to maintain state opens up many possibilities for sophisticated stream processing jobs: joining input streams, grouping messages and aggregating groups of messages. By analogy to SQL, the *select* and *where* clauses of a query are usually stateless, but *join*, *group by* and aggregation functions like *sum* and *count* require state. Samza doesn't yet provide a higher-level SQL-like language, but it does provide lower-level primitives that you can use to implement streaming aggregation and joins. + +### Common use cases for stateful processing + +First, let's look at some simple examples of stateful stream processing that might be seen in the backend of a consumer website. Later in this page we'll discuss how to implement these applications using Samza's built-in key-value storage capabilities. + +#### Windowed aggregation + +*Example: Counting the number of page views for each user per hour* + +In this case, your state typically consists of a number of counters which are incremented when a message is processed. The aggregation is typically limited to a time window (e.g. 1 minute, 1 hour, 1 day) so that you can observe changes of activity over time. This kind of windowed processing is common for ranking and relevance, detecting "trending topics", as well as real-time reporting and monitoring. + +The simplest implementation keeps this state in memory (e.g. a hash map in the task instances), and writes it to a database or output stream at the end of every time window. However, you need to consider what happens when a container fails and your in-memory state is lost. You might be able to restore it by processing all the messages in the current window again, but that might take a long time if the window covers a long period of time. Samza can speed up this recovery by making the state fault-tolerant rather than trying to recompute it. + +#### Table-table join + +*Example: Join a table of user profiles to a table of user settings by user\_id and emit the joined stream* + +You might wonder: does it make sense to join two tables in a stream processing system? It does if your database can supply a log of all the changes in the database. There is a [duality between a database and a changelog stream](http://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying): you can publish every data change to a stream, and if you consume the entire stream from beginning to end, you can reconstruct the entire contents of the database. Samza is designed for data processing jobs that follow this philosophy. + +If you have changelog streams for several database tables, you can write a stream processing job which keeps the latest state of each table in a local key-value store, where you can access it much faster than by making queries to the original database. Now, whenever data in one table changes, you can join it with the latest data for the same key in the other table, and output the joined result. + +There are several real-life examples of data normalization which essentially work in this way: + +* E-commerce companies like Amazon and EBay need to import feeds of merchandise from merchants, normalize them by product, and present products with all the associated merchants and pricing information. +* Web search requires building a crawler which creates essentially a [table of web page contents](http://labs.yahoo.com/files/YahooWebmap.pdf) and joins on all the relevance attributes such as click-through ratio or pagerank. +* Social networks take feeds of user-entered text and need to normalize out entities such as companies, schools, and skills. + +Each of these use cases is a massively complex data normalization problem that can be thought of as constructing a materialized view over many input tables. Samza can help implement such data processing pipelines robustly. + +#### Stream-table join + +*Example: Augment a stream of page view events with the user's ZIP code (perhaps to allow aggregation by zip code in a later stage)* + +Joining side-information to a real-time feed is a classic use for stream processing. It's particularly common in advertising, relevance ranking, fraud detection and other domains. Activity events such as page views generally only include a small number of attributes, such as the ID of the viewer and the viewed items, but not detailed attributes of the viewer and the viewed items, such as the ZIP code of the user. If you want to aggregate the stream by attributes of the viewer or the viewed items, you need to join with the users table or the items table respectively. + +In data warehouse terminology, you can think of the raw event stream as rows in the central fact table, which needs to be joined with dimension tables so that you can use attributes of the dimensions in your analysis. + +#### Stream-stream join + +*Example: Join a stream of ad clicks to a stream of ad impressions (to link the information on when the ad was shown to the information on when it was clicked)* + +A stream join is useful for "nearly aligned" streams, where you expect to receive related events on several input streams, and you want to combine them into a single output event. You cannot rely on the events arriving at the stream processor at the same time, but you can set a maximum period of time over which you allow the events to be spread out. + +In order to perform a join between streams, your job needs to buffer events for the time window over which you want to join. For short time windows, you can do this in memory (at the risk of losing events if the machine fails). You can also use Samza's state store to buffer events, which supports buffering more messages than you can fit in memory. + +#### More + +There are many variations of joins and aggregations, but most are essentially variations and combinations of the above patterns. + +### Approaches to managing task state + +So how do systems support this kind of stateful processing? We'll lead in by describing what we have seen in other stream processing systems, and then describe what Samza does. + +#### In-memory state with checkpointing + +A simple approach, common in academic stream processing systems, is to periodically save the task's entire in-memory data to durable storage. This approach works well if the in-memory state consists of only a few values. However, you have to store the complete task state on each checkpoint, which becomes increasingly expensive as task state grows. Unfortunately, many non-trivial use cases for joins and aggregation have large amounts of state — often many gigabytes. This makes full dumps of the state impractical. + +Some academic systems produce *diffs* in addition to full checkpoints, which are smaller if only some of the state has changed since the last checkpoint. [Storm's Trident abstraction](../comparisons/storm.html) similarly keeps an in-memory cache of state, and periodically writes any changes to a remote store such as Cassandra. However, this optimization only helps if most of the state remains unchanged. In some use cases, such as stream joins, it is normal to have a lot of churn in the state, so this technique essentially degrades to making a remote database request for every message (see below). + +#### Using an external store + +Another common pattern for stateful processing is to store the state in an external database or key-value store. Conventional database replication can be used to make that database fault-tolerant. The architecture looks something like this: + +![state-kv-store](/img/{{site.version}}/learn/documentation/container/stream_job_and_db.png) + +Samza allows this style of processing — there is nothing to stop you querying a remote database or service within your job. However, there are a few reasons why a remote database can be problematic for stateful stream processing: + +1. **Performance**: Making database queries over a network is slow and expensive. A Kafka stream can deliver hundreds of thousands or even millions of messages per second per CPU core to a stream processor, but if you need to make a remote request for every message you process, your throughput is likely to drop by 2-3 orders of magnitude. You can somewhat mitigate this with careful caching of reads and batching of writes, but then you're back to the problems of checkpointing, discussed above. +2. **Isolation**: If your database or service also serves requests to users, it can be dangerous to use the same database with a stream processor. A scalable stream processing system can run with very high throughput, and easily generates a huge amount of load (for example when catching up on a queue backlog). If you're not very careful, you may cause a denial-of-service attack on your own database, and cause problems for interactive requests from users. +3. **Query Capabilities**: Many scalable databases expose very limited query interfaces (e.g. only supporting simple key-value lookups), because the equivalent of a "full table scan" or rich traversal would be too expensive. Stream processes are often less latency-sensitive, so richer query capabilities would be more feasible. +4. **Correctness**: When a stream processor fails and needs to be restarted, how is the database state made consistent with the processing task? For this purpose, some frameworks such as [Storm](../comparisons/storm.html) attach metadata to database entries, but it needs to be handled carefully, otherwise the stream process generates incorrect output. +5. **Reprocessing**: Sometimes it can be useful to re-run a stream process on a large amount of historical data, e.g. after updating your processing task's code. However, the issues above make this impractical for jobs that make external queries. + +### Local state in Samza + +Samza allows tasks to maintain state in a way that is different from the approaches described above: + +* The state is stored on disk, so the job can maintain more state than would fit in memory. +* It is stored on the same machine as the processing task, to avoid the performance problems of making database queries over the network. +* Each job has its own datastore, to avoid the isolation problems of a shared database (if you make an expensive query, it affects only the current task, nobody else). +* Different storage engines can be plugged in, enabling rich query capabilities. +* The state is continuously replicated, enabling fault tolerance without the problems of checkpointing large amounts of state. + +Imagine you take a remote database, partition it to match the number of tasks in the stream processing job, and co-locate each partition with its task. The result looks like this: + +![state-local](/img/{{site.version}}/learn/documentation/container/stateful_job.png) + +If a machine fails, all the tasks running on that machine and their database partitions are lost. In order to make them highly available, all writes to the database partition are replicated to a durable changelog (typically Kafka). Now, when a machine fails, we can restart the tasks on another machine, and consume this changelog in order to restore the contents of the database partition. + +Note that each task only has access to its own database partition, not to any other task's partition. This is important: when you scale out your job by giving it more computing resources, Samza needs to move tasks from one machine to another. By giving each task its own state, tasks can be relocated without affecting the job's operation. If necessary, you can repartition your streams so that all messages for a particular database partition are routed to the same task instance. + +[Log compaction](http://kafka.apache.org/documentation.html#compaction) runs in the background on the changelog topic, and ensures that the changelog does not grow indefinitely. If you overwrite the same value in the store many times, log compaction keeps only the most recent value, and throws away any old values in the log. If you delete an item from the store, log compaction also removes it from the log. With the right tuning, the changelog is not much bigger than the database itself. + +With this architecture, Samza allows tasks to maintain large amounts of fault-tolerant state, at a performance that is almost as good as a pure in-memory implementation. There are just a few limitations: + +* If you have some data that you want to share between tasks (across partition boundaries), you need to go to some additional effort to repartition and distribute the data. Each task will need its own copy of the data, so this may use more space overall. +* When a container is restarted, it can take some time to restore the data in all of its state partitions. The time depends on the amount of data, the storage engine, your access patterns, and other factors. As a rule of thumb, 50 MB/sec is a reasonable restore time to expect. + +Nothing prevents you from using an external database if you want to, but for many use cases, Samza's local state is a powerful tool for enabling stateful stream processing. + +### Key-value storage + +Any storage engine can be plugged into Samza, as described below. Out of the box, Samza ships with a key-value store implementation that is built on [LevelDB](https://code.google.com/p/leveldb) using a [JNI API](https://github.com/fusesource/leveldbjni). + +LevelDB has several nice properties. Its memory allocation is outside of the Java heap, which makes it more memory-efficient and less prone to garbage collection pauses than a Java-based storage engine. It is very fast for small datasets that fit in memory; datasets larger than memory are slower but still possible. It is [log-structured](http://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/), allowing very fast writes. It also includes support for block compression, which helps to reduce I/O and memory usage. + +Samza includes an additional in-memory caching layer in front of LevelDB, which avoids the cost of deserialization for frequently-accessed objects and batches writes. If the same key is updated multiple times in quick succession, the batching coalesces those updates into a single write. The writes are flushed to the changelog when a task [commits](checkpointing.html). + +To use a key-value store in your job, add the following to your job config: + +{% highlight jproperties %} +# Use the key-value store implementation for a store called "my-store" +stores.my-store.factory=org.apache.samza.storage.kv.KeyValueStorageEngineFactory + +# Use the Kafka topic "my-store-changelog" as the changelog stream for this store. +# This enables automatic recovery of the store after a failure. If you don't +# configure this, no changelog stream will be generated. +stores.my-store.changelog=kafka.my-store-changelog + +# Encode keys and values in the store as UTF-8 strings. +serializers.registry.string.class=org.apache.samza.serializers.StringSerdeFactory +stores.my-store.key.serde=string +stores.my-store.msg.serde=string +{% endhighlight %} + +See the [serialization section](serialization.html) for more information on the *serde* options. + +Here is a simple example that writes every incoming message to the store: + +{% highlight java %} +public class MyStatefulTask implements StreamTask, InitableTask { + private KeyValueStore store; + + public void init(Config config, TaskContext context) { + this.store = (KeyValueStore) context.getStore("my-store"); + } + + public void process(IncomingMessageEnvelope envelope, + MessageCollector collector, + TaskCoordinator coordinator) { + store.put((String) envelope.getKey(), (String) envelope.getMessage()); + } +} +{% endhighlight %} + +Here is the complete key-value store API: + +{% highlight java %} +public interface KeyValueStore { + V get(K key); + void put(K key, V value); + void putAll(List> entries); + void delete(K key); + KeyValueIterator range(K from, K to); + KeyValueIterator all(); +} +{% endhighlight %} + +Additional configuration properties for the key-value store are documented in the [configuration reference](../jobs/configuration-table.html#keyvalue). + +### Implementing common use cases with the key-value store + +Earlier in this section we discussed some example use cases for stateful stream processing. Let's look at how each of these could be implemented using a key-value storage engine such as Samza's LevelDB. + +#### Windowed aggregation + +*Example: Counting the number of page views for each user per hour* + +Implementation: You need two processing stages. + +1. The first one re-partitions the input data by user ID, so that all the events for a particular user are routed to the same stream task. If the input stream is already partitioned by user ID, you can skip this. +2. The second stage does the counting, using a key-value store that maps a user ID to the running count. For each new event, the job reads the current count for the appropriate user from the store, increments it, and writes it back. When the window is complete (e.g. at the end of an hour), the job iterates over the contents of the store and emits the aggregates to an output stream. + +Note that this job effectively pauses at the hour mark to output its results. This is totally fine for Samza, as scanning over the contents of the key-value store is quite fast. The input stream is buffered while the job is doing this hourly work. + +#### Table-table join + +*Example: Join a table of user profiles to a table of user settings by user\_id and emit the joined stream* + +Implementation: The job subscribes to the change streams for the user profiles database and the user settings database, both partitioned by user\_id. The job keeps a key-value store keyed by user\_id, which contains the latest profile record and the latest settings record for each user\_id. When a new event comes in from either stream, the job looks up the current value in its store, updates the appropriate fields (depending on whether it was a profile update or a settings update), and writes back the new joined record to the store. The changelog of the store doubles as the output stream of the task. + +#### Table-stream join + +*Example: Augment a stream of page view events with the user's ZIP code (perhaps to allow aggregation by zip code in a later stage)* + +Implementation: The job subscribes to the stream of user profile updates and the stream of page view events. Both streams must be partitioned by user\_id. The job maintains a key-value store where the key is the user\_id and the value is the user's ZIP code. Every time the job receives a profile update, it extracts the user's new ZIP code from the profile update and writes it to the store. Every time it receives a page view event, it reads the zip code for that user from the store, and emits the page view event with an added ZIP code field. + +If the next stage needs to aggregate by ZIP code, the ZIP code can be used as the partitioning key of the job's output stream. That ensures that all the events for the same ZIP code are sent to the same stream partition. + +#### Stream-stream join + +*Example: Join a stream of ad clicks to a stream of ad impressions (to link the information on when the ad was shown to the information on when it was clicked)* + +In this example we assume that each impression of an ad has a unique identifier, e.g. a UUID, and that the same identifier is included in both the impression and the click events. This identifier is used as the join key. + +Implementation: Partition the ad click and ad impression streams by the impression ID or user ID (assuming that two events with the same impression ID always have the same user ID). The task keeps two stores, one containing click events and one containing impression events, using the impression ID as key for both stores. When the job receives a click event, it looks for the corresponding impression in the impression store, and vice versa. If a match is found, the joined pair is emitted and the entry is deleted. If no match is found, the event is written to the appropriate store. Periodically the job scans over both stores and deletes any old events that were not matched within the time window of the join. + +### Other storage engines + +Samza's fault-tolerance mechanism (sending a local store's writes to a replicated changelog) is completely decoupled from the storage engine's data structures and query APIs. While a key-value storage engine is good for general-purpose processing, you can easily add your own storage engines for other types of queries by implementing the [StorageEngine](../api/javadocs/org/apache/samza/storage/StorageEngine.html) interface. Samza's model is especially amenable to embedded storage engines, which run as a library in the same process as the stream task. + +Some ideas for other storage engines that could be useful: a persistent heap (for running top-N queries), [approximate algorithms](http://infolab.stanford.edu/~ullman/mmds/ch4.pdf) such as [bloom filters](http://en.wikipedia.org/wiki/Bloom_filter) and [hyperloglog](http://research.google.com/pubs/pub40671.html), or full-text indexes such as [Lucene](http://lucene.apache.org). (Patches accepted!) + +### Fault tolerance semantics with state + +As discussed in the section on [checkpointing](checkpointing.html), Samza currently only supports at-least-once delivery guarantees in the presence of failure (this is sometimes referred to as "guaranteed delivery"). This means that if a task fails, no messages are lost, but some messages may be redelivered. + +For many of the stateful processing use cases discussed above, this is not a problem: if the effect of a message on state is idempotent, it is safe for the same message to be processed more than once. For example, if the store contains the ZIP code for each user, then processing the same profile update twice has no effect, because the duplicate update does not change the ZIP code. + +However, for non-idempotent operations such as counting, at-least-once delivery guarantees can give incorrect results. If a Samza task fails and is restarted, it may double-count some messages that were processed shortly before the failure. We are planning to address this limitation in a future release of Samza. + +## [Metrics »](metrics.html) diff --git a/docs/learn/documentation/versioned/container/streams.md b/docs/learn/documentation/versioned/container/streams.md new file mode 100644 index 0000000..59e0855 --- /dev/null +++ b/docs/learn/documentation/versioned/container/streams.md @@ -0,0 +1,139 @@ +--- +layout: page +title: Streams +--- + + +The [samza container](samza-container.html) reads and writes messages using the [SystemConsumer](../api/javadocs/org/apache/samza/system/SystemConsumer.html) and [SystemProducer](../api/javadocs/org/apache/samza/system/SystemProducer.html) interfaces. You can integrate any message broker with Samza by implementing these two interfaces. + +{% highlight java %} +public interface SystemConsumer { + void start(); + + void stop(); + + void register( + SystemStreamPartition systemStreamPartition, + String lastReadOffset); + + List poll( + Map systemStreamPartitions, + long timeout) + throws InterruptedException; +} + +public class IncomingMessageEnvelope { + public Object getMessage() { ... } + + public Object getKey() { ... } + + public SystemStreamPartition getSystemStreamPartition() { ... } +} + +public interface SystemProducer { + void start(); + + void stop(); + + void register(String source); + + void send(String source, OutgoingMessageEnvelope envelope); + + void flush(String source); +} + +public class OutgoingMessageEnvelope { + ... + public Object getKey() { ... } + + public Object getMessage() { ... } +} +{% endhighlight %} + +Out of the box, Samza supports Kafka (KafkaSystemConsumer and KafkaSystemProducer). However, any message bus system can be plugged in, as long as it can provide the semantics required by Samza, as described in the [javadoc](../api/javadocs/org/apache/samza/system/SystemConsumer.html). + +SystemConsumers and SystemProducers may read and write messages of any data type. It's ok if they only support byte arrays — Samza has a separate [serialization layer](serialization.html) which converts to and from objects that application code can use. Samza does not prescribe any particular data model or serialization format. + +The job configuration file can include properties that are specific to a particular consumer and producer implementation. For example, the configuration would typically indicate the hostname and port of the message broker to use, and perhaps connection options. + +### How streams are processed + +If a job is consuming messages from more than one input stream, and all input streams have messages available, messages are processed in a round robin fashion by default. For example, if a job is consuming AdImpressionEvent and AdClickEvent, the task instance's process() method is called with a message from AdImpressionEvent, then a message from AdClickEvent, then another message from AdImpressionEvent, ... and continues to alternate between the two. + +If one of the input streams has no new messages available (the most recent message has already been consumed), that stream is skipped, and the job continues to consume from the other inputs. It continues to check for new messages becoming available. + +#### MessageChooser + +When a Samza container has several incoming messages on different stream partitions, how does it decide which to process first? The behavior is determined by a [MessageChooser](../api/javadocs/org/apache/samza/system/chooser/MessageChooser.html). The default chooser is RoundRobinChooser, but you can override it by implementing a custom chooser. + +To plug in your own message chooser, you need to implement the [MessageChooserFactory](../api/javadocs/org/apache/samza/system/chooser/MessageChooserFactory.html) interface, and set the "task.chooser.class" configuration to the fully-qualified class name of your implementation: + +{% highlight jproperties %} +task.chooser.class=com.example.samza.YourMessageChooserFactory +{% endhighlight %} + +#### Prioritizing input streams + +There are certain times when messages from one stream should be processed with higher priority than messages from another stream. For example, some Samza jobs consume two streams: one stream is fed by a real-time system and the other stream is fed by a batch system. In this case, it's useful to prioritize the real-time stream over the batch stream, so that the real-time processing doesn't slow down if there is a sudden burst of data on the batch stream. + +Samza provides a mechanism to prioritize one stream over another by setting this configuration parameter: systems.<system>.streams.<stream>.samza.priority=<number>. For example: + +{% highlight jproperties %} +systems.kafka.streams.my-real-time-stream.samza.priority=2 +systems.kafka.streams.my-batch-stream.samza.priority=1 +{% endhighlight %} + +This declares that my-real-time-stream's messages should be processed with higher priority than my-batch-stream's messages. If my-real-time-stream has any messages available, they are processed first. Only if there are no messages currently waiting on my-real-time-stream, the Samza job continues processing my-batch-stream. + +Each priority level gets its own MessageChooser. It is valid to define two streams with the same priority. If messages are available from two streams at the same priority level, it's up to the MessageChooser for that priority level to decide which message should be processed first. + +It's also valid to only define priorities for some streams. All non-prioritized streams are treated as the lowest priority, and share a MessageChooser. + +#### Bootstrapping + +Sometimes, a Samza job needs to fully consume a stream (from offset 0 up to the most recent message) before it processes messages from any other stream. This is useful in situations where the stream contains some prerequisite data that the job needs, and it doesn't make sense to process messages from other streams until the job has loaded that prerequisite data. Samza supports this use case with *bootstrap streams*. + +A bootstrap stream seems similar to a stream with a high priority, but is subtly different. Before allowing any other stream to be processed, a bootstrap stream waits for the consumer to explicitly confirm that the stream has been fully consumed. Until then, the bootstrap stream is the exclusive input to the job: even if a network issue or some other factor causes the bootstrap stream consumer to slow down, other inputs can't sneak their messages in. + +Another difference between a bootstrap stream and a high-priority stream is that the bootstrap stream's special treatment is temporary: when it has been fully consumed (we say it has "caught up"), its priority drops to be the same as all the other input streams. + +To configure a stream called "my-bootstrap-stream" to be a fully-consumed bootstrap stream, use the following settings: + +{% highlight jproperties %} +systems.kafka.streams.my-bootstrap-stream.samza.bootstrap=true +systems.kafka.streams.my-bootstrap-stream.samza.reset.offset=true +systems.kafka.streams.my-bootstrap-stream.samza.offset.default=oldest +{% endhighlight %} + +The bootstrap=true parameter enables the bootstrap behavior (prioritization over other streams). The combination of reset.offset=true and offset.default=oldest tells Samza to always start reading the stream from the oldest offset, every time a container starts up (rather than starting to read from the most recent checkpoint). + +It is valid to define multiple bootstrap streams. In this case, the order in which they are bootstrapped is determined by the priority. + +#### Batching + +In some cases, you can improve performance by consuming several messages from the same stream partition in sequence. Samza supports this mode of operation, called *batching*. + +For example, if you want to read 100 messages in a row from each stream partition (regardless of the MessageChooser), you can use this configuration parameter: + +{% highlight jproperties %} +task.consumer.batch.size=100 +{% endhighlight %} + +With this setting, Samza tries to read a message from the most recently used [SystemStreamPartition](../api/javadocs/org/apache/samza/system/SystemStreamPartition.html). This behavior continues either until no more messages are available for that SystemStreamPartition, or until the batch size has been reached. When that happens, Samza defers to the MessageChooser to determine the next message to process. It then again tries to continue consume from the chosen message's SystemStreamPartition until the batch size is reached. + +## [Serialization »](serialization.html) diff --git a/docs/learn/documentation/versioned/container/windowing.md b/docs/learn/documentation/versioned/container/windowing.md new file mode 100644 index 0000000..b10e5d4 --- /dev/null +++ b/docs/learn/documentation/versioned/container/windowing.md @@ -0,0 +1,61 @@ +--- +layout: page +title: Windowing +--- + + +Sometimes a stream processing job needs to do something in regular time intervals, regardless of how many incoming messages the job is processing. For example, say you want to report the number of page views per minute. To do this, you increment a counter every time you see a page view event. Once per minute, you send the current counter value to an output stream and reset the counter to zero. + +Samza's *windowing* feature provides a way for tasks to do something in regular time intervals, for example once per minute. To enable windowing, you just need to set one property in your job configuration: + +{% highlight jproperties %} +# Call the window() method every 60 seconds +task.window.ms=60000 +{% endhighlight %} + +Next, your stream task needs to implement the [WindowableTask](../api/javadocs/org/apache/samza/task/WindowableTask.html) interface. This interface defines a window() method which is called by Samza in the regular interval that you configured. + +For example, this is how you would implement a basic per-minute event counter: + +{% highlight java %} +public class EventCounterTask implements StreamTask, WindowableTask { + + public static final SystemStream OUTPUT_STREAM = + new SystemStream("kafka", "events-per-minute"); + + private int eventsSeen = 0; + + public void process(IncomingMessageEnvelope envelope, + MessageCollector collector, + TaskCoordinator coordinator) { + eventsSeen++; + } + + public void window(MessageCollector collector, + TaskCoordinator coordinator) { + collector.send(new OutgoingMessageEnvelope(OUTPUT_STREAM, eventsSeen)); + eventsSeen = 0; + } +} +{% endhighlight %} + +If you need to send messages to output streams, you can use the [MessageCollector](../api/javadocs/org/apache/samza/task/MessageCollector.html) object passed to the window() method. Please only use that MessageCollector object for sending messages, and don't use it outside of the call to window(). + +Note that Samza uses [single-threaded execution](event-loop.html), so the window() call can never happen concurrently with a process() call. This has the advantage that you don't need to worry about thread safety in your code (no need to synchronize anything), but the downside that the window() call may be delayed if your process() method takes a long time to return. + +## [Event Loop »](event-loop.html) diff --git a/docs/learn/documentation/versioned/index.html b/docs/learn/documentation/versioned/index.html new file mode 100644 index 0000000..626631b --- /dev/null +++ b/docs/learn/documentation/versioned/index.html @@ -0,0 +1,92 @@ +--- +layout: page +title: Documentation +--- + + +

Introduction

+ + + +

Comparisons

+ + + +

API

+ + + +

Container

+ + + +

Jobs

+ + + +

YARN

+ + + +

Operations

+ +
    +
  • Security
  • +
  • Kafka
  • + diff --git a/docs/learn/documentation/versioned/introduction/architecture.md b/docs/learn/documentation/versioned/introduction/architecture.md new file mode 100644 index 0000000..1a160dd --- /dev/null +++ b/docs/learn/documentation/versioned/introduction/architecture.md @@ -0,0 +1,110 @@ +--- +layout: page +title: Architecture +--- + + +Samza is made up of three layers: + +1. A streaming layer. +2. An execution layer. +3. A processing layer. + +Samza provides out of the box support for all three layers. + +1. **Streaming:** [Kafka](http://kafka.apache.org/) +2. **Execution:** [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html) +3. **Processing:** [Samza API](../api/overview.html) + +These three pieces fit together to form Samza: + +![diagram-medium](/img/{{site.version}}/learn/documentation/introduction/samza-ecosystem.png) + +This architecture follows a similar pattern to Hadoop (which also uses YARN as execution layer, HDFS for storage, and MapReduce as processing API): + +![diagram-medium](/img/{{site.version}}/learn/documentation/introduction/samza-hadoop.png) + +Before going in-depth on each of these three layers, it should be noted that Samza's support is not limited to Kafka and YARN. Both Samza's execution and streaming layer are pluggable, and allow developers to implement alternatives if they prefer. + +### Kafka + +[Kafka](http://kafka.apache.org/) is a distributed pub/sub and message queueing system that provides at-least once messaging guarantees (i.e. the system guarantees that no messages are lost, but in certain fault scenarios, a consumer might receive the same message more than once), and highly available partitions (i.e. a stream's partitions continue to be available even if a machine goes down). + +In Kafka, each stream is called a *topic*. Each topic is partitioned and replicated across multiple machines called *brokers*. When a *producer* sends a message to a topic, it provides a key, which is used to determine which partition the message should be sent to. The Kafka brokers receive and store the messages that the producer sends. Kafka *consumers* can then read from a topic by subscribing to messages on all partitions of a topic. + +Kafka has some interesting properties: + +* All messages with the same key are guaranteed to be in the same topic partition. This means that if you wish to read all messages for a specific user ID, you only have to read the messages from the partition that contains the user ID, not the whole topic (assuming the user ID is used as key). +* A topic partition is a sequence of messages in order of arrival, so you can reference any message in the partition using a monotonically increasing *offset* (like an index into an array). This means that the broker doesn't need to keep track of which messages have been seen by a particular consumer — the consumer can keep track itself by storing the offset of the last message it has processed. It then knows that every message with a lower offset than the current offset has already been processed; every message with a higher offset has not yet been processed. + +For more details on Kafka, see Kafka's [documentation](http://kafka.apache.org/documentation.html) pages. + +### YARN + +[YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html) (Yet Another Resource Negotiator) is Hadoop's next-generation cluster scheduler. It allows you to allocate a number of *containers* (processes) in a cluster of machines, and execute arbitrary commands on them. + +When an application interacts with YARN, it looks something like this: + +1. **Application**: I want to run command X on two machines with 512MB memory. +2. **YARN**: Cool, where's your code? +3. **Application**: http://path.to.host/jobs/download/my.tgz +4. **YARN**: I'm running your job on node-1.grid and node-2.grid. + +Samza uses YARN to manage deployment, fault tolerance, logging, resource isolation, security, and locality. A brief overview of YARN is below; see [this page from Hortonworks](http://hortonworks.com/blog/apache-hadoop-yarn-background-and-an-overview/) for a much better overview. + +#### YARN Architecture + +YARN has three important pieces: a *ResourceManager*, a *NodeManager*, and an *ApplicationMaster*. In a YARN grid, every machine runs a NodeManager, which is responsible for launching processes on that machine. A ResourceManager talks to all of the NodeManagers to tell them what to run. Applications, in turn, talk to the ResourceManager when they wish to run something on the cluster. The third piece, the ApplicationMaster, is actually application-specific code that runs in the YARN cluster. It's responsible for managing the application's workload, asking for containers (usually UNIX processes), and handling notifications when one of its containers fails. + +#### Samza and YARN + +Samza provides a YARN ApplicationMaster and a YARN job runner out of the box. The integration between Samza and YARN is outlined in the following diagram (different colors indicate different host machines): + +![diagram-small](/img/{{site.version}}/learn/documentation/introduction/samza-yarn-integration.png) + +The Samza client talks to the YARN RM when it wants to start a new Samza job. The YARN RM talks to a YARN NM to allocate space on the cluster for Samza's ApplicationMaster. Once the NM allocates space, it starts the Samza AM. After the Samza AM starts, it asks the YARN RM for one or more YARN containers to run [SamzaContainers](../container/samza-container.html). Again, the RM works with NMs to allocate space for the containers. Once the space has been allocated, the NMs start the Samza containers. + +### Samza + +Samza uses YARN and Kafka to provide a framework for stage-wise stream processing and partitioning. Everything, put together, looks like this (different colors indicate different host machines): + +![diagram-small](/img/{{site.version}}/learn/documentation/introduction/samza-yarn-kafka-integration.png) + +The Samza client uses YARN to run a Samza job: YARN starts and supervises one or more [SamzaContainers](../container/samza-container.html), and your processing code (using the [StreamTask](../api/overview.html) API) runs inside those containers. The input and output for the Samza StreamTasks come from Kafka brokers that are (usually) co-located on the same machines as the YARN NMs. + +### Example + +Let's take a look at a real example: suppose we want to count the number of page views. In SQL, you would write something like: + +{% highlight sql %} +SELECT user_id, COUNT(*) FROM PageViewEvent GROUP BY user_id +{% endhighlight %} + +Although Samza doesn't support SQL right now, the idea is the same. Two jobs are required to calculate this query: one to group messages by user ID, and the other to do the counting. + +In the first job, the grouping is done by sending all messages with the same user ID to the same partition of an intermediate topic. You can do this by using the user ID as key of the messages that are emitted by the first job, and this key is mapped to one of the intermediate topic's partitions (usually by taking a hash of the key mod the number of partitions). The second job consumes the intermediate topic. Each task in the second job consumes one partition of the intermediate topic, i.e. all the messages for a subset of user IDs. The task has a counter for each user ID in its partition, and the appropriate counter is incremented every time the task receives a message with a particular user ID. + +Repartitioning for a GROUP BY + +If you are familiar with Hadoop, you may recognize this as a Map/Reduce operation, where each record is associated with a particular key in the mappers, records with the same key are grouped together by the framework, and then counted in the reduce step. The difference between Hadoop and Samza is that Hadoop operates on a fixed input, whereas Samza works with unbounded streams of data. + +Kafka takes the messages emitted by the first job and buffers them on disk, distributed across multiple machines. This helps make the system fault-tolerant: if one machine fails, no messages are lost, because they have been replicated to other machines. And if the second job goes slow or stops consuming messages for any reason, the first job is unaffected: the disk buffer can absorb the backlog of messages from the first job until the second job catches up again. + +By partitioning topics, and by breaking a stream process down into jobs and parallel tasks that run on multiple machines, Samza scales to streams with very high message throughput. By using YARN and Kafka, Samza achieves fault-tolerance: if a process or machine fails, it is automatically restarted on another machine and continues processing messages from the point where it left off. + +## [Comparison Introduction »](../comparisons/introduction.html) diff --git a/docs/learn/documentation/versioned/introduction/background.md b/docs/learn/documentation/versioned/introduction/background.md new file mode 100644 index 0000000..e09497b --- /dev/null +++ b/docs/learn/documentation/versioned/introduction/background.md @@ -0,0 +1,71 @@ +--- +layout: page +title: Background +--- + + +This page provides some background about stream processing, describes what Samza is, and why it was built. + +### What is messaging? + +Messaging systems are a popular way of implementing near-realtime asynchronous computation. Messages can be added to a message queue (ActiveMQ, RabbitMQ), pub-sub system (Kestrel, Kafka), or log aggregation system (Flume, Scribe) when something happens. Downstream *consumers* read messages from these systems, and process them or take actions based on the message contents. + +Suppose you have a website, and every time someone loads a page, you send a "user viewed page" event to a messaging system. You might then have consumers which do any of the following: + +* Store the message in Hadoop for future analysis +* Count page views and update a dashboard +* Trigger an alert if a page view fails +* Send an email notification to another user +* Join the page view event with the user's profile, and send the message back to the messaging system + +A messaging system lets you decouple all of this work from the actual web page serving. + +### What is stream processing? + +A messaging system is a fairly low-level piece of infrastructure—it stores messages and waits for consumers to consume them. When you start writing code that produces or consumes messages, you quickly find that there are a lot of tricky problems that have to be solved in the processing layer. Samza aims to help with these problems. + +Consider the counting example, above (count page views and update a dashboard). What happens when the machine that your consumer is running on fails, and your current counter values are lost? How do you recover? Where should the processor be run when it restarts? What if the underlying messaging system sends you the same message twice, or loses a message? (Unless you are careful, your counts will be incorrect.) What if you want to count page views grouped by the page URL? How do you distribute the computation across multiple machines if it's too much for a single machine to handle? + +Stream processing is a higher level of abstraction on top of messaging systems, and it's meant to address precisely this category of problems. + +### Samza + +Samza is a stream processing framework with the following features: + +* **Simple API:** Unlike most low-level messaging system APIs, Samza provides a very simple callback-based "process message" API comparable to MapReduce. +* **Managed state:** Samza manages snapshotting and restoration of a stream processor's state. When the processor is restarted, Samza restores its state to a consistent snapshot. Samza is built to handle large amounts of state (many gigabytes per partition). +* **Fault tolerance:** Whenever a machine in the cluster fails, Samza works with YARN to transparently migrate your tasks to another machine. +* **Durability:** Samza uses Kafka to guarantee that messages are processed in the order they were written to a partition, and that no messages are ever lost. +* **Scalability:** Samza is partitioned and distributed at every level. Kafka provides ordered, partitioned, replayable, fault-tolerant streams. YARN provides a distributed environment for Samza containers to run in. +* **Pluggable:** Though Samza works out of the box with Kafka and YARN, Samza provides a pluggable API that lets you run Samza with other messaging systems and execution environments. +* **Processor isolation:** Samza works with Apache YARN, which supports Hadoop's security model, and resource isolation through Linux CGroups. + +### Alternatives + +The available open source stream processing systems are actually quite young, and no single system offers a complete solution. New problems in this area include: how a stream processor's state should be managed, whether or not a stream should be buffered remotely on disk, what to do when duplicate messages are received or messages are lost, and how to model underlying messaging systems. + +Samza's main differentiators are: + +* Samza supports fault-tolerant local state. State can be thought of as tables that are split up and co-located with the processing tasks. State is itself modeled as a stream. If the local state is lost due to machine failure, the state stream is replayed to restore it. +* Streams are ordered, partitioned, replayable, and fault tolerant. +* YARN is used for processor isolation, security, and fault tolerance. +* Jobs are decoupled: if one job goes slow and builds up a backlog of unprocessed messages, the rest of the system is not affected. + +For a more in-depth discussion on Samza, and how it relates to other stream processing systems, have a look at Samza's [Comparisons](../comparisons/introduction.html) documentation. + +## [Concepts »](concepts.html) diff --git a/docs/learn/documentation/versioned/introduction/concepts.md b/docs/learn/documentation/versioned/introduction/concepts.md new file mode 100644 index 0000000..25ef5ee --- /dev/null +++ b/docs/learn/documentation/versioned/introduction/concepts.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Concepts +--- + + +This page gives an introduction to the high-level concepts in Samza. + +### Streams + +Samza processes *streams*. A stream is composed of immutable *messages* of a similar type or category. For example, a stream could be all the clicks on a website, or all the updates to a particular database table, or all the logs produced by a service, or any other type of event data. Messages can be appended to a stream or read from a stream. A stream can have any number of *consumers*, and reading from a stream doesn't delete the message (so each message is effectively broadcast to all consumers). Messages can optionally have an associated key which is used for partitioning, which we'll talk about in a second. + +Samza supports pluggable *systems* that implement the stream abstraction: in [Kafka](https://kafka.apache.org/) a stream is a topic, in a database we might read a stream by consuming updates from a table, in Hadoop we might tail a directory of files in HDFS. + +![job](/img/{{site.version}}/learn/documentation/introduction/job.png) + +### Jobs + +A Samza *job* is code that performs a logical transformation on a set of input streams to append output messages to set of output streams. + +If scalability were not a concern, streams and jobs would be all we need. However, in order to scale the throughput of the stream processor, we chop streams and jobs up into smaller units of parallelism: *partitions* and *tasks*. + +### Partitions + +Each stream is broken into one or more partitions. Each partition in the stream is a totally ordered sequence of messages. + +Each message in this sequence has an identifier called the *offset*, which is unique per partition. The offset can be a sequential integer, byte offset, or string depending on the underlying system implementation. + +When a message is appended to a stream, it is appended to only one of the stream's partitions. The assignment of the message to its partition is done with a key chosen by the writer. For example, if the user ID is used as the key, that ensures that all messages related to a particular user end up in the same partition. + +![stream](/img/{{site.version}}/learn/documentation/introduction/stream.png) + +### Tasks + +A job is scaled by breaking it into multiple *tasks*. The *task* is the unit of parallelism of the job, just as the partition is to the stream. Each task consumes data from one partition for each of the job's input streams. + +A task processes messages from each of its input partitions sequentially, in the order of message offset. There is no defined ordering across partitions. This allows each task to operate independently. The YARN scheduler assigns each task to a machine, so the job as a whole can be distributed across many machines. + +The number of tasks in a job is determined by the number of input partitions (there cannot be more tasks than input partitions, or there would be some tasks with no input). However, you can change the computational resources assigned to the job (the amount of memory, number of CPU cores, etc.) to satisfy the job's needs. See notes on *containers* below. + +The assignment of partitions to tasks never changes: if a task is on a machine that fails, the task is restarted elsewhere, still consuming the same stream partitions. + +![job-detail](/img/{{site.version}}/learn/documentation/introduction/job_detail.png) + +### Dataflow Graphs + +We can compose multiple jobs to create a dataflow graph, where the nodes are streams containing data, and the edges are jobs performing transformations. This composition is done purely through the streams the jobs take as input and output. The jobs are otherwise totally decoupled: they need not be implemented in the same code base, and adding, removing, or restarting a downstream job will not impact an upstream job. + +These graphs are often acyclic—that is, data usually doesn't flow from a job, through other jobs, back to itself. However, it is possible to create cyclic graphs if you need to. + +Directed acyclic job graph + +### Containers + +Partitions and tasks are both *logical* units of parallelism—they don't correspond to any particular assignment of computational resources (CPU, memory, disk space, etc). Containers are the unit of physical parallelism, and a container is essentially a Unix process (or Linux [cgroup](http://en.wikipedia.org/wiki/Cgroups)). Each container runs one or more tasks. The number of tasks is determined automatically from the number of partitions in the input and is fixed, but the number of containers (and the CPU and memory resources associated with them) is specified by the user at run time and can be changed at any time. + +## [Architecture »](architecture.html) diff --git a/docs/learn/documentation/versioned/jobs/configuration-table.html b/docs/learn/documentation/versioned/jobs/configuration-table.html new file mode 100644 index 0000000..d7a5cf7 --- /dev/null +++ b/docs/learn/documentation/versioned/jobs/configuration-table.html @@ -0,0 +1,1157 @@ + + + + + + Samza Configuration Reference + + + + +

    Samza Configuration Reference

    +

    The following table lists all the standard properties that can be included in a Samza job configuration file.

    +

    Words highlighted like this are placeholders for your own variable names.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDefaultDescription
    Samza job configuration
    job.factory.class + Required: The job factory to use for running this job. + The value is a fully-qualified Java classname, which must implement + StreamJobFactory. + Samza ships with two implementations: +
    +
    org.apache.samza.job.local.ThreadJobFactory
    +
    Runs your job on your local machine using threads. This is intended only for + development, not for production deployments.
    +
    org.apache.samza.job.local.ProcessJobFactory
    +
    Runs your job on your local machine as a subprocess. An optional command builder + property can also be specified (see + task.command.class for details). This is intended only for development, + not for production deployments.
    +
    org.apache.samza.job.yarn.YarnJobFactory
    +
    Runs your job on a YARN grid. See below for YARN-specific configuration.
    +
    +
    job.name + Required: The name of your job. This name appears on the Samza dashboard, and it + is used to tell apart this job's checkpoints from other jobs' checkpoints. +
    job.id1 + If you run several instances of your job at the same time, you need to give each execution a + different job.id. This is important, since otherwise the jobs will overwrite each + others' checkpoints, and perhaps interfere with each other in other ways. +
    job.config.rewriter.
    rewriter-name.class
    + You can optionally define configuration rewriters, which have the opportunity to dynamically + modify the job configuration before the job is started. For example, this can be useful for + pulling configuration from an external configuration management system, or for determining + the set of input streams dynamically at runtime. The value of this property is a + fully-qualified Java classname which must implement + ConfigRewriter. + Samza ships with one rewriter by default: +
    +
    org.apache.samza.config.RegExTopicGenerator
    +
    When consuming from Kafka, this allows you to consume all Kafka topics that match + some regular expression (rather than having to list each topic explicitly). + This rewriter has additional configuration.
    +
    +
    job.config.rewriters + If you have defined configuration rewriters, you need to list them here, in the order in + which they should be applied. The value of this property is a comma-separated list of + rewriter-name tokens. +
    Task configuration
    task.class + Required: The fully-qualified name of the Java class which processes + incoming messages from input streams. The class must implement + StreamTask, and may optionally implement + InitableTask, + ClosableTask and/or + WindowableTask. + The class will be instantiated several times, once for every + input stream partition. +
    task.inputs + Required: A comma-separated list of streams that are consumed by this job. + Each stream is given in the format + system-name.stream-name. + For example, if you have one input system called my-kafka, and want to consume two + Kafka topics called PageViewEvent and UserActivityEvent, then you would set + task.inputs=my-kafka.PageViewEvent, my-kafka.UserActivityEvent. +
    task.window.ms-1 + If task.class implements + WindowableTask, it can + receive a windowing callback in regular intervals. + This property specifies the time between window() calls, in milliseconds. If the number is + negative (the default), window() is never called. Note that Samza is + single-threaded, so a window() call will never + occur concurrently with the processing of a message. If a message is being processed at the + time when a window() call is due, the window() call occurs after the processing of the current + message has completed. +
    task.checkpoint.factory + To enable checkpointing, you must set + this property to the fully-qualified name of a Java class that implements + CheckpointManagerFactory. + This is not required, but recommended for most jobs. If you don't configure checkpointing, + and a job or container restarts, it does not remember which messages it has already processed. + Without checkpointing, consumer behavior is determined by the + ...samza.offset.default + setting, which by default skips any messages that were published while the container was + restarting. Checkpointing allows a job to start up where it previously left off. + Samza ships with two checkpoint managers by default: +
    +
    org.apache.samza.checkpoint.file.FileSystemCheckpointManagerFactory
    +
    Writes checkpoints to files on the local filesystem. You can configure the file path + with the task.checkpoint.path + property. This is a simple option if your job always runs on the same machine. + On a multi-machine cluster, this would require a network filesystem mount.
    +
    org.apache.samza.checkpoint.kafka.KafkaCheckpointManagerFactory
    +
    Writes checkpoints to a dedicated topic on a Kafka cluster. This is the recommended + option if you are already using Kafka for input or output streams. Use the + task.checkpoint.system + property to configure which Kafka cluster to use for checkpoints.
    +
    +
    task.commit.ms60000 + If task.checkpoint.factory is + configured, this property determines how often a checkpoint is written. The value is + the time between checkpoints, in milliseconds. The frequency of checkpointing affects + failure recovery: if a container fails unexpectedly (e.g. due to crash or machine failure) + and is restarted, it resumes processing at the last checkpoint. Any messages processed + since the last checkpoint on the failed container are processed again. Checkpointing + more frequently reduces the number of messages that may be processed twice, but also + uses more resources. +
    task.command.classorg.apache.samza.job.
    ShellCommandBuilder
    + The fully-qualified name of the Java class which determines the command line and environment + variables for a container. It must be a subclass of + CommandBuilder. + This defaults to task.command.class=org.apache.samza.job.ShellCommandBuilder. +
    task.opts + Any JVM options to include in the command line when executing Samza containers. For example, + this can be used to set the JVM heap size, to tune the garbage collector, or to enable + remote debugging. Note + there are some issues with the current implementation of task.opts: +
      +
    • If you set this property, the log configuration is disrupted. Please see + SAMZA-109 for a workaround.
    • +
    • This cannot be used when running with ThreadJobFactory
    • +
    +
    task.executebin/run-container.sh + The command that starts a Samza container. The script must be included in the + job package. There is usually no need to customize this. +
    task.chooser.classorg.apache.samza.
    system.chooser.
    RoundRobinChooserFactory
    + This property can be optionally set to override the default + message chooser, which determines the + order in which messages from multiple input streams are processed. The value of this + property is the fully-qualified name of a Java class that implements + MessageChooserFactory. +
    task.lifecycle.listener.
    listener-name.class
    + Use this property to register a + lifecycle listener, which can receive + a notification when a container starts up or shuts down, or when a message is processed. + The value is the fully-qualified name of a Java class that implements + TaskLifecycleListenerFactory. + You can define multiple lifecycle listeners, each with a different listener-name, + and reference them in task.lifecycle.listeners. +
    task.lifecycle.listeners + If you have defined lifecycle listeners with + task.lifecycle.listener.*.class, + you need to list them here in order to enable them. The value of this property is a + comma-separated list of listener-name tokens. +
    task.drop.deserialization.errors + This property is to define how the system deals with deserialization failure situation. If set to true, the system will + skip the error messages and keep running. If set to false, the system with throw exceptions and fail the container. Default + is false. +
    task.drop.serialization.errors + This property is to define how the system deals with serialization failure situation. If set to true, the system will + drop the error messages and keep running. If set to false, the system with throw exceptions and fail the container. Default + is false. +
    task.poll.interval.ms + Samza's container polls for more messages under two conditions. The first condition arises when there are simply no remaining + buffered messages to process for any input SystemStreamPartition. The second condition arises when some input + SystemStreamPartitions have empty buffers, but some do not. In the latter case, a polling interval is defined to determine how + often to refresh the empty SystemStreamPartition buffers. By default, this interval is 50ms, which means that any empty + SystemStreamPartition buffer will be refreshed at least every 50ms. A higher value here means that empty SystemStreamPartitions + will be refreshed less often, which means more latency is introduced, but less CPU and network will be used. Decreasing this + value means that empty SystemStreamPartitions are refreshed more frequently, thereby introducing less latency, but increasing + CPU and network utilization. +
    Systems (input and output streams)
    systems.system-name.
    samza.factory
    + Required: The fully-qualified name of a Java class which provides a + system. A system can provide input streams which you can consume in your Samza job, + or output streams to which you can write, or both. The requirements on a system are very + flexible — it may connect to a message broker, or read and write files, or use a database, + or anything else. The class must implement + SystemFactory. + Samza ships with the following implementations: +
    +
    org.apache.samza.system.kafka.KafkaSystemFactory
    +
    Connects to a cluster of Kafka brokers, allows + Kafka topics to be consumed as streams in Samza, allows messages to be published to + Kafka topics, and allows Kafka to be used for checkpointing (see + task.checkpoint.factory). + See also configuration of a Kafka system.
    +
    org.apache.samza.system.filereader.FileReaderSystemFactory
    +
    Reads data from a file on the local filesystem (the stream name is the path of the + file to read). The file is read as ASCII, and treated as a stream of messages separated + by newline (\n) characters. A task can consume each line of the file as + a java.lang.String object. This system does not provide output streams.
    +
    +
    systems.system-name.
    samza.key.serde
    + The serde which will be used to deserialize the + key of messages on input streams, and to serialize the key of messages on + output streams. This property can be defined either for an individual stream, or for all + streams within a system (if both are defined, the stream-level definition takes precedence). + The value of this property must be a serde-name that is registered + with serializers.registry.*.class. + If this property is not set, messages are passed unmodified between the input stream consumer, + the task and the output stream producer. +
    systems.system-name.
    streams.stream-name.
    samza.key.serde
    systems.system-name.
    samza.msg.serde
    + The serde which will be used to deserialize the + value of messages on input streams, and to serialize the value of messages on + output streams. This property can be defined either for an individual stream, or for all + streams within a system (if both are defined, the stream-level definition takes precedence). + The value of this property must be a serde-name that is registered + with serializers.registry.*.class. + If this property is not set, messages are passed unmodified between the input stream consumer, + the task and the output stream producer. +
    systems.system-name.
    streams.stream-name.
    samza.msg.serde
    systems.system-name.
    samza.offset.default
    upcoming + If a container starts up without a checkpoint, + this property determines where in the input stream we should start consuming. The value must be an + OffsetType, + one of the following: +
    +
    upcoming
    +
    Start processing messages that are published after the job starts. Any messages published while + the job was not running are not processed.
    +
    oldest
    +
    Start processing at the oldest available message in the system, and + reprocess the entire available message history.
    +
    + This property can be defined either for an individual stream, or for all streams within a system + (if both are defined, the stream-level definition takes precedence). +
    systems.system-name.
    streams.stream-name.
    samza.offset.default
    systems.system-name.
    streams.stream-name.
    samza.reset.offset
    false + If set to true, when a Samza container starts up, it ignores any + checkpointed offset for this particular input + stream. Its behavior is thus determined by the samza.offset.default setting. + Note that the reset takes effect every time a container is started, which may be + every time you restart your job, or more frequently if a container fails and is restarted + by the framework. +
    systems.system-name.
    streams.stream-name.
    samza.priority
    -1 + If one or more streams have a priority set (any positive integer), they will be processed + with higher priority than the other streams. + You can set several streams to the same priority, or define multiple priority levels by + assigning a higher number to the higher-priority streams. If a higher-priority stream has + any messages available, they will always be processed first; messages from lower-priority + streams are only processed when there are no new messages on higher-priority inputs. +
    systems.system-name.
    streams.stream-name.
    samza.bootstrap
    false + If set to true, this stream will be processed as a + bootstrap stream. This means that every time + a Samza container starts up, this stream will be fully consumed before messages from any + other stream are processed. +
    task.consumer.batch.size1 + If set to a positive integer, the task will try to consume + batches with the given number of messages + from each input stream, rather than consuming round-robin from all the input streams on + each individual message. Setting this property can improve performance in some cases. +
    Serializers/Deserializers (Serdes)
    serializers.registry.
    serde-name.class
    + Use this property to register a serializer/deserializer, + which defines a way of encoding application objects as an array of bytes (used for messages + in streams, and for data in persistent storage). You can give a serde any + serde-name you want, and reference that name in properties like + systems.*.samza.key.serde, + systems.*.samza.msg.serde, + stores.*.key.serde and + stores.*.msg.serde. + The value of this property is the fully-qualified name of a Java class that implements + SerdeFactory. + Samza ships with several serdes: +
    +
    org.apache.samza.serializers.ByteSerdeFactory
    +
    A no-op serde which passes through the undecoded byte array.
    +
    org.apache.samza.serializers.IntegerSerdeFactory
    +
    Encodes java.lang.Integer objects as binary (4 bytes fixed-length big-endian encoding).
    +
    org.apache.samza.serializers.StringSerdeFactory
    +
    Encodes java.lang.String objects as UTF-8.
    +
    org.apache.samza.serializers.JsonSerdeFactory
    +
    Encodes nested structures of java.util.Map, java.util.List etc. as JSON.
    +
    org.apache.samza.serializers.MetricsSnapshotSerdeFactory
    +
    Encodes org.apache.samza.metrics.reporter.MetricsSnapshot objects (which are + used for reporting metrics) as JSON.
    +
    org.apache.samza.serializers.KafkaSerdeFactory
    +
    Adapter which allows existing kafka.serializer.Encoder and + kafka.serializer.Decoder implementations to be used as Samza serdes. + Set serializers.registry.serde-name.encoder and + serializers.registry.serde-name.decoder to the appropriate + class names.
    +
    +
    + Using the filesystem for checkpoints
    + + (This section applies if you have set + task.checkpoint.factory + = org.apache.samza.checkpoint.file.FileSystemCheckpointManagerFactory) + +
    task.checkpoint.path + Required if you are using the filesystem for checkpoints. Set this to the path on your local filesystem + where checkpoint files should be stored. +
    + Using Kafka for input streams, output streams and checkpoints
    + + (This section applies if you have set + systems.*.samza.factory + = org.apache.samza.system.kafka.KafkaSystemFactory) + +
    systems.system-name.
    consumer.zookeeper.connect
    + The hostname and port of one or more Zookeeper nodes where information about the + Kafka cluster can be found. This is given as a comma-separated list of + hostname:port pairs, such as + zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181. + If the cluster information is at some sub-path of the Zookeeper namespace, you need to + include the path at the end of the list of hostnames, for example: + zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181/clusters/my-kafka +
    systems.system-name.
    consumer.auto.offset.reset
    largest + This setting determines what happens if a consumer attempts to read an offset that is + outside of the current valid range. This could happen if the topic does not exist, or + if a checkpoint is older than the maximum message history retained by the brokers. + This property is not to be confused with + systems.*.samza.offset.default, + which determines what happens if there is no checkpoint. The following are valid + values for auto.offset.reset: +
    +
    smallest
    +
    Start consuming at the smallest (oldest) offset available on the broker + (process as much message history as available).
    +
    largest
    +
    Start consuming at the largest (newest) offset available on the broker + (skip any messages published while the job was not running).
    +
    anything else
    +
    Throw an exception and refuse to start up the job.
    +
    +
    systems.system-name.
    consumer.*
    + Any Kafka consumer configuration + can be included here. For example, to change the socket timeout, you can set + systems.system-name.consumer.socket.timeout.ms. + (There is no need to configure group.id or client.id, + as they are automatically configured by Samza. Also, there is no need to set + auto.commit.enable because Samza has its own checkpointing mechanism.) +
    systems.system-name.
    producer.metadata.broker.list
    + A list of network endpoints where the Kafka brokers are running. This is given as + a comma-separated list of hostname:port pairs, for example + kafka1.example.com:9092,kafka2.example.com:9092,kafka3.example.com:9092. + It's not necessary to list every single Kafka node in the cluster: Samza uses this + property in order to discover which topics and partitions are hosted on which broker. + This property is needed even if you are only consuming from Kafka, and not writing + to it, because Samza uses it to discover metadata about streams being consumed. +
    systems.system-name.
    producer.producer.type
    sync + Controls whether messages emitted from a stream processor should be buffered before + they are sent to Kafka. The options are: +
    +
    sync
    +
    Any messages sent to output streams are synchronously flushed to the Kafka brokers + before the next message from an input stream is processed.
    +
    async
    +
    Messages sent to output streams are buffered within the Samza container, and published + to the Kafka brokers as a batch. This setting can increase throughput, but + risks buffered messages being lost if a container abruptly fails. The maximum + number of messages to buffer is controlled with + systems.system-name.producer.batch.num.messages + and the maximum time (in milliseconds) to wait before flushing the buffer is set with + systems.system-name.producer.queue.buffering.max.ms.
    +
    +
    systems.system-name.
    producer.*
    + Any Kafka producer configuration + can be included here. For example, to change the request timeout, you can set + systems.system-name.producer.request.timeout.ms. + (There is no need to configure client.id as it is automatically + configured by Samza.) +
    systems.system-name.
    samza.fetch.threshold
    50000 + When consuming streams from Kafka, a Samza container maintains an in-memory buffer + for incoming messages in order to increase throughput (the stream task can continue + processing buffered messages while new messages are fetched from Kafka). This + parameter determines the number of messages we aim to buffer across all stream + partitions consumed by a container. For example, if a container consumes 50 partitions, + it will try to buffer 1000 messages per partition by default. When the number of + buffered messages falls below that threshold, Samza fetches more messages from the + Kafka broker to replenish the buffer. Increasing this parameter can increase a job's + processing throughput, but also increases the amount of memory used. +
    task.checkpoint.system + This property is required if you are using Kafka for checkpoints + (task.checkpoint.factory + = org.apache.samza.checkpoint.kafka.KafkaCheckpointManagerFactory). + You must set it to the system-name of a Kafka system. The stream + name (topic name) within that system is automatically determined from the job name and ID: + __samza_checkpoint_${job.name}_${job.id} + (with underscores in the job name and ID replaced by hyphens). +
    task.checkpoint.
    replication.factor
    3 + If you are using Kafka for checkpoints, this is the number of Kafka nodes to which you want the + checkpoint topic replicated for durability. +
    + Consuming all Kafka topics matching a regular expression
    + + (This section applies if you have set + job.config.rewriter.*.class + = org.apache.samza.config.RegExTopicGenerator) + +
    job.config.rewriter.
    rewriter-name.system
    + Set this property to the system-name of the Kafka system + from which you want to consume all matching topics. +
    job.config.rewriter.
    rewriter-name.regex
    + A regular expression specifying which topics you want to consume within the Kafka system + job.config.rewriter.*.system. + Any topics matched by this regular expression will be consumed in addition to any + topics you specify with task.inputs. +
    job.config.rewriter.
    rewriter-name.config.*
    + Any properties specified within this namespace are applied to the configuration of streams + that match the regex in + job.config.rewriter.*.regex. + For example, you can set job.config.rewriter.*.config.samza.msg.serde to configure + the deserializer for messages in the matching streams, which is equivalent to setting + systems.*.streams.*.samza.msg.serde + for each topic that matches the regex. +
    Storage and State Management
    stores.store-name.factory + This property defines a store, Samza's mechanism for efficient + stateful stream processing. You can give a + store any store-name, and use that name to get a reference to the + store in your stream task (call + TaskContext.getStore() + in your task's + init() + method). The value of this property is the fully-qualified name of a Java class that implements + StorageEngineFactory. + Samza currently ships with one storage engine implementation: +
    +
    org.apache.samza.storage.kv.KeyValueStorageEngineFactory
    +
    An on-disk storage engine with a key-value interface, implemented using + LevelDB. It supports fast random-access + reads and writes, as well as range queries on keys. LevelDB can be configured with + various additional tuning parameters.
    +
    +
    stores.store-name.key.serde + If the storage engine expects keys in the store to be simple byte arrays, this + serde allows the stream task to access the + store using another object type as key. The value of this property must be a + serde-name that is registered with + serializers.registry.*.class. + If this property is not set, keys are passed unmodified to the storage engine + (and the changelog stream, if appropriate). +
    stores.store-name.msg.serde + If the storage engine expects values in the store to be simple byte arrays, this + serde allows the stream task to access the + store using another object type as value. The value of this property must be a + serde-name that is registered with + serializers.registry.*.class. + If this property is not set, values are passed unmodified to the storage engine + (and the changelog stream, if appropriate). +
    stores.store-name.changelog + Samza stores are local to a container. If the container fails, the contents of the + store are lost. To prevent loss of data, you need to set this property to configure + a changelog stream: Samza then ensures that writes to the store are replicated to + this stream, and the store is restored from this stream after a failure. The value + of this property is given in the form + system-name.stream-name. + Any output stream can be used as changelog, but you must ensure that only one job + ever writes to a given changelog stream (each instance of a job and each store + needs its own changelog stream). +
    + Using LevelDB for key-value storage
    + + (This section applies if you have set + stores.*.factory + = org.apache.samza.storage.kv.KeyValueStorageEngineFactory) + +
    stores.store-name.
    write.batch.size
    500 + For better write performance, the storage engine buffers writes and applies them + to the underlying store in a batch. If the same key is written multiple times + in quick succession, this buffer also deduplicates writes to the same key. This + property is set to the number of key/value pairs that should be kept in this + in-memory buffer, per task instance. The number cannot be greater than + stores.*.object.cache.size. +
    stores.store-name.
    object.cache.size
    1000 + Samza maintains an additional cache in front of LevelDB for frequently-accessed + objects. This cache contains deserialized objects (avoiding the deserialization + overhead on cache hits), in contrast to the LevelDB block cache + (stores.*.container.cache.size.bytes), + which caches serialized objects. This property determines the number of objects + to keep in Samza's cache, per task instance. This same cache is also used for + write buffering (see stores.*.write.batch.size). + A value of 0 disables all caching and batching. +
    stores.store-name.container.
    cache.size.bytes
    104857600 + The size of LevelDB's block cache in bytes, per container. If there are several + task instances within one container, each is given a proportional share of this cache. + Note that this is an off-heap memory allocation, so the container's total memory use + is the maximum JVM heap size plus the size of this cache. +
    stores.store-name.container.
    write.buffer.size.bytes
    33554432 + The amount of memory (in bytes) that LevelDB uses for buffering writes before they are + written to disk, per container. If there are several task instances within one + container, each is given a proportional share of this buffer. This setting also + determines the size of LevelDB's segment files. +
    stores.store-name.
    compaction.delete.threshold
    -1 + Setting this property forces a LevelDB compaction to be performed after a certain + number of keys have been deleted from the store. This is used to work around + performance issues + in certain workloads. +
    stores.store-name.
    leveldb.compression
    snappy + This property controls whether LevelDB should compress data on disk and in the + block cache. The following values are valid: +
    +
    snappy
    +
    Compress data using the Snappy codec.
    +
    none
    +
    Do not compress data.
    +
    +
    stores.store-name.
    leveldb.block.size.bytes
    4096 + If compression is enabled, LevelDB groups approximately this many uncompressed bytes + into one compressed block. You probably don't need to change this property. +
    + Running your job on a YARN cluster
    + + (This section applies if you have set + job.factory.class + = org.apache.samza.job.yarn.YarnJobFactory) + +
    yarn.package.path + Required for YARN jobs: The URL from which the job package can + be downloaded, for example a http:// or hdfs:// URL. + The job package is a .tar.gz file with a + specific directory structure. +
    yarn.container.count1 + The number of YARN containers to request for running your job. This is the main parameter + for controlling the scale (allocated computing resources) of your job: to increase the + parallelism of processing, you need to increase the number of containers. The minimum is one + container, and the maximum number of containers is the number of task instances (usually the + number of input stream partitions). + Task instances are evenly distributed across the number of containers that you specify. +
    yarn.container.memory.mb1024 + How much memory, in megabytes, to request from YARN per container of your job. Along with + yarn.container.cpu.cores, this + property determines how many containers YARN will run on one machine. If the container + exceeds this limit, YARN will kill it, so it is important that the container's actual + memory use remains below the limit. The amount of memory used is normally the JVM heap + size (configured with task.opts), plus the + size of any off-heap memory allocation (for example + stores.*.container.cache.size.bytes), + plus a safety margin to allow for JVM overheads. +
    yarn.container.cpu.cores1 + The number of CPU cores to request from YARN per container of your job. Each node in the + YARN cluster has a certain number of CPU cores available, so this number (along with + yarn.container.memory.mb) + determines how many containers can be run on one machine. Samza is + single-threaded and designed to run on one + CPU core, so you shouldn't normally need to change this property. +
    yarn.container.
    retry.count
    8 + If a container fails, it is automatically restarted by YARN. However, if a container keeps + failing shortly after startup, that indicates a deeper problem, so we should kill the job + rather than retrying indefinitely. This property determines the maximum number of times we are + willing to restart a failed container in quick succession (the time period is configured with + yarn.container.retry.window.ms). + Each container in the job is counted separately. If this property is set to 0, any failed + container immediately causes the whole job to fail. If it is set to a negative number, there + is no limit on the number of retries. +
    yarn.container.
    retry.window.ms
    300000 + This property determines how frequently a container is allowed to fail before we give up and + fail the job. If the same container has failed more than + yarn.container.retry.count + times, and the time between failures was less than this property + yarn.container.retry.window.ms (in milliseconds), then we fail the job. + There is no limit to the number of times we will restart a container if the time between + failures is greater than yarn.container.retry.window.ms. +
    yarn.am.container.
    memory.mb
    1024 + Each Samza job has one special container, the + ApplicationMaster (AM), which manages the + execution of the job. This property determines how much memory, in megabytes, to request + from YARN for running the ApplicationMaster. +
    yarn.am.opts + Any JVM options to include in the command line when executing the Samza + ApplicationMaster. For example, this can be + used to set the JVM heap size, to tune the garbage collector, or to enable remote debugging. +
    yarn.am.poll.interval.ms1000 + THe Samza ApplicationMaster sends regular heartbeats to the YARN ResourceManager + to confirm that it is alive. This property determines the time (in milliseconds) + between heartbeats. +
    yarn.am.jmx.enabledtrue + Determines whether a JMX server should be started on this job's YARN ApplicationMaster + (true or false). +
    Metrics
    metrics.reporter.
    reporter-name.class
    + Samza automatically tracks various metrics which are useful for monitoring the health + of a job, and you can also track your own metrics. + With this property, you can define any number of metrics reporters which send + the metrics to a system of your choice (for graphing, alerting etc). You give each reporter + an arbitrary reporter-name. To enable the reporter, you need + to reference the reporter-name in + metrics.reporters. + The value of this property is the fully-qualified name of a Java class that implements + MetricsReporterFactory. + Samza ships with these implementations by default: +
    +
    org.apache.samza.metrics.reporter.JmxReporterFactory
    +
    With this reporter, every container exposes its own metrics as JMX MBeans. The JMX + server is started on a random port to avoid + collisions between containers running on the same machine.
    +
    org.apache.samza.metrics.reporter.MetricsSnapshotReporterFactory
    +
    This reporter sends the latest values of all metrics as messages to an output + stream once per minute. The output stream is configured with + metrics.reporter.*.stream + and it can use any system supported by Samza.
    +
    +
    metrics.reporters + If you have defined any metrics reporters with + metrics.reporter.*.class, you + need to list them here in order to enable them. The value of this property is a + comma-separated list of reporter-name tokens. +
    metrics.reporter.
    reporter-name.stream
    + If you have registered the metrics reporter + metrics.reporter.*.class + = org.apache.samza.metrics.reporter.MetricsSnapshotReporterFactory, + you need to set this property to configure the output stream to which the metrics data + should be sent. The stream is given in the form + system-name.stream-name, + and the system must be defined in the job configuration. It's fine for many different jobs + to publish their metrics to the same metrics stream. Samza defines a simple + JSON encoding for metrics; in order to use this + encoding, you also need to configure a serde for the metrics stream: + +
    + + diff --git a/docs/learn/documentation/versioned/jobs/configuration.md b/docs/learn/documentation/versioned/jobs/configuration.md new file mode 100644 index 0000000..cb2ec79 --- /dev/null +++ b/docs/learn/documentation/versioned/jobs/configuration.md @@ -0,0 +1,63 @@ +--- +layout: page +title: Configuration +--- + + +All Samza jobs have a configuration file that defines the job. A very basic configuration file looks like this: + +{% highlight jproperties %} +# Job +job.factory.class=samza.job.local.ThreadJobFactory +job.name=hello-world + +# Task +task.class=samza.task.example.MyJavaStreamerTask +task.inputs=example-system.example-stream + +# Serializers +serializers.registry.json.class=org.apache.samza.serializers.JsonSerdeFactory +serializers.registry.string.class=org.apache.samza.serializers.StringSerdeFactory + +# Systems +systems.example-system.samza.factory=samza.stream.example.ExampleConsumerFactory +systems.example-system.samza.key.serde=string +systems.example-system.samza.msg.serde=json +{% endhighlight %} + +There are four major sections to a configuration file: + +1. The job section defines things like the name of the job, and whether to use the YarnJobFactory or ProcessJobFactory/ThreadJobFactory. +2. The task section is where you specify the class name for your [StreamTask](../api/overview.html). It's also where you define what the [input streams](../container/streams.html) are for your task. +3. The serializers section defines the classes of the [serdes](../container/serialization.html) used for serialization and deserialization of specific objects that are received and sent along different streams. +4. The system section defines systems that your StreamTask can read from along with the types of serdes used for sending keys and messages from that system. Usually, you'll define a Kafka system, if you're reading from Kafka, although you can also specify your own self-implemented Samza-compatible systems. See the [hello-samza example project](/startup/hello-samza/{{site.version}})'s Wikipedia system for a good example of a self-implemented system. + +### Required Configuration + +Configuration keys that absolutely must be defined for a Samza job are: + +* `job.factory.class` +* `job.name` +* `task.class` +* `task.inputs` + +### Configuration Keys + +A complete list of configuration keys can be found on the [Configuration Table](configuration-table.html) page. + +## [Packaging »](packaging.html) diff --git a/docs/learn/documentation/versioned/jobs/job-runner.md b/docs/learn/documentation/versioned/jobs/job-runner.md new file mode 100644 index 0000000..c2f6b09 --- /dev/null +++ b/docs/learn/documentation/versioned/jobs/job-runner.md @@ -0,0 +1,60 @@ +--- +layout: page +title: JobRunner +--- + + +Samza jobs are started using a script called run-job.sh. + +{% highlight bash %} +samza-example/target/bin/run-job.sh \ + --config-factory=samza.config.factories.PropertiesConfigFactory \ + --config-path=file://$PWD/config/hello-world.properties +{% endhighlight %} + +You provide two parameters to the run-job.sh script. One is the config location, and the other is a factory class that is used to read your configuration file. The run-job.sh script is actually executing a Samza class called JobRunner. The JobRunner uses your ConfigFactory to get a Config object from the config path. + +{% highlight java %} +public interface ConfigFactory { + Config getConfig(URI configUri); +} +{% endhighlight %} + +The Config object is just a wrapper around Map, with some nice helper methods. Out of the box, Samza ships with the PropertiesConfigFactory, but developers can implement any kind of ConfigFactory they wish. + +Once the JobRunner gets your configuration, it gives your configuration to the StreamJobFactory class defined by the "job.factory" property. Samza ships with three job factory implementations: ThreadJobFactory, ProcessJobFactory and YarnJobFactory. The StreamJobFactory's responsibility is to give the JobRunner a job that it can run. + +{% highlight java %} +public interface StreamJob { + StreamJob submit(); + + StreamJob kill(); + + ApplicationStatus waitForFinish(long timeoutMs); + + ApplicationStatus waitForStatus(ApplicationStatus status, long timeoutMs); + + ApplicationStatus getStatus(); +} +{% endhighlight %} + +Once the JobRunner gets a job, it calls submit() on the job. This method is what tells the StreamJob implementation to start the SamzaContainer. In the case of LocalJobRunner, it uses a run-container.sh script to execute the SamzaContainer in a separate process, which will start one SamzaContainer locally on the machine that you ran run-job.sh on. + +This flow differs slightly when you use YARN, but we'll get to that later. + +## [Configuration »](configuration.html) diff --git a/docs/learn/documentation/versioned/jobs/logging.md b/docs/learn/documentation/versioned/jobs/logging.md new file mode 100644 index 0000000..6af3d4d --- /dev/null +++ b/docs/learn/documentation/versioned/jobs/logging.md @@ -0,0 +1,93 @@ +--- +layout: page +title: Logging +--- + + +Samza uses [SLF4J](http://www.slf4j.org/) for all of its logging. By default, Samza only depends on slf4j-api, so you must add an SLF4J runtime dependency to your Samza packages for whichever underlying logging platform you wish to use. + +### Log4j + +The [hello-samza](/startup/hello-samza/{{site.version}}) project shows how to use [log4j](http://logging.apache.org/log4j/1.2/) with Samza. To turn on log4j logging, you just need to make sure slf4j-log4j12 is in your SamzaContainer's classpath. In Maven, this can be done by adding the following dependency to your Samza package project. + +{% highlight xml %} + + org.slf4j + slf4j-log4j12 + runtime + 1.6.2 + +{% endhighlight %} + +If you're not using Maven, just make sure that slf4j-log4j12 ends up in your Samza package's lib directory. + +#### Log4j configuration + +Samza's [run-class.sh](packaging.html) script will automatically set the following setting if log4j.xml exists in your [Samza package's](packaging.html) lib directory. + +{% highlight bash %} +-Dlog4j.configuration=file:$base_dir/lib/log4j.xml +{% endhighlight %} + +The [run-class.sh](packaging.html) script will also set the following Java system properties: + +{% highlight bash %} +-Dsamza.log.dir=$SAMZA_LOG_DIR -Dsamza.container.name=$SAMZA_CONTAINER_NAME= +{% endhighlight %} + +These settings are very useful if you're using a file-based appender. For example, you can use a daily rolling appender by configuring log4j.xml like this: + +{% highlight xml %} + + + + + + + +{% endhighlight %} + +Setting up a file-based appender is recommended as a better alternative to using standard out. Standard out log files (see below) don't roll, and can get quite large if used for logging. + +**NOTE:** If you use the `task.opts` configuration property, the log configuration is disrupted. This is a known bug; please see [SAMZA-109](https://issues.apache.org/jira/browse/SAMZA-109) for a workaround. + +### Log Directory + +Samza will look for the `SAMZA_LOG_DIR` environment variable when it executes. If this variable is defined, all logs will be written to this directory. If the environment variable is empty, or not defined, then Samza will use /tmp. This environment variable can also be referenced inside log4j.xml files (see above). + +### Garbage Collection Logging + +Samza's will automatically set the following garbage collection logging setting, and will output it to `$SAMZA_LOG_DIR/gc.log`. + +{% highlight bash %} +-XX:+PrintGCDateStamps -Xloggc:$SAMZA_LOG_DIR/gc.log +{% endhighlight %} + +#### Rotation + +In older versions of Java, it is impossible to have GC logs roll over based on time or size without the use of a secondary tool. This means that your GC logs will never be deleted until a Samza job ceases to run. As of [Java 6 Update 34](http://www.oracle.com/technetwork/java/javase/2col/6u34-bugfixes-1733379.html), and [Java 7 Update 2](http://www.oracle.com/technetwork/java/javase/7u2-relnotes-1394228.html), [new GC command line switches](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6941923) have been added to support this functionality. If you are using a version of Java that supports GC log rotation, it's highly recommended that you turn it on. + +### YARN + +When a Samza job executes on a YARN grid, the `$SAMZA_LOG_DIR` environment variable will point to a directory that is secured such that only the user executing the Samza job can read and write to it, if YARN is [securely configured](http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/ClusterSetup.html). + +#### STDOUT + +Samza's [ApplicationMaster](../yarn/application-master.html) pipes all STDOUT and STDERR output to logs/stdout and logs/stderr, respectively. These files are never rotated. + +## [Reprocessing »](reprocessing.html) diff --git a/docs/learn/documentation/versioned/jobs/packaging.md b/docs/learn/documentation/versioned/jobs/packaging.md new file mode 100644 index 0000000..9e55f9a --- /dev/null +++ b/docs/learn/documentation/versioned/jobs/packaging.md @@ -0,0 +1,47 @@ +--- +layout: page +title: Packaging +--- + + +The [JobRunner](job-runner.html) page talks about run-job.sh, and how it's used to start a job either locally (ProcessJobFactory/ThreadJobFactory) or with YARN (YarnJobFactory). In the diagram that shows the execution flow, it also shows a run-container.sh script. This script, along with a run-am.sh script, are what Samza actually calls to execute its code. + +``` +bin/run-am.sh +bin/run-container.sh +``` + +The run-container.sh script is responsible for starting the [SamzaContainer](../container/samza-container.html). The run-am.sh script is responsible for starting Samza's application master for YARN. Thus, the run-am.sh script is only used by the YarnJob, but both YarnJob and ProcessJob use run-container.sh. + +Typically, these two scripts are bundled into a tar.gz file that has a structure like this: + +``` +bin/run-am.sh +bin/run-class.sh +bin/run-job.sh +bin/run-container.sh +lib/*.jar +``` + +To run a Samza job, you un-zip its tar.gz file, and execute the run-job.sh script, as defined in the JobRunner section. There are a number of interesting implications from this packaging scheme. First, you'll notice that there is no configuration in the package. Second, you'll notice that the lib directory contains all JARs that you'll need to run your Samza job. + +The reason that configuration is decoupled from your Samza job packaging is that it allows configuration to be updated without having to re-build the entire Samza package. This makes life easier for everyone when you just need to tweak one parameter, and don't want to have to worry about which branch your package was built from, or whether trunk is in a stable state. It also has the added benefit of forcing configuration to be fully resolved at runtime. This means that that the configuration for a job is resolved at the time run-job.sh is called (using --config-path and --config-provider parameters), and from that point on, the configuration is immutable, and passed where it needs to be by Samza (and YARN, if you're using it). + +The second statement, that your Samza package contains all JARs that it needs to run, means that a Samza package is entirely self contained. This allows Samza jobs to run on independent Samza versions without conflicting with each other. This is in contrast to Hadoop, where JARs are pulled in from the local machine that the job is running on (using environment variables). With Samza, you might run your job on version 0.7.0, and someone else might run their job on version 0.8.0. There is no problem with this. + +## [YARN Jobs »](yarn-jobs.html) diff --git a/docs/learn/documentation/versioned/jobs/reprocessing.md b/docs/learn/documentation/versioned/jobs/reprocessing.md new file mode 100644 index 0000000..28d9925 --- /dev/null +++ b/docs/learn/documentation/versioned/jobs/reprocessing.md @@ -0,0 +1,83 @@ +--- +layout: page +title: Reprocessing previously processed data +--- + + +From time to time you may want to deploy a new version of your Samza job that computes results differently. Perhaps you fixed a bug or introduced a new feature. For example, say you have a Samza job that classifies messages as spam or not-spam, using a machine learning model that you train offline. Periodically you want to deploy an updated version of your Samza job which includes the latest classification model. + +When you start up a new version of your job, a question arises: what do you want to do with messages that were previously processed with the old version of your job? The answer depends on the behavior you want: + +1. **No reprocessing:** By default, Samza assumes that messages processed by the old version don't need to be processed again. When the new version starts up, it will resume processing at the point where the old version left off (assuming you have [checkpointing](../container/checkpointing.html) enabled). If this is the behavior you want, there's nothing special you need to do. + +2. **Simple rewind:** Perhaps you want to go back and re-process old messages using the new version of your job. For example, maybe the old version of your classifier marked things as spam too aggressively, so you now want to revisit its previous spam/not-spam decisions using an improved classifier. You can do this by restarting the job at an older point in time in the stream, and running through all the messages since that time. Thus your job starts off reprocessing messages that it has already seen, but it then seamlessly continues with new messages when the reprocessing is done. + + This approach requires an input system such as Kafka, which allows you to jump back in time to a previous point in the stream. We discuss below how this works in practice. + +3. **Parallel rewind:** This approach avoids a downside of the *simple rewind* approach. With simple rewind, any new messages that appear while the job is reprocessing old data are queued up, and are processed when the reprocessing is done. The queueing delay needn't be long, because Samza can stream through historical data very quickly, but some latency-sensitive applications need to process messages faster. + + In the *parallel rewind* approach, you run two jobs in parallel: one job continues to handle live updates with low latency (the *real-time job*), while the other is started at an older point in the stream and reprocesses historical data (the *reprocessing job*). The two jobs consume the same input stream at different points in time, and eventually the reprocessing job catches up with the real-time job. + + There are a few details that you need to think through before deploying parallel rewind, which we discuss below. + +### Jumping Back in Time + +A common aspect of the *simple rewind* and *parallel rewind* approaches is: you have a job which jumps back to an old point in time in the input streams, and consumes all messages since that time. You achieve this by working with Samza's checkpoints. + +Normally, when a Samza job starts up, it reads the latest checkpoint to determine at which offset in the input streams it needs to resume processing. If you need to rewind to an earlier time, you do that in one of two ways: + +1. You can stop the job, manipulate its last checkpoint to point to an older offset, and start the job up again. Samza includes a command-line tool called [CheckpointTool](../container/checkpointing.html#toc_0) which you can use to manipulate checkpoints. +2. You can start a new job with a different *job.name* or *job.id* (e.g. increment *job.id* every time you need to jump back in time). This gives the job a new checkpoint stream, with none of the old checkpoint information. You also need to set [samza.offset.default=oldest](../container/checkpointing.html), so that when the job starts up without checkpoint, it starts consuming at the oldest offset available. + +With either of these approaches you can get Samza to reprocess the entire history of messages in the input system. Input systems such as Kafka can retain a large amount of history — see discussion below. In order to speed up the reprocessing of historical data, you can increase the container count (*yarn.container.count* if you're running Samza on YARN) to boost your job's computational resources. + +If your job maintains any [persistent state](../container/state-management.html), you need to be careful when jumping back in time: resetting a checkpoint does not automatically change persistent state, so you could end up reprocessing old messages while using state from a later point in time. In most cases, a job that jumps back in time should start with an empty state. You can reset the state by deleting the changelog topic, or by changing the name of the changelog topic in your job configuration. + +When you're jumping back in time, you're using Samza somewhat like a batch processing framework (e.g. MapReduce) — with the difference that your job doesn't stop when it has processed all the historical data, but instead continues running, incrementally processing the stream of new messages as they come in. This has the advantage that you don't need to write and maintain separate batch and streaming versions of your job: you can just use the same Samza API for processing both real-time and historical data. + +### Retention of history + +Samza doesn't maintain history itself — that is the responsibility of the input system, such as Kafka. How far back in time you can jump depends on the amount of history that is retained in that system. + +Kafka is designed to keep a fairly large amount of history: it is common for Kafka brokers to keep one or two weeks of message history accessible, even for high volume topics. The retention period is mostly determined by how much disk space you have available. Kafka's performance [remains high](http://engineering.linkedin.com/kafka/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines) even if you have terabytes of history. + +There are two different kinds of history which require different configuration: + +* **Activity events** are things like user tracking events, web server log events and the like. This kind of stream is typically configured with a time-based retention, e.g. a few weeks. Events older than the retention period are deleted (or archived in an offline system such as HDFS). +* **Database changes** are events that show inserts, updates and deletes in a database. In this kind of stream, each event typically has a primary key, and a newer event for a key overwrites any older events for the same key. If the same key is updated many times, you're only really interested in the most recent value. (The [changelog streams](../container/state-management.html) used by Samza's persistent state fall in this category.) + +In a database change stream, when you're reprocessing data, you typically want to reprocess the entire database. You don't want to miss a value just because it was last updated more than a few weeks ago. In other words, you don't want change events to be deleted just because they are older than some threshold. In this case, when you're jumping back in time, you need to rewind to the *beginning of time*, to the first change ever made to the database (known in Kafka as "offset 0"). + +Fortunately this can be done efficiently, using a Kafka feature called [log compaction](http://kafka.apache.org/documentation.html#compaction). + +For example, imagine your database contains counters: every time something happens, you increment the appropriate counters and update the database with the new counter values. Every update is sent to the changelog, and because there are many updates, the changelog stream will take up a lot of space. With log compaction turned on, Kafka deduplicates the stream in the background, keeping only the most recent counter value for each key, and deleting any old values for the same counter. This reduces the size of the stream so much that you can keep the most recent update for every key, even if it was last updated long ago. + +With log compaction enabled, the stream of database changes becomes a full copy of the entire database. By jumping back to offset 0, your Samza job can scan over the entire database and reprocess it. This is a very powerful way of building scalable applications. + +### Details of Parallel Rewind + +If you are taking the *parallel rewind* approach described above, running two jobs in parallel, you need to configure them carefully to avoid problems. In particular, some things to look out for: + +* Make sure that the two jobs don't interfere with each other. They need different *job.name* or *job.id* configuration properties, so that each job gets its own checkpoint stream. If the jobs maintain [persistent state](../container/state-management.html), each job needs its own changelog (two different jobs writing to the same changelog produces undefined results). +* What happens to job output? If the job sends its results to an output stream, or writes to a database, then the easiest solution is for each job to have a separate output stream or database table. If they write to the same output, you need to take care to ensure that newer data isn't overwritten with older data (due to race conditions between the two jobs). +* Do you need to support A/B testing between the old and the new version of your job, e.g. to test whether the new version improves your metrics? Parallel rewind is ideal for this: each job writes to a separate output, and clients or consumers of the output can read from either the old or the new version's output, depending on whether a user is in test group A or B. +* Reclaiming resources: you might want to keep the old version of your job running for a while, even when the new version has finished reprocessing historical data (especially if the old version's output is being used in an A/B test). However, eventually you'll want to shut it down, and delete the checkpoint and changelog streams belonging to the old version. + +Samza gives you a lot of flexibility for reprocessing historical data, and you don't need to program against a separate batch processing API to take advantage of it. If you're mindful of these issues, you can build a data system that is very robust, but still gives you lots of freedom to change your processing logic in future. + +## [Application Master »](../yarn/application-master.html) diff --git a/docs/learn/documentation/versioned/jobs/yarn-jobs.md b/docs/learn/documentation/versioned/jobs/yarn-jobs.md new file mode 100644 index 0000000..58ca50d --- /dev/null +++ b/docs/learn/documentation/versioned/jobs/yarn-jobs.md @@ -0,0 +1,34 @@ +--- +layout: page +title: YARN Jobs +--- + + +When you define `job.factory.class=org.apache.samza.job.yarn.YarnJobFactory` in your job's configuration, Samza will use YARN to execute your job. The YarnJobFactory will use the YARN_HOME environment variable on the machine that run-job.sh is executed on to get the appropriate YARN configuration, which will define where the YARN resource manager is. The YarnJob will work with the resource manager to get your job started on the YARN cluster. + +If you want to use YARN to run your Samza job, you'll also need to define the location of your Samza job's package. For example, you might say: + +{% highlight jproperties %} +yarn.package.path=http://my.http.server/jobs/ingraphs-package-0.0.55.tgz +{% endhighlight %} + +This .tgz file follows the conventions outlined on the [Packaging](packaging.html) page (it has bin/run-am.sh and bin/run-container.sh). YARN NodeManagers will take responsibility for downloading this .tgz file on the appropriate machines, and untar'ing them. From there, YARN will execute run-am.sh or run-container.sh for the Samza Application Master, and SamzaContainer, respectively. + + + +## [Logging »](logging.html) diff --git a/docs/learn/documentation/versioned/operations/kafka.md b/docs/learn/documentation/versioned/operations/kafka.md new file mode 100644 index 0000000..29833e4 --- /dev/null +++ b/docs/learn/documentation/versioned/operations/kafka.md @@ -0,0 +1,34 @@ +--- +layout: page +title: Kafka +--- + + + + + + +Kafka has a great [operations wiki](http://kafka.apache.org/08/ops.html), which provides some detail on how to operate Kafka at scale. + +### Auto-Create Topics + +Kafka brokers should be configured to automatically create topics. Without this, it's going to be very cumbersome to run Samze jobs, since jobs will write to arbitrary (and sometimes new) topics. + +{% highlight jproperties %} +auto.create.topics.enable=true +{% endhighlight %} diff --git a/docs/learn/documentation/versioned/operations/security.md b/docs/learn/documentation/versioned/operations/security.md new file mode 100644 index 0000000..b7ef24e --- /dev/null +++ b/docs/learn/documentation/versioned/operations/security.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Security +--- + + +Samza provides no security. All security is implemented in the stream system, or in the environment that Samza containers run. + +### Securing Streaming Systems + +Samza does not provide any security at the stream system level. It is up to individual streaming systems to enforce their own security. If a stream system requires usernames and passwords in order to consume from specific streams, these values must be supplied via configuration, and used at the StreamConsumer/StreamConsumerFactory implementation. The same holds true if the streaming system uses SSL certificates or Kerberos. The environment in which Samza runs must provide the appropriate certificate or Kerberos ticket, and the StreamConsumer must be implemented to use these certificates or tickets. + +#### Securing Kafka + +Kafka provides no security for its topics, and therefore Samza doesn't provide any security when using Kafka topics. + +### Securing Samza's Environment + +The most important thing to keep in mind when securing an environment that Samza containers run in is that **Samza containers execute arbitrary user code**. They must considered an adversarial application, and the environment must be locked down accordingly. + +#### Configuration + +Samza reads all configuration at the time a Samza job is started using the run-job.sh script. If configuration contains sensitive information, then care must be taken to provide the JobRunner with the configuration. This means implementing a ConfigFactory that understands the configuration security model, and resolves configuration to Samza's Config object in a secure way. + +During the duration of a Samza job's execution, the configuration is kept in memory. The only time configuration is visible is: + +1. When configuration is resolved using a ConfigFactory. +2. The configuration is printed to STDOUT when run-job.sh is run. +3. The configuration is written to the logs when a Samza container starts. + +If configuration contains sensitive data, then these three points must be secured. + +#### Ports + +The only port that a Samza container opens by default is an un-secured JMX port that is randomly selected at start time. If this is not desired, JMX can be disabled through configuration. See the [Configuration](configuration.html) page for details. + +Users might open ports from inside a Samza container. If this is not desired, then the user that executes the Samza container must have the appropriate permissions revoked, usually using iptables. + +#### Logs + +Samza container logs contain configuration, and might contain arbitrary sensitive data logged by the user. A secure log directory must be provided to the Samza container. + +#### Starting a Samza Job + +If operators do not wish to allow Samza containers to be executed by arbitrary users, then the mechanism that Samza containers are deployed must secured. Usually, this means controlling execution of the run-job.sh script. The recommended pattern is to lock down the machines that Samza containers run on, and execute run-job.sh from either a blessed web service or special machine, and only allow access to the service or machine by specific users. + +#### Shell Scripts + +Please see the [Packaging](packaging.html) section for details on the the shell scripts that Samza uses. Samza containers allow users to execute arbitrary shell commands, so user permissions must be locked down to prevent users from damaging the environment or reading sensitive data. + +#### YARN + + + +Samza provides out-of-the-box YARN integration. Take a look at Samza's YARN Security page for details. + +## [Kafka »](kafka.html) diff --git a/docs/learn/documentation/versioned/yarn/application-master.md b/docs/learn/documentation/versioned/yarn/application-master.md new file mode 100644 index 0000000..d20aece --- /dev/null +++ b/docs/learn/documentation/versioned/yarn/application-master.md @@ -0,0 +1,69 @@ +--- +layout: page +title: Application Master +--- + + +YARN is Hadoop's next-generation cluster manager. It allows developers to deploy and execute arbitrary commands on a grid. If you're unfamiliar with YARN, or the concept of an ApplicationMaster (AM), please read Hadoop's [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html) page. + +### Integration + +Samza's main integration with YARN comes in the form of a Samza ApplicationMaster. This is the chunk of code responsible for managing a Samza job in a YARN grid. It decides what to do when a stream processor fails, which machines a Samza job's [containers](../container/samza-container.html) should run on, and so on. + +When the Samza ApplicationMaster starts up, it does the following: + +1. Receives configuration from YARN via the STREAMING_CONFIG environment variable. +2. Starts a JMX server on a random port. +3. Instantiates a metrics registry and reporters to keep track of relevant metrics. +4. Registers the AM with YARN's RM. +5. Get the total number of partitions for the Samza job using each input stream's PartitionManager (see the [Streams](../container/streams.html) page for details). +6. Read the total number of containers requested from the Samza job's configuration. +7. Assign each partition to a container (called a Task Group in Samza's AM dashboard). +8. Make a [ResourceRequest](http://hadoop.apache.org/docs/current/api/org/apache/hadoop/yarn/api/records/ResourceRequest.html) to YARN for each container. +9. Poll the YARN RM every second to check for allocated and released containers. + +From this point on, the ApplicationMaster just reacts to events from the RM. + +### Fault Tolerance + +Whenever a container is allocated, the AM will work with the YARN NM to start a SamzaContainer (with appropriate partitions assigned to it) in the container. If a container fails with a non-zero return code, the AM will request a new container, and restart the SamzaContainer. If a SamzaContainer fails too many times, too quickly, the ApplicationMaster will fail the whole Samza job with a non-zero return code. See the yarn.container.retry.count and yarn.container.retry.window.ms [configuration](../jobs/configuration.html) parameters for details. + +When the AM receives a reboot signal from YARN, it will throw a SamzaException. This will trigger a clean and successful shutdown of the AM (YARN won't think the AM failed). + +If the AM, itself, fails, YARN will handle restarting the AM. When the AM is restarted, all containers that were running will be killed, and the AM will start from scratch. The same list of operations, shown above, will be executed. The AM will request new containers for its SamzaContainers, and proceed as though it has just started for the first time. YARN has a yarn.resourcemanager.am.max-retries configuration parameter that's defined in [yarn-site.xml](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-common/yarn-default.xml). This configuration defaults to 1, which means that, by default, a single AM failure will cause your Samza job to stop running. + +### Dashboard + +Samza's ApplicationMaster comes with a dashboard to show useful information such as: + +1. Where containers are located. +2. Links to logs. +3. The Samza job's configuration. +4. Container failure count. + +You can find this dashboard by going to your YARN grid's ResourceManager page (usually something like [http://localhost:8088/cluster](http://localhost:8088/cluster)), and clicking on the "ApplicationMaster" link of a running Samza job. + +Screenshot of ApplicationMaster dashboard + +### Security + +The Samza dashboard's HTTP access is currently un-secured, even when using YARN in secure-mode. This means that users with access to a YARN grid could port-scan a Samza ApplicationMaster's HTTP server, and open the dashboard in a browser to view its contents. Sensitive configuration can be viewed by anyone, in this way, and care should be taken. There are plans to secure Samza's ApplicationMaster using [Hadoop's security](http://docs.hortonworks.com/HDPDocuments/HDP1/HDP-1.3.0/bk_installing_manually_book/content/rpm-chap14-2-3-1.html) features ([SPENAGO](http://en.wikipedia.org/wiki/SPNEGO)). + +See Samza's [security](../operations/security.html) page for more details. + +## [Isolation »](isolation.html) diff --git a/docs/learn/documentation/versioned/yarn/isolation.md b/docs/learn/documentation/versioned/yarn/isolation.md new file mode 100644 index 0000000..1eb3bf5 --- /dev/null +++ b/docs/learn/documentation/versioned/yarn/isolation.md @@ -0,0 +1,46 @@ +--- +layout: page +title: Isolation +--- + + +When running Samza jobs in a shared, distributed environment, the stream processors can have an impact on one another's performance. A stream processor that uses 100% of a machine's CPU will slow down all other stream processors on the machine. + +One of [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html)'s responsibilities is to manage resources so that this doesn't happen. Each of YARN's Node Managers (NM) has a chunk of "resources" dedicated to it. The YARN Resource Manager (RM) will only allow a container to be allocated on a NM if it has enough resources to satisfy the container's needs. + +YARN currently supports resource management for memory and CPU. + +### Memory + +YARN will automatically enforce memory limits for all containers that it executes. All containers must have a max-memory size defined when they're created. If the sum of all memory usage for processes associated with a single YARN container exceeds this maximum, YARN will kill the container. + +Samza supports memory limits using the yarn.container.memory.mb and yarn.am.container.memory.mb configuration parameters. Keep in mind that this is simply the amount of memory YARN will allow a [SamzaContainer](../container/samza-container.html) or [ApplicationMaster](application-master.html) to have. You'll still need to configure your heap settings appropriately using task.opts, when using Java (the default is -Xmx160M). See the [Configuration](../jobs/configuration.html) and [Packaging](../jobs/packaging.html) pages for details. + +### CPU + +YARN has the concept of a virtual core. Each NM is assigned a total number of virtual cores (32, by default). When a container request is made, it must specify how many virtual cores it needs. The YARN RM will only assign the container to a NM that has enough virtual cores to satisfy the request. + +#### CGroups + +Unlike memory, which YARN can enforce itself (by looking at the /proc folder), YARN can't enforce CPU isolation, since this must be done at the Linux kernel level. One of YARN's interesting new features is its support for Linux [CGroups](https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt). CGroups are a way to control process utilization at the kernel level in Linux. + +If YARN is setup to use CGroups, then YARN will guarantee that a container will get at least the amount of CPU that it requires. Currently, YARN will give you more CPU, if it's available. For details on enforcing "at most" CPU usage, see [YARN-810](https://issues.apache.org/jira/browse/YARN-810). + +See [this blog post](http://riccomini.name/posts/hadoop/2013-06-14-yarn-with-cgroups/) for details on setting up YARN with CGroups. + +## [Security »](../operations/security.html) diff --git a/docs/learn/tutorials/0.7.0/deploy-samza-job-from-hdfs.md b/docs/learn/tutorials/0.7.0/deploy-samza-job-from-hdfs.md deleted file mode 100644 index ab33dd3..0000000 --- a/docs/learn/tutorials/0.7.0/deploy-samza-job-from-hdfs.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: page -title: Deploying a Samza job from HDFS ---- - - -This tutorial uses [hello-samza](../../../startup/hello-samza/0.7.0/) to illustrate how to run a Samza job if you want to publish the Samza job's .tar.gz package to HDFS. - -### Upload the package - -{% highlight bash %} -hadoop fs -put ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz /path/for/tgz -{% endhighlight %} - -### Add HDFS configuration - -Put the hdfs-site.xml file of your cluster into ~/.samza/conf directory (The same place as the yarn-site.xml). If you set HADOOP\_CONF\_DIR, put the hdfs-site.xml in your configuration directory if the hdfs-site.xml is not there. - -### Change properties file - -Change the yarn.package.path in the properties file to your HDFS location. - -{% highlight jproperties %} -yarn.package.path=hdfs://:/path/to/tgz -{% endhighlight %} - -Then you should be able to run the Samza job as described in [hello-samza](../../../startup/hello-samza/0.7.0/). \ No newline at end of file diff --git a/docs/learn/tutorials/0.7.0/index.md b/docs/learn/tutorials/0.7.0/index.md deleted file mode 100644 index 91bddc5..0000000 --- a/docs/learn/tutorials/0.7.0/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -layout: page -title: Tutorials ---- - - -[Remote Debugging with Samza](remote-debugging-samza.html) - -[Deploying a Samza Job from HDFS](deploy-samza-job-from-hdfs.html) - -[Run Hello-samza in Multi-node YARN](run-in-multi-node-yarn.html) - -[Run Hello-samza without Internet](run-hello-samza-without-internet.html) - - diff --git a/docs/learn/tutorials/0.7.0/remote-debugging-samza.md b/docs/learn/tutorials/0.7.0/remote-debugging-samza.md deleted file mode 100644 index 89d0856..0000000 --- a/docs/learn/tutorials/0.7.0/remote-debugging-samza.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -layout: page -title: Remote Debugging with Samza ---- - - -Let's use Eclipse to attach a remote debugger to a Samza container. If you're an IntelliJ user, you'll have to fill in the blanks, but the process should be pretty similar. This tutorial assumes you've already run through the [Hello Samza](../../../startup/hello-samza/0.7.0/) tutorial. - -### Get the Code - -Start by checking out Samza, so we have access to the source. - -{% highlight bash %} -git clone http://git-wip-us.apache.org/repos/asf/incubator-samza.git -{% endhighlight %} - -Next, grab hello-samza. - -{% highlight bash %} -git clone git://git.apache.org/incubator-samza-hello-samza.git -{% endhighlight %} - -### Setup the Environment - -Now, let's setup the Eclipse project files. - -{% highlight bash %} -cd incubator-samza -./gradlew eclipse -{% endhighlight %} - -Let's also release Samza to Maven's local repository, so hello-samza has access to the JARs that it needs. - -{% highlight bash %} -./gradlew -PscalaVersion=2.9.2 clean publishToMavenLocal -{% endhighlight %} - -Next, open Eclipse, and import the Samza source code into your workspace: "File" > "Import" > "Existing Projects into Workspace" > "Browse". Select 'incubator-samza' folder, and hit 'finish'. - -### Enable Remote Debugging - -Now, go back to the hello-samza project, and edit ./samza-job-package/src/main/config/wikipedia-feed.properties to add the following line: - -{% highlight jproperties %} -task.opts=-agentlib:jdwp=transport=dt_socket,address=localhost:9009,server=y,suspend=y -{% endhighlight %} - -The [task.opts](../../documentation/0.7.0/jobs/configuration-table.html) configuration parameter is a way to override Java parameters at runtime for your Samza containers. In this example, we're setting the agentlib parameter to enable remote debugging on localhost, port 9009. In a more realistic environment, you might also set Java heap settings (-Xmx, -Xms, etc), as well as garbage collection and logging settings. - -*NOTE: If you're running multiple Samza containers on the same machine, there is a potential for port collisions. You must configure your task.opts to assign different ports for different Samza jobs. If a Samza job has more than one container (e.g. if you're using YARN with yarn.container.count=2), those containers must be run on different machines.* - -### Start the Grid - -Now that the Samza job has been setup to enable remote debugging when a Samza container starts, let's start the ZooKeeper, Kafka, and YARN. - -{% highlight bash %} -bin/grid -{% endhighlight %} - -If you get a complaint that JAVA_HOME is not set, then you'll need to set it. This can be done on OSX by running: - -{% highlight bash %} -export JAVA_HOME=$(/usr/libexec/java_home) -{% endhighlight %} - -Once the grid starts, you can start the wikipedia-feed Samza job. - -{% highlight bash %} -mvn clean package -mkdir -p deploy/samza -tar -xvf ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz -C deploy/samza -deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties -{% endhighlight %} - -When the wikipedia-feed job starts up, a single Samza container will be created to process all incoming messages. This is the container that we'll want to connect to from the remote debugger. - -### Connect the Remote Debugger - -Switch back to Eclipse, and set a break point in TaskInstance.process by clicking on a line inside TaskInstance.process, and clicking "Run" > "Toggle Breakpoint". A blue circle should appear to the left of the line. This will let you see incoming messages as they arrive. - -Setup a remote debugging session: "Run" > "Debug Configurations..." > right click on "Remote Java Application" > "New". Set the name to 'wikipedia-feed-debug'. Set the port to 9009 (matching the port in the task.opts configuration). Click "Source" > "Add..." > "Java Project". Select all of the Samza projects that you imported (i.e. samza-api, samza-core, etc). If you would like to set breakpoints in your own Stream task, also add the project that contains your StreamTask implementation. Click 'Debug'. - -After a few moments, Eclipse should connect to the wikipedia-feed job, and ask you to switch to Debug mode. Once in debug, you'll see that it's broken at the TaskInstance.process method. From here, you can step through code, inspect variable values, etc. - -Congratulations, you've got a remote debug connection to your StreamTask! diff --git a/docs/learn/tutorials/0.7.0/run-hello-samza-without-internet.md b/docs/learn/tutorials/0.7.0/run-hello-samza-without-internet.md deleted file mode 100644 index a5503ef..0000000 --- a/docs/learn/tutorials/0.7.0/run-hello-samza-without-internet.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: page -title: Run Hello Samza without Internet ---- - - -This tutorial is to help you run [Hello Samza](../../../startup/hello-samza/0.7.0/) if you can not connect to the internet. - -### Test Your Connection - -Ping irc.wikimedia.org. Sometimes the firewall in your company blocks this service. - -{% highlight bash %} -telnet irc.wikimedia.org 6667 -{% endhighlight %} - -You should see something like this: - -``` -Trying 208.80.152.178... -Connected to ekrem.wikimedia.org. -Escape character is '^]'. -NOTICE AUTH :*** Processing connection to irc.pmtpa.wikimedia.org -NOTICE AUTH :*** Looking up your hostname... -NOTICE AUTH :*** Checking Ident -NOTICE AUTH :*** Found your hostname -``` - -Otherwise, you may have the connection problem. - -### Use Local Data to Run Hello Samza - -We provide an alternative to get wikipedia feed data. Instead of running - -{% highlight bash %} -deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties -{% endhighlight %} - -You will run - -{% highlight bash %} -bin/produce-wikipedia-raw-data.sh -{% endhighlight %} - -This script will read wikipedia feed data from local file and produce them to the Kafka broker. By default, it produces to localhost:9092 as the Kafka broker and uses localhost:2181 as zookeeper. You can overwrite them: - -{% highlight bash %} -bin/produce-wikipedia-raw-data.sh -b yourKafkaBrokerAddress -z yourZookeeperAddress -{% endhighlight %} - -Now you can go back to Generate Wikipedia Statistics section in [Hello Samza](../../../startup/hello-samza/0.7.0/) and follow the remaining steps. - -### A Little Explanation - -The goal of - -{% highlight bash %} -deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties -{% endhighlight %} - -is to deploy a Samza job which listens to wikipedia API, receives the feed in realtime and produces the feed to the Kafka topic wikipedia-raw. The alternative in this tutorial is reading local wikipedia feed in an infinite loop and producing the data to Kafka wikipedia-raw. The follow-up job, wikipedia-parser is getting data from Kafka topic wikipedia-raw, so as long as we have correct data in Kafka topic wikipedia-raw, we are fine. All Samza jobs are connected by the Kafka and do not depend on each other. - - diff --git a/docs/learn/tutorials/0.7.0/run-in-multi-node-yarn.md b/docs/learn/tutorials/0.7.0/run-in-multi-node-yarn.md deleted file mode 100644 index c079233..0000000 --- a/docs/learn/tutorials/0.7.0/run-in-multi-node-yarn.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -layout: page -title: Run Hello-samza in Multi-node YARN ---- - - -You must successfully run the [hello-samza](../../../startup/hello-samza/0.7.0/) project in a single-node YARN by following the [hello-samza](../../../startup/hello-samza/0.7.0/) tutorial. Now it's time to run the Samza job in a "real" YARN grid (with more than one node). - -## Set Up Multi-node YARN - -If you already have a multi-node YARN cluster (such as CDH5 cluster), you can skip this set-up section. - -### Basic YARN Setting - -1\. Dowload [YARN 2.3](http://mirror.symnds.com/software/Apache/hadoop/common/hadoop-2.3.0/hadoop-2.3.0.tar.gz) to /tmp and untar it. - -{% highlight bash %} -cd /tmp -tar -xvf hadoop-2.3.0.tar.gz -cd hadoop-2.3.0 -{% endhighlight %} - -2\. Set up environment variables. - -{% highlight bash %} -export HADOOP_YARN_HOME=$(pwd) -mkdir conf -export HADOOP_CONF_DIR=$HADOOP_YARN_HOME/conf -{% endhighlight %} - -3\. Configure YARN setting file. - -{% highlight bash %} -cp ./etc/hadoop/yarn-site.xml conf -vi conf/yarn-site.xml -{% endhighlight %} - -Add the following property to yarn-site.xml: - -{% highlight xml %} - - yarn.resourcemanager.hostname - - yourHostname - -{% endhighlight %} - -Download and add capacity-schedule.xml. - -``` -curl http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/resources/capacity-scheduler.xml?view=co > conf/capacity-scheduler.xml -``` - -### Set Up Http Filesystem for YARN - -The goal of these steps is to configure YARN to read http filesystem because we will use Http server to deploy Samza job package. If you want to use HDFS to deploy Samza job package, you can skip step 4~6 and follow [Deploying a Samza Job from HDFS](deploy-samza-job-from-hdfs.html) - -4\. Download Scala package and untar it. - -{% highlight bash %} -cd /tmp -curl http://www.scala-lang.org/files/archive/scala-2.10.3.tgz > scala-2.10.3.tgz -tar -xvf scala-2.10.3.tgz -{% endhighlight %} - -5\. Add Scala and its log jars. - -{% highlight bash %} -cp /tmp/scala-2.10.3/lib/scala-compiler.jar $HADOOP_YARN_HOME/share/hadoop/hdfs/lib -cp /tmp/scala-2.10.3/lib/scala-library.jar $HADOOP_YARN_HOME/share/hadoop/hdfs/lib -curl http://search.maven.org/remotecontent?filepath=org/clapper/grizzled-slf4j_2.10/1.0.1/grizzled-slf4j_2.10-1.0.1.jar > $HADOOP_YARN_HOME/share/hadoop/hdfs/lib/grizzled-slf4j_2.10-1.0.1.jar -{% endhighlight %} - -6\. Add http configuration in core-site.xml (create the core-site.xml file and add content). - -{% highlight xml %} -vi $HADOOP_YARN_HOME/conf/core-site.xml -{% endhighlight %} - -Add the following code: - -{% highlight xml %} - - - - fs.http.impl - org.apache.samza.util.hadoop.HttpFileSystem - - -{% endhighlight %} - -### Distribute Hadoop File to Slaves - -7\. Basically, you copy the hadoop file in your host machine to slave machines. (172.21.100.35, in my case): - -{% highlight bash %} -scp -r . 172.21.100.35:/tmp/hadoop-2.3.0 -echo 172.21.100.35 > conf/slaves -sbin/start-yarn.sh -{% endhighlight %} - -* If you get "172.21.100.35: Error: JAVA_HOME is not set and could not be found.", you'll need to add a conf/hadoop-env.sh file to the machine with the failure (172.21.100.35, in this case), which has "export JAVA_HOME=/export/apps/jdk/JDK-1_6_0_27" (or wherever your JAVA_HOME actually is). - -8\. Validate that your nodes are up by visiting http://yourHostname:8088/cluster/nodes. - -## Deploy Samza Job - -Some of the following steps are exactlly identical to what you have seen in [hello-samza](../../../startup/hello-samza/0.7.0/). You may skip them if you have already done so. - -1\. Download Samza and publish it to Maven local repository. - -{% highlight bash %} -cd /tmp -git clone http://git-wip-us.apache.org/repos/asf/incubator-samza.git -cd incubator-samza -./gradlew clean publishToMavenLocal -cd .. -{% endhighlight %} - -2\. Download hello-samza project and change the job properties file. - -{% highlight bash %} -git clone git://github.com/linkedin/hello-samza.git -cd hello-samza -vi samza-job-package/src/main/config/wikipedia-feed.properties -{% endhighlight %} - -Change the yarn.package.path property to be: - -{% highlight jproperties %} -yarn.package.path=http://yourHostname:8000/samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz -{% endhighlight %} - -3\. Complie hello-samza. - -{% highlight bash %} -mvn clean package -mkdir -p deploy/samza -tar -xvf ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz -C deploy/samza -{% endhighlight %} - -4\. Deploy Samza job package to Http server.. - -Open a new terminal, and run: - -{% highlight bash %} -cd /tmp/hello-samza && python -m SimpleHTTPServer -{% endhighlight %} - -Go back to the original terminal (not the one running the HTTP server): - -{% highlight bash %} -deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties -{% endhighlight %} - -Go to http://yourHostname:8088 and find the wikipedia-feed job. Click on the ApplicationMaster link to see that it's running. - -Congratulations! You now run the Samza job in a "real" YARN grid! - diff --git a/docs/learn/tutorials/versioned/deploy-samza-job-from-hdfs.md b/docs/learn/tutorials/versioned/deploy-samza-job-from-hdfs.md new file mode 100644 index 0000000..ec455d7 --- /dev/null +++ b/docs/learn/tutorials/versioned/deploy-samza-job-from-hdfs.md @@ -0,0 +1,42 @@ +--- +layout: page +title: Deploying a Samza job from HDFS +--- + + +This tutorial uses [hello-samza](../../../startup/hello-samza/{{site.version}}/) to illustrate how to run a Samza job if you want to publish the Samza job's .tar.gz package to HDFS. + +### Upload the package + +{% highlight bash %} +hadoop fs -put ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz /path/for/tgz +{% endhighlight %} + +### Add HDFS configuration + +Put the hdfs-site.xml file of your cluster into ~/.samza/conf directory (The same place as the yarn-site.xml). If you set HADOOP\_CONF\_DIR, put the hdfs-site.xml in your configuration directory if the hdfs-site.xml is not there. + +### Change properties file + +Change the yarn.package.path in the properties file to your HDFS location. + +{% highlight jproperties %} +yarn.package.path=hdfs://:/path/to/tgz +{% endhighlight %} + +Then you should be able to run the Samza job as described in [hello-samza](../../../startup/hello-samza/{{site.version}}/). \ No newline at end of file diff --git a/docs/learn/tutorials/versioned/index.md b/docs/learn/tutorials/versioned/index.md new file mode 100644 index 0000000..91bddc5 --- /dev/null +++ b/docs/learn/tutorials/versioned/index.md @@ -0,0 +1,39 @@ +--- +layout: page +title: Tutorials +--- + + +[Remote Debugging with Samza](remote-debugging-samza.html) + +[Deploying a Samza Job from HDFS](deploy-samza-job-from-hdfs.html) + +[Run Hello-samza in Multi-node YARN](run-in-multi-node-yarn.html) + +[Run Hello-samza without Internet](run-hello-samza-without-internet.html) + + diff --git a/docs/learn/tutorials/versioned/remote-debugging-samza.md b/docs/learn/tutorials/versioned/remote-debugging-samza.md new file mode 100644 index 0000000..b84584e --- /dev/null +++ b/docs/learn/tutorials/versioned/remote-debugging-samza.md @@ -0,0 +1,100 @@ +--- +layout: page +title: Remote Debugging with Samza +--- + + +Let's use Eclipse to attach a remote debugger to a Samza container. If you're an IntelliJ user, you'll have to fill in the blanks, but the process should be pretty similar. This tutorial assumes you've already run through the [Hello Samza](../../../startup/hello-samza/{{site.version}}/) tutorial. + +### Get the Code + +Start by checking out Samza, so we have access to the source. + +{% highlight bash %} +git clone http://git-wip-us.apache.org/repos/asf/incubator-samza.git +{% endhighlight %} + +Next, grab hello-samza. + +{% highlight bash %} +git clone git://git.apache.org/incubator-samza-hello-samza.git +{% endhighlight %} + +### Setup the Environment + +Now, let's setup the Eclipse project files. + +{% highlight bash %} +cd incubator-samza +./gradlew eclipse +{% endhighlight %} + +Let's also release Samza to Maven's local repository, so hello-samza has access to the JARs that it needs. + +{% highlight bash %} +./gradlew -PscalaVersion=2.9.2 clean publishToMavenLocal +{% endhighlight %} + +Next, open Eclipse, and import the Samza source code into your workspace: "File" > "Import" > "Existing Projects into Workspace" > "Browse". Select 'incubator-samza' folder, and hit 'finish'. + +### Enable Remote Debugging + +Now, go back to the hello-samza project, and edit ./samza-job-package/src/main/config/wikipedia-feed.properties to add the following line: + +{% highlight jproperties %} +task.opts=-agentlib:jdwp=transport=dt_socket,address=localhost:9009,server=y,suspend=y +{% endhighlight %} + +The [task.opts](../../documentation/{{site.version}}/jobs/configuration-table.html) configuration parameter is a way to override Java parameters at runtime for your Samza containers. In this example, we're setting the agentlib parameter to enable remote debugging on localhost, port 9009. In a more realistic environment, you might also set Java heap settings (-Xmx, -Xms, etc), as well as garbage collection and logging settings. + +*NOTE: If you're running multiple Samza containers on the same machine, there is a potential for port collisions. You must configure your task.opts to assign different ports for different Samza jobs. If a Samza job has more than one container (e.g. if you're using YARN with yarn.container.count=2), those containers must be run on different machines.* + +### Start the Grid + +Now that the Samza job has been setup to enable remote debugging when a Samza container starts, let's start the ZooKeeper, Kafka, and YARN. + +{% highlight bash %} +bin/grid +{% endhighlight %} + +If you get a complaint that JAVA_HOME is not set, then you'll need to set it. This can be done on OSX by running: + +{% highlight bash %} +export JAVA_HOME=$(/usr/libexec/java_home) +{% endhighlight %} + +Once the grid starts, you can start the wikipedia-feed Samza job. + +{% highlight bash %} +mvn clean package +mkdir -p deploy/samza +tar -xvf ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz -C deploy/samza +deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties +{% endhighlight %} + +When the wikipedia-feed job starts up, a single Samza container will be created to process all incoming messages. This is the container that we'll want to connect to from the remote debugger. + +### Connect the Remote Debugger + +Switch back to Eclipse, and set a break point in TaskInstance.process by clicking on a line inside TaskInstance.process, and clicking "Run" > "Toggle Breakpoint". A blue circle should appear to the left of the line. This will let you see incoming messages as they arrive. + +Setup a remote debugging session: "Run" > "Debug Configurations..." > right click on "Remote Java Application" > "New". Set the name to 'wikipedia-feed-debug'. Set the port to 9009 (matching the port in the task.opts configuration). Click "Source" > "Add..." > "Java Project". Select all of the Samza projects that you imported (i.e. samza-api, samza-core, etc). If you would like to set breakpoints in your own Stream task, also add the project that contains your StreamTask implementation. Click 'Debug'. + +After a few moments, Eclipse should connect to the wikipedia-feed job, and ask you to switch to Debug mode. Once in debug, you'll see that it's broken at the TaskInstance.process method. From here, you can step through code, inspect variable values, etc. + +Congratulations, you've got a remote debug connection to your StreamTask! diff --git a/docs/learn/tutorials/versioned/run-hello-samza-without-internet.md b/docs/learn/tutorials/versioned/run-hello-samza-without-internet.md new file mode 100644 index 0000000..e276cdb --- /dev/null +++ b/docs/learn/tutorials/versioned/run-hello-samza-without-internet.md @@ -0,0 +1,78 @@ +--- +layout: page +title: Run Hello Samza without Internet +--- + + +This tutorial is to help you run [Hello Samza](../../../startup/hello-samza/{{site.version}}/) if you can not connect to the internet. + +### Test Your Connection + +Ping irc.wikimedia.org. Sometimes the firewall in your company blocks this service. + +{% highlight bash %} +telnet irc.wikimedia.org 6667 +{% endhighlight %} + +You should see something like this: + +``` +Trying 208.80.152.178... +Connected to ekrem.wikimedia.org. +Escape character is '^]'. +NOTICE AUTH :*** Processing connection to irc.pmtpa.wikimedia.org +NOTICE AUTH :*** Looking up your hostname... +NOTICE AUTH :*** Checking Ident +NOTICE AUTH :*** Found your hostname +``` + +Otherwise, you may have the connection problem. + +### Use Local Data to Run Hello Samza + +We provide an alternative to get wikipedia feed data. Instead of running + +{% highlight bash %} +deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties +{% endhighlight %} + +You will run + +{% highlight bash %} +bin/produce-wikipedia-raw-data.sh +{% endhighlight %} + +This script will read wikipedia feed data from local file and produce them to the Kafka broker. By default, it produces to localhost:9092 as the Kafka broker and uses localhost:2181 as zookeeper. You can overwrite them: + +{% highlight bash %} +bin/produce-wikipedia-raw-data.sh -b yourKafkaBrokerAddress -z yourZookeeperAddress +{% endhighlight %} + +Now you can go back to Generate Wikipedia Statistics section in [Hello Samza](../../../startup/hello-samza/{{site.version}}/) and follow the remaining steps. + +### A Little Explanation + +The goal of + +{% highlight bash %} +deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties +{% endhighlight %} + +is to deploy a Samza job which listens to wikipedia API, receives the feed in realtime and produces the feed to the Kafka topic wikipedia-raw. The alternative in this tutorial is reading local wikipedia feed in an infinite loop and producing the data to Kafka wikipedia-raw. The follow-up job, wikipedia-parser is getting data from Kafka topic wikipedia-raw, so as long as we have correct data in Kafka topic wikipedia-raw, we are fine. All Samza jobs are connected by the Kafka and do not depend on each other. + + diff --git a/docs/learn/tutorials/versioned/run-in-multi-node-yarn.md b/docs/learn/tutorials/versioned/run-in-multi-node-yarn.md new file mode 100644 index 0000000..b5e6dcb --- /dev/null +++ b/docs/learn/tutorials/versioned/run-in-multi-node-yarn.md @@ -0,0 +1,174 @@ +--- +layout: page +title: Run Hello-samza in Multi-node YARN +--- + + +You must successfully run the [hello-samza](../../../startup/hello-samza/{{site.version}}/) project in a single-node YARN by following the [hello-samza](../../../startup/hello-samza/{{site.version}}/) tutorial. Now it's time to run the Samza job in a "real" YARN grid (with more than one node). + +## Set Up Multi-node YARN + +If you already have a multi-node YARN cluster (such as CDH5 cluster), you can skip this set-up section. + +### Basic YARN Setting + +1\. Dowload [YARN 2.3](http://mirror.symnds.com/software/Apache/hadoop/common/hadoop-2.3.0/hadoop-2.3.0.tar.gz) to /tmp and untar it. + +{% highlight bash %} +cd /tmp +tar -xvf hadoop-2.3.0.tar.gz +cd hadoop-2.3.0 +{% endhighlight %} + +2\. Set up environment variables. + +{% highlight bash %} +export HADOOP_YARN_HOME=$(pwd) +mkdir conf +export HADOOP_CONF_DIR=$HADOOP_YARN_HOME/conf +{% endhighlight %} + +3\. Configure YARN setting file. + +{% highlight bash %} +cp ./etc/hadoop/yarn-site.xml conf +vi conf/yarn-site.xml +{% endhighlight %} + +Add the following property to yarn-site.xml: + +{% highlight xml %} + + yarn.resourcemanager.hostname + + yourHostname + +{% endhighlight %} + +Download and add capacity-schedule.xml. + +``` +curl http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/resources/capacity-scheduler.xml?view=co > conf/capacity-scheduler.xml +``` + +### Set Up Http Filesystem for YARN + +The goal of these steps is to configure YARN to read http filesystem because we will use Http server to deploy Samza job package. If you want to use HDFS to deploy Samza job package, you can skip step 4~6 and follow [Deploying a Samza Job from HDFS](deploy-samza-job-from-hdfs.html) + +4\. Download Scala package and untar it. + +{% highlight bash %} +cd /tmp +curl http://www.scala-lang.org/files/archive/scala-2.10.3.tgz > scala-2.10.3.tgz +tar -xvf scala-2.10.3.tgz +{% endhighlight %} + +5\. Add Scala and its log jars. + +{% highlight bash %} +cp /tmp/scala-2.10.3/lib/scala-compiler.jar $HADOOP_YARN_HOME/share/hadoop/hdfs/lib +cp /tmp/scala-2.10.3/lib/scala-library.jar $HADOOP_YARN_HOME/share/hadoop/hdfs/lib +curl http://search.maven.org/remotecontent?filepath=org/clapper/grizzled-slf4j_2.10/1.0.1/grizzled-slf4j_2.10-1.0.1.jar > $HADOOP_YARN_HOME/share/hadoop/hdfs/lib/grizzled-slf4j_2.10-1.0.1.jar +{% endhighlight %} + +6\. Add http configuration in core-site.xml (create the core-site.xml file and add content). + +{% highlight xml %} +vi $HADOOP_YARN_HOME/conf/core-site.xml +{% endhighlight %} + +Add the following code: + +{% highlight xml %} + + + + fs.http.impl + org.apache.samza.util.hadoop.HttpFileSystem + + +{% endhighlight %} + +### Distribute Hadoop File to Slaves + +7\. Basically, you copy the hadoop file in your host machine to slave machines. (172.21.100.35, in my case): + +{% highlight bash %} +scp -r . 172.21.100.35:/tmp/hadoop-2.3.0 +echo 172.21.100.35 > conf/slaves +sbin/start-yarn.sh +{% endhighlight %} + +* If you get "172.21.100.35: Error: JAVA_HOME is not set and could not be found.", you'll need to add a conf/hadoop-env.sh file to the machine with the failure (172.21.100.35, in this case), which has "export JAVA_HOME=/export/apps/jdk/JDK-1_6_0_27" (or wherever your JAVA_HOME actually is). + +8\. Validate that your nodes are up by visiting http://yourHostname:8088/cluster/nodes. + +## Deploy Samza Job + +Some of the following steps are exactlly identical to what you have seen in [hello-samza](../../../startup/hello-samza/{{site.version}}/). You may skip them if you have already done so. + +1\. Download Samza and publish it to Maven local repository. + +{% highlight bash %} +cd /tmp +git clone http://git-wip-us.apache.org/repos/asf/incubator-samza.git +cd incubator-samza +./gradlew clean publishToMavenLocal +cd .. +{% endhighlight %} + +2\. Download hello-samza project and change the job properties file. + +{% highlight bash %} +git clone git://github.com/linkedin/hello-samza.git +cd hello-samza +vi samza-job-package/src/main/config/wikipedia-feed.properties +{% endhighlight %} + +Change the yarn.package.path property to be: + +{% highlight jproperties %} +yarn.package.path=http://yourHostname:8000/samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz +{% endhighlight %} + +3\. Complie hello-samza. + +{% highlight bash %} +mvn clean package +mkdir -p deploy/samza +tar -xvf ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz -C deploy/samza +{% endhighlight %} + +4\. Deploy Samza job package to Http server.. + +Open a new terminal, and run: + +{% highlight bash %} +cd /tmp/hello-samza && python -m SimpleHTTPServer +{% endhighlight %} + +Go back to the original terminal (not the one running the HTTP server): + +{% highlight bash %} +deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties +{% endhighlight %} + +Go to http://yourHostname:8088 and find the wikipedia-feed job. Click on the ApplicationMaster link to see that it's running. + +Congratulations! You now run the Samza job in a "real" YARN grid! + diff --git a/docs/replace-versioned.sh b/docs/replace-versioned.sh new file mode 100755 index 0000000..e84765b --- /dev/null +++ b/docs/replace-versioned.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# get the version number +version=`cat _config.yml | grep 'version:' | cut -d' ' -f 2` + +echo "version:" $version + +echo "replaced img/versioned to img/"$version +mv -f _site/img/versioned _site/img/$version + +echo "replaced learn/documentation/versioned to learn/documentation/"$version +mv -f _site/learn/documentation/versioned _site/learn/documentation/$version + +echo "replaced learn/tutorials/versioned to learn/tutorials/"$version +mv -f _site/learn/tutorials/versioned _site/learn/tutorials/$version + +echo "replaced startup/hello-samza/versioned to startup/hello-samza/"$version +mv -f _site/startup/hello-samza/versioned _site/startup/hello-samza/$version diff --git a/docs/startup/download/index.md b/docs/startup/download/index.md index 6ee6b1f..e08202d 100644 --- a/docs/startup/download/index.md +++ b/docs/startup/download/index.md @@ -21,7 +21,7 @@ title: Download Samza is released as a source artifact, and also through Maven. -If you just want to play around with Samza for the first time, go to [Hello Samza](/startup/hello-samza/0.7.0). +If you just want to play around with Samza for the first time, go to [Hello Samza](/startup/hello-samza/{{site.version}}). ### Source Releases @@ -80,7 +80,7 @@ A Maven-based Samza project can pull in all required dependencies Samza dependen {% endhighlight %} -[Hello Samza](/startup/hello-samza/0.7.0) is a working Maven project that illustrates how to build projects that have Samza jobs in them. +[Hello Samza](/startup/hello-samza/{{site.version}}) is a working Maven project that illustrates how to build projects that have Samza jobs in them. #### Repositories diff --git a/docs/startup/hello-samza/0.7.0/index.md b/docs/startup/hello-samza/0.7.0/index.md deleted file mode 100644 index 92d5ba2..0000000 --- a/docs/startup/hello-samza/0.7.0/index.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -layout: page -title: Hello Samza ---- - -The [hello-samza](https://github.com/apache/incubator-samza-hello-samza) project is a stand-alone project designed to help you run your first Samza job. - -### Get the Code - -Check out the hello-samza project: - -{% highlight bash %} -git clone git://git.apache.org/incubator-samza-hello-samza.git hello-samza -cd hello-samza -{% endhighlight %} - -This project contains everything you'll need to run your first Samza jobs. - -### Start a Grid - -A Samza grid usually comprises three different systems: [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html), [Kafka](http://kafka.apache.org/), and [ZooKeeper](http://zookeeper.apache.org/). The hello-samza project comes with a script called "grid" to help you setup these systems. Start by running: - -{% highlight bash %} -bin/grid bootstrap -{% endhighlight %} - -This command will download, install, and start ZooKeeper, Kafka, and YARN. It will also check out the latest version of Samza and build it. All package files will be put in a sub-directory called "deploy" inside hello-samza's root folder. - -If you get a complaint that JAVA_HOME is not set, then you'll need to set it to the path where Java is installed on your system. - -Once the grid command completes, you can verify that YARN is up and running by going to [http://localhost:8088](http://localhost:8088). This is the YARN UI. - -### Build a Samza Job Package - -Before you can run a Samza job, you need to build a package for it. This package is what YARN uses to deploy your jobs on the grid. - -{% highlight bash %} -mvn clean package -mkdir -p deploy/samza -tar -xvf ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz -C deploy/samza -{% endhighlight %} - -### Run a Samza Job - -After you've built your Samza package, you can start a job on the grid using the run-job.sh script. - -{% highlight bash %} -deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties -{% endhighlight %} - -The job will consume a feed of real-time edits from Wikipedia, and produce them to a Kafka topic called "wikipedia-raw". Give the job a minute to startup, and then tail the Kafka topic: - -{% highlight bash %} -deploy/kafka/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wikipedia-raw -{% endhighlight %} - -Pretty neat, right? Now, check out the YARN UI again ([http://localhost:8088](http://localhost:8088)). This time around, you'll see your Samza job is running! - -If you can not see any output from Kafka consumer, you may have connection problem. Check [here](../../../learn/tutorials/0.7.0/run-hello-samza-without-internet.html). - -### Generate Wikipedia Statistics - -Let's calculate some statistics based on the messages in the wikipedia-raw topic. Start two more jobs: - -{% highlight bash %} -deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-parser.properties -deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-stats.properties -{% endhighlight %} - -The first job (wikipedia-parser) parses the messages in wikipedia-raw, and extracts information about the size of the edit, who made the change, etc. You can take a look at its output with: - -{% highlight bash %} -deploy/kafka/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wikipedia-edits -{% endhighlight %} - -The last job (wikipedia-stats) reads messages from the wikipedia-edits topic, and calculates counts, every ten seconds, for all edits that were made during that window. It outputs these counts to the wikipedia-stats topic. - -{% highlight bash %} -deploy/kafka/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wikipedia-stats -{% endhighlight %} - -The messages in the stats topic look like this: - -{% highlight json %} -{"is-talk":2,"bytes-added":5276,"edits":13,"unique-titles":13} -{"is-bot-edit":1,"is-talk":3,"bytes-added":4211,"edits":30,"unique-titles":30,"is-unpatrolled":1,"is-new":2,"is-minor":7} -{"bytes-added":3180,"edits":19,"unique-titles":19,"is-unpatrolled":1,"is-new":1,"is-minor":3} -{"bytes-added":2218,"edits":18,"unique-titles":18,"is-unpatrolled":2,"is-new":2,"is-minor":3} -{% endhighlight %} - -If you check the YARN UI, again, you'll see that all three jobs are now listed. - -### Shutdown - -After you're done, you can clean everything up using the same grid script. - -{% highlight bash %} -bin/grid stop all -{% endhighlight %} - -Congratulations! You've now setup a local grid that includes YARN, Kafka, and ZooKeeper, and run a Samza job on it. Next up, check out the [Background](/learn/documentation/0.7.0/introduction/background.html) and [API Overview](/learn/documentation/0.7.0/api/overview.html) pages. diff --git a/docs/startup/hello-samza/versioned/index.md b/docs/startup/hello-samza/versioned/index.md new file mode 100644 index 0000000..db37972 --- /dev/null +++ b/docs/startup/hello-samza/versioned/index.md @@ -0,0 +1,116 @@ +--- +layout: page +title: Hello Samza +--- + +The [hello-samza](https://github.com/apache/incubator-samza-hello-samza) project is a stand-alone project designed to help you run your first Samza job. + +### Get the Code + +Check out the hello-samza project: + +{% highlight bash %} +git clone git://git.apache.org/incubator-samza-hello-samza.git hello-samza +cd hello-samza +{% endhighlight %} + +This project contains everything you'll need to run your first Samza jobs. + +### Start a Grid + +A Samza grid usually comprises three different systems: [YARN](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html), [Kafka](http://kafka.apache.org/), and [ZooKeeper](http://zookeeper.apache.org/). The hello-samza project comes with a script called "grid" to help you setup these systems. Start by running: + +{% highlight bash %} +bin/grid bootstrap +{% endhighlight %} + +This command will download, install, and start ZooKeeper, Kafka, and YARN. It will also check out the latest version of Samza and build it. All package files will be put in a sub-directory called "deploy" inside hello-samza's root folder. + +If you get a complaint that JAVA_HOME is not set, then you'll need to set it to the path where Java is installed on your system. + +Once the grid command completes, you can verify that YARN is up and running by going to [http://localhost:8088](http://localhost:8088). This is the YARN UI. + +### Build a Samza Job Package + +Before you can run a Samza job, you need to build a package for it. This package is what YARN uses to deploy your jobs on the grid. + +{% highlight bash %} +mvn clean package +mkdir -p deploy/samza +tar -xvf ./samza-job-package/target/samza-job-package-0.7.0-dist.tar.gz -C deploy/samza +{% endhighlight %} + +### Run a Samza Job + +After you've built your Samza package, you can start a job on the grid using the run-job.sh script. + +{% highlight bash %} +deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-feed.properties +{% endhighlight %} + +The job will consume a feed of real-time edits from Wikipedia, and produce them to a Kafka topic called "wikipedia-raw". Give the job a minute to startup, and then tail the Kafka topic: + +{% highlight bash %} +deploy/kafka/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wikipedia-raw +{% endhighlight %} + +Pretty neat, right? Now, check out the YARN UI again ([http://localhost:8088](http://localhost:8088)). This time around, you'll see your Samza job is running! + +If you can not see any output from Kafka consumer, you may have connection problem. Check [here](../../../learn/tutorials/{{site.version}}/run-hello-samza-without-internet.html). + +### Generate Wikipedia Statistics + +Let's calculate some statistics based on the messages in the wikipedia-raw topic. Start two more jobs: + +{% highlight bash %} +deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-parser.properties +deploy/samza/bin/run-job.sh --config-factory=org.apache.samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/deploy/samza/config/wikipedia-stats.properties +{% endhighlight %} + +The first job (wikipedia-parser) parses the messages in wikipedia-raw, and extracts information about the size of the edit, who made the change, etc. You can take a look at its output with: + +{% highlight bash %} +deploy/kafka/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wikipedia-edits +{% endhighlight %} + +The last job (wikipedia-stats) reads messages from the wikipedia-edits topic, and calculates counts, every ten seconds, for all edits that were made during that window. It outputs these counts to the wikipedia-stats topic. + +{% highlight bash %} +deploy/kafka/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic wikipedia-stats +{% endhighlight %} + +The messages in the stats topic look like this: + +{% highlight json %} +{"is-talk":2,"bytes-added":5276,"edits":13,"unique-titles":13} +{"is-bot-edit":1,"is-talk":3,"bytes-added":4211,"edits":30,"unique-titles":30,"is-unpatrolled":1,"is-new":2,"is-minor":7} +{"bytes-added":3180,"edits":19,"unique-titles":19,"is-unpatrolled":1,"is-new":1,"is-minor":3} +{"bytes-added":2218,"edits":18,"unique-titles":18,"is-unpatrolled":2,"is-new":2,"is-minor":3} +{% endhighlight %} + +If you check the YARN UI, again, you'll see that all three jobs are now listed. + +### Shutdown + +After you're done, you can clean everything up using the same grid script. + +{% highlight bash %} +bin/grid stop all +{% endhighlight %} + +Congratulations! You've now setup a local grid that includes YARN, Kafka, and ZooKeeper, and run a Samza job on it. Next up, check out the [Background](/learn/documentation/{{site.version}}/introduction/background.html) and [API Overview](/learn/documentation/{{site.version}}/api/overview.html) pages.