背景

本文主要介绍了Spark SQL里眼下的CLI实现,代码之后肯定会有不少变动,所以我关注的是比較核心的逻辑。主要是对照了Hive CLI的实现方式,比較Spark SQL在哪块地方做了改动,哪些地方与Hive CLI是保持一致的。可以先看下总结一节里的内容。

Spark SQL的hive-thriftserver项目里是其CLI实现代码。以下先说明Hive CLI的主要实现类和关系,再说明Spark SQL CLI的做法。

Hive CLI

核心启动类是org.apache.hive.service.server.HiveServer2,启动方式:

    try {
ServerOptionsProcessor oproc = new ServerOptionsProcessor("hiveserver2");
if (!oproc.process(args)) {
LOG.fatal("Error starting HiveServer2 with given arguments");
System.exit(-1);
}
HiveConf hiveConf = new HiveConf();
HiveServer2 server = new HiveServer2();
server.init(hiveConf);
server.start();
} catch (Throwable t) {
LOG.fatal("Error starting HiveServer2", t);
System.exit(-1);
}

HiveServer2继承CompositeService类,CompositeService类内部维护一个serviceList。可以增加、删除、启动、停止不同的服务。

HiveServer2在init(hiveConf)的时候,会增加CLIService和ThriftCLIService两个Service。依据传输模式,假设是http或https的话。就使用ThriftHttpCLIService,否则使用ThriftBinaryCLIService。不管是哪个ThriftCLIService。都传入了CLIService的引用,thrift仅仅是一个封装。

增加了这些服务后,把服务都启动起来。

CLIService也继承自CompositeService,CLIService 在init的时候会增加SessionManager服务,而且依据hiveConf,从 hadoop shims里得到UGI里的serverUsername。

SessionManager管理hive连接的开启、关闭等管理功能,已有的连接会维护在一个HashMap里,value为HiveSession类,里面大致是username、password、hive配置等info。

所以CLIService里差点儿全部的事情都是托付给SessionManager做的。

SessionManager内主要是OperationManager这个服务,是最重要的和运行逻辑有关的类,以下会详细说。

另外,关于ThriftCLIService,有两个实现子类,子类仅仅复写了run()方法。设置thrift server相关的网络连接,其它对CLIService的调用逻辑都在父类ThriftCLIService本身里面。

aaarticlea/png;base64,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" alt="" />

实际上。ThriftCLIService里非常多事情也是托付给CLIService做的。

那么上面大致是Hive CLI、Thrift server启动的流程,以及几个主要类的相互关系。

Spark SQL CLI

依据上面Hive CLI的逻辑,看看Spark SQL的CLI是怎么做的。

Spark里的HiveThriftServer2(这个类名看起来有点奇怪)继承了Hive的HiveServer2。而且复写了init方法,其初始化的时候增加的是SparkSQLCLIService和ThriftBinaryCLIService两个服务。

前者继承了Hive的CLIService,有一些不同的逻辑。后者直接使用的是Hive的类。但传入的是SparkSQLCLIService的引用。

SparkSQLCLIService内部,相似Hive的CLIService。有一个SparkSQLSessionManager,继承自Hive的SessionManager。

也有得到serverUsername的逻辑,代码和CLIService是一样的。

SparkSQLSessionManager复写了init这种方法,里面有Spark自己的SparkSQLOperationManager服务,继承自Hive的OperationManager类。

可能上面这几个类有点看晕了,本质上都是一些封装而已,没什么大的差别。

真正重要的是SparkSQLOperationManager这个类里面,定义了怎样使用Spark SQL来处理query操作。

SparkSQLOperationManager关键逻辑

Hive的CLI Operation父类有例如以下的子类继承体系,代表hive cli会处理的不同操作类型:

aaarticlea/png;base64,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" alt="" />

上半部分ExecuteStatementOperation子类体系是实际和查询相关的操作,下半部分是一些元数据读取操作。SparkSQLOperationManager实际改写的就是ExecuteStatementOperation子类的运行逻辑,而元数据相关的操作还是沿用hive本来的处理逻辑。

原本hive的ExecuteStatementOperation处理逻辑是这种:

  public static ExecuteStatementOperation newExecuteStatementOperation(
HiveSession parentSession, String statement, Map<String, String> confOverlay, boolean runAsync) {
String[] tokens = statement.trim().split("\\s+");
String command = tokens[0].toLowerCase(); if ("set".equals(command)) {
return new SetOperation(parentSession, statement, confOverlay);
} else if ("dfs".equals(command)) {
return new DfsOperation(parentSession, statement, confOverlay);
} else if ("add".equals(command)) {
return new AddResourceOperation(parentSession, statement, confOverlay);
} else if ("delete".equals(command)) {
return new DeleteResourceOperation(parentSession, statement, confOverlay);
} else {
return new SQLOperation(parentSession, statement, confOverlay, runAsync);
}
}

ExecuteStatementOperation也分两部分。HiveCommandOperation和SQLOperation。

