示例#1
0
			/// <summary>
			/// Calls sendMapOutput for the mapId pointed by ReduceContext.mapsToSend
			/// and increments it.
			/// </summary>
			/// <remarks>
			/// Calls sendMapOutput for the mapId pointed by ReduceContext.mapsToSend
			/// and increments it. This method is first called by messageReceived()
			/// maxSessionOpenFiles times and then on the completion of every
			/// sendMapOutput operation. This limits the number of open files on a node,
			/// which can get really large(exhausting file descriptors on the NM) if all
			/// sendMapOutputs are called in one go, as was done previous to this change.
			/// </remarks>
			/// <param name="reduceContext">used to call sendMapOutput with correct params.</param>
			/// <returns>the ChannelFuture of the sendMapOutput, can be null.</returns>
			/// <exception cref="System.Exception"/>
			public virtual ChannelFuture SendMap(ShuffleHandler.ReduceContext reduceContext)
			{
				ChannelFuture nextMap = null;
				if (reduceContext.GetMapsToSend().Get() < reduceContext.GetMapIds().Count)
				{
					int nextIndex = reduceContext.GetMapsToSend().GetAndIncrement();
					string mapId = reduceContext.GetMapIds()[nextIndex];
					try
					{
						ShuffleHandler.Shuffle.MapOutputInfo info = reduceContext.GetInfoMap()[mapId];
						if (info == null)
						{
							info = this.GetMapOutputInfo(reduceContext.GetOutputBasePathStr() + mapId, mapId, 
								reduceContext.GetReduceId(), reduceContext.GetUser());
						}
						nextMap = this.SendMapOutput(reduceContext.GetCtx(), reduceContext.GetCtx().GetChannel
							(), reduceContext.GetUser(), mapId, reduceContext.GetReduceId(), info);
						if (null == nextMap)
						{
							this.SendError(reduceContext.GetCtx(), HttpResponseStatus.NotFound);
							return null;
						}
						nextMap.AddListener(new ShuffleHandler.ReduceMapFileCount(this, reduceContext));
					}
					catch (IOException e)
					{
						ShuffleHandler.Log.Error("Shuffle error :", e);
						string errorMessage = this.GetErrorMessage(e);
						this.SendError(reduceContext.GetCtx(), errorMessage, HttpResponseStatus.InternalServerError
							);
						return null;
					}
				}
				return nextMap;
			}
示例#2
0
			/// <exception cref="System.Exception"/>
			public override void MessageReceived(ChannelHandlerContext ctx, MessageEvent evt)
			{
				HttpRequest request = (HttpRequest)evt.GetMessage();
				if (request.GetMethod() != HttpMethod.Get)
				{
					this.SendError(ctx, HttpResponseStatus.MethodNotAllowed);
					return;
				}
				// Check whether the shuffle version is compatible
				if (!ShuffleHeader.DefaultHttpHeaderName.Equals(request.GetHeader(ShuffleHeader.HttpHeaderName
					)) || !ShuffleHeader.DefaultHttpHeaderVersion.Equals(request.GetHeader(ShuffleHeader
					.HttpHeaderVersion)))
				{
					this.SendError(ctx, "Incompatible shuffle request version", HttpResponseStatus.BadRequest
						);
				}
				IDictionary<string, IList<string>> q = new QueryStringDecoder(request.GetUri()).GetParameters
					();
				IList<string> keepAliveList = q["keepAlive"];
				bool keepAliveParam = false;
				if (keepAliveList != null && keepAliveList.Count == 1)
				{
					keepAliveParam = Sharpen.Extensions.ValueOf(keepAliveList[0]);
					if (ShuffleHandler.Log.IsDebugEnabled())
					{
						ShuffleHandler.Log.Debug("KeepAliveParam : " + keepAliveList + " : " + keepAliveParam
							);
					}
				}
				IList<string> mapIds = this.SplitMaps(q["map"]);
				IList<string> reduceQ = q["reduce"];
				IList<string> jobQ = q["job"];
				if (ShuffleHandler.Log.IsDebugEnabled())
				{
					ShuffleHandler.Log.Debug("RECV: " + request.GetUri() + "\n  mapId: " + mapIds + "\n  reduceId: "
						 + reduceQ + "\n  jobId: " + jobQ + "\n  keepAlive: " + keepAliveParam);
				}
				if (mapIds == null || reduceQ == null || jobQ == null)
				{
					this.SendError(ctx, "Required param job, map and reduce", HttpResponseStatus.BadRequest
						);
					return;
				}
				if (reduceQ.Count != 1 || jobQ.Count != 1)
				{
					this.SendError(ctx, "Too many job/reduce parameters", HttpResponseStatus.BadRequest
						);
					return;
				}
				int reduceId;
				string jobId;
				try
				{
					reduceId = System.Convert.ToInt32(reduceQ[0]);
					jobId = jobQ[0];
				}
				catch (FormatException)
				{
					this.SendError(ctx, "Bad reduce parameter", HttpResponseStatus.BadRequest);
					return;
				}
				catch (ArgumentException)
				{
					this.SendError(ctx, "Bad job parameter", HttpResponseStatus.BadRequest);
					return;
				}
				string reqUri = request.GetUri();
				if (null == reqUri)
				{
					// TODO? add upstream?
					this.SendError(ctx, HttpResponseStatus.Forbidden);
					return;
				}
				HttpResponse response = new DefaultHttpResponse(HttpVersion.Http11, HttpResponseStatus
					.Ok);
				try
				{
					this.VerifyRequest(jobId, ctx, request, response, new Uri("http", string.Empty, this
						.port, reqUri));
				}
				catch (IOException e)
				{
					ShuffleHandler.Log.Warn("Shuffle failure ", e);
					this.SendError(ctx, e.Message, HttpResponseStatus.Unauthorized);
					return;
				}
				IDictionary<string, ShuffleHandler.Shuffle.MapOutputInfo> mapOutputInfoMap = new 
					Dictionary<string, ShuffleHandler.Shuffle.MapOutputInfo>();
				Org.Jboss.Netty.Channel.Channel ch = evt.GetChannel();
				string user = this._enclosing.userRsrc[jobId];
				// $x/$user/appcache/$appId/output/$mapId
				// TODO: Once Shuffle is out of NM, this can use MR APIs to convert
				// between App and Job
				string outputBasePathStr = this.GetBaseLocation(jobId, user);
				try
				{
					this.PopulateHeaders(mapIds, outputBasePathStr, user, reduceId, request, response
						, keepAliveParam, mapOutputInfoMap);
				}
				catch (IOException e)
				{
					ch.Write(response);
					ShuffleHandler.Log.Error("Shuffle error in populating headers :", e);
					string errorMessage = this.GetErrorMessage(e);
					this.SendError(ctx, errorMessage, HttpResponseStatus.InternalServerError);
					return;
				}
				ch.Write(response);
				//Initialize one ReduceContext object per messageReceived call
				ShuffleHandler.ReduceContext reduceContext = new ShuffleHandler.ReduceContext(mapIds
					, reduceId, ctx, user, mapOutputInfoMap, outputBasePathStr);
				for (int i = 0; i < Math.Min(this._enclosing.maxSessionOpenFiles, mapIds.Count); 
					i++)
				{
					ChannelFuture nextMap = this.SendMap(reduceContext);
					if (nextMap == null)
					{
						return;
					}
				}
			}
示例#3
0
			public ReduceMapFileCount(ShuffleHandler _enclosing, ShuffleHandler.ReduceContext
				 rc)
			{
				this._enclosing = _enclosing;
				this.reduceContext = rc;
			}