不同的ExecuteStatementOperation子类终于由相应的CommandProcessor子类来完毕操作请求。

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcUAAACGCAYAAACsepHyAAAgAElEQVR4Ae19DXQV1b3vL3wIigqRmLRcNOEjYJAAlavPAiGQqphABXJZ9MqrVbyuhPdYd5G6yuqjRbPiotK1KBTqxSWsVvBxq+tFS7DFRNGbEHjw7isFpRDyJBAOVYuQQMKHChHJ+//3zJ4zM2f2mfORcBKyZ60zs2fv/f/6zZz5z/6Y/U9qbz/ZDr1pBDQCGgGNgEZAI4BeGgONgEZAI6AR0AhoBAwE+rz2Wo3GQiOgEdAIaAQ0AhoBQiCpnTaNhEZAI6AR0AhoBDQCQB/gbxoHjYBGQCOgEdAIaAQIAT2mqG8DjYBGQCOgEdAImAhQS9F/2/9/emPfrr+h4f814dq1diQlAaOyUnH/1Lsx8bvf+DPQNTQCGgGNgEZAI9ANEKAxxfCfZPzPl5vw4f/9FLfd3h93pNximXSu+UtcvHAZ3/kvQ/Gj/36nla8TGgGNgEZAI6AR6K4IhO0+ZYf4v2uO4+7hybgnOw3pmXdYPz7nfC7nenoLg0DVMiRNfhXHwlTRRTciAgFsLduG3c3x2NYRPEz59bUoe+Ug4lInJlPC2NB8EK/EjVGkSrEetaiPtLqu1yMR8HSKSYPWEBh3Y+eOBowclYohQwdiQdEEzF1wr/W778EhIp+7Ubne8f83IE4Aa1CclE5ds+av+Eb9VCSAdZNtdpK9xVVxQqfJNQIaAY2ARqBDEPB0injo20gaVIJXt/0z2tq+obHEZmz6zV8sgXv/4yTe2nJI5F/+6hsMG3EHdr573CqPOsEtqaSngMqToO5c4zdnByavC0TNqnsQTMTaBtPOhlIcLijEOt2M7B6XTmvZsQikjMei0jnISelYtpqbRiBWBLydInH7H6//k3CMy1d9D82nL+DgXz6xZFy61CbyOP/zU604ffoi6v/6uVUeXYJaiAWvo4gc4oZ8G2X+SuxZkmHLuEGTI5/G8qL9KH8ncIMaqM3SCGgENALdBwHl7NNAy3n88/qHhGN8/MHxDou+uPQVzpxpFXl9evfGN99cQ7/+/Rx1Ij6p2oGNk0rRYHeIIcTctfoUNlr5C1DZvhIGCZe9hDGVs1BeUIa9VEc4WFDrk5wtb5PW1poONpq6RHjsVUzONHgyn6DjNvmsHY2SErcMrunWl7LIRv+Nu1ZzcWT5ZqCA7GVc9jyNkSH87PYzV6c8p71B3IL5ZNq6QmSW7DdVCvJT5btlAEEaQKW3yT6qA4/71OCQRTMc80tzkSXOW7H7lQo05U4HyqlO2n1YvGg8Ukh+kCYZeXnJqK4bZJZZjIwEj2GtP4DTZnb2/IUoFMxdvEPKKUNJy5XtOgBpeXOxKMdkwmN51Y3GSfZ0lBZmmAVeNIPMMtdBxSMKnQRHwiy4OeUDdqy5VrjyCPAKCjJSXjYI/VuRWzoezXRt6+5l3AwMmndvw/q6YR7XWOLrhZVbZxJt3SduheS5ny2ucoufW1Z4/Ix7gnV20gXz6RZjm6tbTMWC/FT5bl7Oa+itNxQyJBo9/ah0ip82tuF/r96F9ta1+K/5m5040TcZSfSTi+H06p2EO+6Id0zRKSJ4ZjzwD5Nja5ctR9HduszmGPejZMUsNFDX60guK0jHxqLNpN9K07FtQNUS6UQjrUsP+lXAa8yTlRF8l2GO5YyJz5F/tcl4FutmbsWSkYa+ois437CiqjgdBYeDFjlS5HhXbJyI+Q0ZlB0QRRsLdpBt1HIWZ372e5RbdPSywN20wgDDcRWPIr6Zr+LJktEkY6v5YiEIBFae+abTDX8NAKfeJs+oDsbD4gw5lFLzwQh+kNLkiKBjBA6Vn6RzcmaCt0EDcm6lNucG2B/+Ugl6SOwC5hGt6K1j3uW1yLKcrou3ozwcrYfeQmQr7VtQ3TQBpSTDcKofYffUDOouZJqPcOdi0lsoYzzAtqZIJy115qOKh79OQVyA+q2bUH5G8vXQ2YG1X7nBx3EtHHhJOfKosEEWYxBycoejuvYkmunap6AV9XUtyM6dY770RIKVobPaZkuYZ8LPFke56djU96oHfkIq5ytsufMg3qpOpnt7jvkSaKpJLw6e+b46GPQOvfklxEuGJyI9M1PpFKVD/Je5r+Omfr1xzbYaXO9evdDnpl7oRY6Rtz69b8L4+/+hcxCULUnpEFlKfjHWTsrFtipydMLx0Bjda9yi4rJHUISPMWYptSZ4GzkMY7EdR2nMLl9UiLRuBpZseFq0qJJsLSqDKe+JjyUjD/MnbTeKpL6mQ+TM/DkLAIdTJIeamY4SQcHji+xMDXLeF1VKB04nkp/KfpgtbXs5M2E6UEvQksOZ1GA9GiCFGJMyFCR97JQtsPLI99PBtNWht5Bm3xkPCaMFSK25xR7jSPUnjdafdIhMnjUeeWkVqK+n1qJwekD2fNlypHJJY5bBerjaZcs0PXgLB4m38TLb27gs5aODt0N2GFqpg11viynZSk5QbCnpuDfthJFmGnJ2WL8J1UaO2Kc1syPl1oR9U/BgW1X2SJ0sXAjKrOGAdIqy3K6z3V7EcC3s9Da5hiUqG2x2ZqUju/wj1DePRw7Jrzs9HLnMJ1KspE022Q6bbaK8kuprb9R2lEtZ0eDHbMLZkjUQqTiA8rIW5/8jRZHvp4OJg0NvFS8vQHponrdT/OCUaCHO/95mMcM0bchtWLbyIQuix/75XqSk3oLa94+j6fMv8enfzmHS9Awq/8KqE3GCnVjBS3jn2NMOx+BPPxFjMv1rxVzD7DoFt1DbM8wWZ0PM7JyEoY7QWR7JmWl/OJWs7lc3vwxsEC1Rbj3STNi9Up/p3vlucus8mmuQgUKrdWcxiDCRjDs74lNYs6sR3BItJcdjdt1FpEQ8tCoBVjecqoJPfmfoBBNr5VdWHXQtPE3LQFZ2DWrrW6mlRC8PedOCLaZ4sfKU1xmZfviRTKUtg8z/CPcabELZafnyKP87rnyl+uGukYKX6K1QMuxRBb28rG1vfZay/4aCOWPBH+lfOHcFq56rcfz21ATw90/P0wf8X4l6I+6JwSEK4dOxdC2o5eSagUndlWL2KTvNvWV40j4TtWoDtbJmYaatdeVlR1x5DQ3YS07lNbMFduyd7WK80penqe8q6zMLcjwrjHFHX1qvCn72h8irwTrGKiSfGo/FyyDUIoe/TiSoNbynllrd+3GEnasq308HL71jyeOWwukDeGs3t5bMrf4gtaSGIUv1pzVpdtVLAnpw1Jrjd5zFjkN+B9dEk8LogTTPfLtvrj9hjS1K6kP1AZmkFuVOVFNrRbRQw9GG6BDAbrsNFkdbIoSGuzfNb+jsOttIQpJR6eTCxQ9rv3JTGSVekdrgMiprKnV71x3Erjrg3ix6ceEtUqxC6rlsNrgZew/9lLbY6WTaD58QXcx7IiTfed13i/uYegAWzaUekhY08csJ6eqZ76eD1NV+VPGy1+nhae+WognKU/+aKlI1732Mb65do3S7Da4kXGi5jOkzRkPWsxVGlRy5ZCvaR9FYoL2rj8cEN2QQH27VbKbJNLlIKpFseZKH2V0qszr6yF20K3KRmVQmOE8qWoBJEcmg1lblAmNcU9SnVtha6j4tj4jYoxK33sLZT+X0Wcdkws7ozDYmwAjcHPlyAhKJoBmvo1ZR/QJTHGOdz2lVvp8OJp+4D/wWO53GXCpoYopkxpMNeDKNaiOaxffR5Bl6sxZV6O06j7oJ6aEasnH3Xm0F1pcdEEVp2cOR5qqUTd12ZTTRx9iCEx1EN66S1q0D02UQC5tzNzkGD24a7rqV46TBWmFTYe0h/vOH05jpJnPSkhsXKg+LtV+5oZkSr7CKhynkLmbqQqxOpQlJ1kWPFCs/m8PIpaLobPHDx62zvCeoNei4X23XnT5PSdlF97F8VvCkLNEFqsr308HDXqUMj7o9NMt3mTfGhdc+/b80AF5/+HNcunQFt97aD2PHD8E/TrlLr33aQ2+cLm02T/ioVcw+VSrOXVM8s9VroouSqAcXdBO8IroXuoktPfhuu56mh20pSkV40e+J3x1Kp/yzb3oxcDsaOp0IBPiBdhApi+TkG5rQU94oPomwGhqJUEvL1AhoBLolAhE5xW5pmVa6hyBA4y/zBtG4IX1uYFps/+6rh4CgzdQIaAQ6CIGIuk87SJZmoxHQCGgENAIagS6NgOfs0y6tsVZOI6AR0AhoBDQCnYSAdoqdBKxmqxHQCGgENALdD4EuM6Z44JOLWPvB73DuUgv9WpF8y+0YfPtglDz0L7jvrtu6H7JaY42ARkAjoBHodgh0iTHFFyrfxrsHqzH+7nQMvOVmC8TzX36FfY2NeGziw3i+YLaVrxMaAY2ARkAjoBHoDAQS3n3KDvHtfe/g0exsPDp2CmaOm4HZE2aK44MjxuL735mILbVvgetd140XAJ/8KpRhDv3Kr6uyWphGIF4EeG3abdjdHA+fjuBhyufvC+lTm7jUicmUMDZ4rIITk4iIiFgPc4WjiOrrSh2FQEKdIneZcgtxxrgJyBk9FbPHz0POiGn47rAp4vjkg89gyqjv4geTp+CP+98H149vM9f6LJYrlsTHLUht8k2iVWLkL5xDDRJ28VSoXcViebgurrZWTyOgEdAIxIhAQp3i6vd+i3uGpGHUt0dgeuZDwoQPPn4Xv6lZje2HjJZhZupo3NpvAMbdPQQv79wSo5km2bFq+pZtIiZt3GGsARoftxBqjrfYTgtt869ybBkyO9z5hoi8Dhm8WLhpFy0bd7jAtUbtddBAi9AIdAkEaIm0RaVzKOxXl9BGK9FJCCR0ok3zpXPk8GhF1Xba0Xa8qRG/31sh0h8GjmLH4Z1ou9omzi9facPZL0+JdKw7XtQb89dg+Vh72KlYuYWnE+GitoWv0+1Kac3U5UVlWPFOAEvcoaq6nTFaYY2ARkAjEIpAQp3i2YstONNyBecvXxGanbrYjAMnTpCTNBYe50DGffv0QW8KYty/T198ceVqqAUR5wTwDi15Mv+1DOSPWoCCFa9iab59UXEjWO9GOz+KkhHc/MqDNTlYMEfGmDS/2JbppJ9EIan2yAgc6wqRaYvZWGkFMnbSOKLdU0SLyZkNWC7rOs652zMXR5ZvBgqewkYrhJSTX1AHVb5N/ZBkZDIcOgseKlmqfAreocBHlQ84eTl1UOkdYmAEGTzuU2MuuM3VbQuI02Lgxlqq02kxeKpjhQuy0/Ai3cmorlOs08pjWOsPWJE8xILhYoFoF29T02A5ZShpubJdBxnF3mTCY3nVZpQRXpC6MMMs8KIxo1iYNayDikcUOglehFlwc8p3Ys21wpVHgFdQkJHyskHo34pcWqC+mdbJrbt3LhbJiCsczb5uGBYv4sXrnbqoV1hy1hOCrfvErZA897PFVW7xc8uy36vM21ke1FmVT7cY22yLSyoDgavy3TKc19BbbyhkSDQ645hQpzj4tmR8cfk8Pm89K2xLv2Mokm+9De0iIgfwTN6PcPNNffGH/TvQcrEJ/fvdFDsGZriphpHEYqQ7hqPxEAV3f+YbIqqK01FwWIrzKzfqbSxIp8C+vBldjntYltiY/iWM4W5IkWc8mItHncSGzFcRT7R7KcHruLFgB0UTIRmWDk/hMMeHdLTywuhmYmHxJse7YuNEzG/IoKyAyPaVwROSkpaRHhw42cAxKh1U+JAu8eDm1FuYEuXOeFioI68b7BxRz80HTzAyvPEgAOwPf6kGle0C5pUuNCKE8EO6vBZZpXKNV8DB21EejtZDbyGSI3q0oLppAsWazDWd6kfYPTWDuguZRhEtXjhpqTMfVTz8dQriwuGUaNm+M5Kvh85sL01EMR7EfuUGHzVeUo48KmyQxVYg65NoJqeYQi9A9XUtyM6dYzrESLAydFbbbAnzTPjZ4ig37zv1veqBn5DK+Qpb7jyIt6qTCf85wZiXTEMvDp75vjoYZjr05pcQLxlG1U7bJ3RM8a7B30Zvag2eOvcJLly+iLsGDcFzs0uQnTEGcx4owBMPzMXD90xFX3yDAf36i7HHWJGo2sYttzwYfmo65hTtRzl1A4rNjCy/1OYERPenFOZXbtaTY4qVxLtkVY2kpkCGO8hZUh6HdxITcXJRshc4fDRADnoYxuJ1FCS5xupMmTKeo2DG4awmvY5tEU52KapkR2RuXvy4KJxugtSmd+Z2cohbHcGgfWXYdY5FBxU+qnwvGXYdTDgcept5wQM/DCiEj/ht856RaUY9l7EZBa2IPN+IehETz+DmiHpu0ky1HAmt25o7PCjWkaKywvHgN2WhBy1y7t4cvB2yw9B66W0xppYrOUGxcQgnGVeLadjZcXgugUkFxZkEzjR7hcZS8GBHorInBBcKoZhlw8VLZ7u9fuWmfWq8zArWQWWDVcGM8XgC9Tw9tvkk6mTczUix8rPZJsor6WeLo9wPH69yFhrOlpSBSEUjyt0zllX5XjLs19A00qG3ipcXIB2Y16cDeUXNaumMIsxavRCpA5Pxy6pfY+GUH+J7o3PEj5mdunAar+97E19/04a/Bhrx81k/iVqGQVCDbdSE24tcW0xGLtmAqiU2xxEjdzdZ/obNKEp6CsVzqJUmvZLVhemuzfEiuTXHrUdymnu5lUmOx13NOo8m2r1FFD6h1C1AdKY+Vqs3PCvvUlNnDmSs2pQ6KPAZOb0TceM4dVHGNrTsChf13KrknzC7GpE3l1pu1E1pdt35E1KNeGhVAqxuOFUFn/zO0Al+Ue476Fp4mpaBrOwa1Na3UkvpBJA3LdhiihcrT3mdkemHH8lU2kJxIcV/hHoAXqGXpdP0IrF4DvUqyP+OK1+pfrhrpODVyROdeil1vQ4Fo1P7YEFOIY5+9hn2B47gxcpf4bk//QIvvrdaHH9WUYZ9xw+i8UyTqBfzyjaiNcTBd81ZlOJIjotaaKLVFRKlnhwUjQlam1+5VVEmpmPp2onYSOOW4jvHEHpqoBUvM2bAUjfgOtHyy8CSPbXUEtyPI+w8Iop2/zGOmh9S8iQianyqtxAdarBuXcCSs8rW+rR0U3PzLvHTORYdVPio8v108NY8+txYop6HRF2nB0etrQXIjkO+eTe14jQ9kGRLtLn+hDW2KJVVRooPRxuigxkRXjL1OobQOKPFWzp70cq8qHRy4eKHtV+5qYMSLzvuUt8IjllTqdu77iB2UUDre7PM8dVIsQqp57LZLt9DP6UtdjqZ9sMnRBfzngjJd1733aJHhHoAFs1FXloLmppIIOnqme+ng9TVflTxstfphHRCW4psT9msucKst/9ciVv7D8DRtgBNR6UsCiN/9eo1HD/1KWZTV6qsJypHueOuU1B0edloM8i5C5XmoWyrodYctToqF1AketuY4NoFNEFCCvIrl/WCx5FL1mBteS59ljEM7RuInj5nmMzdp2YV7moVY300o3PUKsovkAWbzXFNomnfTGOR9tYtO3ZzchDRvbZ2OzKJZwmRTipagElB8R4ptw7MayXVo5aYSjcPLuGzfHRGDDoo8YkRt/AGRFEaQ9RzwtoZdZ3ervOom5AeqiEbdy3VVmB92QFRlJY9HLI3U9ZVRooPS+vWQUaE9+oKlZLcNLZo8bKK39FPp/nDacx0kzlpyY2LH9Z+5YZySrz8dFeVcxczDqA6lSYkWa2XSLGiemFtVgmNxRY/fNw6y3uCWoOL76PJXtQSNNURk7k4TZ+npOyifPmM5ElZYlhAle+ngynAflDKsFfq+HSXWOaNzeIP81dWvozm8+fQq1cvXKPJNkNpzPHHj+i1Tzv+smuOXQYBnjBSq5h9qlSSu6Yq0JRLXbziQaSsqAsEAt0Er4juhW5iSze+8xLeUpTYcdfom8U/laf6qBG4ARHgB9pBpCySM0hpQg9NoOHp71ZD4wa0WpukEehOCHQZp9idQNO6agRiQ4DGX+YNonFD+tzAZBD8Hiw2jppKI6AR6FgEukz3aceapblpBDQCGgGNgEYgegQSOvs0enU1hUZAI6AR0AhoBDoPgevefTr6NWNJt84zSXPWCGgENAIaAY1AKAIfP9kvNNOVc92dIsv//aN9XWoAvdq+wNoPfodzl1ro14rkW27H4NsHo+Shf8G1mwaE1NcZGgGNgEZAI6ARiBSB//ru1xFVTYhTdGtWuf9PIq7i+LvTMWTot6iYf8D5L7+izwuX4bGJD6Ng4vdFnt5pBDQCGgGNgEagsxBI+JgiO8S3972DR7Oz8ejYKZg5bgZmT5gpjg+OGIvvf2cittS+Ba6XuG0nVn7rZ+FXjEmcclqyRiBBCPD/4p/wRiAe8R3Bw5Rf/TPcP2sTPo1HnZhow9gQ2ISn48YoUqX0cypSpMLVS2hLkbtM3z1YjRnjJiBn9FQr0LBUOGfENPzH0R34+lob/rj/fczKzouxK/Uk3pg1DWv+Ijnz8XGs+/xFn1Vg7PU7Ou2h0z8+j4rtCzG0o0VdV36hdhW+fgLL8q6rElqYRkAjoBGICYGEthRXv/db3DMkTUS/mJ75kDDgg4/fxW9qVmP7obfFeWbqaApEPADj7h6Cl3duiclIScQP532fmz9a+W3Jt4ZhZbUs7YgjO4ToeNp1Wpf1AuYu3dkRiiSYx3149j9NnP/zeTQsiLc1kWBztHiNQKwIZCzEq5//AY9nxMpA011vBBLaUmy+dI4cHi112m7MCDre1Ijf760QGHwYOIodh3ei7WqbOL98pQ1nvzzVcfjkvYh9/5mJpx+kbtGEthiDJk3Kf5xWCg+e3xApeig888QL+O2Ok3i8KP2GMEkboRHQCNy4CCS0pXj2YgsaP/8c5y8bn2mcutiMAydOYH9jo/jV1tfhL3T+4d8C+KzlHM5eMIIRd9jlyMjDw//4Bmqt1iL3yQ/D/ebv6Y0nFaK86nGe0UW7dQHxsMY2vOp6saVW5po3kJ05zFaopv104z9Zet7vGO900jjKxPiGbWzUcS5buSa9r/5OOWqsbOYgMhkOnQW5SpYqH1Dho8oHnLycOqj0ttsWaToWOXYaanVvDDN2Jq5p8B4O9oS4bDDv8WA56a+kZdvsOgyD43rvIH3k/8bR0xGGxg2XikcUOt2/4A0XV6d85zUNtclZHgFeLmnwssH6jxn87LiJe9H3f+YW4rbJ/qxx15Xnfra4yhU6OfFh3k5dgrap8q/P/9L9H5coRHpMqFMcfFsyBtx8Mz5vNZxd+h1DkXzrbUgecKv4/WTWf8P/eOy/Y/i3RuDmfjeLTzQiNSz6enwhX0KG7Pb7fCce/uM0j+5VVb1pWEY0z/4jILpExdigqm5QO+FAxQPlWeDfTuBVqzUVhpb+aM8/P5rGRGV3sBwbZZqFaHhhp6ub2OYIg6I9U1sX7EAu87X0d/Iz9Aujm5sr6frbLffh4UeCrUQ/GftE17bUOdQmXx1U+KjyxZ/baadTB8Mop95uQyM5D7XFX45BA6vrfw3wR/fDX8qmh9t64AV5X7z+OLYukDi6bOA6jvJwtKF6B+/TA1jT8Ihxv1FXefaWl8yJN0wTyf+J9VLx8NcpiMsJrHtC4sDHUJ2dWPuVG7ysax6Cl10Wp1U2yHrpePzZx3Hoj9XmRKCT2P3HAyh8lucQRIqVobPaZinL++hni1Wu+O/74dcl/pce/3FvNNS5CXWKd1EUjN5JSTh17hNcuHwRdw0agudmlyA7YwzmULioJx6Yi4fvmYq++AYD+vUXY49qU2ItuQ8Zw4m2ege28o39oHzLNlp9DcdcrcVI67E6EdSVY4rrniDZ63cylbGFo80Yhky8QWOirrE6pqHJOi9YjpVY5RWTo7a3hqUA72Ph69LBUrkXPyYLp5tga8Pxwe14+D+dYyq+Muw6x6KDCh9VvpcMuw7CJn7ZsWFj5gUP/MCS947rushKscgxaZ7Ik0yMh6s8cx6pbNVCQPYihLScXDY4bAxD66W3JZjGjxdPM85Ez4tZwDSR/J9EdQUP+OsUxIXCp/Hwg9y8dLbb61du8nFcczu9lGMdVTZYFei/+AgK/7IduwOUF6jG+395HLl8XSPFytRZabNNlFfSzxZHuR8+XuUsNJwtqv+fKt9Lhsc1cOit4uUFiCIvoWOKS2cUYdbqhUgdmIxfVv0aC6f8EN8bnSN+rO+pC6fx+r438fU3bfhroBE/n/UTXFMYElN29QaswSxUZBA1x3pVzv6kyNr2TVnP5UCZJsK6k1ZtQiG18lbm22ZqKmnTqVVK9czuyPv/whNbyPHYdXSkTcfvyIvzRKkbY2DqkxGPDFNnvi6qTamDAp8Mbs13Fm6St0rZcPkddH3oLfnpB1+gpiL3FFDLXJxzxOoItnhoVeyV10dF4MrvDJ3o3hQvwcr7qoOuhcsU43Qacp9YKMbXc7CdrtOa4Oz3eLHylNcZmX74kUylLdfjfyn/h0aXMD8b99FEp2i2XtFU7ui6F9t7YUFOIY5+9hn2B47gxcpf4bk//QIvvrdaHH9WUYZ9xw+i8UyTqNehK9vwN00LPsaz/2Z+AiHe4l7AluqglXuXOrueREmk9bhyNHUxDU+8cB+2rjG/swpHSw+LN4Se9Ca9nbtsD4DeGSx5z9vHQk3Hn5PBCvH2MU4GRAKf7thuBnU1zkP2ITrspPEscnoh+YAnViEMPTJMXkqdQ2RFoIMKH1W+nw4easeUFYucEPvpz05jz9bGjkP2GDQ24BA9kGRPgdf13Vq10yL9dOOz9JmS2VoJRxuig3kNLE4eiRAa2z1i19mD1MqKSicXLn5Y+5WbSijxitQGyxgjMWnx89T9vQFb/ojgkEKkWIXUc9lsl+Whn9IWO51M++EToksX+V+S3e5nozQp0mNCW4qs5Pfvny10ffvPlbi1/wAcbQvQdFTKSgKuXr2G46c+xWzqSpX1ROUYdzx+t1XS8tsMzToNfhNIbxg0JvI0d5+adbhrc5msbx3D1UtHzmP3YQ3LMd+WIuNpMB9atAbP0jjm3KXDsG9VGDk0ozN9Pem5wFTqiU3Yl8dpfkvaRN1403A//feMjb/HNB0/0b3wwnbMJUNyblYAACAASURBVBtpZArZTzyObFnN8+jWwfi2E9StFY1dnqytTB+d2SbHdYlAByU+MeJm6Rpvws9WL/5u+6kV/gL1CdBDNWTjrqU1dP986wVR5HV9C7GDJsUsNElt3+qGpXXrIK+BqwfFoZCbxhhrD/0/OYicJ3460Zjo/dZ/2o2LH9Z+5YYqSrycmkZ+xl3MeAFrsug/myHJIsWK6oW1WfLzPkZnix8+bp3lPRHm2XA9/pceMtQ9aN44XffQUbwguGrt05WVL6P5/Dn06tUL165dw1Aac/zxI3rtU+9Lp3N7LALcy7EmM8qFHrg7aRoCz9KLnniB6rHoRWh4N8Eronuhm9gS4ZWJtRqvfdplFwT3Moq7Rn86Z2lI0bWQHJ2hEehJCPADbQPSt8tJPjShhybQZNO4YbCXoyfhoW3VCHQuAgnvPu1c8zR3jUB3R4DGjf+NFpmgma1LTFPYIQY/ieju9mn9NQJdC4Eu033atWDR2mgENAIaAY3AjYRAl+4+jTSu1Y10QbQtGgGNgEZAI9D1EbjuLcWuD4nWUCOgEdAIaAR6KgJdZkzxwCcXsfaD3+HcpRb6tSL5ltvFsm4lD/0L7rvrtp56fbTdGgGNgEZAI3AdEegSLcUXKt8WcRXH352OgbfcbJl//suvsI8WB39s4sN4vsD4ntEq1AmNgEZAI6AR0Ah0MAK9Ophf1OzYIb697x08mp2NR8dOwcxxMzB7wkxxfHDEWHz/OxOxpfYtcL3O3wJYNzkdSUnpKL7RQjh1Png3oIQAtpZtw+7meEzrCB6m/PpalL1yEHGpE5MpYWxoPohX4sYoUqVYj1rUR1pd19MIxIBAQrtPucv03YPVmDFuAnJGT4UMNCztyBkxDf9xdAe+vtaGP+5/H7Oy82LsSmVnl4uSvZIzHxegsn0l8m1Zx9Y9i5Kxm9G+Z7ot150M5VVUeRIb7IzcJPpcI6AR0AhoBLoFAgltKa5+77e4Z0iaiH4hHeIHH7+L39SsxvZDRsswM3U0BSIegHF3D8HLO7fEBSo7r/Z281cJFLhahA1H9mPSmGERyJiItQ0mn4ZSHC4oxLpjEZDpKhqBGw2BlPFYVDoHOSk3mmHanp6KQEJbis2XzpHDo6VO22lH2/GmRvx+b4VIfxg4ih2Hd6Ltaps4v3ylDWe/PCXSHbLLX4n2hkxMzlyGKleLMSr+I5/G8qIyrHgngCVLMqIi1ZU1AhoBjYBGoGshkFCnePZiC860XMH5y1cEKqcuNuPAiRPkJHlFcFoTPCkJffv0Qe/eSejfpy++uHJV5HfYbmQe5k8qw7aqlcC2dBRsZM65SCoxulYz1xUis2S/KS60uzVUD6Nr9cjyzdQMfQobJ5WiYc/TGIkaFCfRuUXg5uUsn7S2FnuEg1XlA8cUuqnyEVYHld6WwlEkeNynxhZ9Yzjml+YiS3Boxe5XKtCUS93T5VQn7T4sXjQeKbDTJCMvLxnVdYPMMpdoHsNafwCnzezs+QtRKJi7eIeUU4aSlivbdQDS8uZiUY7JhMfyqjkMCW3Z01FamCGS3jSDzDLXQcUjCp0ER8IsuDl1BuxYc61w5RHgFRRkpLxsEPq3Ird0PJrp2tbdy7gZGDTv3ob1dcM8rrHE1wsrt84k2rpP3ArJcz9bXOUWP7es8PgZ9wTr7KQL5tMtxjZXt5iKBfmp8t28nNfQW28oZEg09DE+BBLqFAfflowvLp/H561nhRXpdwxF8q23oZ0WA+ftmbwf4eab+uIP+3eg5WIT+ve7SeR3xi5/w0lUUvSHFWNMh3TsVUwuGU3jjlsd444hsqneio0TMb8hg4oConhjwQ6io3FGcWY4tsPk6NplS7JqGTn8ZeaYpke5RfcSxnA37UjOMBxX8Sjim/kqnvTSjXTxzDcdoloHIRBOvY286PbGw+IMOZRS88EIfpDS5IigYwQOlZ+kc3JmgrlBA3JupTbnxjEZQzd6SOwC5hGt6K1j3uW1yLKcrou3ozwcrYfeQngr7VtQ3TQBpSTDcKofYffUDOouZJqPcOdi0lsoYzzAtqZIJ23XXsXDX6cgLkD91k0oPyP5eujswNqv3ODjuBYOvKQceVTYIIsxCDm5w1FdexLNdO1T0Ir6uhZk584xX3oiwcrQWW2zJcwz4WeLo9x0bOp71QM/IZXzFbbceRBvVSfTvT3HfAk01aQXB898Xx0Meofe/BLiJcMTEZ0ZCwIJdYp3URSMhr9fwKlzn+DC5Yu4a9AQPDe7BBUfvosRqRl44oG51Iq8QJNsqjCgX38MuSOS8b5oYZiIMZkeNCOHYSzKaNzxYxo/3IolwjHJevtRkpmOEnHK44vO8qJK2wSeqh1Gi1E6RKbJL8baSbmihZpPoXxEi9JeznWYDtRKteRwJkUXPxogeoVuKp39dMgXrOHQ28iy7Y2HxCGRQ625xR7jSPUnjdafdIhcN2s88tIqUF9PrUXh9KixNV+2HKlc0phlsB6uQpBrRw/ewkHibbzM9jZur+Tg7ZAdhlbqYNfbYkq2khMUW0o67k07YaSZhhwm1m9CtZEj9mnN7Ei5NWHfFDzYVpU9UicLF4IyazggnaIst+tst5cCUIuWuKrc61rY6W1yDUtUNtjszEpHdvlHqG8ejxySX3d6OHKZT6RYSZtssh0220R5JdXX3qjtKJeyVPh44cdswtmSNRCpOIDyshbn/yNFke+ng9c1UvHyAkTnxYRAQp3i0hlFmLV6IVIHJuOXVb/Gwik/xPdG54gfW3Pqwmm8vu9NfP1NG/5KUXR/PusnMRmpJKraQI5tFhocDk/Wno4NorXHLTT6TGOv3fnZ07J+tEfTGYcLjG51v7p5Zyh0U+jsJrfOFS8EVrk9kYFCq3Vnz48knYw774yknk8ds6sR3BItJcdjdt35UBnF8dCqBFjdcKoKPvmdoRNMrJtUsjvoWniyz0BWdg1q61uppUQvD3nTgi2meLHylNcZmX74kUylLYPM/wj3GmxC2Wn58ij/O658pfrhrpGCl57opEQz2oJe0RJ0ZP3RqX2wIKcQRz/7DPsDR/Bi5a/w3J9+gRffWy2OP6sow77jB9F4pknU69CVbbgLs4Baga/xmJ/HRl2R68S3ihlYsqeWWnb7cSScA/NgIbLyH0HR3jI8uS4QrGE645ks2CxfZX0XWYN1XDcknxqPxTQpiLmodFPl++nAPDti45bC6QN4aze3lsyt/iC1pIYhS/WnNWl21UsCenDUmuN3nMWOQ34H19SK0/RAmme+3TfXn7DGFiX1ofqATFKLcieqqbUiWqjhaEN0CGC33QaLoy0RQsPdm+Y3dHadbSQhyah0cuHih7VfuamMEq9IbXAZlTWVur3rDmJXHXBvltlijhSrkHoum+2yPPRT2mKnk2k/fEJ0Me+JkHzndd8t7mPqAVg0l3pIWtDELyekq2e+nw5SV/tRxcteR6fjQiChLUXWvGzWXGHA23+uxK39B+BoW4Cmo1JWEnD16jUcP/UpZj9QYNUTlWPcbSxID0524VYYzTr1dIjMn2aVjlpFLcQCU1gRfb+YH4tgbr1tpok2PIFH0vNEG+mMqZw+65hM3aRkMm3GJByAWoOOfFD35kljnFKpm0pnPx2kXvEe+S12Oo25VNDEFMmLJxvwZBrVRjSL76PJM/RmLarQ23UedRPSQzVk4+692gqsLzsgitKyhyPNVSmbur3KaKKPsQUnOohuXCWtWwemyyAWNuducgwe3DTcLSzHSYO1wqbC2kP85w+nMdNN5qQlNy5UHhZrv3JDMyVeYRUPU8hdzNSFWJ1KE5Ksix4pVn42h5FLRdHZ4oePW2d5T1Br0HG/2q47fZ6Ssovu43JTT56UJbpAVfl+OnjYq5ThUVdnxYRAl1jmjTXnD/lXVr6M5vPn0KtXL1yjyTZDaczxx4/otU9jurLdmYgnfNQqZp8q7eKuKZ7Z6jXRRUnUgwu6CV4R3QvdxJYefLd1J9MT3lKUYHHX6JvFP5Wn+thjEOAH2kGkLJKTb2hCT3mj+CTCamj0GCy0oRoBjUCiEegyTjHRQGj5iUKAxl/mDaJxQ/rcwFTB/t1XorTScjUCGoGeiUCX6T7tmfBrqzUCGgGNgEagKyGQ0NmnXQkIrYtGQCOgEdAIaAS0U9T3gEZAI6AR0AhoBEwEusyYIs8+XfvB73DuUgv9WpF8y+0YfPtglDykZ5/qu1UjoBHQCGgErg8CXWJMkQMIc1zF8XenY+AtN1uWn//yK+xrbMRjEx/G8wWzrXyd0AhoBDQCGgGNQGcgkPDuU3aIb+97B49mZ+PRsVMwc9wMzJ4wUxwfHDEW3//ORGypfQtc77pvtELM5CQdK7Hjced1VLfpiPZiQWgFDh4rtnT8dZAc+XroiPYSDX3s2QgktPuUu0y5hThj3ATkjJ4KGWhYXpKcEdPwH0d34OtrbbQo+PuYlZ2H2JZ6MyJMlOyVnPnoDt9kL9NpjYBGQCOgEeiJCCS0pbj6vd/iniFpGPXtEZZD/ODjd/GbmtXYfshoGWamjqZAxAMw7u4heHnnlriuES+T1k6LfItfJYU8TEpHcVUYlrSc2h4KHeWMkBGmvi7SCHQUAjqifUchqfloBKJCIK6W4t69xzB+/D9gwIDgOGA00psvnSOHR0udttOOtuNNjfj93gqR/jBwFDsO70Tb1TZxfvlKG85+eUqkO2SXvxLtDZm05igtsk1roMa0rGmHKKKZaAQ0AhoBjUBXQSAup3jy5FF88slRPPTQJAwebK6IH4VlZy+24EzLFYqZeEVQnbrYjAMnTpCT5BXBaU3wpCT07dMHvXsnoX+fvvjiylWR32G7kXmYP6nMiGuY7xF9/jXgycwGLG8vxtHJuSifbwYgJgVEhPtyCju1hxf2NgIFbzQVm0QBhfeI+IgePEX9WCywxzNketti17RwtY5oT5DwAsyFGQyOGVbqgBVFQyzWLRZn5kI3lpRF0TeCm7vcjjXXClfuuhYmU6f8oCSR4vU9q83IINIGHlNcn+iI9i499alGoAcgEJdTZHzy8h5ERcUO5Ofn4h/+wR2zIDyCg29LxheXz+Pz1rOiYvodQ5F8621op8XAeXsm70e4+aa++MP+HWi52IT+/W4S+Z25c0Sfp4k2xkbho5YvQMmKahxbwk4wgHfK96No+VbTIb6EMQ3ULTuSaxuOsHgURbQwm58OnibH6A7GQ1gdJdzg5ojQbT64g1HMjYe1jmhvYBnEhUP/6Ij20d2PurZG4MZFIG6neOedd2Du3Efw7/9egYKC6cjMzIgYrbsoCkbD3y/g1LlPcOHyRdw1aAiem12Cig/fxYjUDDzxwFxqRV6gSTZVGNCvP4bcMSxi3pFXdAbaVUaf55iEBS/hnWNPYwlFCCzfuwDL2elxVHvsByj0kxUZirInHQ1QTERDCyVPUWxvdcigpAadtY8lQreksVpHtMZo7nBU11pcbQkqU0WAN2s5opY7IrSHoZU62KObW1LJ1qkZxpmOaB+Kg4UTJTjuXnniItrbVdFpjcCNjkDcTpEB4q7TH/xgFjZufAP/+q9PIjl5YES4LZ1RhFmrFyJ1YDJ+WfVrLJzyQ3xvdI74MYNTF07j9X1v4utv2vDXQCN+PusnEfGNuJIZ7LdBtPD8qKZjTtFTWPFOADOxHVi7Rvo88oAUm9GzWzTgx5TKOaZalHH4LK7hInRblfwToquOYhTqiPZhsPKLyN5B18JTgxshor2nYTpTI9DlEOiQ2afnzp3H//pf2/H4449F7BAZidGpfbAgpxBHP/sM+wNH8GLlr/Dcn36BF99bLY4/qyjDvuMH0XimSdSL7XMMBeZVyyiA8MdY+5oM9quoZ8vOX1oKlG/AKgrnMH9mhlFiRrVfZZvFWlVMk3dsdHEnY4nQbdLoiPY0vFh/whpbFK2u0wegxMUPa79y82Iro8DH+P3hdYtoH/fNqhloBLo3AnG3FJubW7Bt2/uYN68g6jFFhq5s1lyB4Nt/rsSt/QfgaFuApqNSVhJw9eo1HD/1KWY/UGDVE5Vj3G0sSKeuTnPj1h3NOo2okShpeGIOxYcvGbvZHD/kAopq31BKs1jTWWWx8acfG8x0xxxiiNDNLVBHhHB35HabZmEjwBv1lFHNw9K6deAJKxnEUEe0t6EfWTKBEe0jU1DX0gjcGAjEtczbG29Uohe1NWOdfWqHkD/kX1n5MprPnyOevXCNJtsMpTHHHz+i1z614xRXOqIo5m4JcjaljmjvRsb7vJvgFdO94G2xztUI3EgIxNVSTE8fFdd3inYguWv0zeKf2rN0Oi4E+OGsI9rHBaEm1ghoBHocAnE5xUmToup87HHgJtZgmhWqI9on9hJo6RoBjUC3QyCu7tNuZ61WWCOgEdAIaAQ0AmEQ6JDZp2H46yKNgEZAI6AR0Ah0GwS0U+w2l0orqhHQCGgENAKdjUBcY4odqRzPPl37we9w7lIL/VqRfMvtGHz7YJQ8pGefdiTOmpdGQCOgEdAIqBHoEmOKHECY4yqOvzsdA2+52dL2/JdfYV9jIx6b+DCeL5ht5euERkAjoBHQCGgEOgOBhHefskN8e987eDQ7G4+OnYKZ42Zg9oSZ4vjgiLH4/ncmYkvtW+B6etMIdH0EeC3bbdjdHI+mHcHDlM/fI9KnOXGpE5MpYWyIcVWfmNQQC+PXoj42Yk3VAxFIqFPkLlNuIc4YNwE5o6di9vh5yBkxDd8dNkUcn3zwGUwZ9V38YPIUWhT8fXD92DaOXEErzlBQYes3+VUci41ZDFSh8sMGN45BgibRCGgENAIagfgRSKhTXP3eb3HPkDSM+vYITM98SFjzwcfv4jc1q7H9kNEyzEwdTYGIB2Dc3UPw8s4tcVnMy6+1txu/yrFlyCyuiYufmthwgk7HNxFrObwUy6dl4Q4XFGLd9fPKalV1iUbgeiOQMh6LSucgJ+V6C9byNAL+CCR0ok3zpXPk8Gip03ba0Xa8qRG/31sh0h8GjmLH4Z1ou9omzi9facPZL0+JdEfs8ucsALZ1BKcYeIx8GsuLykTEjSUiGHEMPDSJRkAjoBHQCHQ4Agl1imcvtuBMyxWKmXhFGHbqYjMOnDhBTpJXBKc1wZOS0LdPH/TunYT+ffriiytXRX78O2rJrXgdk+YX21jVoDjpKWvB8Elra7HHdFjH1hUis4RiJoptASppIXEjVKIXzYkgH16AXISVyrPJcSe5VZmLI8s3AwUk3wpD5eQN2OUyD2d5UF9VPqCyQ5XvluHUQaW3275Izu0xJbm+PdK9XEt0OkUoqcGhtPuweNF4pMBOw4udJ6O6bpBZ5pJphsY6bWZnz5fruLp4h5RThpKWK9t1ANIo9NaiHJMJj+VVNxon2dNRWphhFnjRDDLLXAcVjyh0EhwJs+DmlO/EmmuFK48Ar6AgI+Vlg9C/Fbml49H8SgXq7mXcDAyad2/D+rphHtdY4uuFlVtnEm3dJ26F5LmfLa5yi59blv1eZd7OcuOeYJ1V+XSLsc3VLaZiQX6qfDcv5zX01hsKGaZQfbAhkFCnOPi2ZHxx+Tw+bz0rVEq/YyiSb70N7bQYOG/P5P0IN9/UF3/YvwMtF5vQv99NIj/WXTBKhtGVuWek5MSO5CWM4e5NkWc88ItHUbSLzFfxZMlocoRbg/ETBVkYmvZajBGOjuiF9wxIQcbx2KtYsXEi5jdk0HlA5G0s2EEyZHQNw7EdJsfcLluSHOoqaZnpkD3KBZcwOqnsIF3U9j0FtQ5CIJx6G3nR7Y2HxRmO5SiDEfODtKyWImrkIstkdqj8JJ3LuJMGDci5lYoKxoMAsD/8pRZUtguYR7Sit455l9ciS8XbUR6O1kNvIbKV9i2obpqAUpJhONWPsHtqBnUXMs1HuHMx6S2UMfTemiKdtNSZjyoe/joFcQHqt25C+RnJ10NnB9Z+5QYfx7Vw4CXlyKPCBlkMWopQBL4+iWa69ikUPaW+rgXZuXPMl55IsDJ0VttsCfNM+NniKDcdm/pe9cBPSOV8hS13HsRb1cl0b8+x7nVBQi8Onvm+OhhmOvTmlxAvGZ6I6MyEOsW7KApGw98v4NS5T3Dh8kXcNWgInptdgooP38WI1Aw88cBcakVeoEk2VRjQrz+G3DEsrismQjqRk6oqTkfBqhos2UCtD96qdlALkVqCFP6pxMgR+0lHA0D+MIylcFEFSRR7sWErlkhHGpbGxsRK7keJxZ+dso0X1SmqlK1POmHe3GKUDpF55Bdj7aRcbKvieh7lXCesTgo7Riry/XQQzt6lN+vg2IyHxCGRR625xR7jSPUnjdafdIhcl8NRpVWgvp6coukVs+cHHSQkjVkG6+HqEG6e0IO3cJB4Gy+zvY3bazp4O2SHoZU62PW2mJKt5ATFxiGf0k4YaaYhZ4f1m1Bt5Ih9WjM7Um5N2DcFD7ZVZY/UycKFoMwaDkinKMvtOtvtRQzXwk5vk2tYorLBZifHpyz/CPXN45FD8utOD0cu84kUK2mTTbbDZpsor6T62hu1HeVSVjT4MZtwtmQNRCoOoLysxfn/SFHk++lg4uDQW8XLCxCdh4Q6xaUzijBr9UKkDkzGL6t+jYVTfojvjc4RP742py6cxuv73sTX37Thr4FG/HzWTzrkkuVv2Iwi6iotniNbcsTW6rZ0i8jABtGC49YjzV7dazo0rqakCbiZ0HmoI/So5JM1EWMyqUpDmGpKnRR2jJyuts9TjKmDZ5k7k+NAytadu8zvvIMi2ZtdjeCWaCk5HrPrzk+6KI+HViXA6oZTVfDJ7wydYGLdpJLdQdfCk30GsrJrUFvfSi0lennImxZsMcWLlae8zsj0w49kKm0ZZP5HuNdgE8pOy5dH+d9x5SvVD3eNFLz0RCdPNHt55l6nzNGpfbAgpxBHP/sM+wNH8GLlr/Dcn36BF99bLY4/qyjDvuMH0XimSdTj8FIds03H0rUTsXGF+VlG/iMo2luGVVVB7lXFyyBOqXtxnUhkYMmeWmqt7ccRdkrhaIJsYkuZvJ9cFwjSV22gVuwszOSWaojsGqzjuiH53Cr2scPHPqUOQc3iS0UYyd4hxKTZVS9z6cFRa47fcRY7DvmtYFMrTtMDaZ75dt9cfwKnJZl5PFQfsHKad+9ENbVWRAs1HG2IDgHs3s0tvjBbCA13b5rf0Nl1DsMCUenkwsUPa79yUy8lXpHa4LIvayp1e9cdxK464N4ss8UcKVYh9Vw222V56Ke0xU4n0374hOhi3hMh+c7rvlvcx9QDsGgu9ZC0oIlfTkhXz3w/HaSu9qOKl72OTlsIJLSlyFqUzZorlHn7z5W4tf8AHG0L0HRUykoCrl69huOnPsXsBwqseqJyB+xGLlmDteW59FnGMLRTN+oG+kxiMnVvklixia5WTtFM0VGrKL/AyEfRZrTnczoMDTIwc/5ElEQ00cbk6zhw620zjXPmIqlEFvBEm6dh9N66ZRuTcEByo7cjjH1hdZB6xXvkt9jpNOZSQRNTJC+ebMCTaVQb0Sy+D69QN2SZqEJv13nUTUgP1ZCNu/dqK7C+7IAoSssejjRXpWzqtisrqzFzgxMdRDeuktatA9NlEI9wjtFNA4hJPy59wp6GtYf4zx9OY6abqJuWNzcuVB4Wa79yQzMlXkZx9HvuYqYuxOpUmpBkXfRIsfKzObw60dnih49bZ3lPUGvQcb/arjt9npKyi+7jclNPnpQlukBV+X46eNirlOFRV2ehSyzzxteBP8xfWfkyms+fQ69evXCNJtsMpTHHHz+i1z7V92kECPCEj1rF7FMlOXdNVaAp12uii5KoBxd0E7wiuhe6iS09+G5LlOkJbylKw7lr9M3in8pTfdQIhEGAH2gHkbJITr6hCT3ljeKTCKuhEYZaF2kENAIaARUCXcYpqhTU+RqBUARo/GXeIBo3pM8NzMLg92ChtXWORkAjoBGIFIEu030aqcK6nkZAI6AR0AhoBDoLgYTOPu0sozRfjYBGQCOgEdAIxIKAdoqxoKZpNAIaAY2ARuCGRKDLjCny7NO1H/wO5y610K8VybfcjsG3D0bJQ3r26Q1552mjNAIaAY1AF0SgS4wpcgBhjqs4/u50DLzlZgum819+hX2NjXhs4sN4vmC2la8TGgGNgEZAI6AR6AwEEt59yg7x7X3v4NHsbDw6dgpmjpuB2RNmiuODI8bi+9+ZiC21b4Hr6U0jcP0Q4HVbt2F3XCHrO4KHaTF/e0efocSlTkzghbHBY4WYmERERMR6mKv/RFRfV9IIxIZAQp0id5lyC3HGuAnIGT0Vs8fPQ86IafjusCni+OSDz2DKqO/iB5On0KLg74sP/GMzk6k4ggStTGP+nAGAI+Vqrn8aN59I5el6GgGNgEZAI3A9EUioU1z93m9xz5A0jPr2CEzPfEjY/cHH7+I3Naux/ZDRMsxMHU2BiAdg3N1D8PLOLTFiY4RaQiWFhqLFvds5tNMKc03QsBwNJ+h0oLywt8mHloY7XFCIdcfCMtGFGoEbEwFaPmxR6RwKiXVjmqet6pkIJHSiTfOlc+TwaKnTdtrRdrypEb/fWyHSHwaOYsfhnWi72ibOL19pw9kvT4l01LtjJ3CYoke8JtYsZWpe3Htl1GxCCGhd1OVFZVjxTgBL7GGeQirqDI2ARkAjoBHoDggk1CmevdiCMy1XKGbiFYHVqYvNOHDiBDlJXhGc1gRPSkLfPn3Qu3cS+vfpiy+uXBX5Ue84ZuDepygKxtNm0F83B6MludHMNqLYn6Du1qcoziJtES3sbQQmPrJ8M9UnOiuEk5O3M3o9M3eWG7IzwuQDx9YVIrOE4j+KzVgMnP29Kt8tw6mDSm+TfVQHHvepMRejZkLb4tq0ULaxzuh0oJzqWKF07DS8gHUyqusUa5jyGNb6A1aUC7GYdhbLcfHmLNqC5XSipOWadh1khHfOp43H8qrNCBy8WHNhhsj2pjEjPJg1rIOKRxQ6CV6EWXBze6wP4gAABzZJREFU6uzEmmuFK48Ar6AgI+Vlg9C/Fbm0eHszrSFbd+9cLJLRSDjSe90wLF7EC7s7dVGvPuSsJwRb94lbIXnuZ4ur3OLnlmW/V5m3szyosyqfbjFFdHtVvluG8xp66w2FDImGPsaPQEKd4uDbkvHF5fP4vPWssCT9jqFIvvU2tNNi4Lw9k/cj3HxTX/xh/w60XGxC/343ifzodxRVonIBRbpIJycXdCIGH3ZKL2EMd4mO5BzDSRSPOkmRKqibdXIujiyntGhlBgwSuaewSys2TsT8hgzKCYhcZyR6w+Gpo9d7lAsuYXTKfBVPloymiBlbKdiwbSNdPPNNp6vWweDh1NvGN+Kk8bBQRyU3GDkigpsPnmDUdONBANgf/lIBKtsFzCtdaETP4Id0eS2yKLq98ItUzcHbUR6O1kNvIZKjXSgix6cwjSKSulRGqq3k4a9TEBcONURL2slgwSZuaqw9bGI8aKLK/IjwspQ3EwocrGq07F7ucFTXnkQzOcUUekmpr2tBdu4c0yFGgpWhs9pmS5hnQn3tjeqO8ljwE2zCXPc7D+Itr+j29OLgme+rg4fe/BLiJcMTEZ0ZKwIJdYp3URSMhr9fwKlzn+DC5Yu4a9AQPDe7BBUfvosRqRl44oG51Iq8QJNsqjCgX38MuWNYrHZSrMGV1AJdabSmaKKMCAFFIaPCR6v3ErcfJZnpFNuQt9DAwUWVK4POyi96PXYYLUp31yvTgVqClhxDj0lHA2QHtXopYFJB0sc0trkVS4Qjp3JuDXvl++lgelaH3oY42954YFnhiBZ7jCPFEhFc0liORD5cbaKtJJWpIs6bdRzRxh0R4cPQSh3MFo4lTiSo5To1w8ji8EZpJ4w005CzA4WusqJdUUlaMztSd2tRwYPqKe2ROlm4gOI7DgekU5Tldp3t9lIoLNESV5WbfNV4GWYG9yobgjXAcf7KP0J983jkkPw6ikmZy3IixUrapLLZJsor6WeLo1zKUuHjhR8LDWdL1kCkUvir8rIW5Nn/H6qo9346eF0jFS8vQHRezAgk1CkunVGEWasXInVgMn5Z9WssnPJDfG90jvixRacunMbr+97E19+04a+BRvx81k9iNlQSjlyyFe1LjBZa8RxqAXKB1dUpa8ljQCZsx1BHaCuMMGlGr+dgxapNqRPFTKTJQhvoTXPdZJpNu1fqM907X8WfHPqYTGWhq4BjuFF4JVduZKfhIoJHxkHUMrsakTcXpaXkeMyuu4g4xEOrEmB1w6kq+OR3hk4UP/HOO0kuB6n13DroWnjyzkBWdg1q61up5U4vD3nTrBa8Ouq8J6MEZvrhR6oprzvFTBT/Ee7toPiIp+lFQjhH+d9x5SutDHeNFLz0RCclmrEU9IqFqKNoRqf2wYKcQhz97DPsDxzBi5W/wnN/+gVefG+1OP6sogz7jh9E45kmUY/DS8W0Udfi5OIaF6npFMJFq3dRRH1q8lZGrw+RXYN16wLUGnwERXvLaAw0KLGq2JwtS7asE/k8WagWayftxxF2rqp8Px2CIuJLxRIR3KTZVS9F04Oj1hy/4yx2HPJbwXAR501yZRT1cLQhOpjR0qVKXscQGu7eNL+hs+vsRSvzotLJhYsf1n7lpg5KvCK1QdpiHrOmUrd33UHsomDP92aZLeZIsQqp57LZLstDP6UtdjqZ9sMnRBfzngjJd1733eI+ph6ARXORl9aCJn45IV098/10kLrajype9jo6HTcCCW0psvZls+YKI97+cyVu7T8AR9sCNB2VspKAq1ev4fipTzH7gQKrnqgc7Y5mib42ppAm7jxlURZVnjS7HqmFRZ9WTKauShIpNi4TLUhkYOb8iSiJaKKNxdqW4NbbZhqzzEVSiczmMc2nYfR6umUb4508O1apE9kyahXpWmDyK9qM9nxOq/L9dJB6xXuMISI42emMSE5v13nUTUgP1ZAtbMR5o7YyinpYWrcOMlp6a4gKwQw3jS2SerBS+JSfTvOH05jpJnPSkhsXP6z9yg3VlHiF11xdyl3M1IVYnUoTkqzWS6RYUb2wNqvFckl0tvjh49ZZ3hPUGlx8H032opagqY6YzMVpZXR7mmi0i+rLGGc8WUt0jfrpYAqwH5Qy7JV0Ol4EusQyb2wEf8i/svJlNJ8/h169euEaTbYZSmOOP35Er30a70XuVvQ8IaRWMftUaQh3TVWgKZe6eG1jUsrqPb6gm+AV0b3QTWzp8fdc9wEg4S1FCRV3jb5Z/FN5qo89AgF+oB1EyiI5g5Qm9JQ3gqe/Ww2NHoGDNlIjoBHoKgh0GafYVQDRelxPBGj8Zd4gGjekzw1MscHvwa6nHlqWRkAjoBEwEOgy3af6gmgENAIaAY2ARiDRCCR09mmijdfyNQIaAY2ARkAjYEdAO0U7GjqtEdAIaAQ0Aj0aAe0Ue/Tl18ZrBDQCGgGNgB0B7RTtaOi0RkAjoBHQCPRoBP4/ke8NxTSPEZYAAAAASUVORK5CYII=" alt="" />

那Spark是怎样改写ExecuteStatementOperation的运行逻辑的呢?

最核心的逻辑例如以下:

      def run(): Unit = {
logInfo(s"Running query '$statement'")
setState(OperationState.RUNNING)
try {
result = hiveContext.sql(statement)
logDebug(result.queryExecution.toString())
val groupId = round(random * 1000000).toString
hiveContext.sparkContext.setJobGroup(groupId, statement)
iter = result.queryExecution.toRdd.toLocalIterator
dataTypes = result.queryExecution.analyzed.output.map(_.dataType).toArray
setHasResultSet(true)
} catch {
// Actually do need to catch Throwable as some failures don't inherit from Exception and
// HiveServer will silently swallow them.
case e: Throwable =>
logError("Error executing query:",e)
throw new HiveSQLException(e.toString)
}
setState(OperationState.FINISHED)
}

statement是一个String。即query本身。调用HiveContext的sql()方法,返回的是一个SchemaRDD。HiveContext的这段逻辑例如以下:

  override def sql(sqlText: String): SchemaRDD = {
// TODO: Create a framework for registering parsers instead of just hardcoding if statements.
if (dialect == "sql") {
super.sql(sqlText)
} else if (dialect == "hiveql") {
new SchemaRDD(this, HiveQl.parseSql(sqlText))
} else {
sys.error(s"Unsupported SQL dialect: $dialect. Try 'sql' or 'hiveql'")
}
}

调完sql()后返回的是一个带被解析过了的基础逻辑计划的SchemaRDD。兴许。

logDebug(result.queryExecution.toString())

这一步触发了逻辑运行计划的进一步分析、优化和变成物理运行计划的几个过程。之后,

result.queryExecution.toRdd

toRdd这步是触发计算并返回结果。这几个逻辑在之前Spark SQL源代码分析的文章里都提到过。

除了上面这部分,另一些schema转化、数据类型转化的逻辑,是由于Catalyst这边。有自己的数据行表示方法,也有自己的dataType。而且schema这块呢。在生成SchemaRDD的时候也转化过一次。所以在返回运行结果的时候,须要有转换回Hive的TableSchema、FieldSchema的逻辑。

以上说明了Spark SQL是怎样把query的运行转换到Spark SQL里的。

总结

基本上Spark SQL在CLI这块的实现非常靠近Hive Service项目里的CLI模块,主要类继承体系、运行逻辑差点儿相同都一样。Spark SQL改动的关键逻辑在CLIService内的SessionManager内的OperationManager里,将非元数据查询操作的query丢给了Spark SQL的Hiveproject里的HiveContext.sql()来完毕。通过返回的SchemaRDD,来进一步得到结果数据、得到中间运行计划的Schema信息。

全文完 :)

Spark SQL CLI 实现分析的更多相关文章

  1. SparkSQL使用之Spark SQL CLI

    Spark SQL CLI描述 Spark SQL CLI的引入使得在SparkSQL中通过hive metastore就可以直接对hive进行查询更加方便:当前版本中还不能使用Spark SQL C ...

  2. 第十一篇:Spark SQL 源码分析之 External DataSource外部数据源

    上周Spark1.2刚发布,周末在家没事,把这个特性给了解一下,顺便分析下源码,看一看这个特性是如何设计及实现的. /** Spark SQL源码分析系列文章*/ (Ps: External Data ...

  3. 第十篇:Spark SQL 源码分析之 In-Memory Columnar Storage源码分析之 query

    /** Spark SQL源码分析系列文章*/ 前面讲到了Spark SQL In-Memory Columnar Storage的存储结构是基于列存储的. 那么基于以上存储结构,我们查询cache在 ...

  4. 第九篇:Spark SQL 源码分析之 In-Memory Columnar Storage源码分析之 cache table

    /** Spark SQL源码分析系列文章*/ Spark SQL 可以将数据缓存到内存中,我们可以见到的通过调用cache table tableName即可将一张表缓存到内存中,来极大的提高查询效 ...

  5. 第七篇:Spark SQL 源码分析之Physical Plan 到 RDD的具体实现

    /** Spark SQL源码分析系列文章*/ 接上一篇文章Spark SQL Catalyst源码分析之Physical Plan,本文将介绍Physical Plan的toRDD的具体实现细节: ...

  6. 第一篇:Spark SQL源码分析之核心流程

    /** Spark SQL源码分析系列文章*/ 自从去年Spark Submit 2013 Michael Armbrust分享了他的Catalyst,到至今1年多了,Spark SQL的贡献者从几人 ...

  7. 【Spark SQL 源码分析系列文章】

    从决定写Spark SQL源码分析的文章,到现在一个月的时间里,陆陆续续差不多快完成了,这里也做一个整合和索引,方便大家阅读,这里给出阅读顺序 :) 第一篇 Spark SQL源码分析之核心流程 第二 ...

  8. 6. 运行Spark SQL CLI

    Spark SQL CLI可以很方便的在本地运行Hive元数据服务以及从命令行执行任务查询.需要注意的是,Spark SQL CLI不能与Thrift JDBC服务交互.在Spark目录下执行如下命令 ...

  9. 第6章 运行Spark SQL CLI

    第6章 运行Spark SQL CLI Spark SQL CLI可以很方便的在本地运行Hive元数据服务以及从命令行执行查询任务.需要注意的是,Spark SQL CLI不能与Thrift JDBC ...

随机推荐

  1. C++中图片重命名

    非常简单的小程序,满足自己的需求. #include <iostream> #include <fstream> #include<sstream> using n ...

  2. Appium Python API 汇总(中文版)

    网络搜集而来,留着备用,方便自己也方便他人.感谢总结的人! 1.contexts contexts(self): Returns the contexts within the current ses ...

  3. 微信服务号获取openId流程(订阅号)

    微信公众平台官网:https://mp.weixin.qq.com/ 微信测试开发平台官网:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandb ...

  4. jsp学习笔记 - 内置对象 pageContext

    1.pageContext几乎可以操作所有的页面内置对象 pageContext.getRequest();    得到的对象只是属于ServletRequest类,httpServletReques ...

  5. Java学习3_一些基础3_16.5.7

    字符串的一些常用方法: int length() String replace(CharSequence oldString,CharSequence newString) 用新字符串代替原字符串,返 ...

  6. Masonry 原理与使用说明

    原理: 1)约束生成:MASConstraintMaker: 2)缺省补齐: - (void)setSecondViewAttribute:(id)secondViewAttribute { if ( ...

  7. 后台中的sql注入

    aa.getSqlMap().put("order"," and a.id not in(\'"+po.getId()+"\')"); \' ...

  8. Java之希尔排序

    希尔排序 前面已经知道了插入排序,明白插入排序的原理,不断比较来交换相邻的元素,这样的话效率不高,为此希尔排序,在插入排序上做出了改进,通过间隔增量来比较并交换元素,这样可以减少比较交换的次数. pa ...

  9. Gym - 101670H Dark Ride with Monsters(CTU Open Contest 2017 贪心)

    题目: A narrow gauge train drives the visitors through the sequence of chambers in the Dark Ride attra ...

  10. Ztree加载完成默认选中根节点右侧生成表格

    需求:页面加载完成之后,默认选中ztree的根节点,并执行其点击方法,右侧生成表格: 效果:如下图所示: 思路:在节点点击事件clickNode方法中根据节点的部门code查询这个部门下的所有员工,并 ...