From 31c7ed639d67374fad1d22649b5c09e9575404a2 Mon Sep 17 00:00:00 2001 From: fjy Date: Wed, 4 Dec 2013 13:53:08 -0800 Subject: [PATCH 01/49] first commit --- .../src/main/java/io/druid/query/Query.java | 5 +- .../io/druid/query/select/EventHolder.java | 49 + .../io/druid/query/select/PagingSpec.java | 42 + .../io/druid/query/select/SelectBinaryFn.java | 77 + .../io/druid/query/select/SelectQuery.java | 153 + .../druid/query/select/SelectQueryEngine.java | 139 + .../select/SelectQueryQueryToolChest.java | 228 ++ .../select/SelectQueryRunnerFactory.java | 106 + .../druid/query/select/SelectResultValue.java | 76 + .../select/SelectResultValueBuilder.java | 85 + .../druid/segment/ColumnSelectorFactory.java | 1 + .../segment/QueryableIndexStorageAdapter.java | 33 + .../java/io/druid/segment/StorageAdapter.java | 5 +- .../segment/TimestampColumnSelector.java | 27 + .../segment/incremental/IncrementalIndex.java | 14 + .../IncrementalIndexStorageAdapter.java | 21 + publications/whitepaper/README.md | 4 + .../{vldb.cls => acm_proc_article-sp.cls} | 3056 +++++++++-------- publications/whitepaper/druid.bib | 644 ++-- publications/whitepaper/druid.pdf | Bin 0 -> 527612 bytes publications/whitepaper/druid.tex | 1293 +++---- publications/whitepaper/figures/caching.png | Bin 0 -> 36103 bytes .../figures/cardinality_vs_throughput.png | Bin 0 -> 80455 bytes publications/whitepaper/figures/cluster.png | Bin 0 -> 53735 bytes .../figures/historical_download.png | Bin 0 -> 28917 bytes .../ingestion_latency_vs_num_metrics.png | Bin 0 -> 78682 bytes .../whitepaper/figures/realtime_flow.png | Bin 0 -> 33947 bytes .../whitepaper/figures/realtime_pipeline.png | Bin 0 -> 36023 bytes .../whitepaper/figures/realtime_timeline.png | Bin 0 -> 37015 bytes .../figures/throughput_vs_num_dims.png | Bin 0 -> 74606 bytes .../druid/guice/QueryRunnerFactoryModule.java | 3 + 31 files changed, 3755 insertions(+), 2306 deletions(-) create mode 100644 processing/src/main/java/io/druid/query/select/EventHolder.java create mode 100644 processing/src/main/java/io/druid/query/select/PagingSpec.java create mode 100644 processing/src/main/java/io/druid/query/select/SelectBinaryFn.java create mode 100644 processing/src/main/java/io/druid/query/select/SelectQuery.java create mode 100644 processing/src/main/java/io/druid/query/select/SelectQueryEngine.java create mode 100644 processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java create mode 100644 processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java create mode 100644 processing/src/main/java/io/druid/query/select/SelectResultValue.java create mode 100644 processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java create mode 100644 processing/src/main/java/io/druid/segment/TimestampColumnSelector.java create mode 100644 publications/whitepaper/README.md rename publications/whitepaper/{vldb.cls => acm_proc_article-sp.cls} (65%) create mode 100644 publications/whitepaper/druid.pdf create mode 100644 publications/whitepaper/figures/caching.png create mode 100644 publications/whitepaper/figures/cardinality_vs_throughput.png create mode 100644 publications/whitepaper/figures/cluster.png create mode 100644 publications/whitepaper/figures/historical_download.png create mode 100644 publications/whitepaper/figures/ingestion_latency_vs_num_metrics.png create mode 100644 publications/whitepaper/figures/realtime_flow.png create mode 100644 publications/whitepaper/figures/realtime_pipeline.png create mode 100644 publications/whitepaper/figures/realtime_timeline.png create mode 100644 publications/whitepaper/figures/throughput_vs_num_dims.png diff --git a/processing/src/main/java/io/druid/query/Query.java b/processing/src/main/java/io/druid/query/Query.java index daf1410308e..fdf84266d96 100644 --- a/processing/src/main/java/io/druid/query/Query.java +++ b/processing/src/main/java/io/druid/query/Query.java @@ -25,6 +25,7 @@ import com.metamx.common.guava.Sequence; import io.druid.query.groupby.GroupByQuery; import io.druid.query.metadata.metadata.SegmentMetadataQuery; import io.druid.query.search.search.SearchQuery; +import io.druid.query.select.SelectQuery; import io.druid.query.spec.QuerySegmentSpec; import io.druid.query.timeboundary.TimeBoundaryQuery; import io.druid.query.timeseries.TimeseriesQuery; @@ -40,7 +41,8 @@ import java.util.Map; @JsonSubTypes.Type(name = Query.SEARCH, value = SearchQuery.class), @JsonSubTypes.Type(name = Query.TIME_BOUNDARY, value = TimeBoundaryQuery.class), @JsonSubTypes.Type(name = Query.GROUP_BY, value = GroupByQuery.class), - @JsonSubTypes.Type(name = Query.SEGMENT_METADATA, value = SegmentMetadataQuery.class) + @JsonSubTypes.Type(name = Query.SEGMENT_METADATA, value = SegmentMetadataQuery.class), + @JsonSubTypes.Type(name = Query.SELECT, value = SelectQuery.class) }) public interface Query { @@ -49,6 +51,7 @@ public interface Query public static final String TIME_BOUNDARY = "timeBoundary"; public static final String GROUP_BY = "groupBy"; public static final String SEGMENT_METADATA = "segmentMetadata"; + public static final String SELECT = "select"; public String getDataSource(); diff --git a/processing/src/main/java/io/druid/query/select/EventHolder.java b/processing/src/main/java/io/druid/query/select/EventHolder.java new file mode 100644 index 00000000000..d468e02281c --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/EventHolder.java @@ -0,0 +1,49 @@ +package io.druid.query.select; + +import com.fasterxml.jackson.annotation.JsonValue; +import com.google.common.collect.Maps; +import org.joda.time.DateTime; + +import java.util.Map; + +/** + */ +public class EventHolder +{ + private final long timestamp; + private final Map entries = Maps.newLinkedHashMap(); + + public EventHolder(long timestamp) + { + this.timestamp = timestamp; + } + + public void put(String key, Object val) + { + entries.put(key, val); + } + + public void putAll(Map data) + { + entries.putAll(data); + } + + public Object get(String key) + { + return entries.get(key); + } + + public long getTimestamp() + { + return timestamp; + } + + @JsonValue + public Map getBaseObject() + { + Map retVal = Maps.newLinkedHashMap(); + retVal.put("timestamp", new DateTime(timestamp)); + retVal.putAll(entries); + return retVal; + } +} diff --git a/processing/src/main/java/io/druid/query/select/PagingSpec.java b/processing/src/main/java/io/druid/query/select/PagingSpec.java new file mode 100644 index 00000000000..d831d68c140 --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/PagingSpec.java @@ -0,0 +1,42 @@ +package io.druid.query.select; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Preconditions; + +/** + */ +public class PagingSpec +{ + private final int start; + private final int end; + + @JsonCreator + public PagingSpec( + @JsonProperty("start") int start, + @JsonProperty("end") int end + ) + { + Preconditions.checkArgument(end > start, "end must be greater than start"); + + this.start = start; + this.end = end; + } + + @JsonProperty + public int getStart() + { + return start; + } + + @JsonProperty + public int getEnd() + { + return end; + } + + public int getThreshold() + { + return end - start; + } +} diff --git a/processing/src/main/java/io/druid/query/select/SelectBinaryFn.java b/processing/src/main/java/io/druid/query/select/SelectBinaryFn.java new file mode 100644 index 00000000000..7de46c26b6a --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/SelectBinaryFn.java @@ -0,0 +1,77 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.metamx.common.guava.nary.BinaryFn; +import io.druid.granularity.AllGranularity; +import io.druid.granularity.QueryGranularity; +import io.druid.query.Result; +import org.joda.time.DateTime; + +/** + */ +public class SelectBinaryFn + implements BinaryFn, Result, Result> +{ + private final QueryGranularity gran; + private final PagingSpec pagingSpec; + + public SelectBinaryFn( + QueryGranularity granularity, + PagingSpec pagingSpec + ) + { + this.gran = granularity; + this.pagingSpec = pagingSpec; + } + + @Override + public Result apply( + Result arg1, Result arg2 + ) + { + if (arg1 == null) { + return arg2; + } + + if (arg2 == null) { + return arg1; + } + + final DateTime timestamp = (gran instanceof AllGranularity) + ? arg1.getTimestamp() + : gran.toDateTime(gran.truncate(arg1.getTimestamp().getMillis())); + + SelectResultValueBuilder builder = new SelectResultValueBuilder(timestamp, pagingSpec.getThreshold()); + + SelectResultValue arg1Val = arg1.getValue(); + SelectResultValue arg2Val = arg2.getValue(); + + for (EventHolder event : arg1Val) { + builder.addEntry(event); + } + + for (EventHolder event : arg2Val) { + builder.addEntry(event); + } + + return builder.build(); + } +} diff --git a/processing/src/main/java/io/druid/query/select/SelectQuery.java b/processing/src/main/java/io/druid/query/select/SelectQuery.java new file mode 100644 index 00000000000..50b61e9466b --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/SelectQuery.java @@ -0,0 +1,153 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.druid.granularity.QueryGranularity; +import io.druid.query.BaseQuery; +import io.druid.query.Query; +import io.druid.query.Result; +import io.druid.query.filter.DimFilter; +import io.druid.query.spec.QuerySegmentSpec; + +import java.util.List; +import java.util.Map; + +/** + */ +@JsonTypeName("select") +public class SelectQuery extends BaseQuery> +{ + private static final PagingSpec defaultPagingSpec = new PagingSpec(0, 10); + + private final DimFilter dimFilter; + private final QueryGranularity granularity; + private final List dimensions; + private final List metrics; + private final PagingSpec pagingSpec; + + @JsonCreator + public SelectQuery( + @JsonProperty("dataSource") String dataSource, + @JsonProperty("intervals") QuerySegmentSpec querySegmentSpec, + @JsonProperty("filter") DimFilter dimFilter, + @JsonProperty("granularity") QueryGranularity granularity, + @JsonProperty("dimensions") List dimensions, + @JsonProperty("metrics") List metrics, + @JsonProperty("pagingSpec") PagingSpec pagingSpec, + @JsonProperty("context") Map context + ) + { + super(dataSource, querySegmentSpec, context); + this.dimFilter = dimFilter; + this.granularity = granularity; + this.dimensions = dimensions; + this.metrics = metrics; + this.pagingSpec = pagingSpec == null ? defaultPagingSpec : pagingSpec; + } + + @Override + public boolean hasFilters() + { + return dimFilter != null; + } + + @Override + public String getType() + { + return Query.SELECT; + } + + @JsonProperty("filter") + public DimFilter getDimensionsFilter() + { + return dimFilter; + } + + @JsonProperty + public QueryGranularity getGranularity() + { + return granularity; + } + + @JsonProperty + public List getDimensions() + { + return dimensions; + } + + @JsonProperty + public PagingSpec getPagingSpec() + { + return pagingSpec; + } + + @JsonProperty + public List getMetrics() + { + return metrics; + } + + public SelectQuery withQuerySegmentSpec(QuerySegmentSpec querySegmentSpec) + { + return new SelectQuery( + getDataSource(), + querySegmentSpec, + dimFilter, + granularity, + dimensions, + metrics, + pagingSpec, + getContext() + ); + } + + public SelectQuery withOverriddenContext(Map contextOverrides) + { + return new SelectQuery( + getDataSource(), + getQuerySegmentSpec(), + dimFilter, + granularity, + dimensions, + metrics, + pagingSpec, + computeOverridenContext(contextOverrides) + ); + } + + @Override + public String toString() + { + return "SelectQuery{" + + "dataSource='" + getDataSource() + '\'' + + ", querySegmentSpec=" + getQuerySegmentSpec() + + ", dimFilter=" + dimFilter + + ", granularity=" + granularity + + ", dimensions=" + dimensions + + ", metrics=" + metrics + + ", pagingSpec=" + pagingSpec + + '}'; + } + + +} diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java new file mode 100644 index 00000000000..44b9e4d5df1 --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java @@ -0,0 +1,139 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.metamx.common.guava.BaseSequence; +import com.metamx.common.guava.Sequence; +import io.druid.query.QueryRunnerHelper; +import io.druid.query.Result; +import io.druid.segment.Cursor; +import io.druid.segment.DimensionSelector; +import io.druid.segment.ObjectColumnSelector; +import io.druid.segment.StorageAdapter; +import io.druid.segment.TimestampColumnSelector; +import io.druid.segment.data.IndexedInts; +import io.druid.segment.filter.Filters; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + */ +public class SelectQueryEngine +{ + public Sequence> process(final SelectQuery query, final StorageAdapter adapter) + { + return new BaseSequence<>( + new BaseSequence.IteratorMaker, Iterator>>() + { + @Override + public Iterator> make() + { + final Iterable dims; + if (query.getDimensions() == null || query.getDimensions().isEmpty()) { + dims = adapter.getAvailableDimensions(); + } else { + dims = query.getDimensions(); + } + + final Iterable metrics; + if (query.getMetrics() == null || query.getMetrics().isEmpty()) { + metrics = adapter.getAvailableMetrics(); + } else { + metrics = query.getMetrics(); + } + + return QueryRunnerHelper.makeCursorBasedQuery( + adapter, + query.getQuerySegmentSpec().getIntervals(), + Filters.convertDimensionFilters(query.getDimensionsFilter()), + query.getGranularity(), + new Function>() + { + @Override + public Result apply(Cursor cursor) + { + final TimestampColumnSelector timestampColumnSelector = cursor.makeTimestampColumnSelector(); + final SelectResultValueBuilder builder = new SelectResultValueBuilder(cursor.getTime(), query.getPagingSpec().getThreshold()); + + final Map dimSelectors = Maps.newHashMap(); + for (String dim : dims) { + final DimensionSelector dimSelector = cursor.makeDimensionSelector(dim); + dimSelectors.put(dim, dimSelector); + } + + final Map metSelectors = Maps.newHashMap(); + for (String metric : metrics) { + final ObjectColumnSelector metricSelector = cursor.makeObjectColumnSelector(metric); + metSelectors.put(metric, metricSelector); + } + + while (!cursor.isDone()) { + final EventHolder theEvent = new EventHolder(timestampColumnSelector.getTimestamp()); + + for (Map.Entry dimSelector : dimSelectors.entrySet()) { + final String dim = dimSelector.getKey(); + final DimensionSelector selector = dimSelector.getValue(); + final IndexedInts vals = selector.getRow(); + + if (vals.size() <= 1) { + final String dimVal = selector.lookupName(vals.get(0)); + theEvent.put(dim, dimVal); + } else { + List dimVals = Lists.newArrayList(); + for (int i = 0; i < vals.size(); ++i) { + dimVals.add(selector.lookupName(vals.get(i))); + } + theEvent.put(dim, dimVals); + } + } + + for (Map.Entry metSelector : metSelectors.entrySet()) { + final String metric = metSelector.getKey(); + final ObjectColumnSelector selector = metSelector.getValue(); + theEvent.put(metric, selector.get()); + } + + builder.addEntry(theEvent); + cursor.advance(); + } + + return builder.build(); + } + } + ).iterator(); + } + + @Override + public void cleanup(Iterator> toClean) + { + // https://github.com/metamx/druid/issues/128 + while (toClean.hasNext()) { + toClean.next(); + } + } + } + ); + } +} diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java b/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java new file mode 100644 index 00000000000..1b810b30f73 --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java @@ -0,0 +1,228 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Ordering; +import com.google.inject.Inject; +import com.metamx.common.guava.MergeSequence; +import com.metamx.common.guava.Sequence; +import com.metamx.common.guava.nary.BinaryFn; +import com.metamx.emitter.service.ServiceMetricEvent; +import io.druid.collections.OrderedMergeSequence; +import io.druid.granularity.QueryGranularity; +import io.druid.query.CacheStrategy; +import io.druid.query.IntervalChunkingQueryRunner; +import io.druid.query.Query; +import io.druid.query.QueryConfig; +import io.druid.query.QueryRunner; +import io.druid.query.QueryToolChest; +import io.druid.query.Result; +import io.druid.query.ResultGranularTimestampComparator; +import io.druid.query.ResultMergeQueryRunner; +import io.druid.query.aggregation.AggregatorFactory; +import io.druid.query.aggregation.MetricManipulationFn; +import io.druid.query.filter.DimFilter; +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.joda.time.Minutes; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + */ +public class SelectQueryQueryToolChest extends QueryToolChest, SelectQuery> +{ + private static final byte SELECT_QUERY = 0x13; + + private static final Joiner COMMA_JOIN = Joiner.on(","); + private static final TypeReference OBJECT_TYPE_REFERENCE = + new TypeReference() + { + }; + + private static final TypeReference> TYPE_REFERENCE = + new TypeReference>() + { + }; + + private final QueryConfig config; + + @Inject + public SelectQueryQueryToolChest(QueryConfig config) + { + this.config = config; + } + + @Override + public QueryRunner> mergeResults(QueryRunner> queryRunner) + { + return new ResultMergeQueryRunner>(queryRunner) + { + @Override + protected Ordering> makeOrdering(Query> query) + { + return Ordering.from( + new ResultGranularTimestampComparator( + ((SelectQuery) query).getGranularity() + ) + ); + } + + @Override + protected BinaryFn, Result, Result> createMergeFn( + Query> input + ) + { + SelectQuery query = (SelectQuery) input; + return new SelectBinaryFn( + query.getGranularity(), + query.getPagingSpec() + ); + } + }; + } + + @Override + public Sequence> mergeSequences(Sequence>> seqOfSequences) + { + return new OrderedMergeSequence>(getOrdering(), seqOfSequences); + } + + @Override + public ServiceMetricEvent.Builder makeMetricBuilder(SelectQuery query) + { + int numMinutes = 0; + for (Interval interval : query.getIntervals()) { + numMinutes += Minutes.minutesIn(interval).getMinutes(); + } + + return new ServiceMetricEvent.Builder() + .setUser2(query.getDataSource()) + .setUser4("Select") + .setUser5(COMMA_JOIN.join(query.getIntervals())) + .setUser6(String.valueOf(query.hasFilters())) + .setUser9(Minutes.minutes(numMinutes).toString()); + } + + @Override + public Function, Result> makeMetricManipulatorFn( + final SelectQuery query, final MetricManipulationFn fn + ) + { + return Functions.identity(); + } + + @Override + public TypeReference> getResultTypeReference() + { + return TYPE_REFERENCE; + } + + @Override + public CacheStrategy, Object, SelectQuery> getCacheStrategy(final SelectQuery query) + { + return new CacheStrategy, Object, SelectQuery>() + { + @Override + public byte[] computeCacheKey(SelectQuery query) + { + final DimFilter dimFilter = query.getDimensionsFilter(); + final byte[] filterBytes = dimFilter == null ? new byte[]{} : dimFilter.getCacheKey(); + final byte[] granularityBytes = query.getGranularity().cacheKey(); + + return ByteBuffer + .allocate(1 + granularityBytes.length + filterBytes.length) + .put(SELECT_QUERY) + .put(granularityBytes) + .put(filterBytes) + .array(); + } + + @Override + public TypeReference getCacheObjectClazz() + { + return OBJECT_TYPE_REFERENCE; + } + + @Override + public Function, Object> prepareForCache() + { + return new Function, Object>() + { + @Override + public Object apply(final Result input) + { + return Arrays.asList(input.getTimestamp().getMillis(), input.getValue().getBaseObject()); + } + }; + } + + @Override + public Function> pullFromCache() + { + return new Function>() + { + private final QueryGranularity granularity = query.getGranularity(); + + @Override + public Result apply(Object input) + { + List results = (List) input; + Iterator resultIter = results.iterator(); + + DateTime timestamp = granularity.toDateTime(((Number) resultIter.next()).longValue()); + + return new Result( + timestamp, + new SelectResultValue(Lists.newArrayList(resultIter)) + ); + } + }; + } + + @Override + public Sequence> mergeSequences(Sequence>> seqOfSequences) + { + return new MergeSequence>(getOrdering(), seqOfSequences); + } + }; + } + + @Override + public QueryRunner> preMergeQueryDecoration(QueryRunner> runner) + { + return new IntervalChunkingQueryRunner>(runner, config.getChunkPeriod()); + } + + public Ordering> getOrdering() + { + return Ordering.natural(); + } +} diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java b/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java new file mode 100644 index 00000000000..7e0c4905fd9 --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java @@ -0,0 +1,106 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.google.inject.Inject; +import com.metamx.common.ISE; +import com.metamx.common.guava.Sequence; +import io.druid.query.ChainedExecutionQueryRunner; +import io.druid.query.Query; +import io.druid.query.QueryConfig; +import io.druid.query.QueryRunner; +import io.druid.query.QueryRunnerFactory; +import io.druid.query.QueryToolChest; +import io.druid.query.Result; +import io.druid.segment.Segment; +import io.druid.segment.StorageAdapter; + +import java.util.concurrent.ExecutorService; + +/** + */ +public class SelectQueryRunnerFactory + implements QueryRunnerFactory, SelectQuery> +{ + public static SelectQueryRunnerFactory create() + { + return new SelectQueryRunnerFactory( + new SelectQueryQueryToolChest(new QueryConfig()), + new SelectQueryEngine() + ); + } + + private final SelectQueryQueryToolChest toolChest; + private final SelectQueryEngine engine; + + @Inject + public SelectQueryRunnerFactory( + SelectQueryQueryToolChest toolChest, + SelectQueryEngine engine + ) + { + this.toolChest = toolChest; + this.engine = engine; + } + + @Override + public QueryRunner> createRunner(final Segment segment) + { + return new SelectQueryRunner(engine, segment.asStorageAdapter()); + } + + @Override + public QueryRunner> mergeRunners( + ExecutorService queryExecutor, Iterable>> queryRunners + ) + { + return new ChainedExecutionQueryRunner>( + queryExecutor, toolChest.getOrdering(), queryRunners + ); + } + + @Override + public QueryToolChest, SelectQuery> getToolchest() + { + return toolChest; + } + + private static class SelectQueryRunner implements QueryRunner> + { + private final SelectQueryEngine engine; + private final StorageAdapter adapter; + + private SelectQueryRunner(SelectQueryEngine engine, StorageAdapter adapter) + { + this.engine = engine; + this.adapter = adapter; + } + + @Override + public Sequence> run(Query> input) + { + if (!(input instanceof SelectQuery)) { + throw new ISE("Got a [%s] which isn't a %s", input.getClass(), SelectQuery.class); + } + + return engine.process((SelectQuery) input, adapter); + } + } +} diff --git a/processing/src/main/java/io/druid/query/select/SelectResultValue.java b/processing/src/main/java/io/druid/query/select/SelectResultValue.java new file mode 100644 index 00000000000..a78c74ba123 --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/SelectResultValue.java @@ -0,0 +1,76 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.metamx.common.ISE; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + */ +public class SelectResultValue implements Iterable +{ + private final List value; + + @JsonCreator + public SelectResultValue( + List value + ) + { + this.value = (value == null) ? Lists.newArrayList() : Lists.transform( + value, + new Function() + { + @Override + public EventHolder apply(Object input) + { + if (input instanceof EventHolder) { + return (EventHolder) input; + } else if (input instanceof Map) { + long timestamp = (long) ((Map) input).remove("timestamp"); + EventHolder retVal = new EventHolder(timestamp); + retVal.putAll((Map) input); + return retVal; + } else { + throw new ISE("Unknown type : %s", input.getClass()); + } + } + } + ); + } + + @JsonValue + public List getBaseObject() + { + return value; + } + + @Override + public Iterator iterator() + { + return value.iterator(); + } +} diff --git a/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java b/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java new file mode 100644 index 00000000000..a6f41e4a4c8 --- /dev/null +++ b/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java @@ -0,0 +1,85 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.google.common.collect.Lists; +import com.google.common.collect.MinMaxPriorityQueue; +import com.google.common.primitives.Longs; +import io.druid.query.Result; +import org.joda.time.DateTime; + +import java.util.Comparator; +import java.util.List; + +/** + */ +public class SelectResultValueBuilder +{ + private static final Comparator comparator = new Comparator() + { + @Override + public int compare(EventHolder o1, EventHolder o2) + { + return Longs.compare(o1.getTimestamp(), o2.getTimestamp()); + } + }; + + private final DateTime timestamp; + + private MinMaxPriorityQueue pQueue = null; + + public SelectResultValueBuilder( + DateTime timestamp, + int threshold + ) + { + this.timestamp = timestamp; + + instantiatePQueue(threshold, comparator); + } + + public SelectResultValueBuilder addEntry( + EventHolder event + ) + { + pQueue.add(event); + + return this; + } + + public Result build() + { + // Pull out top aggregated values + List values = Lists.newArrayListWithCapacity(pQueue.size()); + while (!pQueue.isEmpty()) { + values.add(pQueue.remove()); + } + + return new Result( + timestamp, + new SelectResultValue(values) + ); + } + + private void instantiatePQueue(int threshold, final Comparator comparator) + { + this.pQueue = MinMaxPriorityQueue.orderedBy(comparator).maximumSize(threshold).create(); + } +} diff --git a/processing/src/main/java/io/druid/segment/ColumnSelectorFactory.java b/processing/src/main/java/io/druid/segment/ColumnSelectorFactory.java index 1e640591499..318f93af9a3 100644 --- a/processing/src/main/java/io/druid/segment/ColumnSelectorFactory.java +++ b/processing/src/main/java/io/druid/segment/ColumnSelectorFactory.java @@ -24,6 +24,7 @@ package io.druid.segment; */ public interface ColumnSelectorFactory { + public TimestampColumnSelector makeTimestampColumnSelector(); public DimensionSelector makeDimensionSelector(String dimensionName); public FloatColumnSelector makeFloatColumnSelector(String columnName); public ObjectColumnSelector makeObjectColumnSelector(String columnName); diff --git a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java index 443c9cb353f..4e06e4abd4c 100644 --- a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java @@ -23,6 +23,7 @@ import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.google.common.io.Closeables; import com.metamx.common.collect.MoreIterators; import com.metamx.common.guava.FunctionalIterable; @@ -77,6 +78,12 @@ public class QueryableIndexStorageAdapter implements StorageAdapter return index.getAvailableDimensions(); } + @Override + public Iterable getAvailableMetrics() + { + return Sets.difference(Sets.newHashSet(index.getColumnNames()), Sets.newHashSet(index.getAvailableDimensions())); + } + @Override public int getDimensionCardinality(String dimension) { @@ -236,6 +243,19 @@ public class QueryableIndexStorageAdapter implements StorageAdapter cursorOffset = initOffset.clone(); } + @Override + public TimestampColumnSelector makeTimestampColumnSelector() + { + return new TimestampColumnSelector() + { + @Override + public long getTimestamp() + { + return index.getTimeColumn().getGenericColumn().getLongSingleValueRow(cursorOffset.getOffset()); + } + }; + } + @Override public DimensionSelector makeDimensionSelector(String dimension) { @@ -620,6 +640,19 @@ public class QueryableIndexStorageAdapter implements StorageAdapter currRow = initRow; } + @Override + public TimestampColumnSelector makeTimestampColumnSelector() + { + return new TimestampColumnSelector() + { + @Override + public long getTimestamp() + { + return timestamps.getLongSingleValueRow(currRow); + } + }; + } + @Override public DimensionSelector makeDimensionSelector(String dimension) { diff --git a/processing/src/main/java/io/druid/segment/StorageAdapter.java b/processing/src/main/java/io/druid/segment/StorageAdapter.java index ef6ed7c6bd6..a799e3ed6f6 100644 --- a/processing/src/main/java/io/druid/segment/StorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/StorageAdapter.java @@ -17,7 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.segment;import io.druid.segment.data.Indexed; +package io.druid.segment; + +import io.druid.segment.data.Indexed; import org.joda.time.DateTime; import org.joda.time.Interval; @@ -28,6 +30,7 @@ public interface StorageAdapter extends CursorFactory public String getSegmentIdentifier(); public Interval getInterval(); public Indexed getAvailableDimensions(); + public Iterable getAvailableMetrics(); public int getDimensionCardinality(String dimension); public DateTime getMinTime(); public DateTime getMaxTime(); diff --git a/processing/src/main/java/io/druid/segment/TimestampColumnSelector.java b/processing/src/main/java/io/druid/segment/TimestampColumnSelector.java new file mode 100644 index 00000000000..dc36f6a4064 --- /dev/null +++ b/processing/src/main/java/io/druid/segment/TimestampColumnSelector.java @@ -0,0 +1,27 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.segment; + +/** + */ +public interface TimestampColumnSelector +{ + public long getTimestamp(); +} diff --git a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndex.java b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndex.java index 4f6c6016088..c13a1c3c588 100644 --- a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndex.java +++ b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndex.java @@ -45,6 +45,7 @@ import io.druid.segment.ColumnSelectorFactory; import io.druid.segment.DimensionSelector; import io.druid.segment.FloatColumnSelector; import io.druid.segment.ObjectColumnSelector; +import io.druid.segment.TimestampColumnSelector; import io.druid.segment.serde.ComplexMetricExtractor; import io.druid.segment.serde.ComplexMetricSerde; import io.druid.segment.serde.ComplexMetrics; @@ -197,6 +198,19 @@ public class IncrementalIndex implements Iterable aggs[i] = agg.factorize( new ColumnSelectorFactory() { + @Override + public TimestampColumnSelector makeTimestampColumnSelector() + { + return new TimestampColumnSelector() + { + @Override + public long getTimestamp() + { + return in.getTimestampFromEpoch(); + } + }; + } + @Override public FloatColumnSelector makeFloatColumnSelector(String columnName) { diff --git a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java index fee9e728cb1..b4d6460dba2 100644 --- a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java @@ -1,3 +1,4 @@ + /* * Druid - a distributed column store. * Copyright (C) 2012, 2013 Metamarkets Group Inc. @@ -38,6 +39,7 @@ import io.druid.segment.DimensionSelector; import io.druid.segment.FloatColumnSelector; import io.druid.segment.ObjectColumnSelector; import io.druid.segment.StorageAdapter; +import io.druid.segment.TimestampColumnSelector; import io.druid.segment.data.Indexed; import io.druid.segment.data.IndexedInts; import io.druid.segment.data.ListIndexed; @@ -87,6 +89,12 @@ public class IncrementalIndexStorageAdapter implements StorageAdapter return new ListIndexed(index.getDimensions(), String.class); } + @Override + public Iterable getAvailableMetrics() + { + return index.getMetricNames(); + } + @Override public int getDimensionCardinality(String dimension) { @@ -237,6 +245,19 @@ public class IncrementalIndexStorageAdapter implements StorageAdapter } + @Override + public TimestampColumnSelector makeTimestampColumnSelector() + { + return new TimestampColumnSelector() + { + @Override + public long getTimestamp() + { + return currEntry.getKey().getTimestamp(); + } + }; + } + @Override public DimensionSelector makeDimensionSelector(String dimension) { diff --git a/publications/whitepaper/README.md b/publications/whitepaper/README.md new file mode 100644 index 00000000000..44025ab1dbf --- /dev/null +++ b/publications/whitepaper/README.md @@ -0,0 +1,4 @@ +Download [MacTeX](http://tug.org/mactex/) +```bash +make +``` diff --git a/publications/whitepaper/vldb.cls b/publications/whitepaper/acm_proc_article-sp.cls similarity index 65% rename from publications/whitepaper/vldb.cls rename to publications/whitepaper/acm_proc_article-sp.cls index 7ff7547658b..e908c0443c3 100644 --- a/publications/whitepaper/vldb.cls +++ b/publications/whitepaper/acm_proc_article-sp.cls @@ -1,1400 +1,1656 @@ -% VLDB.CLS - Version 1.8c -% -% based on: -% SIG-ALTERNATE.CLS - VERSION 1.8 -% "COMPATIBLE" WITH THE "ACM_PROC_ARTICLE-SP.CLS" V2.7SP -% Gerald Murray July 26th. 2005 -% -% ---- Start of 'updates' ---- -% -% Allowance made to switch default fonts between those systems using -% METAFONT and those using 'Type 1' or 'Truetype' fonts. -% See LINE NUMBER 252 for details. -% Also provided for enumerated/annotated Corollaries 'surrounded' by -% enumerated Theorems (line 841). -% Gerry November 11th. 1999 -% -% Made the Permission Statement / Conference Info / Copyright Info -% 'user definable' in the source .tex file OR automatic if -% not specified. -% -% Georgia fixed bug in sub-sub-section numbering in paragraphs (July 29th. 2002) -% JS/GM fix to vertical spacing before Proofs (July 30th. 2002) -% -% Footnotes inside table cells using \minipage (Oct. 2002) -% -% Enforced 'US letter' page size and updated PVLDB copyright (UR, Oct 2010) -% -% Made the file template-able, so vol/no information can be dynmacally generated. (AhmetSacan, Sep 2012) -% -% Added widow line penalties. (AhmetSacan, Sep 2012) -% ---- End of 'updates' ---- -% -\def\fileversion{v1.8c} % for VLDB's and ACM's tracking purposes -\def\filedate{July 26, 2005} % Gerry Murray's tracking data -\def\docdate {Tuesday 26th. July 2005} % Gerry Murray (with deltas to doc} -\usepackage[pdftex,letterpaper]{geometry} % fixed to US letter size for output (since version 1.8c - UR 2010) -\usepackage{epsfig} -\usepackage{amssymb} -\usepackage{amsmath} -\usepackage{amsfonts} -% -% VLDB DOCUMENT STYLE -% based on ACM's sig-alternate.cls, modified 31 Oct 2010 for PVLDB, -% with VLDB-specific copyright notice and fixed US letter paper size. -% -% SIG-ALTERNATE DOCUMENT STYLE -% G.K.M. Tobin August-October 1999 -% adapted from ARTICLE document style by Ken Traub, Olin Shivers -% also using elements of esub2acm.cls -% HEAVILY MODIFIED, SUBSEQUENTLY, BY GERRY MURRAY 2000 -% ARTICLE DOCUMENT STYLE -- Released 16 March 1988 -% for LaTeX version 2.09 -% Copyright (C) 1988 by Leslie Lamport -% -% -%%% sig-alternate.cls is an 'ALTERNATE' document style for producing -%%% two-column camera-ready pages for ACM conferences. -%%% THIS FILE DOES NOT STRICTLY ADHERE TO THE SIGS (BOARD-ENDORSED) -%%% PROCEEDINGS STYLE. It has been designed to produce a 'tighter' -%%% paper in response to concerns over page budgets. -%%% The main features of this style are: -%%% -%%% 1) Two columns. -%%% 2) Side and top margins of 4.5pc, bottom margin of 6pc, column gutter of -%%% 2pc, hence columns are 20pc wide and 55.5pc tall. (6pc =3D 1in, approx) -%%% 3) First page has title information, and an extra 6pc of space at the -%%% bottom of the first column for the ACM copyright notice. -%%% 4) Text is 9pt on 10pt baselines; titles (except main) are 9pt bold. -%%% 5) US letter paper size (since v1.8c) -%%% -%%% -%%% There are a few restrictions you must observe: -%%% -%%% 1) You cannot change the font size; ACM wants you to use 9pt. -%%% 3) You must start your paper with the \maketitle command. Prior to the -%%% \maketitle you must have \title and \author commands. If you have a -%%% \date command it will be ignored; no date appears on the paper, since -%%% the proceedings will have a date on the front cover. -%%% 4) Marginal paragraphs, tables of contents, lists of figures and tables, -%%% and page headings are all forbidden. -%%% 5) The `figure' environment will produce a figure one column wide; if you -%%% want one that is two columns wide, use `figure*'. -%%% -% -%%% Copyright Space: -%%% This style automatically reserves 1" blank space at the bottom of page 1/ -%%% column 1. This space can optionally be filled with some text using the -%%% \toappear{...} command. If used, this command must be BEFORE the \maketitle -%%% command. If this command is defined AND [preprint] is on, then the -%%% space is filled with the {...} text (at the bottom); otherwise, it is -%%% blank. If you use \toappearbox{...} instead of \toappear{...} then a -%%% box will be drawn around the text (if [preprint] is on). -%%% -%%% A typical usage looks like this: -%%% \toappear{To appear in the Ninth AES Conference on Medievil Lithuanian -%%% Embalming Technique, June 1991, Alfaretta, Georgia.} -%%% This will be included in the preprint, and left out of the conference -%%% version. -%%% -%%% WARNING: -%%% Some dvi-ps converters heuristically allow chars to drift from their -%%% true positions a few pixels. This may be noticeable with the 9pt sans-serif -%%% bold font used for section headers. -%%% You may turn this hackery off via the -e option: -%%% dvips -e 0 foo.dvi >foo.ps -%%% -\typeout{Document Class 'vldb' - based on 'sig-alternate' <26th. July '05>. Modified by G.K.M. Tobin/Gerry Murray} -\typeout{Based in part upon document Style `acmconf' <22 May 89>. Hacked 4/91 by} -\typeout{shivers@cs.cmu.edu, 4/93 by theobald@cs.mcgill.ca} -\typeout{Excerpts were taken from (Journal Style) 'esub2acm.cls'.} -\typeout{****** Bugs/comments/suggestions/technicalities to Gerry Murray -- murray@hq.acm.org ******} -\typeout{Questions on the style, SIGS policies, etc. to Adrienne Griscti griscti@acm.org} -\oddsidemargin 4.5pc -\evensidemargin 4.5pc -\advance\oddsidemargin by -1in % Correct for LaTeX gratuitousness -\advance\evensidemargin by -1in % Correct for LaTeX gratuitousness -\marginparwidth 0pt % Margin pars are not allowed. -\marginparsep 11pt % Horizontal space between outer margin and - % marginal note - - % Top of page: -\topmargin 4.5pc % Nominal distance from top of page to top of - % box containing running head. -\advance\topmargin by -1in % Correct for LaTeX gratuitousness -\headheight 0pt % Height of box containing running head. -\headsep 0pt % Space between running head and text. - % Bottom of page: -\footskip 30pt % Distance from baseline of box containing foot - % to baseline of last line of text. -\@ifundefined{footheight}{\newdimen\footheight}{}% this is for LaTeX2e -\footheight 12pt % Height of box containing running foot. - -%% Must redefine the top margin so there's room for headers and -%% page numbers if you are using the preprint option. Footers -%% are OK as is. Olin. -\advance\topmargin by -37pt % Leave 37pt above text for headers -\headheight 12pt % Height of box containing running head. -\headsep 25pt % Space between running head and text. - -\textheight 666pt % 9 1/4 column height -\textwidth 42pc % Width of text line. - % For two-column mode: -\columnsep 2pc % Space between columns -\columnseprule 0pt % Width of rule between columns. -\hfuzz 1pt % Allow some variation in column width, otherwise it's - % too hard to typeset in narrow columns. - -\footnotesep 5.6pt % Height of strut placed at the beginning of every - % footnote =3D height of normal \footnotesize strut, - % so no extra space between footnotes. - -\skip\footins 8.1pt plus 4pt minus 2pt % Space between last line of text and - % top of first footnote. -\floatsep 11pt plus 2pt minus 2pt % Space between adjacent floats moved - % to top or bottom of text page. -\textfloatsep 18pt plus 2pt minus 4pt % Space between main text and floats - % at top or bottom of page. -\intextsep 11pt plus 2pt minus 2pt % Space between in-text figures and - % text. -\@ifundefined{@maxsep}{\newdimen\@maxsep}{}% this is for LaTeX2e -\@maxsep 18pt % The maximum of \floatsep, - % \textfloatsep and \intextsep (minus - % the stretch and shrink). -\dblfloatsep 11pt plus 2pt minus 2pt % Same as \floatsep for double-column - % figures in two-column mode. -\dbltextfloatsep 18pt plus 2pt minus 4pt% \textfloatsep for double-column - % floats. -\@ifundefined{@dblmaxsep}{\newdimen\@dblmaxsep}{}% this is for LaTeX2e -\@dblmaxsep 18pt % The maximum of \dblfloatsep and - % \dbltexfloatsep. -\@fptop 0pt plus 1fil % Stretch at top of float page/column. (Must be - % 0pt plus ...) -\@fpsep 8pt plus 2fil % Space between floats on float page/column. -\@fpbot 0pt plus 1fil % Stretch at bottom of float page/column. (Must be - % 0pt plus ... ) -\@dblfptop 0pt plus 1fil % Stretch at top of float page. (Must be 0pt plus ...) -\@dblfpsep 8pt plus 2fil % Space between floats on float page. -\@dblfpbot 0pt plus 1fil % Stretch at bottom of float page. (Must be - % 0pt plus ... ) -\marginparpush 5pt % Minimum vertical separation between two marginal - % notes. - -\parskip 0pt plus 1pt % Extra vertical space between paragraphs. -\parindent 9pt % GM July 2000 / was 0pt - width of paragraph indentation. -\partopsep 2pt plus 1pt minus 1pt% Extra vertical space, in addition to - % \parskip and \topsep, added when user - % leaves blank line before environment. - -\@lowpenalty 51 % Produced by \nopagebreak[1] or \nolinebreak[1] -\@medpenalty 151 % Produced by \nopagebreak[2] or \nolinebreak[2] -\@highpenalty 301 % Produced by \nopagebreak[3] or \nolinebreak[3] - -\@beginparpenalty -\@lowpenalty % Before a list or paragraph environment. -\@endparpenalty -\@lowpenalty % After a list or paragraph environment. -\@itempenalty -\@lowpenalty % Between list items. - -% Try to prevent widow lines. -\clubpenalty=9996 -\widowpenalty=9999 -\brokenpenalty=4991 -\predisplaypenalty=10000 -\postdisplaypenalty=1549 -\displaywidowpenalty=1602 - -\@namedef{ds@10pt}{\@latexerr{The `10pt' option is not allowed in the `acmconf' - document style.}\@eha} -\@namedef{ds@11pt}{\@latexerr{The `11pt' option is not allowed in the `acmconf' - document style.}\@eha} -\@namedef{ds@12pt}{\@latexerr{The `12pt' option is not allowed in the `acmconf' - document style.}\@eha} - -\@options - -\lineskip 2pt % \lineskip is 1pt for all font sizes. -\normallineskip 2pt -\def\baselinestretch{1} - -\abovedisplayskip 9pt plus2pt minus4.5pt% -\belowdisplayskip \abovedisplayskip -\abovedisplayshortskip \z@ plus3pt% -\belowdisplayshortskip 5.4pt plus3pt minus3pt% -\let\@listi\@listI % Setting of \@listi added 9 Jun 87 - -\def\small{\@setsize\small{9pt}\viiipt\@viiipt -\abovedisplayskip 7.6pt plus 3pt minus 4pt% -\belowdisplayskip \abovedisplayskip -\abovedisplayshortskip \z@ plus2pt% -\belowdisplayshortskip 3.6pt plus2pt minus 2pt -\def\@listi{\leftmargin\leftmargini %% Added 22 Dec 87 -\topsep 4pt plus 2pt minus 2pt\parsep 2pt plus 1pt minus 1pt -\itemsep \parsep}} - -\def\footnotesize{\@setsize\footnotesize{9pt}\ixpt\@ixpt -\abovedisplayskip 6.4pt plus 2pt minus 4pt% -\belowdisplayskip \abovedisplayskip -\abovedisplayshortskip \z@ plus 1pt% -\belowdisplayshortskip 2.7pt plus 1pt minus 2pt -\def\@listi{\leftmargin\leftmargini %% Added 22 Dec 87 -\topsep 3pt plus 1pt minus 1pt\parsep 2pt plus 1pt minus 1pt -\itemsep \parsep}} - -\newcount\aucount -\newcount\originalaucount -\newdimen\auwidth -\auwidth=\textwidth -\newdimen\auskip -\newcount\auskipcount -\newdimen\auskip -\global\auskip=1pc -\newdimen\allauboxes -\allauboxes=\auwidth -\newtoks\addauthors -\newcount\addauflag -\global\addauflag=0 %Haven't shown additional authors yet - -\newtoks\subtitletext -\gdef\subtitle#1{\subtitletext={#1}} - -\gdef\additionalauthors#1{\addauthors={#1}} - -\gdef\numberofauthors#1{\global\aucount=#1 -\ifnum\aucount>3\global\originalaucount=\aucount \global\aucount=3\fi %g} -\global\auskipcount=\aucount\global\advance\auskipcount by 1 -\global\multiply\auskipcount by 2 -\global\multiply\auskip by \auskipcount -\global\advance\auwidth by -\auskip -\global\divide\auwidth by \aucount} - -% \and was modified to count the number of authors. GKMT 12 Aug 1999 -\def\alignauthor{% % \begin{tabular} -\end{tabular}% - \begin{tabular}[t]{p{\auwidth}}\centering}% - -% *** NOTE *** NOTE *** NOTE *** NOTE *** -% If you have 'font problems' then you may need -% to change these, e.g. 'arialb' instead of "arialbd". -% Gerry Murray 11/11/1999 -% *** OR ** comment out block A and activate block B or vice versa. -% ********************************************** -% -% -- Start of block A -- (Type 1 or Truetype fonts) -%\newfont{\secfnt}{timesbd at 12pt} % was timenrb originally - now is timesbd -%\newfont{\secit}{timesbi at 12pt} %13 Jan 00 gkmt -%\newfont{\subsecfnt}{timesi at 11pt} % was timenrri originally - now is timesi -%\newfont{\subsecit}{timesbi at 11pt} % 13 Jan 00 gkmt -- was times changed to timesbi gm 2/4/2000 -% % because "normal" is italic, "italic" is Roman -%\newfont{\ttlfnt}{arialbd at 18pt} % was arialb originally - now is arialbd -%\newfont{\ttlit}{arialbi at 18pt} % 13 Jan 00 gkmt -%\newfont{\subttlfnt}{arial at 14pt} % was arialr originally - now is arial -%\newfont{\subttlit}{ariali at 14pt} % 13 Jan 00 gkmt -%\newfont{\subttlbf}{arialbd at 14pt} % 13 Jan 00 gkmt -%\newfont{\aufnt}{arial at 12pt} % was arialr originally - now is arial -%\newfont{\auit}{ariali at 12pt} % 13 Jan 00 gkmt -%\newfont{\affaddr}{arial at 10pt} % was arialr originally - now is arial -%\newfont{\affaddrit}{ariali at 10pt} %13 Jan 00 gkmt -%\newfont{\eaddfnt}{arial at 12pt} % was arialr originally - now is arial -%\newfont{\ixpt}{times at 9pt} % was timenrr originally - now is times -%\newfont{\confname}{timesi at 8pt} % was timenrri - now is timesi -%\newfont{\crnotice}{times at 8pt} % was timenrr originally - now is times -%\newfont{\ninept}{times at 9pt} % was timenrr originally - now is times - -% ********************************************* -% -- End of block A -- -% -% -% -- Start of block B -- METAFONT -% +++++++++++++++++++++++++++++++++++++++++++++ -% Next (default) block for those using Metafont -% Gerry Murray 11/11/1999 -% *** THIS BLOCK FOR THOSE USING METAFONT ***** -% ********************************************* -\newfont{\secfnt}{ptmb at 12pt} -\newfont{\secit}{ptmbi at 12pt} %13 Jan 00 gkmt -\newfont{\subsecfnt}{ptmri at 11pt} -\newfont{\subsecit}{ptmbi at 11pt} % 13 Jan 00 gkmt -- was ptmr changed to ptmbi gm 2/4/2000 - % because "normal" is italic, "italic" is Roman -\newfont{\ttlfnt}{phvb at 18pt} -\newfont{\ttlit}{phvbo at 18pt} % GM 2/4/2000 -\newfont{\subttlfnt}{phvr at 14pt} -\newfont{\subttlit}{phvro at 14pt} % GM 2/4/2000 -\newfont{\subttlbf}{phvb at 14pt} % 13 Jan 00 gkmt -\newfont{\aufnt}{phvr at 12pt} -\newfont{\auit}{phvro at 12pt} % GM 2/4/2000 -\newfont{\affaddr}{phvr at 10pt} -\newfont{\affaddrit}{phvro at 10pt} % GM 2/4/2000 -\newfont{\eaddfnt}{phvr at 12pt} -\newfont{\ixpt}{ptmr at 9pt} -\newfont{\confname}{ptmri at 8pt} -\newfont{\crnotice}{ptmr at 8pt} -\newfont{\ninept}{ptmr at 9pt} -% +++++++++++++++++++++++++++++++++++++++++++++ -% -- End of block B -- - - -\def\email#1{{{\eaddfnt{\vskip 4pt#1}}}} - -\def\addauthorsection{\ifnum\originalaucount>3 - \section{Additional Authors}\the\addauthors - \fi} - -\newcount\savesection -\newcount\sectioncntr -\global\sectioncntr=1 - -\setcounter{secnumdepth}{3} - -\def\appendix{\par -\section*{APPENDIX} -\setcounter{section}{0} - \setcounter{subsection}{0} - \def\thesection{\Alph{section}} } - -\leftmargini 22.5pt -\leftmarginii 19.8pt % > \labelsep + width of '(m)' -\leftmarginiii 16.8pt % > \labelsep + width of 'vii.' -\leftmarginiv 15.3pt % > \labelsep + width of 'M.' -\leftmarginv 9pt -\leftmarginvi 9pt - -\leftmargin\leftmargini -\labelsep 4.5pt -\labelwidth\leftmargini\advance\labelwidth-\labelsep - -\def\@listI{\leftmargin\leftmargini \parsep 3.6pt plus 2pt minus 1pt% -\topsep 7.2pt plus 2pt minus 4pt% -\itemsep 3.6pt plus 2pt minus 1pt} - -\let\@listi\@listI -\@listi - -\def\@listii{\leftmargin\leftmarginii - \labelwidth\leftmarginii\advance\labelwidth-\labelsep - \topsep 3.6pt plus 2pt minus 1pt - \parsep 1.8pt plus 0.9pt minus 0.9pt - \itemsep \parsep} - -\def\@listiii{\leftmargin\leftmarginiii - \labelwidth\leftmarginiii\advance\labelwidth-\labelsep - \topsep 1.8pt plus 0.9pt minus 0.9pt - \parsep \z@ \partopsep 1pt plus 0pt minus 1pt - \itemsep \topsep} - -\def\@listiv{\leftmargin\leftmarginiv - \labelwidth\leftmarginiv\advance\labelwidth-\labelsep} - -\def\@listv{\leftmargin\leftmarginv - \labelwidth\leftmarginv\advance\labelwidth-\labelsep} - -\def\@listvi{\leftmargin\leftmarginvi - \labelwidth\leftmarginvi\advance\labelwidth-\labelsep} - -\def\labelenumi{\theenumi.} -\def\theenumi{\arabic{enumi}} - -\def\labelenumii{(\theenumii)} -\def\theenumii{\alph{enumii}} -\def\p@enumii{\theenumi} - -\def\labelenumiii{\theenumiii.} -\def\theenumiii{\roman{enumiii}} -\def\p@enumiii{\theenumi(\theenumii)} - -\def\labelenumiv{\theenumiv.} -\def\theenumiv{\Alph{enumiv}} -\def\p@enumiv{\p@enumiii\theenumiii} - -\def\labelitemi{$\bullet$} -\def\labelitemii{\bf --} -\def\labelitemiii{$\ast$} -\def\labelitemiv{$\cdot$} - -\def\verse{\let\\=\@centercr - \list{}{\itemsep\z@ \itemindent -1.5em\listparindent \itemindent - \rightmargin\leftmargin\advance\leftmargin 1.5em}\item[]} -\let\endverse\endlist - -\def\quotation{\list{}{\listparindent 1.5em - \itemindent\listparindent - \rightmargin\leftmargin \parsep 0pt plus 1pt}\item[]} -\let\endquotation=\endlist - -\def\quote{\list{}{\rightmargin\leftmargin}\item[]} -\let\endquote=\endlist - -\def\descriptionlabel#1{\hspace\labelsep \bf #1} -\def\description{\list{}{\labelwidth\z@ \itemindent-\leftmargin - \let\makelabel\descriptionlabel}} - -\let\enddescription\endlist - -\def\theequation{\arabic{equation}} - -\arraycolsep 4.5pt % Half the space between columns in an array environment. -\tabcolsep 5.4pt % Half the space between columns in a tabular environment. -\arrayrulewidth .4pt % Width of rules in array and tabular environment. -\doublerulesep 1.8pt % Space between adjacent rules in array or tabular env. - -\tabbingsep \labelsep % Space used by the \' command. (See LaTeX manual.) - -\skip\@mpfootins =\skip\footins - -\fboxsep =2.7pt % Space left between box and text by \fbox and \framebox. -\fboxrule =.4pt % Width of rules in box made by \fbox and \framebox. - -\def\thepart{\Roman{part}} % Roman numeral part numbers. -\def\thesection {\arabic{section}} -\def\thesubsection {\thesection.\arabic{subsection}} -%\def\thesubsubsection {\thesubsection.\arabic{subsubsection}} % GM 7/30/2002 -%\def\theparagraph {\thesubsubsection.\arabic{paragraph}} % GM 7/30/2002 -\def\thesubparagraph {\theparagraph.\arabic{subparagraph}} - -\def\@pnumwidth{1.55em} -\def\@tocrmarg {2.55em} -\def\@dotsep{4.5} -\setcounter{tocdepth}{3} - -\def\tableofcontents{\@latexerr{\tableofcontents: Tables of contents are not - allowed in the `acmconf' document style.}\@eha} - -\def\l@part#1#2{\addpenalty{\@secpenalty} - \addvspace{2.25em plus 1pt} % space above part line - \begingroup - \@tempdima 3em % width of box holding part number, used by - \parindent \z@ \rightskip \@pnumwidth %% \numberline - \parfillskip -\@pnumwidth - {\large \bf % set line in \large boldface - \leavevmode % TeX command to enter horizontal mode. - #1\hfil \hbox to\@pnumwidth{\hss #2}}\par - \nobreak % Never break after part entry - \endgroup} - -\def\l@section#1#2{\addpenalty{\@secpenalty} % good place for page break - \addvspace{1.0em plus 1pt} % space above toc entry - \@tempdima 1.5em % width of box holding section number - \begingroup - \parindent \z@ \rightskip \@pnumwidth - \parfillskip -\@pnumwidth - \bf % Boldface. - \leavevmode % TeX command to enter horizontal mode. - \advance\leftskip\@tempdima %% added 5 Feb 88 to conform to - \hskip -\leftskip %% 25 Jan 88 change to \numberline - #1\nobreak\hfil \nobreak\hbox to\@pnumwidth{\hss #2}\par - \endgroup} - - -\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -\def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} -\def\l@subparagraph{\@dottedtocline{5}{10em}{5em}} - -\def\listoffigures{\@latexerr{\listoffigures: Lists of figures are not - allowed in the `acmconf' document style.}\@eha} - -\def\l@figure{\@dottedtocline{1}{1.5em}{2.3em}} - -\def\listoftables{\@latexerr{\listoftables: Lists of tables are not - allowed in the `acmconf' document style.}\@eha} -\let\l@table\l@figure - -\def\footnoterule{\kern-3\p@ - \hrule width .4\columnwidth - \kern 2.6\p@} % The \hrule has default height of .4pt . -% ------ -\long\def\@makefntext#1{\noindent -%\hbox to .5em{\hss$^{\@thefnmark}$}#1} % original -\hbox to .5em{\hss\textsuperscript{\@thefnmark}}#1} % C. Clifton / GM Oct. 2nd. 2002 -% ------- - -\long\def\@maketntext#1{\noindent -#1} - -\long\def\@maketitlenotetext#1#2{\noindent - \hbox to 1.8em{\hss$^{#1}$}#2} - -\setcounter{topnumber}{2} -\def\topfraction{.7} -\setcounter{bottomnumber}{1} -\def\bottomfraction{.3} -\setcounter{totalnumber}{3} -\def\textfraction{.2} -\def\floatpagefraction{.5} -\setcounter{dbltopnumber}{2} -\def\dbltopfraction{.7} -\def\dblfloatpagefraction{.5} - -% -\long\def\@makecaption#1#2{ - \vskip \baselineskip - \setbox\@tempboxa\hbox{\textbf{#1: #2}} - \ifdim \wd\@tempboxa >\hsize % IF longer than one line: - \textbf{#1: #2}\par % THEN set as ordinary paragraph. - \else % ELSE center. - \hbox to\hsize{\hfil\box\@tempboxa\hfil}\par - \fi} - -% - -\long\def\@makecaption#1#2{ - \vskip 10pt - \setbox\@tempboxa\hbox{\textbf{#1: #2}} - \ifdim \wd\@tempboxa >\hsize % IF longer than one line: - \textbf{#1: #2}\par % THEN set as ordinary paragraph. - \else % ELSE center. - \hbox to\hsize{\hfil\box\@tempboxa\hfil} - \fi} - -\@ifundefined{figure}{\newcounter {figure}} % this is for LaTeX2e - -\def\fps@figure{tbp} -\def\ftype@figure{1} -\def\ext@figure{lof} -\def\fnum@figure{Figure \thefigure} -\def\figure{\@float{figure}} -\let\endfigure\end@float -\@namedef{figure*}{\@dblfloat{figure}} -\@namedef{endfigure*}{\end@dblfloat} - -\@ifundefined{table}{\newcounter {table}} % this is for LaTeX2e - -\def\fps@table{tbp} -\def\ftype@table{2} -\def\ext@table{lot} -\def\fnum@table{Table \thetable} -\def\table{\@float{table}} -\let\endtable\end@float -\@namedef{table*}{\@dblfloat{table}} -\@namedef{endtable*}{\end@dblfloat} - -\newtoks\titleboxnotes -\newcount\titleboxnoteflag - -\def\maketitle{\par - \begingroup - \def\thefootnote{\fnsymbol{footnote}} - \def\@makefnmark{\hbox - to 0pt{$^{\@thefnmark}$\hss}} - \twocolumn[\@maketitle] -\@thanks - \endgroup - \setcounter{footnote}{0} - \let\maketitle\relax - \let\@maketitle\relax - \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\gdef\@subtitle{}\let\thanks\relax - \@copyrightspace} - -%% CHANGES ON NEXT LINES -\newif\if@ll % to record which version of LaTeX is in use - -\expandafter\ifx\csname LaTeXe\endcsname\relax % LaTeX2.09 is used -\else% LaTeX2e is used, so set ll to true -\global\@lltrue -\fi - -\if@ll - \NeedsTeXFormat{LaTeX2e} - \ProvidesClass{vldb} [2010/10/19 - V1.8b - based on sig-alternate V1.8 - based on acmproc.cls V1.3 ] - \RequirePackage{latexsym}% QUERY: are these two really needed? - \let\dooptions\ProcessOptions -\else - \let\dooptions\@options -\fi -%% END CHANGES - -\def\@height{height} -\def\@width{width} -\def\@minus{minus} -\def\@plus{plus} -\def\hb@xt@{\hbox to} -\newif\if@faircopy -\@faircopyfalse -\def\ds@faircopy{\@faircopytrue} - -\def\ds@preprint{\@faircopyfalse} - -\@twosidetrue -\@mparswitchtrue -\def\ds@draft{\overfullrule 5\p@} -%% CHANGE ON NEXT LINE -\dooptions - -\lineskip \p@ -\normallineskip \p@ -\def\baselinestretch{1} -\def\@ptsize{0} %needed for amssymbols.sty - -%% CHANGES ON NEXT LINES -\if@ll% allow use of old-style font change commands in LaTeX2e -\@maxdepth\maxdepth -% -\DeclareOldFontCommand{\rm}{\ninept\rmfamily}{\mathrm} -\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} -\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} -\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} -\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} -\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} -\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} -\DeclareRobustCommand*{\cal}{\@fontswitch{\relax}{\mathcal}} -\DeclareRobustCommand*{\mit}{\@fontswitch{\relax}{\mathnormal}} -\fi -% -\if@ll - \renewcommand{\rmdefault}{cmr} % was 'ttm' -% Note! I have also found 'mvr' to work ESPECIALLY well. -% Gerry - October 1999 -% You may need to change your LV1times.fd file so that sc is -% mapped to cmcsc - -for smallcaps -- that is if you decide -% to change {cmr} to {times} above. (Not recommended) - \renewcommand{\@ptsize}{} - \renewcommand{\normalsize}{% - \@setfontsize\normalsize\@ixpt{10.5\p@}%\ninept% - \abovedisplayskip 6\p@ \@plus2\p@ \@minus\p@ - \belowdisplayskip \abovedisplayskip - \abovedisplayshortskip 6\p@ \@minus 3\p@ - \belowdisplayshortskip 6\p@ \@minus 3\p@ - \let\@listi\@listI - } -\else - \def\@normalsize{%changed next to 9 from 10 - \@setsize\normalsize{9\p@}\ixpt\@ixpt - \abovedisplayskip 6\p@ \@plus2\p@ \@minus\p@ - \belowdisplayskip \abovedisplayskip - \abovedisplayshortskip 6\p@ \@minus 3\p@ - \belowdisplayshortskip 6\p@ \@minus 3\p@ - \let\@listi\@listI - }% -\fi -\if@ll - \newcommand\scriptsize{\@setfontsize\scriptsize\@viipt{8\p@}} - \newcommand\tiny{\@setfontsize\tiny\@vpt{6\p@}} - \newcommand\large{\@setfontsize\large\@xiipt{14\p@}} - \newcommand\Large{\@setfontsize\Large\@xivpt{18\p@}} - \newcommand\LARGE{\@setfontsize\LARGE\@xviipt{20\p@}} - \newcommand\huge{\@setfontsize\huge\@xxpt{25\p@}} - \newcommand\Huge{\@setfontsize\Huge\@xxvpt{30\p@}} -\else - \def\scriptsize{\@setsize\scriptsize{8\p@}\viipt\@viipt} - \def\tiny{\@setsize\tiny{6\p@}\vpt\@vpt} - \def\large{\@setsize\large{14\p@}\xiipt\@xiipt} - \def\Large{\@setsize\Large{18\p@}\xivpt\@xivpt} - \def\LARGE{\@setsize\LARGE{20\p@}\xviipt\@xviipt} - \def\huge{\@setsize\huge{25\p@}\xxpt\@xxpt} - \def\Huge{\@setsize\Huge{30\p@}\xxvpt\@xxvpt} -\fi -\normalsize - -% make aubox hsize/number of authors up to 3, less gutter -% then showbox gutter showbox gutter showbox -- GKMT Aug 99 -\newbox\@acmtitlebox -\def\@maketitle{\newpage - \null - \setbox\@acmtitlebox\vbox{% -\baselineskip 20pt -\vskip 2em % Vertical space above title. - \begin{center} - {\ttlfnt \@title\par} % Title set in 18pt Helvetica (Arial) bold size. - \vskip 1.5em % Vertical space after title. -%This should be the subtitle. -{\subttlfnt \the\subtitletext\par}\vskip 1.25em%\fi - {\baselineskip 16pt\aufnt % each author set in \12 pt Arial, in a - \lineskip .5em % tabular environment - \begin{tabular}[t]{c}\@author - \end{tabular}\par} - \vskip 1.5em % Vertical space after author. - \end{center}} - \dimen0=\ht\@acmtitlebox - \advance\dimen0 by -12.75pc\relax % Increased space for title box -- KBT - \unvbox\@acmtitlebox - \ifdim\dimen0<0.0pt\relax\vskip-\dimen0\fi} - - -\newcount\titlenotecount -\global\titlenotecount=0 -\newtoks\tntoks -\newtoks\tntokstwo -\newtoks\tntoksthree -\newtoks\tntoksfour -\newtoks\tntoksfive - -\def\abstract{ -\ifnum\titlenotecount>0 % was =1 - \insert\footins{% - \reset@font\footnotesize - \interlinepenalty\interfootnotelinepenalty - \splittopskip\footnotesep - \splitmaxdepth \dp\strutbox \floatingpenalty \@MM - \hsize\columnwidth \@parboxrestore - \protected@edef\@currentlabel{% - }% - \color@begingroup -\ifnum\titlenotecount=1 - \@maketntext{% - \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\@finalstrut\strutbox}% -\fi -\ifnum\titlenotecount=2 - \@maketntext{% - \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\@finalstrut\strutbox}% -\fi -\ifnum\titlenotecount=3 - \@maketntext{% - \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\@finalstrut\strutbox}% -\fi -\ifnum\titlenotecount=4 - \@maketntext{% - \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\S$}\rule\z@\footnotesep\ignorespaces\the\tntoksfour\@finalstrut\strutbox}% -\fi -\ifnum\titlenotecount=5 - \@maketntext{% - \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\S$}\rule\z@\footnotesep\ignorespaces\the\tntoksfour\par\@finalstrut\strutbox}% -\@maketntext{% - \raisebox{4pt}{$\P$}\rule\z@\footnotesep\ignorespaces\the\tntoksfive\@finalstrut\strutbox}% -\fi - \color@endgroup} %g} -\fi -\setcounter{footnote}{0} -\section*{ABSTRACT}\normalsize%\ninept -} - -\def\endabstract{\if@twocolumn\else\endquotation\fi} - -\def\keywords{\if@twocolumn -\section*{Keywords} -\else \small -\quotation -\fi} - -\def\terms{\if@twocolumn -\section*{General Terms} -\else \small -\quotation -\fi} - -% -- Classification needs to be a bit smart due to optionals - Gerry/Georgia November 2nd. 1999 -\newcount\catcount -\global\catcount=1 - -\def\category#1#2#3{% -\ifnum\catcount=1 -\section*{Categories and Subject Descriptors} -\advance\catcount by 1\else{\unskip; }\fi - \@ifnextchar [{\@category{#1}{#2}{#3}}{\@category{#1}{#2}{#3}[]}% -} - -\def\@category#1#2#3[#4]{% - \begingroup - \let\and\relax - #1 [\textbf{#2}]% - \if!#4!% - \if!#3!\else : #3\fi - \else - :\space - \if!#3!\else #3\kern\z@---\hskip\z@\fi - \textit{#4}% - \fi - \endgroup -} -% - -%%% This section (written by KBT) handles the 1" box in the lower left -%%% corner of the left column of the first page by creating a picture, -%%% and inserting the predefined string at the bottom (with a negative -%%% displacement to offset the space allocated for a non-existent -%%% caption). -%%% -\newtoks\copyrightnotice -\def\ftype@copyrightbox{8} -\def\@copyrightspace{ -\@float{copyrightbox}[b] -\begin{center} -\setlength{\unitlength}{1pc} -\begin{picture}(20,6) %Space for copyright notice -\put(0,-0.95){\crnotice{\@toappear}} -\end{picture} -\end{center} -\end@float} - -\def\@toappear{} % Default setting blank - commands below change this. -\long\def\toappear#1{\def\@toappear{\parbox[b]{20pc}{\baselineskip 9pt#1}}} -\def\toappearbox#1{\def\@toappear{\raisebox{5pt}{\framebox[20pc]{\parbox[b]{19pc}{#1}}}}} - -\newtoks\conf -\newtoks\confinfo -\def\conferenceinfo#1#2{\global\conf={#1}\global\confinfo{#2}} - - -\def\marginpar{\@latexerr{The \marginpar command is not allowed in the - `acmconf' document style.}\@eha} - -\mark{{}{}} % Initializes TeX's marks - -\def\today{\ifcase\month\or - January\or February\or March\or April\or May\or June\or - July\or August\or September\or October\or November\or December\fi - \space\number\day, \number\year} - -\def\@begintheorem#1#2{% - \parskip 0pt % GM July 2000 (for tighter spacing) - \trivlist - \item[% - \hskip 10\p@ - \hskip \labelsep - {{\sc #1}\hskip 5\p@\relax#2.}% - ] - \it -} -\def\@opargbegintheorem#1#2#3{% - \parskip 0pt % GM July 2000 (for tighter spacing) - \trivlist - \item[% - \hskip 10\p@ - \hskip \labelsep - {\sc #1\ #2\ % This mod by Gerry to enumerate corollaries - \setbox\@tempboxa\hbox{(#3)} % and bracket the 'corollary title' - \ifdim \wd\@tempboxa>\z@ % and retain the correct numbering of e.g. theorems - \hskip 5\p@\relax % if they occur 'around' said corollaries. - \box\@tempboxa % Gerry - Nov. 1999. - \fi.}% - ] - \it -} -\newif\if@qeded -\global\@qededfalse - -% -- original -%\def\proof{% -% \vspace{-\parskip} % GM July 2000 (for tighter spacing) -% \global\@qededfalse -% \@ifnextchar[{\@xproof}{\@proof}% -%} -% -- end of original - -% (JSS) Fix for vertical spacing bug - Gerry Murray July 30th. 2002 -\def\proof{% -\vspace{-\lastskip}\vspace{-\parsep}\penalty-51% -\global\@qededfalse -\@ifnextchar[{\@xproof}{\@proof}% -} - -\def\endproof{% - \if@qeded\else\qed\fi - \endtrivlist -} -\def\@proof{% - \trivlist - \item[% - \hskip 10\p@ - \hskip \labelsep - {\sc Proof.}% - ] - \ignorespaces -} -\def\@xproof[#1]{% - \trivlist - \item[\hskip 10\p@\hskip \labelsep{\sc Proof #1.}]% - \ignorespaces -} -\def\qed{% - \unskip - \kern 10\p@ - \begingroup - \unitlength\p@ - \linethickness{.4\p@}% - \framebox(6,6){}% - \endgroup - \global\@qededtrue -} - -\def\newdef#1#2{% - \expandafter\@ifdefinable\csname #1\endcsname - {\@definecounter{#1}% - \expandafter\xdef\csname the#1\endcsname{\@thmcounter{#1}}% - \global\@namedef{#1}{\@defthm{#1}{#2}}% - \global\@namedef{end#1}{\@endtheorem}% - }% -} -\def\@defthm#1#2{% - \refstepcounter{#1}% - \@ifnextchar[{\@ydefthm{#1}{#2}}{\@xdefthm{#1}{#2}}% -} -\def\@xdefthm#1#2{% - \@begindef{#2}{\csname the#1\endcsname}% - \ignorespaces -} -\def\@ydefthm#1#2[#3]{% - \trivlist - \item[% - \hskip 10\p@ - \hskip \labelsep - {\it #2% - \savebox\@tempboxa{#3}% - \ifdim \wd\@tempboxa>\z@ - \ \box\@tempboxa - \fi.% - }]% - \ignorespaces -} -\def\@begindef#1#2{% - \trivlist - \item[% - \hskip 10\p@ - \hskip \labelsep - {\it #1\ \rm #2.}% - ]% -} -\def\theequation{\arabic{equation}} - -\newcounter{part} -\newcounter{section} -\newcounter{subsection}[section] -\newcounter{subsubsection}[subsection] -\newcounter{paragraph}[subsubsection] -\def\thepart{\Roman{part}} -\def\thesection{\arabic{section}} -\def\thesubsection{\thesection.\arabic{subsection}} -\def\thesubsubsection{\thesubsection.\arabic{subsubsection}} %removed \subsecfnt 29 July 2002 gkmt -\def\theparagraph{\thesubsubsection.\arabic{paragraph}} %removed \subsecfnt 29 July 2002 gkmt -\newif\if@uchead -\@ucheadfalse - -%% CHANGES: NEW NOTE -%% NOTE: OK to use old-style font commands below, since they were -%% suitably redefined for LaTeX2e -%% END CHANGES -\setcounter{secnumdepth}{3} -\def\part{% - \@startsection{part}{9}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@} - {4\p@}{\normalsize\@ucheadtrue}% -} -\def\section{% - \@startsection{section}{1}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@}% GM - {4\p@}{\baselineskip 14pt\secfnt\@ucheadtrue}% -} - -\def\subsection{% - \@startsection{subsection}{2}{\z@}{-8\p@ \@plus -2\p@ \@minus -\p@} - {4\p@}{\secfnt}% -} -\def\subsubsection{% - \@startsection{subsubsection}{3}{\z@}{-8\p@ \@plus -2\p@ \@minus -\p@}% - {4\p@}{\subsecfnt}% -} -\def\paragraph{% - \vskip 12pt\@startsection{paragraph}{3}{\z@}{6\p@ \@plus \p@}% - {-5\p@}{\subsecfnt}% -} -\let\@period=. -\def\@startsection#1#2#3#4#5#6{% - \if@noskipsec %gkmt, 11 aug 99 - \global\let\@period\@empty - \leavevmode - \global\let\@period.% - \fi - \par % - \@tempskipa #4\relax - \@afterindenttrue - \ifdim \@tempskipa <\z@ - \@tempskipa -\@tempskipa - \@afterindentfalse - \fi - \if@nobreak - \everypar{}% - \else - \addpenalty\@secpenalty - \addvspace\@tempskipa - \fi -\parskip=0pt % GM July 2000 (non numbered) section heads - \@ifstar - {\@ssect{#3}{#4}{#5}{#6}} - {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}% -} -\def\@sect#1#2#3#4#5#6[#7]#8{% - \ifnum #2>\c@secnumdepth - \let\@svsec\@empty - \else - \refstepcounter{#1}% - \edef\@svsec{% - \begingroup - %\ifnum#2>2 \noexpand\rm \fi % changed to next 29 July 2002 gkmt - \ifnum#2>2 \noexpand#6 \fi - \csname the#1\endcsname - \endgroup - \ifnum #2=1\relax .\fi - \hskip 1em - }% - \fi - \@tempskipa #5\relax - \ifdim \@tempskipa>\z@ - \begingroup - #6\relax - \@hangfrom{\hskip #3\relax\@svsec}% - \begingroup - \interlinepenalty \@M - \if@uchead - \uppercase{#8}% - \else - #8% - \fi - \par - \endgroup - \endgroup - \csname #1mark\endcsname{#7}% - \vskip -12pt %gkmt, 11 aug 99 and GM July 2000 (was -14) - numbered section head spacing -\addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - #7% - }% - \else - \def\@svsechd{% - #6% - \hskip #3\relax - \@svsec - \if@uchead - \uppercase{#8}% - \else - #8% - \fi - \csname #1mark\endcsname{#7}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - #7% - }% - }% - \fi - \@xsect{#5}\hskip 1pt - \par -} -\def\@xsect#1{% - \@tempskipa #1\relax - \ifdim \@tempskipa>\z@ - \par - \nobreak - \vskip \@tempskipa - \@afterheading - \else - \global\@nobreakfalse - \global\@noskipsectrue - \everypar{% - \if@noskipsec - \global\@noskipsecfalse - \clubpenalty\@M - \hskip -\parindent - \begingroup - \@svsechd - \@period - \endgroup - \unskip - \@tempskipa #1\relax - \hskip -\@tempskipa - \else - \clubpenalty \@clubpenalty - \everypar{}% - \fi - }% - \fi - \ignorespaces -} -\def\@trivlist{% - \@topsepadd\topsep - \if@noskipsec - \global\let\@period\@empty - \leavevmode - \global\let\@period.% - \fi - \ifvmode - \advance\@topsepadd\partopsep - \else - \unskip - \par - \fi - \if@inlabel - \@noparitemtrue - \@noparlisttrue - \else - \@noparlistfalse - \@topsep\@topsepadd - \fi - \advance\@topsep \parskip - \leftskip\z@skip - \rightskip\@rightskip - \parfillskip\@flushglue - \@setpar{\if@newlist\else{\@@par}\fi} - \global\@newlisttrue - \@outerparskip\parskip -} - -%%% Actually, 'abbrev' works just fine as the default -%%% Bibliography style. - -\typeout{Using 'Abbrev' bibliography style} -\newcommand\bibyear[2]{% - \unskip\quad\ignorespaces#1\unskip - \if#2..\quad \else \quad#2 \fi -} -\newcommand{\bibemph}[1]{{\em#1}} -\newcommand{\bibemphic}[1]{{\em#1\/}} -\newcommand{\bibsc}[1]{{\sc#1}} -\def\@normalcite{% - \def\@cite##1##2{[##1\if@tempswa , ##2\fi]}% -} -\def\@citeNB{% - \def\@cite##1##2{##1\if@tempswa , ##2\fi}% -} -\def\@citeRB{% - \def\@cite##1##2{##1\if@tempswa , ##2\fi]}% -} -\def\start@cite#1#2{% - \edef\citeauthoryear##1##2##3{% - ###1% - \ifnum#2=\z@ \else\ ###2\fi - }% - \ifnum#1=\thr@@ - \let\@@cite\@citeyear - \else - \let\@@cite\@citenormal - \fi - \@ifstar{\@citeNB\@@cite}{\@normalcite\@@cite}% -} -\def\cite{\start@cite23} -\def\citeNP{\cite*} -\def\citeA{\start@cite10} -\def\citeANP{\citeA*} -\def\shortcite{\start@cite23} -\def\shortciteNP{\shortcite*} -\def\shortciteA{\start@cite20} -\def\shortciteANP{\shortciteA*} -\def\citeyear{\start@cite30} -\def\citeyearNP{\citeyear*} -\def\citeN{% - \@citeRB - \def\citeauthoryear##1##2##3{##1\ [##3% - \def\reserved@a{##1}% - \def\citeauthoryear####1####2####3{% - \def\reserved@b{####1}% - \ifx\reserved@a\reserved@b - ####3% - \else - \errmessage{Package acmart Error: author mismatch - in \string\citeN^^J^^J% - See the acmart package documentation for explanation}% - \fi - }% - }% - \@ifstar\@citeyear\@citeyear -} -\def\shortciteN{% - \@citeRB - \def\citeauthoryear##1##2##3{##2\ [##3% - \def\reserved@a{##2}% - \def\citeauthoryear####1####2####3{% - \def\reserved@b{####2}% - \ifx\reserved@a\reserved@b - ####3% - \else - \errmessage{Package acmart Error: author mismatch - in \string\shortciteN^^J^^J% - See the acmart package documentation for explanation}% - \fi - }% - }% - \@ifstar\@citeyear\@citeyear % GM July 2000 -} -\def\@citenormal{% - \@ifnextchar [{\@tempswatrue\@citex;} - {\@tempswafalse\@citex,[]}% % GM July 2000 -} -\def\@citeyear{% - \@ifnextchar [{\@tempswatrue\@citex,}% - {\@tempswafalse\@citex,[]}% -} -\def\@citex#1[#2]#3{% - \let\@citea\@empty - \@cite{% - \@for\@citeb:=#3\do{% - \@citea - \def\@citea{#1 }% - \edef\@citeb{\expandafter\@iden\@citeb}% - \if@filesw - \immediate\write\@auxout{\string\citation{\@citeb}}% - \fi - \@ifundefined{b@\@citeb}{% - {\bf ?}% - \@warning{% - Citation `\@citeb' on page \thepage\space undefined% - }% - }% - {\csname b@\@citeb\endcsname}% - }% - }{#2}% -} -\let\@biblabel\@gobble -\newdimen\bibindent -\setcounter{enumi}{1} -\bibindent=0em -\def\thebibliography#1{% -\ifnum\addauflag=0\addauthorsection\global\addauflag=1\fi - \section[References]{% <=== OPTIONAL ARGUMENT ADDED HERE - {References} % was uppercased but this affects pdf bookmarks (SP/GM October 2004) - \vskip -9pt % GM July 2000 (for tighter spacing) - \@mkboth{{\refname}}{{\refname}}% - }% - \list{[\arabic{enumi}]}{% - \settowidth\labelwidth{[#1]}% - \leftmargin\labelwidth - \advance\leftmargin\labelsep - \advance\leftmargin\bibindent - \parsep=0pt\itemsep=1pt % GM July 2000 - \itemindent -\bibindent - \listparindent \itemindent - \usecounter{enumi} - }% - \let\newblock\@empty - \raggedright % GM July 2000 - \sloppy - \sfcode`\.=1000\relax -} - - -\gdef\balancecolumns -{\vfill\eject -\global\@colht=\textheight -\global\ht\@cclv=\textheight -} - -\newcount\colcntr -\global\colcntr=0 -\newbox\savebox - -\gdef \@makecol {% -\global\advance\colcntr by 1 -\ifnum\colcntr>2 \global\colcntr=1\fi - \ifvoid\footins - \setbox\@outputbox \box\@cclv - \else - \setbox\@outputbox \vbox{% -\boxmaxdepth \@maxdepth - \@tempdima\dp\@cclv - \unvbox \@cclv - \vskip-\@tempdima - \vskip \skip\footins - \color@begingroup - \normalcolor - \footnoterule - \unvbox \footins - \color@endgroup - }% - \fi - \xdef\@freelist{\@freelist\@midlist}% - \global \let \@midlist \@empty - \@combinefloats - \ifvbox\@kludgeins - \@makespecialcolbox - \else - \setbox\@outputbox \vbox to\@colht {% -\@texttop - \dimen@ \dp\@outputbox - \unvbox \@outputbox - \vskip -\dimen@ - \@textbottom - }% - \fi - \global \maxdepth \@maxdepth -} -\def\titlenote{\@ifnextchar[\@xtitlenote{\stepcounter\@mpfn -\global\advance\titlenotecount by 1 -\ifnum\titlenotecount=1 - \raisebox{9pt}{$\ast$} -\fi -\ifnum\titlenotecount=2 - \raisebox{9pt}{$\dagger$} -\fi -\ifnum\titlenotecount=3 - \raisebox{9pt}{$\ddagger$} -\fi -\ifnum\titlenotecount=4 -\raisebox{9pt}{$\S$} -\fi -\ifnum\titlenotecount=5 -\raisebox{9pt}{$\P$} -\fi - \@titlenotetext -}} - -\long\def\@titlenotetext#1{\insert\footins{% -\ifnum\titlenotecount=1\global\tntoks={#1}\fi -\ifnum\titlenotecount=2\global\tntokstwo={#1}\fi -\ifnum\titlenotecount=3\global\tntoksthree={#1}\fi -\ifnum\titlenotecount=4\global\tntoksfour={#1}\fi -\ifnum\titlenotecount=5\global\tntoksfive={#1}\fi - \reset@font\footnotesize - \interlinepenalty\interfootnotelinepenalty - \splittopskip\footnotesep - \splitmaxdepth \dp\strutbox \floatingpenalty \@MM - \hsize\columnwidth \@parboxrestore - \protected@edef\@currentlabel{% - }% - \color@begingroup - \color@endgroup}} - -%%%%%%%%%%%%%%%%%%%%%%%%% -\ps@plain -\baselineskip=11pt -\let\thepage\relax % For NO page numbers - GM Nov. 30th. 1999 and July 2000 -\def\setpagenumber#1{\global\setcounter{page}{#1}} -\pagenumbering{arabic} % Arabic page numbers GM July 2000 -\twocolumn % Double column. -\flushbottom % Even bottom -- alas, does not balance columns at end of document -\pagestyle{plain} - -% Need Copyright Year and Copyright Data to be user definable (in .tex file). -% Gerry Nov. 30th. 1999 -\newtoks\copyrtyr -\newtoks\acmcopyr -\newtoks\boilerplate -\global\acmcopyr={X-XXXXX-XX-X/XX/XX} % Default - 5/11/2001 *** Gerry -\global\copyrtyr={200X} % Default - 3/3/2003 *** Gerry -\def\CopyrightYear#1{\global\copyrtyr{#1}} -\def\crdata#1{\global\acmcopyr{#1}} -\def\permission#1{\global\boilerplate{#1}} -% -%\global\boilerplate={Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee.} -%\newtoks\copyrightetc -%\global\copyrightetc{Copyright \the\copyrtyr\ ACM \the\acmcopyr\ ...\$5.00} - -\global\boilerplate={Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Articles from this volume were invited to present their results at The 38th International Conference on Very Large Data Bases, August 26th - 31st 2013, Riva del Garda, Trento, Italy. } - -\global\conf{Proceedings of the VLDB Endowment,} -\global\confinfo{Vol. 6, No. XXX} -\newtoks\copyrightetc -\global\copyrightetc{Copyright 2011 VLDB Endowment 2150-8097/11/11... \$ 10.00} - -%ahmetsacan, 20111024: disabled showing conference name and Vol/Issue/Month. We now stamp this on the papers ourselves. -%\toappear{\the\boilerplate\par -%{\confname{\the\conf}} \the\confinfo\par \the\copyrightetc. -%} -% -%% End of vldb.cls -- V1.8c - 05/15/2011 -- -%% Ahmet Sacan -- December 2011 (volume, issue, and dates are dynamically updated) -%% Uwe Roehm -- Oct-Dec 2010 & Jan-Apr 2011 -%% Gerry Murray -- Wednesday July 26th. 2005 +% ACM_PROC_ARTICLE-SP.CLS - VERSION 3.2SP +% COMPATIBLE WITH THE "SIG-ALTERNATE" V2.4 +% Gerald Murray - April 22nd. 2009 +% +% ---- Start of 'updates' ---- +% +% April 22nd. 2009 - Fixed 'Natbib' incompatibility problem - Gerry +% April 22nd. 2009 - Fixed 'Babel' incompatibility problem - Gerry +% April 22nd. 2009 - Inserted various bug-fixes and improvements - Gerry +% +% To produce Type 1 fonts in the document plus allow for 'normal LaTeX accenting' in the critical areas; +% title, author block, section-heads, etc. etc. +% i.e. the whole purpose of this version update is to NOT resort to 'inelegant accent patches'. +% After much research, three extra .sty packages were added to the the tail (ae, aecompl, aeguill) to solve, +% in particular, the accenting problem(s). We _could_ ask authors (via instructions/sample file) to 'include' these in +% the source .tex file - in the preamble - but if everything is already provided ('behind the scenes' - embedded IN the .cls) +% then this is less work for authors and also makes everything appear 'vanilla'. +% NOTE: all 'patchwork accenting" has been commented out (here) and is no longer 'used' in the sample .tex file (either). +% Gerry June 2007 +% +% Rule widths changed to .5, author count (>6) fixed, roll-back for Type 3 problem. Gerry March 20th. 2007 +% Changes made to 'modernize' the fontnames but esp. for MikTeX users V2.4/2.5 - Nov. 30th. 2006 +% Updated the \email definition to allow for its use inside of 'shared affiliations' - Nov. 30th. 2006 +% Fixed the 'section number depth value' - Nov. 30th. 2006 +% +% Footnotes inside table cells using \minipage (Oct. 2002) +% Georgia fixed bug in sub-sub-section numbering in paragraphs (July 29th. 2002) +% JS/GM fix to vertical spacing before Proofs (July 30th. 2002) +% +% Allowance made to switch default fonts between those systems using +% normal/modern font names and those using 'Type 1' or 'Truetype' fonts. +% See LINE NUMBER 269 for details. +% Also provided for enumerated/annotated Corollaries 'surrounded' by +% enumerated Theorems (line 844). +% Gerry November 11th. 1999 +% +% This 'sp' version does NOT produce the permission block. +% +% Major change in January 2000 was to include a "blank line" in between +% new paragraphs. This involved major changes to the, then, acmproc-sp.cls 1.0SP +% file, precipitating a 'new' name: "acm_proc_article-sp.cls" V2.01SP. +% +% ---- End of 'updates' ---- +% +\def\fileversion{V3.2SP} % for ACM's tracking purposes +\def\filedate{April 22, 2009} % Gerry Murray's tracking data +\def\docdate {Wednesday 22nd. April 2009} % Gerry Murray (with deltas to doc} +\usepackage{epsfig} +\usepackage{amssymb} +\usepackage{amsmath} +\usepackage{amsfonts} +% Need this for accents in Arial/Helvetica +%\usepackage[T1]{fontenc} % Gerry March 12, 2007 - causes Type 3 problems (body text) +%\usepackage{textcomp} +% +% ACM_PROC_ARTICLE-SP DOCUMENT STYLE +% G.K.M. Tobin August-October 1999 +% adapted from ARTICLE document style by Ken Traub, Olin Shivers +% also using elements of esub2acm.cls +% LATEST REVISION V3.2SP - APRIL 2009 +% ARTICLE DOCUMENT STYLE -- Released 16 March 1988 +% for LaTeX version 2.09 +% Copyright (C) 1988 by Leslie Lamport +% +% +%%% ACM_PROC_ARTICLE-SP is a document style for producing two-column camera-ready pages for +%%% ACM conferences, according to ACM specifications. The main features of +%%% this style are: +%%% +%%% 1) Two columns. +%%% 2) Side and top margins of 4.5pc, bottom margin of 6pc, column gutter of +%%% 2pc, hence columns are 20pc wide and 55.5pc tall. (6pc =3D 1in, approx) +%%% 3) First page has title information, and an extra 6pc of space at the +%%% bottom of the first column for the ACM copyright notice. +%%% 4) Text is 9pt on 10pt baselines; titles (except main) are 9pt bold. +%%% +%%% +%%% There are a few restrictions you must observe: +%%% +%%% 1) You cannot change the font size; ACM wants you to use 9pt. +%%% 3) You must start your paper with the \maketitle command. Prior to the +%%% \maketitle you must have \title and \author commands. If you have a +%%% \date command it will be ignored; no date appears on the paper, since +%%% the proceedings will have a date on the front cover. +%%% 4) Marginal paragraphs, tables of contents, lists of figures and tables, +%%% and page headings are all forbidden. +%%% 5) The `figure' environment will produce a figure one column wide; if you +%%% want one that is two columns wide, use `figure*'. +%%% +% +%%% Copyright Space: +%%% This style automatically leaves 1" blank space at the bottom of page 1/ +%%% column 1. This space can optionally be filled with some text using the +%%% \toappear{...} command. If used, this command must be BEFORE the \maketitle +%%% command. If this command is defined AND [preprint] is on, then the +%%% space is filled with the {...} text (at the bottom); otherwise, it is +%%% blank. If you use \toappearbox{...} instead of \toappear{...} then a +%%% box will be drawn around the text (if [preprint] is on). +%%% +%%% A typical usage looks like this: +%%% \toappear{To appear in the Ninth AES Conference on Medievil Lithuanian +%%% Embalming Technique, June 1991, Alfaretta, Georgia.} +%%% This will be included in the preprint, and left out of the conference +%%% version. +%%% +%%% WARNING: +%%% Some dvi-ps converters heuristically allow chars to drift from their +%%% true positions a few pixels. This may be noticeable with the 9pt sans-serif +%%% bold font used for section headers. +%%% You may turn this hackery off via the -e option: +%%% dvips -e 0 foo.dvi >foo.ps +%%% +\typeout{Document Class 'acm_proc_article-sp' <22nd. April '09>. Modified by G.K.M. Tobin} +\typeout{Based in part upon document Style `acmconf' <22 May 89>. Hacked 4/91 by} +\typeout{shivers@cs.cmu.edu, 4/93 by theobald@cs.mcgill.ca} +\typeout{Excerpts were taken from (Journal Style) 'esub2acm.cls'.} +\typeout{****** Bugs/comments/suggestions to Gerry Murray -- murray@hq.acm.org ******} + +\oddsidemargin 4.5pc +\evensidemargin 4.5pc +\advance\oddsidemargin by -1in % Correct for LaTeX gratuitousness +\advance\evensidemargin by -1in % Correct for LaTeX gratuitousness +\marginparwidth 0pt % Margin pars are not allowed. +\marginparsep 11pt % Horizontal space between outer margin and + % marginal note + + % Top of page: +\topmargin 4.5pc % Nominal distance from top of page to top of + % box containing running head. +\advance\topmargin by -1in % Correct for LaTeX gratuitousness +\headheight 0pt % Height of box containing running head. +\headsep 0pt % Space between running head and text. + % Bottom of page: +\footskip 30pt % Distance from baseline of box containing foot + % to baseline of last line of text. +\@ifundefined{footheight}{\newdimen\footheight}{}% this is for LaTeX2e +\footheight 12pt % Height of box containing running foot. + + +%% Must redefine the top margin so there's room for headers and +%% page numbers if you are using the preprint option. Footers +%% are OK as is. Olin. +\advance\topmargin by -37pt % Leave 37pt above text for headers +\headheight 12pt % Height of box containing running head. +\headsep 25pt % Space between running head and text. + +\textheight 666pt % 9 1/4 column height +\textwidth 42pc % Width of text line. + % For two-column mode: +\columnsep 2pc % Space between columns +\columnseprule 0pt % Width of rule between columns. +\hfuzz 1pt % Allow some variation in column width, otherwise it's + % too hard to typeset in narrow columns. + +\footnotesep 5.6pt % Height of strut placed at the beginning of every + % footnote =3D height of normal \footnotesize strut, + % so no extra space between footnotes. + +\skip\footins 8.1pt plus 4pt minus 2pt % Space between last line of text and + % top of first footnote. +\floatsep 11pt plus 2pt minus 2pt % Space between adjacent floats moved + % to top or bottom of text page. +\textfloatsep 18pt plus 2pt minus 4pt % Space between main text and floats + % at top or bottom of page. +\intextsep 11pt plus 2pt minus 2pt % Space between in-text figures and + % text. +\@ifundefined{@maxsep}{\newdimen\@maxsep}{}% this is for LaTeX2e +\@maxsep 18pt % The maximum of \floatsep, + % \textfloatsep and \intextsep (minus + % the stretch and shrink). +\dblfloatsep 11pt plus 2pt minus 2pt % Same as \floatsep for double-column + % figures in two-column mode. +\dbltextfloatsep 18pt plus 2pt minus 4pt% \textfloatsep for double-column + % floats. +\@ifundefined{@dblmaxsep}{\newdimen\@dblmaxsep}{}% this is for LaTeX2e +\@dblmaxsep 18pt % The maximum of \dblfloatsep and + % \dbltexfloatsep. +\@fptop 0pt plus 1fil % Stretch at top of float page/column. (Must be + % 0pt plus ...) +\@fpsep 8pt plus 2fil % Space between floats on float page/column. +\@fpbot 0pt plus 1fil % Stretch at bottom of float page/column. (Must be + % 0pt plus ... ) +\@dblfptop 0pt plus 1fil % Stretch at top of float page. (Must be 0pt plus ...) +\@dblfpsep 8pt plus 2fil % Space between floats on float page. +\@dblfpbot 0pt plus 1fil % Stretch at bottom of float page. (Must be + % 0pt plus ... ) +\marginparpush 5pt % Minimum vertical separation between two marginal + % notes. + +\parskip 0pt % Extra vertical space between paragraphs. + % Set to 0pt outside sections, to keep section heads + % uniformly spaced. The value of parskip is set + % to leading value _within_ sections. + % 12 Jan 2000 gkmt +\parindent 0pt % Width of paragraph indentation. +\partopsep 2pt plus 1pt minus 1pt% Extra vertical space, in addition to + % \parskip and \topsep, added when user + % leaves blank line before environment. + +\@lowpenalty 51 % Produced by \nopagebreak[1] or \nolinebreak[1] +\@medpenalty 151 % Produced by \nopagebreak[2] or \nolinebreak[2] +\@highpenalty 301 % Produced by \nopagebreak[3] or \nolinebreak[3] + +\@beginparpenalty -\@lowpenalty % Before a list or paragraph environment. +\@endparpenalty -\@lowpenalty % After a list or paragraph environment. +\@itempenalty -\@lowpenalty % Between list items. + +%\@namedef{ds@10pt}{\@latexerr{The `10pt' option is not allowed in the `acmconf' +\@namedef{ds@10pt}{\ClassError{The `10pt' option is not allowed in the `acmconf' % January 2008 + document style.}\@eha} +%\@namedef{ds@11pt}{\@latexerr{The `11pt' option is not allowed in the `acmconf' +\@namedef{ds@11pt}{\ClassError{The `11pt' option is not allowed in the `acmconf' % January 2008 + document style.}\@eha} +%\@namedef{ds@12pt}{\@latexerr{The `12pt' option is not allowed in the `acmconf' +\@namedef{ds@12pt}{\ClassError{The `12pt' option is not allowed in the `acmconf' % January 2008 + document style.}\@eha} + +\@options + +\lineskip 2pt % \lineskip is 1pt for all font sizes. +\normallineskip 2pt +\def\baselinestretch{1} + +\abovedisplayskip 9pt plus2pt minus4.5pt% +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip \z@ plus3pt% +\belowdisplayshortskip 5.4pt plus3pt minus3pt% +\let\@listi\@listI % Setting of \@listi added 9 Jun 87 + +\def\small{\@setsize\small{9pt}\viiipt\@viiipt +\abovedisplayskip 7.6pt plus 3pt minus 4pt% +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip \z@ plus2pt% +\belowdisplayshortskip 3.6pt plus2pt minus 2pt +\def\@listi{\leftmargin\leftmargini %% Added 22 Dec 87 +\topsep 4pt plus 2pt minus 2pt\parsep 2pt plus 1pt minus 1pt +\itemsep \parsep}} + +\def\footnotesize{\@setsize\footnotesize{9pt}\ixpt\@ixpt +\abovedisplayskip 6.4pt plus 2pt minus 4pt% +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip \z@ plus 1pt% +\belowdisplayshortskip 2.7pt plus 1pt minus 2pt +\def\@listi{\leftmargin\leftmargini %% Added 22 Dec 87 +\topsep 3pt plus 1pt minus 1pt\parsep 2pt plus 1pt minus 1pt +\itemsep \parsep}} + +\newcount\aucount +\newcount\originalaucount +\newdimen\auwidth +\auwidth 130pc +\newdimen\auskip +\newcount\auskipcount +\newdimen\auskip +\global\auskip=1pc +\newdimen\allauboxes +\allauboxes=\auwidth +\newtoks\addauthors +\newcount\addauflag +\global\addauflag=0 %Haven't shown additional authors yet + +\newtoks\subtitletext +\gdef\subtitle#1{\subtitletext={#1}} + +\gdef\additionalauthors#1{\addauthors={#1}} + +\gdef\numberofauthors#1{\global\aucount=#1 +\ifnum\aucount>3\global\originalaucount=\aucount \global\aucount=3\fi %g} % 3 OK - Gerry March 2007 +\global\auskipcount=\aucount\global\advance\auskipcount by 1 +\global\multiply\auskipcount by 2 +\global\multiply\auskip by \auskipcount +\global\advance\auwidth by -\auskip +\global\divide\auwidth by \aucount} + +% \and was modified to count the number of authors. GKMT 12 Aug 1999 +\def\alignauthor{% % \begin{tabular} +\end{tabular}% + \begin{tabular}[t]{p{\auwidth}}\centering}% + + +% *** NOTE *** NOTE *** NOTE *** NOTE *** +% If you have 'font problems' then you may need +% to change these, e.g. 'arialb' instead of "arialbd". +% Gerry Murray 11/11/1999 +% *** OR ** comment out block A and activate block B or vice versa. +% ********************************************** +% +% -- Start of block A -- (Type 1 or Truetype fonts) +%\newfont{\secfnt}{timesbd at 12pt} % was timenrb originally - now is timesbd +%\newfont{\secit}{timesbi at 12pt} %13 Jan 00 gkmt +%\newfont{\subsecfnt}{timesi at 11pt} % was timenrri originally - now is timesi +%\newfont{\subsecit}{timesbi at 11pt} % 13 Jan 00 gkmt -- was times changed to timesbi gm 2/4/2000 +% % because "normal" is italic, "italic" is Roman +%\newfont{\ttlfnt}{arialbd at 18pt} % was arialb originally - now is arialbd +%\newfont{\ttlit}{arialbi at 18pt} % 13 Jan 00 gkmt +%\newfont{\subttlfnt}{arial at 14pt} % was arialr originally - now is arial +%\newfont{\subttlit}{ariali at 14pt} % 13 Jan 00 gkmt +%\newfont{\subttlbf}{arialbd at 14pt} % 13 Jan 00 gkmt +%\newfont{\aufnt}{arial at 12pt} % was arialr originally - now is arial +%\newfont{\auit}{ariali at 12pt} % 13 Jan 00 gkmt +%\newfont{\affaddr}{arial at 10pt} % was arialr originally - now is arial +%\newfont{\affaddrit}{ariali at 10pt} %13 Jan 00 gkmt +%\newfont{\eaddfnt}{arial at 12pt} % was arialr originally - now is arial +%\newfont{\ixpt}{times at 9pt} % was timenrr originally - now is times +%\newfont{\confname}{timesi at 8pt} % was timenrri - now is timesi +%\newfont{\crnotice}{times at 8pt} % was timenrr originally - now is times +%\newfont{\ninept}{times at 9pt} % was timenrr originally - now is times +% ********************************************* +% -- End of block A -- +% +% +% -- Start of block B -- UPDATED FONT NAMES +% ********************************************* +% Gerry Murray 11/30/2006 +% ********************************************* +\newfont{\secfnt}{ptmb8t at 12pt} +\newfont{\secit}{ptmbi8t at 12pt} %13 Jan 00 gkmt +\newfont{\subsecfnt}{ptmri8t at 11pt} +\newfont{\subsecit}{ptmbi8t at 11pt} % +\newfont{\ttlfnt}{phvb8t at 18pt} +\newfont{\ttlit}{phvbo8t at 18pt} % GM 2/4/2000 +\newfont{\subttlfnt}{phvr8t at 14pt} +\newfont{\subttlit}{phvro8t at 14pt} % GM 2/4/2000 +\newfont{\subttlbf}{phvb8t at 14pt} % 13 Jan 00 gkmt +\newfont{\aufnt}{phvr8t at 12pt} +\newfont{\auit}{phvro8t at 12pt} % GM 2/4/2000 +\newfont{\affaddr}{phvr8t at 10pt} +\newfont{\affaddrit}{phvro8t at 10pt} % GM 2/4/2000 +\newfont{\eaddfnt}{phvr8t at 12pt} +\newfont{\ixpt}{ptmr8t at 9pt} +\newfont{\confname}{ptmri8t at 8pt} +\newfont{\crnotice}{ptmr8t at 8pt} +\newfont{\ninept}{ptmr8t at 9pt} +% +++++++++++++++++++++++++++++++++++++++++++++ +% -- End of block B -- + +%\def\email#1{{{\eaddfnt{\vskip 4pt#1}}}} +% If we have an email, inside a "shared affiliation" then we need the following instead +\def\email#1{{{\eaddfnt{\par #1}}}} % revised - GM - 11/30/2006 + +\def\addauthorsection{\ifnum\originalaucount>6 % was 3 - Gerry March 2007 + \section{Additional Authors}\the\addauthors + \fi} + +\newcount\savesection +\newcount\sectioncntr +\global\sectioncntr=1 + +\setcounter{secnumdepth}{3} + +\def\appendix{\par +\section*{APPENDIX} +\setcounter{section}{0} + \setcounter{subsection}{0} + \def\thesection{\Alph{section}} } + + +\leftmargini 22.5pt +\leftmarginii 19.8pt % > \labelsep + width of '(m)' +\leftmarginiii 16.8pt % > \labelsep + width of 'vii.' +\leftmarginiv 15.3pt % > \labelsep + width of 'M.' +\leftmarginv 9pt +\leftmarginvi 9pt + +\leftmargin\leftmargini +\labelsep 4.5pt +\labelwidth\leftmargini\advance\labelwidth-\labelsep + +\def\@listI{\leftmargin\leftmargini \parsep 3.6pt plus 2pt minus 1pt% +\topsep 7.2pt plus 2pt minus 4pt% +\itemsep 3.6pt plus 2pt minus 1pt} + +\let\@listi\@listI +\@listi + +\def\@listii{\leftmargin\leftmarginii + \labelwidth\leftmarginii\advance\labelwidth-\labelsep + \topsep 3.6pt plus 2pt minus 1pt + \parsep 1.8pt plus 0.9pt minus 0.9pt + \itemsep \parsep} + +\def\@listiii{\leftmargin\leftmarginiii + \labelwidth\leftmarginiii\advance\labelwidth-\labelsep + \topsep 1.8pt plus 0.9pt minus 0.9pt + \parsep \z@ \partopsep 1pt plus 0pt minus 1pt + \itemsep \topsep} + +\def\@listiv{\leftmargin\leftmarginiv + \labelwidth\leftmarginiv\advance\labelwidth-\labelsep} + +\def\@listv{\leftmargin\leftmarginv + \labelwidth\leftmarginv\advance\labelwidth-\labelsep} + +\def\@listvi{\leftmargin\leftmarginvi + \labelwidth\leftmarginvi\advance\labelwidth-\labelsep} + +\def\labelenumi{\theenumi.} +\def\theenumi{\arabic{enumi}} + +\def\labelenumii{(\theenumii)} +\def\theenumii{\alph{enumii}} +\def\p@enumii{\theenumi} + +\def\labelenumiii{\theenumiii.} +\def\theenumiii{\roman{enumiii}} +\def\p@enumiii{\theenumi(\theenumii)} + +\def\labelenumiv{\theenumiv.} +\def\theenumiv{\Alph{enumiv}} +\def\p@enumiv{\p@enumiii\theenumiii} + +\def\labelitemi{$\bullet$} +\def\labelitemii{\bf --} +\def\labelitemiii{$\ast$} +\def\labelitemiv{$\cdot$} + +\def\verse{\let\\=\@centercr + \list{}{\itemsep\z@ \itemindent -1.5em\listparindent \itemindent + \rightmargin\leftmargin\advance\leftmargin 1.5em}\item[]} +\let\endverse\endlist + +\def\quotation{\list{}{\listparindent 1.5em + \itemindent\listparindent + \rightmargin\leftmargin \parsep 0pt plus 1pt}\item[]} +\let\endquotation=\endlist + +\def\quote{\list{}{\rightmargin\leftmargin}\item[]} +\let\endquote=\endlist + +\def\descriptionlabel#1{\hspace\labelsep \bf #1} +\def\description{\list{}{\labelwidth\z@ \itemindent-\leftmargin + \let\makelabel\descriptionlabel}} + +\let\enddescription\endlist + +\def\theequation{\arabic{equation}} + +\arraycolsep 4.5pt % Half the space between columns in an array environment. +\tabcolsep 5.4pt % Half the space between columns in a tabular environment. +\arrayrulewidth .5pt % Width of rules in array and tabular environment. % (was .4) updated Gerry March 20 2007 +\doublerulesep 1.8pt % Space between adjacent rules in array or tabular env. + +\tabbingsep \labelsep % Space used by the \' command. (See LaTeX manual.) + +\skip\@mpfootins =\skip\footins + +\fboxsep =2.7pt % Space left between box and text by \fbox and \framebox. +\fboxrule =.5pt % Width of rules in box made by \fbox and \framebox. % (was .4) updated Gerry March 20 2007 + +\def\thepart{\Roman{part}} % Roman numeral part numbers. +\def\thesection {\arabic{section}} +\def\thesubsection {\thesection.\arabic{subsection}} +%\def\thesubsubsection {\thesubsection.\arabic{subsubsection}} % GM 7/30/2002 +%\def\theparagraph {\thesubsubsection.\arabic{paragraph}} % GM 7/30/2002 +\def\thesubparagraph {\theparagraph.\arabic{subparagraph}} + +\def\@pnumwidth{1.55em} +\def\@tocrmarg {2.55em} +\def\@dotsep{4.5} +\setcounter{tocdepth}{3} + +%\def\tableofcontents{\@latexerr{\tableofcontents: Tables of contents are not +% allowed in the `acmconf' document style.}\@eha} + +\def\tableofcontents{\ClassError{% + \string\tableofcontents\space is not allowed in the `acmconf' document % January 2008 + style}\@eha} + +\def\l@part#1#2{\addpenalty{\@secpenalty} + \addvspace{2.25em plus 1pt} % space above part line + \begingroup + \@tempdima 3em % width of box holding part number, used by + \parindent \z@ \rightskip \@pnumwidth %% \numberline + \parfillskip -\@pnumwidth + {\large \bf % set line in \large boldface + \leavevmode % TeX command to enter horizontal mode. + #1\hfil \hbox to\@pnumwidth{\hss #2}}\par + \nobreak % Never break after part entry + \endgroup} + +\def\l@section#1#2{\addpenalty{\@secpenalty} % good place for page break + \addvspace{1.0em plus 1pt} % space above toc entry + \@tempdima 1.5em % width of box holding section number + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \bf % Boldface. + \leavevmode % TeX command to enter horizontal mode. + \advance\leftskip\@tempdima %% added 5 Feb 88 to conform to + \hskip -\leftskip %% 25 Jan 88 change to \numberline + #1\nobreak\hfil \nobreak\hbox to\@pnumwidth{\hss #2}\par + \endgroup} + + +\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} +\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} +\def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} +\def\l@subparagraph{\@dottedtocline{5}{10em}{5em}} + +%\def\listoffigures{\@latexerr{\listoffigures: Lists of figures are not +% allowed in the `acmconf' document style.}\@eha} + +\def\listoffigures{\ClassError{% + \string\listoffigures\space is not allowed in the `acmconf' document % January 2008 + style}\@eha} + +\def\l@figure{\@dottedtocline{1}{1.5em}{2.3em}} + +%\def\listoftables{\@latexerr{\listoftables: Lists of tables are not +% allowed in the `acmconf' document style.}\@eha} +%\let\l@table\l@figure + +\def\listoftables{\ClassError{% + \string\listoftables\space is not allowed in the `acmconf' document % January 2008 + style}\@eha} + \let\l@table\l@figure + +\def\footnoterule{\kern-3\p@ + \hrule width .5\columnwidth % (was .4) updated Gerry March 20 2007 + \kern 2.6\p@} % The \hrule has default height of .4pt % (was .4) updated Gerry March 20 2007 +% ------ +\long\def\@makefntext#1{\noindent +%\hbox to .5em{\hss$^{\@thefnmark}$}#1} % original +\hbox to .5em{\hss\textsuperscript{\@thefnmark}}#1} % C. Clifton / GM Oct. 2nd. 2002 +% ------- + +\long\def\@maketntext#1{\noindent +#1} + +\long\def\@maketitlenotetext#1#2{\noindent + \hbox to 1.8em{\hss$^{#1}$}#2} + +\setcounter{topnumber}{2} +\def\topfraction{.7} +\setcounter{bottomnumber}{1} +\def\bottomfraction{.3} +\setcounter{totalnumber}{3} +\def\textfraction{.2} +\def\floatpagefraction{.5} +\setcounter{dbltopnumber}{2} +\def\dbltopfraction{.7} +\def\dblfloatpagefraction{.5} + +\long\def\@makecaption#1#2{ + \vskip \baselineskip + \setbox\@tempboxa\hbox{\textbf{#1: #2}} + \ifdim \wd\@tempboxa >\hsize % IF longer than one line: + \textbf{#1: #2}\par % THEN set as ordinary paragraph. + \else % ELSE center. + \hbox to\hsize{\hfil\box\@tempboxa\hfil}\par + \fi} + +\@ifundefined{figure}{\newcounter {figure}} % this is for LaTeX2e + +\def\fps@figure{tbp} +\def\ftype@figure{1} +\def\ext@figure{lof} +\def\fnum@figure{Figure \thefigure} +\def\figure{\@float{figure}} +%\let\endfigure\end@float +\def\endfigure{\end@float} % Gerry January 2008 +\@namedef{figure*}{\@dblfloat{figure}} +\@namedef{endfigure*}{\end@dblfloat} + +\@ifundefined{table}{\newcounter {table}} % this is for LaTeX2e + +\def\fps@table{tbp} +\def\ftype@table{2} +\def\ext@table{lot} +\def\fnum@table{Table \thetable} +\def\table{\@float{table}} +%\let\endtable\end@float +\def\endtable{\end@float} % Gerry January 2008 +\@namedef{table*}{\@dblfloat{table}} +\@namedef{endtable*}{\end@dblfloat} + +\newtoks\titleboxnotes +\newcount\titleboxnoteflag + +\def\maketitle{\par + \begingroup + \def\thefootnote{\fnsymbol{footnote}} + \def\@makefnmark{\hbox + to 0pt{$^{\@thefnmark}$\hss}} + \twocolumn[\@maketitle] +\@thanks + \endgroup + \setcounter{footnote}{0} + \let\maketitle\relax + \let\@maketitle\relax + \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\gdef\@subtitle{}\let\thanks\relax} + +%% CHANGES ON NEXT LINES +\newif\if@ll % to record which version of LaTeX is in use + +\expandafter\ifx\csname LaTeXe\endcsname\relax % LaTeX2.09 is used +\else% LaTeX2e is used, so set ll to true +\global\@lltrue +\fi + +\if@ll + \NeedsTeXFormat{LaTeX2e} + \ProvidesClass{acm_proc_article-sp} [2009/04/22 - V3.2SP - based on esub2acm.sty <23 April 96>] + \RequirePackage{latexsym}% QUERY: are these two really needed? + \let\dooptions\ProcessOptions +\else + \let\dooptions\@options +\fi +%% END CHANGES + +\def\@height{height} +\def\@width{width} +\def\@minus{minus} +\def\@plus{plus} +\def\hb@xt@{\hbox to} +\newif\if@faircopy +\@faircopyfalse +\def\ds@faircopy{\@faircopytrue} + +\def\ds@preprint{\@faircopyfalse} + +\@twosidetrue +\@mparswitchtrue +\def\ds@draft{\overfullrule 5\p@} +%% CHANGE ON NEXT LINE +\dooptions + +\lineskip \p@ +\normallineskip \p@ +\def\baselinestretch{1} +\def\@ptsize{0} %needed for amssymbols.sty + +%% CHANGES ON NEXT LINES +\if@ll% allow use of old-style font change commands in LaTeX2e +\@maxdepth\maxdepth +% +\DeclareOldFontCommand{\rm}{\ninept\rmfamily}{\mathrm} +\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} +\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} +\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} +\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} +\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} +\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} +\DeclareRobustCommand*{\cal}{\@fontswitch{\relax}{\mathcal}} +\DeclareRobustCommand*{\mit}{\@fontswitch{\relax}{\mathnormal}} +\fi +% +\if@ll + \renewcommand{\rmdefault}{cmr} % was 'ttm' +% Note! I have also found 'mvr' to work ESPECIALLY well. +% Gerry - October 1999 +% You may need to change your LV1times.fd file so that sc is +% mapped to cmcsc - -for smallcaps -- that is if you decide +% to change {cmr} to {times} above. (Not recommended) + \renewcommand{\@ptsize}{} + \renewcommand{\normalsize}{% + \@setfontsize\normalsize\@ixpt{10.5\p@}%\ninept% + \abovedisplayskip 6\p@ \@plus2\p@ \@minus\p@ + \belowdisplayskip \abovedisplayskip + \abovedisplayshortskip 6\p@ \@minus 3\p@ + \belowdisplayshortskip 6\p@ \@minus 3\p@ + \let\@listi\@listI + } +\else + \def\@normalsize{%changed next to 9 from 10 + \@setsize\normalsize{9\p@}\ixpt\@ixpt + \abovedisplayskip 6\p@ \@plus2\p@ \@minus\p@ + \belowdisplayskip \abovedisplayskip + \abovedisplayshortskip 6\p@ \@minus 3\p@ + \belowdisplayshortskip 6\p@ \@minus 3\p@ + \let\@listi\@listI + }% +\fi +\if@ll + \newcommand\scriptsize{\@setfontsize\scriptsize\@viipt{8\p@}} + \newcommand\tiny{\@setfontsize\tiny\@vpt{6\p@}} + \newcommand\large{\@setfontsize\large\@xiipt{14\p@}} + \newcommand\Large{\@setfontsize\Large\@xivpt{18\p@}} + \newcommand\LARGE{\@setfontsize\LARGE\@xviipt{20\p@}} + \newcommand\huge{\@setfontsize\huge\@xxpt{25\p@}} + \newcommand\Huge{\@setfontsize\Huge\@xxvpt{30\p@}} +\else + \def\scriptsize{\@setsize\scriptsize{8\p@}\viipt\@viipt} + \def\tiny{\@setsize\tiny{6\p@}\vpt\@vpt} + \def\large{\@setsize\large{14\p@}\xiipt\@xiipt} + \def\Large{\@setsize\Large{18\p@}\xivpt\@xivpt} + \def\LARGE{\@setsize\LARGE{20\p@}\xviipt\@xviipt} + \def\huge{\@setsize\huge{25\p@}\xxpt\@xxpt} + \def\Huge{\@setsize\Huge{30\p@}\xxvpt\@xxvpt} +\fi +\normalsize + +% make aubox hsize/number of authors up to 3, less gutter +% then showbox gutter showbox gutter showbox -- GKMT Aug 99 +\newbox\@acmtitlebox +\def\@maketitle{\newpage + \null + \setbox\@acmtitlebox\vbox{% +\baselineskip 20pt +\vskip 2em % Vertical space above title. + \begin{center} + {\ttlfnt \@title\par} % Title set in 18pt Helvetica (Arial) bold size. + \vskip 1.5em % Vertical space after title. +%This should be the subtitle. +{\subttlfnt \the\subtitletext\par}\vskip 1.25em%\fi + {\baselineskip 16pt\aufnt % each author set in \12 pt Arial, in a + \lineskip .5em % tabular environment + \begin{tabular}[t]{c}\@author + \end{tabular}\par} + \vskip 1.5em % Vertical space after author. + \end{center}} + \dimen0=\ht\@acmtitlebox + \advance\dimen0 by -12.75pc\relax % Increased space for title box -- KBT + \unvbox\@acmtitlebox + \ifdim\dimen0<0.0pt\relax\vskip-\dimen0\fi} + + +\newcount\titlenotecount +\global\titlenotecount=0 +\newtoks\tntoks +\newtoks\tntokstwo +\newtoks\tntoksthree +\newtoks\tntoksfour +\newtoks\tntoksfive + +\def\abstract{ +\ifnum\titlenotecount>0 % was =1 + \insert\footins{% + \reset@font\footnotesize + \interlinepenalty\interfootnotelinepenalty + \splittopskip\footnotesep + \splitmaxdepth \dp\strutbox \floatingpenalty \@MM + \hsize\columnwidth \@parboxrestore + \protected@edef\@currentlabel{% + }% + \color@begingroup +\ifnum\titlenotecount=1 + \@maketntext{% + \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\@finalstrut\strutbox}% +\fi +\ifnum\titlenotecount=2 + \@maketntext{% + \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\@finalstrut\strutbox}% +\fi +\ifnum\titlenotecount=3 + \@maketntext{% + \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\@finalstrut\strutbox}% +\fi +\ifnum\titlenotecount=4 + \@maketntext{% + \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\S$}\rule\z@\footnotesep\ignorespaces\the\tntoksfour\@finalstrut\strutbox}% +\fi +\ifnum\titlenotecount=5 + \@maketntext{% + \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\S$}\rule\z@\footnotesep\ignorespaces\the\tntoksfour\par\@finalstrut\strutbox}% +\@maketntext{% + \raisebox{4pt}{$\P$}\rule\z@\footnotesep\ignorespaces\the\tntoksfive\@finalstrut\strutbox}% +\fi + \color@endgroup} %g} +\fi +\setcounter{footnote}{0} +\section*{ABSTRACT}\normalsize %\the\parskip \the\baselineskip%\ninept +} + +\def\endabstract{\if@twocolumn\else\endquotation\fi} + +\def\keywords{\if@twocolumn +\section*{Keywords} +\else \small +\quotation +\fi} + +% I've pulled the check for 2 cols, since proceedings are _always_ +% two-column 11 Jan 2000 gkmt +\def\terms{%\if@twocolumn +\section*{General Terms} +%\else \small +%\quotation\the\parskip +%\fi} +} + +% -- Classification needs to be a bit smart due to optionals - Gerry/Georgia November 2nd. 1999 +\newcount\catcount +\global\catcount=1 + +\def\category#1#2#3{% +\ifnum\catcount=1 +\section*{Categories and Subject Descriptors} +\advance\catcount by 1\else{\unskip; }\fi + \@ifnextchar [{\@category{#1}{#2}{#3}}{\@category{#1}{#2}{#3}[]}% +} + +\def\@category#1#2#3[#4]{% + \begingroup + \let\and\relax + #1 [\textbf{#2}]% + \if!#4!% + \if!#3!\else : #3\fi + \else + :\space + \if!#3!\else #3\kern\z@---\hskip\z@\fi + \textit{#4}% + \fi + \endgroup +} +% + +%%% This section (written by KBT) handles the 1" box in the lower left +%%% corner of the left column of the first page by creating a picture, +%%% and inserting the predefined string at the bottom (with a negative +%%% displacement to offset the space allocated for a non-existent +%%% caption). +%%% + +\def\@toappear{} % Default setting blank - commands below change this. +\long\def\toappear#1{\def\@toappear{\parbox[b]{20pc}{\baselineskip 9pt#1}}} +\def\toappearbox#1{\def\@toappear{\raisebox{5pt}{\framebox[20pc]{\parbox[b]{19pc}{#1}}}}} + +\newtoks\conf +\newtoks\confinfo +\def\conferenceinfo#1#2{\global\conf={#1}\global\confinfo{#2}} + + +%\def\marginpar{\@latexerr{The \marginpar command is not allowed in the +% `acmconf' document style.}\@eha} + +\def\marginpar{\ClassError{% + \string\marginpar\space is not allowed in the `acmconf' document % January 2008 + style}\@eha} + +\mark{{}{}} % Initializes TeX's marks + +\def\today{\ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi + \space\number\day, \number\year} + +\def\@begintheorem#1#2{% + \trivlist + \item[% + \hskip 10\p@ + \hskip \labelsep + {{\sc #1}\hskip 5\p@\relax#2.}% + ] + \it +} +\def\@opargbegintheorem#1#2#3{% + \trivlist + \item[% + \hskip 10\p@ + \hskip \labelsep + {\sc #1\ #2\ % This mod by Gerry to enumerate corollaries + \setbox\@tempboxa\hbox{(#3)} % and bracket the 'corollary title' + \ifdim \wd\@tempboxa>\z@ % and retain the correct numbering of e.g. theorems + \hskip 5\p@\relax % if they occur 'around' said corollaries. + \box\@tempboxa % Gerry - Nov. 1999. + \fi.}% + ] + \it +} +\newif\if@qeded +\global\@qededfalse + +% -- original +%\def\proof{% +% \vspace{-\parskip} % GM July 2000 (for tighter spacing) +% \global\@qededfalse +% \@ifnextchar[{\@xproof}{\@proof}% +%} +% -- end of original + +% (JSS) Fix for vertical spacing bug - Gerry Murray July 30th. 2002 +\def\proof{% +\vspace{-\lastskip}\vspace{-\parsep}\penalty-51% +\global\@qededfalse +\@ifnextchar[{\@xproof}{\@proof}% +} + +\def\endproof{% + \if@qeded\else\qed\fi + \endtrivlist +} +\def\@proof{% + \trivlist + \item[% + \hskip 10\p@ + \hskip \labelsep + {\sc Proof.}% + ] + \ignorespaces +} +\def\@xproof[#1]{% + \trivlist + \item[\hskip 10\p@\hskip \labelsep{\sc Proof #1.}]% + \ignorespaces +} +\def\qed{% + \unskip + \kern 10\p@ + \begingroup + \unitlength\p@ + \linethickness{.4\p@}% + \framebox(6,6){}% + \endgroup + \global\@qededtrue +} + +\def\newdef#1#2{% + \expandafter\@ifdefinable\csname #1\endcsname + {\@definecounter{#1}% + \expandafter\xdef\csname the#1\endcsname{\@thmcounter{#1}}% + \global\@namedef{#1}{\@defthm{#1}{#2}}% + \global\@namedef{end#1}{\@endtheorem}% + }% +} +\def\@defthm#1#2{% + \refstepcounter{#1}% + \@ifnextchar[{\@ydefthm{#1}{#2}}{\@xdefthm{#1}{#2}}% +} +\def\@xdefthm#1#2{% + \@begindef{#2}{\csname the#1\endcsname}% + \ignorespaces +} +\def\@ydefthm#1#2[#3]{% + \trivlist + \item[% + \hskip 10\p@ + \hskip \labelsep + {\it #2% +% \savebox\@tempboxa{#3}% + \saveb@x\@tempboxa{#3}% % January 2008 + \ifdim \wd\@tempboxa>\z@ + \ \box\@tempboxa + \fi.% + }]% + \ignorespaces +} +\def\@begindef#1#2{% + \trivlist + \item[% + \hskip 10\p@ + \hskip \labelsep + {\it #1\ \rm #2.}% + ]% +} +\def\theequation{\arabic{equation}} + +\newcounter{part} +\newcounter{section} +\newcounter{subsection}[section] +\newcounter{subsubsection}[subsection] +\newcounter{paragraph}[subsubsection] +\def\thepart{\Roman{part}} +\def\thesection{\arabic{section}} +\def\thesubsection{\thesection.\arabic{subsection}} +\def\thesubsubsection{\thesubsection.\arabic{subsubsection}} %removed \subsecfnt 29 July 2002 gkmt +\def\theparagraph{\thesubsubsection.\arabic{paragraph}} %removed \subsecfnt 29 July 2002 gkmt + +\newif\if@uchead +\@ucheadfalse + +%% CHANGES: NEW NOTE +%% NOTE: OK to use old-style font commands below, since they were +%% suitably redefined for LaTeX2e +%% END CHANGES +\setcounter{secnumdepth}{3} +\def\part{% + \@startsection{part}{9}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@} + {4\p@}{\normalsize\@ucheadtrue}% +} + +% Rationale for changes made in next four definitions: +% "Before skip" is made elastic to provide some give in setting columns (vs. +% parskip, which is non-elastic to keep section headers "anchored" to their +% subsequent text. +% +% "After skip" is minimized -- BUT setting it to 0pt resulted in run-in heads, despite +% the documentation asserted only after-skip < 0pt would have result. +% +% Baselineskip added to style to ensure multi-line section titles, and section heads +% followed by another section head rather than text, are decently spaced vertically. +% 12 Jan 2000 gkmt +\def\section{% + \@startsection{section}{1}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@}% + {0.5pt}{\baselineskip=14pt\secfnt\@ucheadtrue}% +} + +\def\subsection{% + \@startsection{subsection}{2}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@} + {0.5pt}{\baselineskip=14pt\secfnt}% +} +\def\subsubsection{% + \@startsection{subsubsection}{3}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@}% + {0.5pt}{\baselineskip=14pt\subsecfnt}% +} + +%\def\paragraph{% +% \vskip 12pt\@startsection{paragraph}{3}{\z@}{6\p@ \@plus \p@}% original +% {-5\p@}{\subsecfnt}% +%} +% If one wants sections, subsections and subsubsections numbered, +% but not paragraphs, one usually sets secnumepth to 3. +% For that, the "depth" of paragraphs must be given correctly +% in the definition (``4'' instead of ``3'' as second argument +% of @startsection): +\def\paragraph{% + \vskip 12pt\@startsection{paragraph}{4}{\z@}{6\p@ \@plus \p@}% % GM and Wolfgang May - 11/30/06 + {-5\p@}{\subsecfnt}% +} + +\let\@period=. +\def\@startsection#1#2#3#4#5#6{% + \if@noskipsec %gkmt, 11 aug 99 + \global\let\@period\@empty + \leavevmode + \global\let\@period.% + \fi + \par + \@tempskipa #4\relax + \@afterindenttrue + \ifdim \@tempskipa <\z@ + \@tempskipa -\@tempskipa + \@afterindentfalse + \fi + %\if@nobreak 11 Jan 00 gkmt + %\everypar{} + %\else + \addpenalty\@secpenalty + \addvspace\@tempskipa + %\fi + \parskip=0pt + \@ifstar + {\@ssect{#3}{#4}{#5}{#6}} + {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}% +} + + +\def\@ssect#1#2#3#4#5{% + \@tempskipa #3\relax + \ifdim \@tempskipa>\z@ + \begingroup + #4{% + \@hangfrom{\hskip #1}% + \interlinepenalty \@M #5\@@par}% + \endgroup + \else + \def\@svsechd{#4{\hskip #1\relax #5}}% + \fi + \vskip -10.5pt %gkmt, 7 jan 00 -- had been -14pt, now set to parskip + \@xsect{#3}\parskip=10.5pt} % within the starred section, parskip = leading 12 Jan 2000 gkmt + + +\def\@sect#1#2#3#4#5#6[#7]#8{% + \ifnum #2>\c@secnumdepth + \let\@svsec\@empty + \else + \refstepcounter{#1}% + \edef\@svsec{% + \begingroup + %\ifnum#2>2 \noexpand\rm \fi % changed to next 29 July 2002 gkmt + \ifnum#2>2 \noexpand#6 \fi + \csname the#1\endcsname + \endgroup + \ifnum #2=1\relax .\fi + \hskip 1em + }% + \fi + \@tempskipa #5\relax + \ifdim \@tempskipa>\z@ + \begingroup + #6\relax + \@hangfrom{\hskip #3\relax\@svsec}% + \begingroup + \interlinepenalty \@M + \if@uchead + \uppercase{#8}% + \else + #8% + \fi + \par + \endgroup + \endgroup + \csname #1mark\endcsname{#7}% + \vskip -10.5pt % -14pt gkmt, 11 aug 99 -- changed to -\parskip 11 Jan 2000 + \addcontentsline{toc}{#1}{% + \ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}% + \fi + #7% + }% + \else + \def\@svsechd{% + #6% + \hskip #3\relax + \@svsec + \if@uchead + \uppercase{#8}% + \else + #8% + \fi + \csname #1mark\endcsname{#7}% + \addcontentsline{toc}{#1}{% + \ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}% + \fi + #7% + }% + }% + \fi + \@xsect{#5}\parskip=10.5pt% within the section, parskip = leading 12 Jan 2000 gkmt +} +\def\@xsect#1{% + \@tempskipa #1\relax + \ifdim \@tempskipa>\z@ + \par + \nobreak + \vskip \@tempskipa + \@afterheading + \else + \global\@nobreakfalse + \global\@noskipsectrue + \everypar{% + \if@noskipsec + \global\@noskipsecfalse + \clubpenalty\@M + \hskip -\parindent + \begingroup + \@svsechd + \@period + \endgroup + \unskip + \@tempskipa #1\relax + \hskip -\@tempskipa + \else + \clubpenalty \@clubpenalty + \everypar{}% + \fi + }% + \fi + \ignorespaces +} + +\def\@trivlist{% + \@topsepadd\topsep + \if@noskipsec + \global\let\@period\@empty + \leavevmode + \global\let\@period.% + \fi + \ifvmode + \advance\@topsepadd\partopsep + \else + \unskip + \par + \fi + \if@inlabel + \@noparitemtrue + \@noparlisttrue + \else + \@noparlistfalse + \@topsep\@topsepadd + \fi + \advance\@topsep \parskip + \leftskip\z@skip + \rightskip\@rightskip + \parfillskip\@flushglue + \@setpar{\if@newlist\else{\@@par}\fi} + \global\@newlisttrue + \@outerparskip\parskip +} + +%%% Actually, 'abbrev' works just fine as the default - Gerry Feb. 2000 +%%% Bibliography style. + +\parindent 0pt +\typeout{Using 'Abbrev' bibliography style} +\newcommand\bibyear[2]{% + \unskip\quad\ignorespaces#1\unskip + \if#2..\quad \else \quad#2 \fi +} +\newcommand{\bibemph}[1]{{\em#1}} +\newcommand{\bibemphic}[1]{{\em#1\/}} +\newcommand{\bibsc}[1]{{\sc#1}} +\def\@normalcite{% + \def\@cite##1##2{[##1\if@tempswa , ##2\fi]}% +} +\def\@citeNB{% + \def\@cite##1##2{##1\if@tempswa , ##2\fi}% +} +\def\@citeRB{% + \def\@cite##1##2{##1\if@tempswa , ##2\fi]}% +} +\def\start@cite#1#2{% + \edef\citeauthoryear##1##2##3{% + ###1% + \ifnum#2=\z@ \else\ ###2\fi + }% + \ifnum#1=\thr@@ + \let\@@cite\@citeyear + \else + \let\@@cite\@citenormal + \fi + \@ifstar{\@citeNB\@@cite}{\@normalcite\@@cite}% +} +%\def\cite{\start@cite23} +\DeclareRobustCommand\cite{\start@cite23} % January 2008 +\def\citeNP{\cite*} % No Parentheses e.g. 5 +%\def\citeA{\start@cite10} +\DeclareRobustCommand\citeA{\start@cite10} % January 2008 +\def\citeANP{\citeA*} +%\def\shortcite{\start@cite23} +\DeclareRobustCommand\shortcite{\start@cite23} % January 2008 +\def\shortciteNP{\shortcite*} +%\def\shortciteA{\start@cite20} +\DeclareRobustCommand\shortciteA{\start@cite20} % January 2008 +\def\shortciteANP{\shortciteA*} +%\def\citeyear{\start@cite30} +\DeclareRobustCommand\citeyear{\start@cite30} % January 2008 +\def\citeyearNP{\citeyear*} +%\def\citeN{% +\DeclareRobustCommand\citeN{% % January 2008 + \@citeRB + \def\citeauthoryear##1##2##3{##1\ [##3% + \def\reserved@a{##1}% + \def\citeauthoryear####1####2####3{% + \def\reserved@b{####1}% + \ifx\reserved@a\reserved@b + ####3% + \else + \errmessage{Package acmart Error: author mismatch + in \string\citeN^^J^^J% + See the acmart package documentation for explanation}% + \fi + }% + }% + \@ifstar\@citeyear\@citeyear +} +%\def\shortciteN{% +\DeclareRobustCommand\shortciteN{% % January 2008 + \@citeRB + \def\citeauthoryear##1##2##3{##2\ [##3% + \def\reserved@a{##2}% + \def\citeauthoryear####1####2####3{% + \def\reserved@b{####2}% + \ifx\reserved@a\reserved@b + ####3% + \else + \errmessage{Package acmart Error: author mismatch + in \string\shortciteN^^J^^J% + See the acmart package documentation for explanation}% + \fi + }% + }% + \@ifstar\@citeyear\@citeyear % changed from "\@ifstart" 12 Jan 2000 gkmt +} + +\def\@citenormal{% + \@ifnextchar [{\@tempswatrue\@citex;}% +% original {\@tempswafalse\@citex,[]}% was ; Gerry 2/24/00 +{\@tempswafalse\@citex[]}% % GERRY FIX FOR BABEL 3/20/2009 +} + +\def\@citeyear{% + \@ifnextchar [{\@tempswatrue\@citex,}% +% original {\@tempswafalse\@citex,[]}% +{\@tempswafalse\@citex[]}% % GERRY FIX FOR BABEL 3/20/2009 +} + +\def\@citex#1[#2]#3{% + \let\@citea\@empty + \@cite{% + \@for\@citeb:=#3\do{% + \@citea +% original \def\@citea{#1 }% + \def\@citea{#1, }% % GERRY FIX FOR BABEL 3/20/2009 -- SO THAT YOU GET [1, 2] IN THE BODY TEXT + \edef\@citeb{\expandafter\@iden\@citeb}% + \if@filesw + \immediate\write\@auxout{\string\citation{\@citeb}}% + \fi + \@ifundefined{b@\@citeb}{% + {\bf ?}% + \@warning{% + Citation `\@citeb' on page \thepage\space undefined% + }% + }% + {\csname b@\@citeb\endcsname}% + }% + }{#2}% +} +%\let\@biblabel\@gobble % Dec. 2008 - Gerry +% ---- +\def\@biblabelnum#1{[#1]} % Gerry's solution #1 - for Natbib +\let\@biblabel=\@biblabelnum % Gerry's solution #1 - for Natbib +\def\newblock{\relax} % Gerry Dec. 2008 +% --- +\newdimen\bibindent +\setcounter{enumi}{1} +\bibindent=0em +\def\thebibliography#1{% +\ifnum\addauflag=0\addauthorsection\global\addauflag=1\fi + \section[References]{% <=== OPTIONAL ARGUMENT ADDED HERE + {References} % was uppercased but this affects pdf bookmarks (SP/GM October 2004) + \@mkboth{{\refname}}{{\refname}}% + }% + \list{[\arabic{enumi}]}{% + \settowidth\labelwidth{[#1]}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \advance\leftmargin\bibindent + \parsep=0pt\itemsep=1pt % GM July 2000 + \itemindent -\bibindent + \listparindent \itemindent + \usecounter{enumi} + }% + \let\newblock\@empty + \raggedright % GM July 2000 + \sloppy + \sfcode`\.=1000\relax +} + + +\gdef\balancecolumns +{\vfill\eject +\global\@colht=\textheight +\global\ht\@cclv=\textheight +} + +\newcount\colcntr +\global\colcntr=0 +%\newbox\savebox +\newbox\saveb@x % January 2008 + +\gdef \@makecol {% +\global\advance\colcntr by 1 +\ifnum\colcntr>2 \global\colcntr=1\fi + \ifvoid\footins + \setbox\@outputbox \box\@cclv + \else + \setbox\@outputbox \vbox{% +\boxmaxdepth \@maxdepth + \@tempdima\dp\@cclv + \unvbox \@cclv + \vskip-\@tempdima + \vskip \skip\footins + \color@begingroup + \normalcolor + \footnoterule + \unvbox \footins + \color@endgroup + }% + \fi + \xdef\@freelist{\@freelist\@midlist}% + \global \let \@midlist \@empty + \@combinefloats + \ifvbox\@kludgeins + \@makespecialcolbox + \else + \setbox\@outputbox \vbox to\@colht {% +\@texttop + \dimen@ \dp\@outputbox + \unvbox \@outputbox + \vskip -\dimen@ + \@textbottom + }% + \fi + \global \maxdepth \@maxdepth +} +\def\titlenote{\@ifnextchar[\@xtitlenote{\stepcounter\@mpfn +\global\advance\titlenotecount by 1 +\ifnum\titlenotecount=1 + \raisebox{9pt}{$\ast$} +\fi +\ifnum\titlenotecount=2 + \raisebox{9pt}{$\dagger$} +\fi +\ifnum\titlenotecount=3 + \raisebox{9pt}{$\ddagger$} +\fi +\ifnum\titlenotecount=4 +\raisebox{9pt}{$\S$} +\fi +\ifnum\titlenotecount=5 +\raisebox{9pt}{$\P$} +\fi + \@titlenotetext +}} + +\long\def\@titlenotetext#1{\insert\footins{% +\ifnum\titlenotecount=1\global\tntoks={#1}\fi +\ifnum\titlenotecount=2\global\tntokstwo={#1}\fi +\ifnum\titlenotecount=3\global\tntoksthree={#1}\fi +\ifnum\titlenotecount=4\global\tntoksfour={#1}\fi +\ifnum\titlenotecount=5\global\tntoksfive={#1}\fi + \reset@font\footnotesize + \interlinepenalty\interfootnotelinepenalty + \splittopskip\footnotesep + \splitmaxdepth \dp\strutbox \floatingpenalty \@MM + \hsize\columnwidth \@parboxrestore + \protected@edef\@currentlabel{% + }% + \color@begingroup + \color@endgroup}} + +%%%%%%%%%%%%%%%%%%%%%%%%% +\ps@plain +\baselineskip=11pt +\let\thepage\relax % For NO page numbers - Gerry Nov. 30th. 1999 +\def\setpagenumber#1{\global\setcounter{page}{#1}} +%\pagenumbering{arabic} % Arabic page numbers but commented out for NO page numbes - Gerry Nov. 30th. 1999 +\twocolumn % Double column. +\flushbottom % Even bottom -- alas, does not balance columns at end of document +\pagestyle{plain} + +% Need Copyright Year and Copyright Data to be user definable (in .tex file). +% Gerry Nov. 30th. 1999 +\newtoks\copyrtyr +\newtoks\acmcopyr +\newtoks\boilerplate +\def\CopyrightYear#1{\global\copyrtyr{#1}} +\def\crdata#1{\global\acmcopyr{#1}} +\def\permission#1{\global\boilerplate{#1}} +% + +\toappear{\the\boilerplate\par +{\confname{\the\conf}} \the\confinfo\par \the\copyrightetc} +% End of ACM_PROC_ARTICLE-SP.CLS -- V3.2SP - 04/22/2009 -- +% Gerry Murray -- Wednesday April 22nd. 2009 +% +% The following section (i.e. 3 .sty inclusions) was added in May 2007 so as to fix the problems that many +% authors were having with accents. Sometimes accents would occur, but the letter-character would be of a different +% font. Conversely the letter-character font would be correct but, e.g. a 'bar' would appear superimposed on the +% character instead of, say, an unlaut/diaresis. Sometimes the letter-character would NOT appear at all. +% Using [T1]{fontenc} outright was not an option as this caused 99% of the authors to 'produce' a Type-3 (bitmapped) +% PDF file - useless for production. +% +% For proper (font) accenting we NEED these packages to be part of the .cls file i.e. 'ae', 'aecompl' and 'aeguil' +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% This is file `ae.sty' +\def\fileversion{1.3} +\def\filedate{2001/02/12} +\NeedsTeXFormat{LaTeX2e} +%\ProvidesPackage{ae}[\filedate\space\fileversion\space % GM +% Almost European Computer Modern] % GM - keeping the log file clean(er) +\newif\if@ae@slides \@ae@slidesfalse +\DeclareOption{slides}{\@ae@slidestrue} +\ProcessOptions +\fontfamily{aer} +\RequirePackage[T1]{fontenc} +\if@ae@slides + \renewcommand{\sfdefault}{laess} + \renewcommand{\rmdefault}{laess} % no roman + \renewcommand{\ttdefault}{laett} +\else + \renewcommand{\sfdefault}{aess} + \renewcommand{\rmdefault}{aer} + \renewcommand{\ttdefault}{aett} +\fi +\endinput +%% +%% End of file `ae.sty'. +% +% +\def\fileversion{0.9} +\def\filedate{1998/07/23} +\NeedsTeXFormat{LaTeX2e} +%\ProvidesPackage{aecompl}[\filedate\space\fileversion\space % GM +%T1 Complements for AE fonts (D. Roegel)] % GM -- keeping the log file clean(er) + +\def\@ae@compl#1{{\fontencoding{T1}\fontfamily{cmr}\selectfont\symbol{#1}}} +\def\guillemotleft{\@ae@compl{19}} +\def\guillemotright{\@ae@compl{20}} +\def\guilsinglleft{\@ae@compl{14}} +\def\guilsinglright{\@ae@compl{15}} +\def\TH{\@ae@compl{222}} +\def\NG{\@ae@compl{141}} +\def\ng{\@ae@compl{173}} +\def\th{\@ae@compl{254}} +\def\DJ{\@ae@compl{208}} +\def\dj{\@ae@compl{158}} +\def\DH{\@ae@compl{208}} +\def\dh{\@ae@compl{240}} +\def\@perthousandzero{\@ae@compl{24}} +\def\textperthousand{\%\@perthousandzero} +\def\textpertenthousand{\%\@perthousandzero\@perthousandzero} +\endinput +% +% +%% This is file `aeguill.sty' +% This file gives french guillemets (and not guillemots!) +% built with the Polish CMR fonts (default), WNCYR fonts, the LASY fonts +% or with the EC fonts. +% This is useful in conjunction with the ae package +% (this package loads the ae package in case it has not been loaded) +% and with or without the french(le) package. +% +% In order to get the guillemets, it is necessary to either type +% \guillemotleft and \guillemotright, or to use an 8 bit encoding +% (such as ISO-Latin1) which selects these two commands, +% or, if you use the french package (but not the frenchle package), +% to type << or >>. +% +% By default, you get the Polish CMR guillemets; if this package is loaded +% with the `cm' option, you get the LASY guillemets; with `ec,' you +% get the EC guillemets, and with `cyr,' you get the cyrillic guillemets. +% +% In verbatim mode, you always get the EC/TT guillemets. +% +% The default option is interesting in conjunction with PDF, +% because there is a Type 1 version of the Polish CMR fonts +% and these guillemets are very close in shape to the EC guillemets. +% There are no free Type 1 versions of the EC fonts. +% +% Support for Polish CMR guillemets was kindly provided by +% Rolf Niepraschk in version 0.99 (2000/05/22). +% Bernd Raichle provided extensive simplifications to the code +% for version 1.00. +% +% This package is released under the LPPL. +% +% Changes: +% Date version +% 2001/04/12 1.01 the frenchle and french package are now distinguished. +% +\def\fileversion{1.01} +\def\filedate{2001/04/12} +\NeedsTeXFormat{LaTeX2e} +%\ProvidesPackage{aeguill}[2001/04/12 1.01 % % GM +%AE fonts with french guillemets (D. Roegel)] % GM - keeping the log file clean(er) +%\RequirePackage{ae} % GM May 2007 - already embedded here + +\newcommand{\@ae@switch}[4]{#4} +\DeclareOption{ec}{\renewcommand\@ae@switch[4]{#1}} +\DeclareOption{cm}{\renewcommand\@ae@switch[4]{#2}} +\DeclareOption{cyr}{\renewcommand\@ae@switch[4]{#3}} +\DeclareOption{pl}{\renewcommand\@ae@switch[4]{#4}} +\ExecuteOptions{pl} +\ProcessOptions + +% +% Load necessary packages +% +\@ae@switch{% ec + % do nothing +}{% cm + \RequirePackage{latexsym}% GM - May 2007 - already 'mentioned as required' up above +}{% cyr + \RequirePackage[OT2,T1]{fontenc}% +}{% pl + \RequirePackage[OT4,T1]{fontenc}% +} + +% The following command will be compared to \frenchname, +% as defined in french.sty and frenchle.sty. +\def\aeguillfrenchdefault{french}% + +\let\guill@verbatim@font\verbatim@font +\def\verbatim@font{\guill@verbatim@font\ecguills{cmtt}% + \let\guillemotleft\@oguills\let\guillemotright\@fguills} + +\begingroup \catcode`\<=13 \catcode`\>=13 +\def\x{\endgroup + \def\ae@lfguill{<<}% + \def\ae@rfguill{>>}% +}\x + +\newcommand{\ecguills}[1]{% + \def\selectguillfont{\fontencoding{T1}\fontfamily{#1}\selectfont}% + \def\@oguills{{\selectguillfont\symbol{19}}}% + \def\@fguills{{\selectguillfont\symbol{20}}}% + } + +\newcommand{\aeguills}{% + \ae@guills + % We redefine \guillemotleft and \guillemotright + % in order to catch them when they are used + % with \DeclareInputText (in latin1.def for instance) + % We use \auxWARNINGi as a safe indicator that french.sty is used. + \gdef\guillemotleft{\ifx\auxWARNINGi\undefined + \@oguills % neither french.sty nor frenchle.sty + \else + \ifx\aeguillfrenchdefault\frenchname + \ae@lfguill % french.sty + \else + \@oguills % frenchle.sty + \fi + \fi}% + \gdef\guillemotright{\ifx\auxWARNINGi\undefined + \@fguills % neither french.sty nor frenchle.sty + \else + \ifx\aeguillfrenchdefault\frenchname + \ae@rfguill % french.sty + \else + \@fguills % frenchle.sty + \fi + \fi}% + } + +% +% Depending on the class option +% define the internal command \ae@guills +\@ae@switch{% ec + \newcommand{\ae@guills}{% + \ecguills{cmr}}% +}{% cm + \newcommand{\ae@guills}{% + \def\selectguillfont{\fontencoding{U}\fontfamily{lasy}% + \fontseries{m}\fontshape{n}\selectfont}% + \def\@oguills{\leavevmode\nobreak + \hbox{\selectguillfont (\kern-.20em(\kern.20em}\nobreak}% + \def\@fguills{\leavevmode\nobreak + \hbox{\selectguillfont \kern.20em)\kern-.2em)}% + \ifdim\fontdimen\@ne\font>\z@\/\fi}}% +}{% cyr + \newcommand{\ae@guills}{% + \def\selectguillfont{\fontencoding{OT2}\fontfamily{wncyr}\selectfont}% + \def\@oguills{{\selectguillfont\symbol{60}}}% + \def\@fguills{{\selectguillfont\symbol{62}}}} +}{% pl + \newcommand{\ae@guills}{% + \def\selectguillfont{\fontencoding{OT4}\fontfamily{cmr}\selectfont}% + \def\@oguills{{\selectguillfont\symbol{174}}}% + \def\@fguills{{\selectguillfont\symbol{175}}}} +} + + +\AtBeginDocument{% + \ifx\GOfrench\undefined + \aeguills + \else + \let\aeguill@GOfrench\GOfrench + \gdef\GOfrench{\aeguill@GOfrench \aeguills}% + \fi + } + +\endinput +% + + diff --git a/publications/whitepaper/druid.bib b/publications/whitepaper/druid.bib index 0d1418305bb..797207adeb6 100644 --- a/publications/whitepaper/druid.bib +++ b/publications/whitepaper/druid.bib @@ -1,348 +1,368 @@ -@article{cattell2011scalable, - title={Scalable SQL and NoSQL data stores}, - author={Cattell, Rick}, - journal={ACM SIGMOD Record}, - volume={39}, - number={4}, - pages={12--27}, - year={2011}, - publisher={ACM} -} + @article{cattell2011scalable, + title={Scalable SQL and NoSQL data stores}, + author={Cattell, Rick}, + journal={ACM SIGMOD Record}, + volume={39}, + number={4}, + pages={12--27}, + year={2011}, + publisher={ACM} + } -@article{chang2008bigtable, - title={Bigtable: A distributed storage system for structured data}, - author={Chang, Fay and Dean, Jeffrey and Ghemawat, Sanjay and Hsieh, Wilson C and Wallach, Deborah A and Burrows, Mike and Chandra, Tushar and Fikes, Andrew and Gruber, Robert E}, - journal={ACM Transactions on Computer Systems (TOCS)}, - volume={26}, - number={2}, - pages={4}, - year={2008}, - publisher={ACM} -} + @article{chang2008bigtable, + title={Bigtable: A distributed storage system for structured data}, + author={Chang, Fay and Dean, Jeffrey and Ghemawat, Sanjay and Hsieh, Wilson C and Wallach, Deborah A and Burrows, Mike and Chandra, Tushar and Fikes, Andrew and Gruber, Robert E}, + journal={ACM Transactions on Computer Systems (TOCS)}, + volume={26}, + number={2}, + pages={4}, + year={2008}, + publisher={ACM} + } -@inproceedings{decandia2007dynamo, - title={Dynamo: amazon's highly available key-value store}, - author={DeCandia, Giuseppe and Hastorun, Deniz and Jampani, Madan and Kakulapati, Gunavardhan and Lakshman, Avinash and Pilchin, Alex and Sivasubramanian, Swaminathan and Vosshall, Peter and Vogels, Werner}, - booktitle={ACM SIGOPS Operating Systems Review}, - volume={41}, - number={6}, - pages={205--220}, - year={2007}, - organization={ACM} -} + @inproceedings{decandia2007dynamo, + title={Dynamo: amazon's highly available key-value store}, + author={DeCandia, Giuseppe and Hastorun, Deniz and Jampani, Madan and Kakulapati, Gunavardhan and Lakshman, Avinash and Pilchin, Alex and Sivasubramanian, Swaminathan and Vosshall, Peter and Vogels, Werner}, + booktitle={ACM SIGOPS Operating Systems Review}, + volume={41}, + number={6}, + pages={205--220}, + year={2007}, + organization={ACM} + } -@inproceedings{bear2012vertica, - title={The vertica database: SQL RDBMS for managing big data}, - author={Bear, Chuck and Lamb, Andrew and Tran, Nga}, - booktitle={Proceedings of the 2012 workshop on Management of big data systems}, - pages={37--38}, - year={2012}, - organization={ACM} -} + @inproceedings{bear2012vertica, + title={The vertica database: SQL RDBMS for managing big data}, + author={Bear, Chuck and Lamb, Andrew and Tran, Nga}, + booktitle={Proceedings of the 2012 workshop on Management of big data systems}, + pages={37--38}, + year={2012}, + organization={ACM} + } -@article{lakshman2010cassandra, - title={Cassandra—A decentralized structured storage system}, - author={Lakshman, Avinash and Malik, Prashant}, - journal={Operating systems review}, - volume={44}, - number={2}, - pages={35}, - year={2010} -} + @article{lakshman2010cassandra, + title={Cassandra—A decentralized structured storage system}, + author={Lakshman, Avinash and Malik, Prashant}, + journal={Operating systems review}, + volume={44}, + number={2}, + pages={35}, + year={2010} + } -@article{melnik2010dremel, - title={Dremel: interactive analysis of web-scale datasets}, - author={Melnik, Sergey and Gubarev, Andrey and Long, Jing Jing and Romer, Geoffrey and Shivakumar, Shiva and Tolton, Matt and Vassilakis, Theo}, - journal={Proceedings of the VLDB Endowment}, - volume={3}, - number={1-2}, - pages={330--339}, - year={2010}, - publisher={VLDB Endowment} -} + @article{melnik2010dremel, + title={Dremel: interactive analysis of web-scale datasets}, + author={Melnik, Sergey and Gubarev, Andrey and Long, Jing Jing and Romer, Geoffrey and Shivakumar, Shiva and Tolton, Matt and Vassilakis, Theo}, + journal={Proceedings of the VLDB Endowment}, + volume={3}, + number={1-2}, + pages={330--339}, + year={2010}, + publisher={VLDB Endowment} + } -@article{hall2012processing, - title={Processing a trillion cells per mouse click}, - author={Hall, Alexander and Bachmann, Olaf and B{\"u}ssow, Robert and G{\u{a}}nceanu, Silviu and Nunkesser, Marc}, - journal={Proceedings of the VLDB Endowment}, - volume={5}, - number={11}, - pages={1436--1446}, - year={2012}, - publisher={VLDB Endowment} -} + @article{hall2012processing, + title={Processing a trillion cells per mouse click}, + author={Hall, Alexander and Bachmann, Olaf and B{\"u}ssow, Robert and G{\u{a}}nceanu, Silviu and Nunkesser, Marc}, + journal={Proceedings of the VLDB Endowment}, + volume={5}, + number={11}, + pages={1436--1446}, + year={2012}, + publisher={VLDB Endowment} + } -@inproceedings{shvachko2010hadoop, - title={The hadoop distributed file system}, - author={Shvachko, Konstantin and Kuang, Hairong and Radia, Sanjay and Chansler, Robert}, - booktitle={Mass Storage Systems and Technologies (MSST), 2010 IEEE 26th Symposium on}, - pages={1--10}, - year={2010}, - organization={IEEE} -} + @inproceedings{shvachko2010hadoop, + title={The hadoop distributed file system}, + author={Shvachko, Konstantin and Kuang, Hairong and Radia, Sanjay and Chansler, Robert}, + booktitle={Mass Storage Systems and Technologies (MSST), 2010 IEEE 26th Symposium on}, + pages={1--10}, + year={2010}, + organization={IEEE} + } -@article{colantonio2010concise, - title={Concise: Compressed ‘n’Composable Integer Set}, - author={Colantonio, Alessandro and Di Pietro, Roberto}, - journal={Information Processing Letters}, - volume={110}, - number={16}, - pages={644--650}, - year={2010}, - publisher={Elsevier} -} + @article{colantonio2010concise, + title={Concise: Compressed ‘n’Composable Integer Set}, + author={Colantonio, Alessandro and Di Pietro, Roberto}, + journal={Information Processing Letters}, + volume={110}, + number={16}, + pages={644--650}, + year={2010}, + publisher={Elsevier} + } -@article{lerner2010redis, - title={At the Forge: Redis}, - author={Lerner, Richard}, - journal={Linux Journal}, - volume={2010}, - number={197}, - pages={3}, - year={2010} -} + @inproceedings{stonebraker2005c, + title={C-store: a column-oriented DBMS}, + author={Stonebraker, Mike and Abadi, Daniel J and Batkin, Adam and Chen, Xuedong and Cherniack, Mitch and Ferreira, Miguel and Lau, Edmond and Lin, Amerson and Madden, Sam and O'Neil, Elizabeth and others}, + booktitle={Proceedings of the 31st international conference on Very large data bases}, + pages={553--564}, + year={2005}, + organization={VLDB Endowment} + } -@inproceedings{stonebraker2005c, - title={C-store: a column-oriented DBMS}, - author={Stonebraker, Mike and Abadi, Daniel J and Batkin, Adam and Chen, Xuedong and Cherniack, Mitch and Ferreira, Miguel and Lau, Edmond and Lin, Amerson and Madden, Sam and O'Neil, Elizabeth and others}, - booktitle={Proceedings of the 31st international conference on Very large data bases}, - pages={553--564}, - year={2005}, - organization={VLDB Endowment} -} + @inproceedings{engle2012shark, + title={Shark: fast data analysis using coarse-grained distributed memory}, + author={Engle, Cliff and Lupher, Antonio and Xin, Reynold and Zaharia, Matei and Franklin, Michael J and Shenker, Scott and Stoica, Ion}, + booktitle={Proceedings of the 2012 international conference on Management of Data}, + pages={689--692}, + year={2012}, + organization={ACM} + } -@inproceedings{engle2012shark, - title={Shark: fast data analysis using coarse-grained distributed memory}, - author={Engle, Cliff and Lupher, Antonio and Xin, Reynold and Zaharia, Matei and Franklin, Michael J and Shenker, Scott and Stoica, Ion}, - booktitle={Proceedings of the 2012 international conference on Management of Data}, - pages={689--692}, - year={2012}, - organization={ACM} -} + @inproceedings{zaharia2012discretized, + title={Discretized streams: an efficient and fault-tolerant model for stream processing on large clusters}, + author={Zaharia, Matei and Das, Tathagata and Li, Haoyuan and Shenker, Scott and Stoica, Ion}, + booktitle={Proceedings of the 4th USENIX conference on Hot Topics in Cloud Computing}, + pages={10--10}, + year={2012}, + organization={USENIX Association} + } -@inproceedings{zaharia2012discretized, - title={Discretized streams: an efficient and fault-tolerant model for stream processing on large clusters}, - author={Zaharia, Matei and Das, Tathagata and Li, Haoyuan and Shenker, Scott and Stoica, Ion}, - booktitle={Proceedings of the 4th USENIX conference on Hot Topics in Cloud Computing}, - pages={10--10}, - year={2012}, - organization={USENIX Association} -} + @misc{marz2013storm, + author = {Marz, Nathan}, + title = {Storm: Distributed and Fault-Tolerant Realtime Computation}, + month = {February}, + year = {2013}, + howpublished = "\url{http://storm-project.net/}" + } -@misc{marz2013storm, -author = {Marz, Nathan}, -title = {Storm: Distributed and Fault-Tolerant Realtime Computation}, -month = {February}, -year = {2013}, -howpublished = "\url{http://storm-project.net/}" -} + @misc{tschetter2011druid, + author = {Eric Tschetter}, + title = {Introducing Druid: Real-Time Analytics at a Billion Rows Per Second}, + month = {April}, + year = {2011}, + howpublished = "\url{http://metamarkets.com/2011/druid-part-i-real-time-analytics-at-a-billion-rows-per-second/}" + } -@article{farber2012sap, - title={SAP HANA database: data management for modern business applications}, - author={F{\"a}rber, Franz and Cha, Sang Kyun and Primsch, J{\"u}rgen and Bornh{\"o}vd, Christof and Sigg, Stefan and Lehner, Wolfgang}, - journal={ACM Sigmod Record}, - volume={40}, - number={4}, - pages={45--51}, - year={2012}, - publisher={ACM} -} + @article{farber2012sap, + title={SAP HANA database: data management for modern business applications}, + author={F{\"a}rber, Franz and Cha, Sang Kyun and Primsch, J{\"u}rgen and Bornh{\"o}vd, Christof and Sigg, Stefan and Lehner, Wolfgang}, + journal={ACM Sigmod Record}, + volume={40}, + number={4}, + pages={45--51}, + year={2012}, + publisher={ACM} + } -@misc{voltdb2010voltdb, - title={VoltDB Technical Overview}, - author={VoltDB, LLC}, - year={2010}, -howpublished = "\url{https://voltdb.com/}" -} + @misc{voltdb2010voltdb, + title={VoltDB Technical Overview}, + author={VoltDB, LLC}, + year={2010}, + howpublished = "\url{https://voltdb.com/}" + } -@inproceedings{macnicol2004sybase, - title={Sybase IQ multiplex-designed for analytics}, - author={MacNicol, Roger and French, Blaine}, - booktitle={Proceedings of the Thirtieth international conference on Very large data bases-Volume 30}, - pages={1227--1230}, - year={2004}, - organization={VLDB Endowment} -} + @inproceedings{macnicol2004sybase, + title={Sybase IQ multiplex-designed for analytics}, + author={MacNicol, Roger and French, Blaine}, + booktitle={Proceedings of the Thirtieth international conference on Very large data bases-Volume 30}, + pages={1227--1230}, + year={2004}, + organization={VLDB Endowment} + } -@inproceedings{singh2011introduction, - title={Introduction to the IBM Netezza warehouse appliance}, - author={Singh, Malcolm and Leonhardi, Ben}, - booktitle={Proceedings of the 2011 Conference of the Center for Advanced Studies on Collaborative Research}, - pages={385--386}, - year={2011}, - organization={IBM Corp.} -} + @inproceedings{singh2011introduction, + title={Introduction to the IBM Netezza warehouse appliance}, + author={Singh, Malcolm and Leonhardi, Ben}, + booktitle={Proceedings of the 2011 Conference of the Center for Advanced Studies on Collaborative Research}, + pages={385--386}, + year={2011}, + organization={IBM Corp.} + } -@inproceedings{miner2012unified, - title={Unified analytics platform for big data}, - author={Miner, Donald}, - booktitle={Proceedings of the WICSA/ECSA 2012 Companion Volume}, - pages={176--176}, - year={2012}, - organization={ACM} -} + @inproceedings{miner2012unified, + title={Unified analytics platform for big data}, + author={Miner, Donald}, + booktitle={Proceedings of the WICSA/ECSA 2012 Companion Volume}, + pages={176--176}, + year={2012}, + organization={ACM} + } -@inproceedings{fink2012distributed, - title={Distributed computation on dynamo-style distributed storage: riak pipe}, - author={Fink, Bryan}, - booktitle={Proceedings of the eleventh ACM SIGPLAN workshop on Erlang workshop}, - pages={43--50}, - year={2012}, - organization={ACM} -} + @inproceedings{fink2012distributed, + title={Distributed computation on dynamo-style distributed storage: riak pipe}, + author={Fink, Bryan}, + booktitle={Proceedings of the eleventh ACM SIGPLAN workshop on Erlang workshop}, + pages={43--50}, + year={2012}, + organization={ACM} + } -@misc{paraccel2013, -key = {ParAccel Analytic Database}, -title = {ParAccel Analytic Database}, -month = {March}, -year = {2013}, -howpublished = "\url{http://www.paraccel.com/resources/Datasheets/ParAccel-Core-Analytic-Database.pdf}" -} + @misc{paraccel2013, + key = {ParAccel Analytic Database}, + title = {ParAccel Analytic Database}, + month = {March}, + year = {2013}, + howpublished = "\url{http://www.paraccel.com/resources/Datasheets/ParAccel-Core-Analytic-Database.pdf}" + } -@article{barroso2009datacenter, - title={The datacenter as a computer: An introduction to the design of warehouse-scale machines}, - author={Barroso, Luiz Andr{\'e} and H{\"o}lzle, Urs}, - journal={Synthesis Lectures on Computer Architecture}, - volume={4}, - number={1}, - pages={1--108}, - year={2009}, - publisher={Morgan \& Claypool Publishers} -} + @misc{cloudera2013, + key = {Cloudera Impala}, + title = {Cloudera Impala}, + month = {March}, + year = {2013}, + url = {}, + howpublished = "\url{http://blog.cloudera.com/blog}" + } -@article{chaudhuri1997overview, - title={An overview of data warehousing and OLAP technology}, - author={Chaudhuri, Surajit and Dayal, Umeshwar}, - journal={ACM Sigmod record}, - volume={26}, - number={1}, - pages={65--74}, - year={1997} -} + @inproceedings{hunt2010zookeeper, + title={ZooKeeper: Wait-free coordination for Internet-scale systems}, + author={Hunt, Patrick and Konar, Mahadev and Junqueira, Flavio P and Reed, Benjamin}, + booktitle={USENIX ATC}, + volume={10}, + year={2010} + } -@article{dewitt1992parallel, - title={Parallel database systems: the future of high performance database systems}, - author={DeWitt, David and Gray, Jim}, - journal={Communications of the ACM}, - volume={35}, - number={6}, - pages={85--98}, - year={1992}, - publisher={ACM} -} + @inproceedings{kreps2011kafka, + title={Kafka: A distributed messaging system for log processing}, + author={Kreps, Jay and Narkhede, Neha and Rao, Jun}, + booktitle={Proceedings of 6th International Workshop on Networking Meets Databases (NetDB), Athens, Greece}, + year={2011} + } -@misc{cloudera2013, -key = {Cloudera Impala}, -title = {Cloudera Impala}, -month = {March}, -year = {2013}, -url = {}, -howpublished = "\url{http://blog.cloudera.com/blog}" -} + @misc{liblzf2013, + title = {LibLZF}, + key = {LibLZF}, + month = {March}, + year = {2013}, + howpublished = "\url{http://freecode.com/projects/liblzf}" + } -@inproceedings{hunt2010zookeeper, - title={ZooKeeper: Wait-free coordination for Internet-scale systems}, - author={Hunt, Patrick and Konar, Mahadev and Junqueira, Flavio P and Reed, Benjamin}, - booktitle={USENIX ATC}, - volume={10}, - year={2010} -} + @inproceedings{tomasic1993performance, + title={Performance of inverted indices in shared-nothing distributed text document information retrieval systems}, + author={Tomasic, Anthony and Garcia-Molina, Hector}, + booktitle={Parallel and Distributed Information Systems, 1993., Proceedings of the Second International Conference on}, + pages={8--17}, + year={1993}, + organization={IEEE} + } -@inproceedings{kreps2011kafka, - title={Kafka: A distributed messaging system for log processing}, - author={Kreps, Jay and Narkhede, Neha and Rao, Jun}, - booktitle={Proceedings of 6th International Workshop on Networking Meets Databases (NetDB), Athens, Greece}, - year={2011} -} + @inproceedings{antoshenkov1995byte, + title={Byte-aligned bitmap compression}, + author={Antoshenkov, Gennady}, + booktitle={Data Compression Conference, 1995. DCC'95. Proceedings}, + pages={476}, + year={1995}, + organization={IEEE} + } -@misc{liblzf2013, -title = {LibLZF}, -key = {LibLZF}, -month = {March}, -year = {2013}, -howpublished = "\url{http://freecode.com/projects/liblzf}" -} + @inproceedings{van2011memory, + title={A memory efficient reachability data structure through bit vector compression}, + author={van Schaik, Sebastiaan J and de Moor, Oege}, + booktitle={Proceedings of the 2011 international conference on Management of data}, + pages={913--924}, + year={2011}, + organization={ACM} + } -@inproceedings{tomasic1993performance, - title={Performance of inverted indices in shared-nothing distributed text document information retrieval systems}, - author={Tomasic, Anthony and Garcia-Molina, Hector}, - booktitle={Parallel and Distributed Information Systems, 1993., Proceedings of the Second International Conference on}, - pages={8--17}, - year={1993}, - organization={IEEE} -} + @inproceedings{o1993lru, + title={The LRU-K page replacement algorithm for database disk buffering}, + author={O'neil, Elizabeth J and O'neil, Patrick E and Weikum, Gerhard}, + booktitle={ACM SIGMOD Record}, + volume={22}, + number={2}, + pages={297--306}, + year={1993}, + organization={ACM} + } -@inproceedings{antoshenkov1995byte, - title={Byte-aligned bitmap compression}, - author={Antoshenkov, Gennady}, - booktitle={Data Compression Conference, 1995. DCC'95. Proceedings}, - pages={476}, - year={1995}, - organization={IEEE} -} + @article{kim2001lrfu, + title={LRFU: A spectrum of policies that subsumes the least recently used and least frequently used policies}, + author={Kim, Chong Sang}, + journal={IEEE Transactions on Computers}, + volume={50}, + number={12}, + year={2001} + } -@inproceedings{van2011memory, - title={A memory efficient reachability data structure through bit vector compression}, - author={van Schaik, Sebastiaan J and de Moor, Oege}, - booktitle={Proceedings of the 2011 international conference on Management of data}, - pages={913--924}, - year={2011}, - organization={ACM} -} + @article{wu2006optimizing, + title={Optimizing bitmap indices with efficient compression}, + author={Wu, Kesheng and Otoo, Ekow J and Shoshani, Arie}, + journal={ACM Transactions on Database Systems (TODS)}, + volume={31}, + number={1}, + pages={1--38}, + year={2006}, + publisher={ACM} + } -@inproceedings{o1993lru, - title={The LRU-K page replacement algorithm for database disk buffering}, - author={O'neil, Elizabeth J and O'neil, Patrick E and Weikum, Gerhard}, - booktitle={ACM SIGMOD Record}, - volume={22}, - number={2}, - pages={297--306}, - year={1993}, - organization={ACM} -} + @misc{twitter2013, + key = {Twitter Public Streams}, + title = {Twitter Public Streams}, + month = {March}, + year = {2013}, + howpublished = "\url{https://dev.twitter.com/docs/streaming-apis/streams/public}" + } -@article{kim2001lrfu, - title={LRFU: A spectrum of policies that subsumes the least recently used and least frequently used policies}, - author={Kim, Chong Sang}, - journal={IEEE Transactions on Computers}, - volume={50}, - number={12}, - year={2001} -} + @article{fitzpatrick2004distributed, + title={Distributed caching with memcached}, + author={Fitzpatrick, Brad}, + journal={Linux journal}, + number={124}, + pages={72--74}, + year={2004} + } -@article{wu2006optimizing, - title={Optimizing bitmap indices with efficient compression}, - author={Wu, Kesheng and Otoo, Ekow J and Shoshani, Arie}, - journal={ACM Transactions on Database Systems (TODS)}, - volume={31}, - number={1}, - pages={1--38}, - year={2006}, - publisher={ACM} -} + @inproceedings{amdahl1967validity, + title={Validity of the single processor approach to achieving large scale computing capabilities}, + author={Amdahl, Gene M}, + booktitle={Proceedings of the April 18-20, 1967, spring joint computer conference}, + pages={483--485}, + year={1967}, + organization={ACM} + } + @book{sarawagi1998discovery, + title={Discovery-driven exploration of OLAP data cubes}, + author={Sarawagi, Sunita and Agrawal, Rakesh and Megiddo, Nimrod}, + year={1998}, + publisher={Springer} + } + @inproceedings{abadi2008column, + title={Column-Stores vs. Row-Stores: How different are they really?}, + author={Abadi, Daniel J and Madden, Samuel R and Hachem, Nabil}, + booktitle={Proceedings of the 2008 ACM SIGMOD international conference on Management of data}, + pages={967--980}, + year={2008}, + organization={ACM} + } + @article{hu2011stream, + title={Stream Database Survey}, + author={Hu, Bo}, + year={2011} + } -@misc{twitter2013, -key = {Twitter Public Streams}, -title = {Twitter Public Streams}, -month = {March}, -year = {2013}, -howpublished = "\url{https://dev.twitter.com/docs/streaming-apis/streams/public}" -} + @article{dean2008mapreduce, + title={MapReduce: simplified data processing on large clusters}, + author={Dean, Jeffrey and Ghemawat, Sanjay}, + journal={Communications of the ACM}, + volume={51}, + number={1}, + pages={107--113}, + year={2008}, + publisher={ACM} + } -@article{fitzpatrick2004distributed, - title={Distributed caching with memcached}, - author={Fitzpatrick, Brad}, - journal={Linux journal}, - number={124}, - pages={72--74}, - year={2004} -} + @misc{linkedin2013senseidb, + author = {LinkedIn}, + title = {SenseiDB}, + month = {July}, + year = {2013}, + howpublished = "\url{http://www.senseidb.com/}" + } -@inproceedings{amdahl1967validity, - title={Validity of the single processor approach to achieving large scale computing capabilities}, - author={Amdahl, Gene M}, - booktitle={Proceedings of the April 18-20, 1967, spring joint computer conference}, - pages={483--485}, - year={1967}, - organization={ACM} -} + @misc{apache2013solr, + author = {Apache}, + title = {Apache Solr}, + month = {February}, + year = {2013}, + howpublished = "\url{http://lucene.apache.org/solr/}" + } + + @misc{banon2013elasticsearch, + author = {Banon, Shay}, + title = {ElasticSearch}, + month = {July}, + year = {2013}, + howpublished = "\url{http://www.elasticseach.com/}" + } diff --git a/publications/whitepaper/druid.pdf b/publications/whitepaper/druid.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f4d1d8b1720954681b127c84652500e999c6fbd0 GIT binary patch literal 527612 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
    QL?iFl)a&R0pZTi!S@bl&>HGAgZaC|BQ?hX?* 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 -% Removed the requirement to include *bbl file in here. (AhmetSacan, Sep2012) -% Fixed the equation on page 3 to prevent line overflow. (AhmetSacan, Sep2012) - -%\documentclass[draft]{vldb} -\documentclass{vldb} +\documentclass{acm_proc_article-sp} \usepackage{graphicx} -\usepackage{balance} % for \balance command ON LAST PAGE (only there!) +\usepackage{balance} \usepackage{fontspec} \setmainfont[Ligatures={TeX}]{Times} \usepackage{hyperref} @@ -21,509 +14,531 @@ \title{Druid: A Real-time Analytical Data Store} -% possible, but not really needed or used for PVLDB: -%\subtitle{[Extended Abstract] -%\titlenote{A full version of this paper is available as\textit{Author's Guide to Preparing ACM SIG Proceedings Using \LaTeX$2_\epsilon$\ and BibTeX} at \texttt{www.acm.org/eaddress.htm}}} - % ****************** AUTHORS ************************************** -% You need the command \numberofauthors to handle the 'placement -% and alignment' of the authors beneath the title. -% -% For aesthetic reasons, we recommend 'three authors at a time' -% i.e. three 'name/affiliation blocks' be placed beneath the title. -% -% NOTE: You are NOT restricted in how many 'rows' of -% "name/affiliations" may appear. We just ask that you restrict -% the number of 'columns' to three. -% -% Because of the available 'opening page real-estate' -% we ask you to refrain from putting more than six authors -% (two rows with three columns) beneath the article title. -% More than six makes the first-page appear very cluttered indeed. -% -% Use the \alignauthor commands to handle the names -% and affiliations for an 'aesthetic maximum' of six authors. -% Add names, affiliations, addresses for -% the seventh etc. author(s) as the argument for the -% \additionalauthors command. -% These 'additional authors' will be output/set for you -% without further effort on your part as the last section in -% the body of your article BEFORE References or any Appendices. - -\numberofauthors{7} % in this sample file, there are a *total* -% of EIGHT authors. SIX appear on the 'first-page' (for formatting -% reasons) and the remaining two appear in the \additionalauthors section. - +\numberofauthors{6} \author{ -% You can go ahead and credit any number of authors here, -% e.g. one 'row of three' or two rows (consisting of one row of three -% and a second row of one, two or three). -% -% The command \alignauthor (no curly braces needed) should -% precede each author name, affiliation/snail-mail address and -% e-mail address. Additionally, tag each line of -% affiliation/address with \affaddr, and tag the -% e-mail address with \email. -% -% 1st. author -\alignauthor Fangjin Yang\\ -\affaddr{Metamarkets Group, Inc.}\\ -\affaddr{625 2nd Street, Suite 230}\\ -\affaddr{San Francisco, CA, USA}\\ -\email{fangjin@metamarkets.com} -\alignauthor Eric Tschetter\\ -\affaddr{Metamarkets Group, Inc.}\\ -\affaddr{625 2nd Street, Suite 230}\\ -\affaddr{San Francisco, CA, USA}\\ -\email{eric@metamarkets.com} -\alignauthor Gian Merlino\\ -\affaddr{Metamarkets Group, Inc.}\\ -\affaddr{625 2nd Street, Suite 230}\\ -\affaddr{San Francisco, CA, USA}\\ -\email{gian@metamarkets.com} -\and -\alignauthor Nelson Ray\\ -\affaddr{Metamarkets Group, Inc.}\\ -\affaddr{625 2nd Street, Suite 230}\\ -\affaddr{San Francisco, CA, USA}\\ -\email{nelson@metamarkets.com} -\alignauthor Xavier Léauté\\ -\affaddr{Metamarkets Group, Inc.}\\ -\affaddr{625 2nd Street, Suite 230}\\ -\affaddr{San Francisco, CA, USA}\\ -\email{xavier@metamarkets.com} -\alignauthor Deep Ganguli\\ -\affaddr{Metamarkets Group, Inc.}\\ -\affaddr{625 2nd Street, Suite 230}\\ -\affaddr{San Francisco, CA, USA}\\ -\email{deep@metamarkets.com} +\alignauthor Fangjin Yang, Eric Tschetter, Gian Merlino, Nelson Ray, Xavier Léauté, Deep Ganguli, Himadri Singh\\ +\email{\{fangjin, cheddar, gian, nelson, xavier, deep, himadri\}@metamarkets.com} } -% There's nothing stopping you putting the seventh, eighth, etc. -% author on the opening page (as the 'third row') but we ask, -% for aesthetic reasons that you place these 'additional authors' -% in the \additional authors block, viz. -\additionalauthors{Michael Driscoll (Metamarkets, \texttt{mike@metamarkets.com})} \date{21 March 2013} -% Just remember to make sure that the TOTAL number of authors -% is the number that will appear on the first page PLUS the -% number that will appear in the \additionalauthors section. \maketitle -\begin{abstract} -Druid is an open source\footnote{\href{https://github.com/metamx/druid}{https://github.com/metamx/druid}}, real-time analytical data store that supports -fast ad-hoc queries on large-scale data sets. The system combines a -column-oriented data layout, a shared-nothing architecture, and an advanced -indexing structure to allow for the arbitrary exploration of billion-row -tables with sub-second latencies. Druid scales horizontally and is the -core engine of the Metamarkets data analytics platform. In this paper, we detail Druid's architecture, and describe how it supports real-time data ingestion and interactive analytical queries. +\begin{abstract} +Druid is an open +source\footnote{\href{https://github.com/metamx/druid}{https://github.com/metamx/druid}} +data store designed for real-time exploratory analytics on large data sets. +The system combines a column-oriented storage layout, a distributed, +shared-nothing architecture, and an advanced indexing structure to allow for +the arbitrary exploration of billion-row tables with sub-second latencies. In +this paper, we describe Druid's architecture, and detail how it supports fast +aggregations, flexible filters, and low latency data ingestion. \end{abstract} -\section{Introduction} -Enterprises routinely collect diverse data sets that can contain up to terabytes of information per day. Companies are increasingly realizing the importance of efficiently storing and analyzing this data in order to increase both productivity and profitability. Numerous database systems (e.g., IBM’s Netezza \cite{singh2011introduction}, HP's Vertica \cite{bear2012vertica}, EMC’s Greenplum \cite{miner2012unified}) and several research papers \cite{barroso2009datacenter, chaudhuri1997overview, dewitt1992parallel} offer solutions for how to store and extract information from large data sets. However, many of these Relational Database Management Systems (RDBMS) and NoSQL architectures do not support interactive queries and real-time data ingestion. +\section{Introduction} +In recent years, the proliferation of internet technology has +created a surge in machine-generated events. Individually, these +events contain minimal useful information and are of low value. Given the +time and resources required to extract meaning from large collections of +events, many companies were willing to discard this data instead. Although +infrastructure has been built handle event based data (e.g. IBM's +Netezza\cite{singh2011introduction}, HP's Vertica\cite{bear2012vertica}, and EMC's +Greenplum\cite{miner2012unified}), they are largely sold at high price points +and are only targeted towards those companies who can afford the offerings. -Metamarkets built Druid to directly address the need for a real-time analytical data store in the big-data ecosystem. Druid shares some similarities with main-memory databases \cite{farber2012sap} and interactive query systems such as Dremel \cite{melnik2010dremel} and PowerDrill \cite{hall2012processing}. Druid's focus is fast aggregations, arbitrarily deep data exploration, and low-latency data ingestion. Furthermore, Druid is highly configurable and allows users to easily adjust fault tolerance and performance properties. Queries on in-memory data typically complete in milliseconds, and real-time data ingestion means that new events are immediately available for analysis. +A few years ago, Google introduced MapReduce \cite{dean2008mapreduce} as their +mechanism of leveraging commodity hardware to index the internet and analyze +logs. The Hadoop \cite{shvachko2010hadoop} project soon followed and was +largely patterned after the insights that came out of the original MapReduce +paper. Hadoop is currently deployed in many organizations to store and analyze +large amounts of log data. Hadoop has contributed much to helping companies +convert their low-value event streams into high-value aggregates for a variety +of applications such as business intelligence and A-B testing. -In this paper, we make the following contributions: -\begin{itemize} -\item We describe Druid’s real-time data ingestion implementation. -\item We detail how the architecture enables fast multi-dimensional data exploration. -\item We present Druid performance benchmarks. -\end{itemize} +As with a lot of great systems, Hadoop has opened our eyes to a new space of +problems. Specifically, Hadoop excels at storing and providing access to large +amounts of data, however, it does not make any performance guarantees around +how quickly that data can be accessed. Furthermore, although Hadoop is a +highly available system, performance degrades under heavy concurrent load. +Lastly, while Hadoop works well for storing data, it is not optimized for +ingesting data and making that data immediately readable. -The outline is as follows: Section \ref{sec:data-model} describes the Druid data model. Section \ref{sec:cluster} presents an overview of the components of a Druid cluster. Section \ref{sec:query-api} outlines the query API. Section \ref{sec:storage} describes data storage format in greater detail. Section \ref{sec:robustness} discusses Druid robustness and failure responsiveness. Section \ref{sec:benchmarks} presents experiments benchmarking query performance. Section \ref{sec:related} discusses related work and Section \ref{sec:conclusions} presents our conclusions. +Early on in the development of the Metamarkets product, we ran into each of +these issues and came to the realization that Hadoop is a great back-office, +batch processing, and data warehousing system. However, as a company that has +product-level guarantees around query performance and data availability in a +highly concurrent environment (1000+ users), Hadoop wasn't going to meet our +needs. We explored different solutions in the space, and after +trying both Relational Database Management Systems and NoSQL architectures, we +came to the conclusion that there was nothing in the open source world that +could be fully leveraged for our requirements. -\section{Data Model} -\label{sec:data-model} -The fundamental storage unit in Druid is the segment. Each table in Druid (called a \emph{data source}) -is partitioned into a collection of segments, each typically comprising 5--10 million rows. A sample table -containing advertising data is shown in Table~\ref{tab:sample_data}. Many core Druid concepts can be described -using this simple table. +We ended up creating Druid, an open-source, distributed, column-oriented, +realtime analytical data store. In many ways, Druid shares similarities with +other interactive query systems \cite{melnik2010dremel}, main-memory databases +\cite{farber2012sap}, and widely-known distributed data stores such as BigTable +\cite{chang2008bigtable}, Dynamo \cite{decandia2007dynamo}, and Cassandra +\cite{lakshman2010cassandra}. The distribution and query model also +borrow ideas from current generation search infrastructure +\cite{linkedin2013senseidb, apache2013solr, banon2013elasticsearch}. + +This paper describes the architecture of Druid, explores the various design +decisions made in creating an always-on production system that powers a hosted +service, and attempts to help inform anyone who faces a similar problem about a +potential method of solving it. Druid is deployed in production at several technology companies\footnote{\href{http://druid.io/druid.html}{http://druid.io/druid.html}}. + +The structure of the paper is as follows: we first describe the problem in +Section \ref{sec:problem-definition}. Next, we detail system architecture from +the point of view of how data flows through the system in Section +\ref{sec:architecture}. We then discuss how and why data gets converted into a +binary format in Section \ref{sec:storage-format}. We briefly describe the +query API in Section \ref{sec:query-api}. Lastly, we leave off with some +benchmarks in Section \ref{sec:benchmarks}, related work in Section +\ref{sec:related} and conclusions are Section \ref{sec:conclusions}. + +\section{Problem Definition} +\label{sec:problem-definition} + +Druid was originally designed to solve problems around ingesting and exploring +large quantities of transactional events (log data). This form of timeseries data is +commonly found in OLAP workflows and the nature of the data tends to be very +append heavy. For example, consider the data shown in +Table~\ref{tab:sample_data}. Table~\ref{tab:sample_data} contains data for +edits that have occured on Wikipedia. Each time a user edits a page in +Wikipedia, an event is generated that contains metadata about the edit. This +metadata is comprised of 3 distinct components. First, there is a timestamp +column indicating when the edit was made. Next, there are a set dimension +columns indicating various attributes about the edit such as the page that was +edited, the user who made the edit, and the location of the user. Finally, +there are a set of metric columns that contain values (usually numeric) to +aggregate over, such as the number of characters added or removed in an edit. \begin{table*} \centering - \caption{Sample Druid data} + \caption{Sample Druid data for edits that have occurred on Wikipedia.} \label{tab:sample_data} \begin{tabular}{| l | l | l | l | l | l | l | l |} \hline - \textbf{Timestamp} & \textbf{Publisher} & \textbf{Advertiser} & \textbf{Gender} & \textbf{Country} & \textbf{Impressions} & \textbf{Clicks} & \textbf{Revenue} \\ \hline - 2011-01-01T01:00:00Z & bieberfever.com & google.com & Male & USA & 1800 & 25 & 15.70 \\ \hline - 2011-01-01T01:00:00Z & bieberfever.com & google.com & Male & USA & 2912 & 42 & 29.18 \\ \hline - 2011-01-01T02:00:00Z & ultratrimfast.com & google.com & Male & USA & 1953 & 17 & 17.31 \\ \hline - 2011-01-01T02:00:00Z & ultratrimfast.com & google.com & Male & USA & 3194 & 170 & 34.01 \\ \hline + \textbf{Timestamp} & \textbf{Page} & \textbf{Username} & \textbf{Gender} & \textbf{City} & \textbf{Characters Added} & \textbf{Characters Removed} \\ \hline + 2011-01-01T01:00:00Z & Justin Bieber & Boxer & Male & San Francisco & 1800 & 25 \\ \hline + 2011-01-01T01:00:00Z & Justin Bieber & Reach & Male & Waterloo & 2912 & 42 \\ \hline + 2011-01-01T02:00:00Z & Ke\$ha & Helz & Male & Calgary & 1953 & 17 \\ \hline + 2011-01-01T02:00:00Z & Ke\$ha & Xeno & Male & Taiyuan & 3194 & 170 \\ \hline \end{tabular} \end{table*} -Druid always requires a timestamp column as a method of simplifying data distribution policies, data retention policies, and first-level query pruning. Druid partitions its data sources into well-defined time intervals, typically an hour or a day, and may further partition on values from other columns to achieve the desired segment size. Segments are uniquely identified by a data source -identifer, the time interval of the data, a version string that increases whenever a new segment is created, and a partition number. This segment metadata is used by the system for concurrency control; read operations always access data in a particular time range -from the segments with the latest version identifier for that time -range. +Our goal is to rapidly compute drill-downs and aggregates over this data. We +want to answer questions like “How many edits were made on the page Justin +Bieber from males in San Francisco?” and “What is the average number of +characters that were added by people from Calgary over the span of a month?”. We also +want queries over any arbitrary combination of dimensions to return with +sub-second latencies. -Most segments in a Druid cluster are immutable \emph{historical} segments. Such segments are persisted on local disk or in a distributed filesystem ("deep" storage) such as S3 \cite{decandia2007dynamo} or HDFS \cite{shvachko2010hadoop}. All historical -segments have associated metadata describing properties of the segment -such as size in bytes, compression format, and location in deep -storage. Data for intervals covered by historical segments can be updated by creating new historical segments that obsolete the old ones. +The need for Druid was faciliated by the fact that existing open source +Relational Database Management Systems and NoSQL key/value stores were unable +to provide a low latency data ingestion and query platform for interactive +applications \cite{tschetter2011druid}. In the early days of Metamarkets, the +company was focused on building a web-based dashboard that would allow users to +arbitrary explore and visualize event streams. Interactivity was very important +to us; we didn't want our users sitting around waiting for their data +visualizations to update. -Segments covering very recent intervals are mutable \emph{real-time} segments. Real-time segments are incrementally updated as new events are ingested, and are available for queries throughout the incremental indexing process. Periodically, real-time segments are converted into -historical segments through a finalization and handoff process described in Section~\ref{sec:realtime}. +In addition to the query latency needs, the system had to be multi-tenant and +highly available. Downtime is costly and many businesses cannot afford to wait +if a system is unavailable in the face of software upgrades or network failure. +Downtime for startups, many of whom have no internal operations teams, can +mean the difference between business success and failure. -Druid is best used for aggregating event streams, and both historical and real-time segments are built through an incremental indexing process that takes advantage of this assumption. Incremental indexing works by computing running aggregates of interesting metrics (e.g. number of impressions, sum of revenue from the data in Table~\ref{tab:sample_data}) across all rows that have identical attributes (e.g. publisher, advertiser). This often produces an order of magnitude compression in the data without sacrificing analytical value. Of course, this comes at the cost of not being able to support queries over the non-aggregated metrics. +Finally, another key problem that Metamarkets faced in the early stages of the +company was to allow users and alerting systems to be able to make business +decisions in real-time. The time from when an event was created to when that +event could be queried determined how fast users and systems were able to react +to potentially catastrophic occurences in their systems. -\section{Cluster} -\label{sec:cluster} -A Druid cluster consists of different types of nodes, each performing -a specific function. The composition of a Druid cluster is shown in -Figure~\ref{fig:druid_cluster}. +The problems of data exploration, ingestion, and availability span multiple +industries. Since Druid was open sourced in October 2012, it been deployed as a +video, network monitoring, operation monitoring, and advertising analytics +platform. + +\section{Architecture} +\label{sec:architecture} +A Druid cluster consists of different types of nodes and each node type is +designed to perform a very specific set of things. We believe this design +allows for a separation of functionality concerns and simplifies the +architecture and complexity of the system. There is minimal interaction +between the different node types and hence, intra-cluster communication +failures have minimal impact on data availability. The different node types +operate fairly independent of each other. To solve complex data analysis +problems, the node types come together to form a fully working system. The +name Druid comes from the Druid class in many role-playing games: it is a +shape-shifter, capable of taking many different forms to fulfill various +different roles in a group. The composition and flow of data of a Druid +cluster are shown in Figure~\ref{fig:cluster}. \begin{figure*} \centering -\includegraphics[width = 4.5in]{druid_cluster} -\caption{An overview of a Druid cluster.} -\label{fig:druid_cluster} +\includegraphics[width = 4.5in]{cluster} +\caption{An overview of a Druid cluster and the flow of data through the cluster.} +\label{fig:cluster} \end{figure*} -Recall that the Druid data model has the notion of historical and real-time segments. The Druid cluster is architected to reflect this -conceptual separation of data. Real-time nodes are responsible for -ingesting, storing, and responding to queries for the most recent -events. Similarly, historical historical nodes are responsible for -loading and responding to queries for historical events. +\subsection{Real-time Nodes} +\label{sec:realtime} +Real-time nodes encapsulate the functionality to ingest and query real-time +event streams. Events indexed via these nodes are immediately available for +querying. The nodes are only concerned with events for some small time range +and periodically hand off immutable batches of events they've collected over +this small time range to other nodes in the Druid cluster that are specialized +in dealing with batches of immutable events. -Data in Druid is stored on storage nodes. Storage nodes can be either -compute or real-time nodes. Queries to access this data will -typically first hit a layer of broker nodes. Broker nodes are -responsible for finding and routing queries down to the storage nodes -that host the pertinent data. The storage nodes compute their portion -of the query response in parallel and return their results to the -brokers. Broker nodes, historical nodes, and realtime nodes are jointly -classified as queryable nodes. +Real-time nodes maintain an in-memory index buffer for all incoming events. +These indexes are incrementally populated as new events are ingested and the +indexes are also directly queryable. Druid virtually behaves as a row store +for queries on events that exist in this JVM heap-based buffer. To avoid heap overflow +problems, real-time nodes persist their in-memory indexes to disk either +periodically or after some maximum row limit is reached. This persist process +converts data stored in the in-memory buffer to a column oriented storage +format described in \ref{sec:storage-format}. Each persisted index is immutable and +real-time nodes load persisted indexes into off-heap memory such that they can +still be queried. -Druid also has a set of coordination nodes to manage load assignment, -distribution, and replication. Coordination nodes are not queryable -and instead focus on maintaining cluster stability. Coordination nodes -have an external dependency on a MySQL database. +Real-time nodes maintain a consolidated view of their in-memory index and of +all indexes persisted to disk. This unified view allows all indexes on a node +to be queried. On a periodic basis, each node will schedule a background task +that searches for all locally persisted indexes. The task merges these indexes +together and builds an immutable block of data that contains all the events +that have ingested by a real-time node for some span of time. We refer to this +block of data as a "segment". During the hand-off stage, a real-time node +uploads this segment to a permanent backup storage, typically a distributed +file system such as S3 \cite{decandia2007dynamo} or HDFS +\cite{shvachko2010hadoop}, which Druid refers to as "deep storage". The ingest, +persist, merge, and handoff steps are fluid; there is no data loss during this +process. Figure~\ref{fig:realtime_flow} illustrates the process. -Druid relies on Apache Zookeeper \cite{hunt2010zookeeper} -for coordination. Most intra-cluster communication is over Zookeeper, although -queries are typically forwarded over HTTP. +\begin{figure} +\centering +\includegraphics[width = 2.8in]{realtime_flow} +\caption{Real-time nodes first buffer events in memory. After some period of +time, in-memory indexes are persisted to disk. After another period of time, +all persisted indexes are merged together and handed off. Queries on data hit +both the in-memory index and the persisted indexes.} +\label{fig:realtime_flow} +\end{figure} -\subsection{Historical historical nodes} -Historical historical nodes are the main workers of a Druid cluster and -are self-contained and self-sufficient. historical nodes load historical -segments from permanent/deep storage and expose them for -querying. There is no single point of contention between the nodes and -nodes have no knowledge of one another. historical nodes are -operationally simple; they only know how to perform the tasks they are -assigned. To help other services discover historical nodes and the data -they hold, every historical node maintains a constant Zookeeper -connection. historical nodes announce their online state and the segments -they serve by creating ephemeral nodes under specifically configured -Zookeeper paths. Instructions for a given historical node to load new -segments or drop existing segments are sent by creating ephemeral -znodes under a special “load queue” path associated with the compute -node. Figure~\ref{fig:zookeeper} illustrates a simple historical node and Zookeeper interaction. -Each historical node announces themselves under an "announcements" path when they come online -and each compute has a load queue path associated with it. +Real-time nodes leverage Zookeeper \cite{hunt2010zookeeper} for coordination +with the rest of the Druid cluster. The nodes announce their online state and +the data they are serving in Zookeeper. To better understand the flow of data +through a real-time node, consider the following example. First, we start a +real-time node at 13:37. The node will announce that it is serving a segment of +data for a period of time from 13:00 to 14:00 and will only accept events with +timestamps in this time range. Every 10 minutes (the persist period is +configurable), the node will flush and persist its in-memory buffer to disk. +Near the end of the hour, the node will likely see events with timestamps from +14:00 to 15:00. When this occurs, the real-time node prepares to serve data for +the next hour by creating a new in-memory index and announces that it is also +serving a segment for data from 14:00 to 15:00. The node does not immediately +merge the indexes it persisted from 13:00 to 14:00, instead it waits for a +configurable window period for straggling events from 13:00 to 14:00 to come +in. Having a window period minimizes the risk of data loss from delays in event +delivery. At the end of the window period, the real-time node merges all +persisted indexes from 13:00 to 14:00 into a single immutable segment and hands +the segment off. Once this segment is loaded and queryable somewhere else in +the Druid cluster, the real-time node flushes all information about the data it +has collected for 13:00 to 14:00 and unannounces it is serving this data. This +process is shown in Figure~\ref{fig:realtime_timeline}. + +\begin{figure*} +\centering +\includegraphics[width = 4.5in]{realtime_timeline} +\caption{A timelime that represents the typical operations a real-time node +undergoes. The node starts, ingests data, persists, and periodically hands data +off. This process repeats indefinitely. The time intervals between different +real-time node operations are configurable.} +\label{fig:realtime_timeline} +\end{figure*} + +\subsubsection{Availability and Scalability} +Real-time nodes are a consumer of data and require a corresponding producer to +provide the data stream. Typically, for data durability purposes, a message +bus such as Kafka \cite{kreps2011kafka} sits between the producer and the +real-time node as shown in Figure~\ref{fig:realtime_pipeline}. Real-time nodes +ingest data by reading events from the message bus. The time from event +creation to event consumption is typically on the order of hundreds of +milliseconds. \begin{figure} \centering -\includegraphics[width = 2.8in]{zookeeper} -\caption{historical nodes create ephemeral znodes under specifically configured Zookeeper paths.} -\label{fig:zookeeper} +\includegraphics[width = 2.8in]{realtime_pipeline} +\caption{Multiple real-time nodes can read from the same message bus. Each node maintains its own offset.} +\label{fig:realtime_pipeline} \end{figure} -To expose a segment for querying, a historical node must first possess a -local copy of the segment. Before a historical node downloads a segment -from deep storage, it first checks a local disk directory (cache) to -see if the segment already exists in local storage. If no cache -information about the segment is present, the historical node will -download metadata about the segment from Zookeeper. This metadata -includes information about where the segment is located in deep -storage and about how to decompress and process the segment. Once a -historical node completes processing a segment, the node announces (in -Zookeeper) that it is serving the segment. At this point, the segment -is queryable. +The purpose of the message bus in Figure~\ref{fig:realtime_pipeline} is two-fold. +First, the message bus acts as a buffer for incoming events. A message bus such +as Kafka maintains offsets indicating the position in an event stream that a +consumer (a real-time node) has read up to and consumers can programatically +update these offsets. Typically, real-time nodes update this offset each time +they persist their in-memory buffers to disk. This means that in a fail and +recover scenario, if a node has not lost disk, it can reload all persisted +indexes from disk and continue reading events from the last offset it +committed. Ingesting events from a recently committed offset greatly reduces a +node's recovery time. In practice, we see real-time nodes recover from such +failure scenarios in an order of seconds. +The second purpose of the message bus is to act as a single endpoint from which +multiple real-time nodes can read events. Multiple real-time nodes can ingest +the same set of events from the bus, thus creating a replication of events. In +a scenario where a node completely fails and does not recover, replicated +streams ensure that no data is lost. A single ingestion endpoint also allows +for data streams for be partitioned such that multiple real-time nodes may each +ingest a portion of a stream. This allows additional real-time nodes to be +seamlessly added. In practice, this model has allowed the largest production +Druid cluster that runs real-time nodes be able to consume raw data at +approximately 500 MB/s (150,000 events/s or 2 TB/hour). + +\subsection{Historical Nodes} +Historical nodes encapsulate the functionality to load and serve the immutable +blocks of data (segments) created by real-time nodes. In many real-world workflows, most +of the data loaded in a Druid cluster is immutable and hence, historical nodes +are typically the main workers of a Druid cluster. Historical nodes follow a +shared-nothing architecture and there is no single point of contention among +the nodes. The nodes have no knowledge of one another and are operationally +simple; they only know how to load, drop, and serve immutable segments. + +Similar to real-time nodes, historical nodes announce their online state and +the data they are serving in Zookeeper. Instructions to load and drop segments +are sent over Zookeeper and contain information about where the segment is +located in deep storage and about how to decompress and process the segment. +Before a historical node downloads a particular segment from deep storage, it +first checks a local cache that maintains information about what segments +already exist on the node. If information about a segment is not present, the +historical node will proceed to download the segment from deep storage. This +process is shown in Figure~\ref{fig:historical_download}. Once processing is +complete, the availability of the segment is announced. At this point, the +segment is queryable. The local cache also allows for historical nodes to be +quickly updated and restarted. On startup, the node examines its cache and +immediately serves whatever data it finds. + +\begin{figure} +\centering +\includegraphics[width = 2.8in]{historical_download} +\caption{Historical nodes download immutable segments from deep storage.} +\label{fig:historical_download} +\end{figure} + +Historical nodes can support read consistency because they only deal with +immutable data. Immutable data blocks also enable a simple parallelization +model: historical nodes can scan and aggregate immutable blocks concurrently +without blocking. + \subsubsection{Tiers} \label{sec:tiers} -historical nodes can be grouped in different tiers, where all nodes in a +Historical nodes can be grouped in different tiers, where all nodes in a given tier are identically configured. Different performance and fault-tolerance parameters can be set for each tier. The purpose of tiered nodes is to enable higher or lower priority segments to be distributed according to their importance. For example, it is possible to spin up a “hot” tier of historical nodes that have a high number of -cores and a large RAM capacity. The “hot” cluster can be configured to -download more frequently accessed segments. A parallel “cold” cluster +cores and large memory capacity. The “hot” cluster can be configured to +download more frequently accessed data. A parallel “cold” cluster can also be created with much less powerful backing hardware. The “cold” cluster would only contain less frequently accessed segments. -\subsection{Real-time Nodes} -\label{sec:realtime} -Real-time nodes encapsulate the functionality to ingest and query -real-time data streams. Data indexed via these nodes is immediately -available for querying. Real-time nodes are a consumer of data and -require a corresponding producer to provide the data -stream. Typically, for data durability purposes, a message bus such as -Kafka \cite{kreps2011kafka} sits between the producer and the real-time node as shown -in Figure~\ref{fig:data_reading}. - -The purpose of the message bus in Figure~\ref{fig:data_reading} is to act as a buffer for -incoming events. The message bus can maintain offsets indicating the -position in an event stream that a real-time node has read up to and -real-time nodes can update these offsets periodically. The message bus also acts as backup storage for recent events. -Real-time nodes ingest data by reading events from the message bus. The time from event creation to message bus storage to -event consumption is on the order of hundreds of milliseconds. - -Real-time nodes maintain an in-memory index buffer for all incoming -events. These indexes are incrementally populated as new events appear on the message bus. The indexes are also directly queryable. -Real-time nodes persist their indexes to disk either periodically or after some maximum row limit is -reached. After each persist, a real-time node updates the message bus -with the offset of the last event of the most recently persisted -index. Each persisted index is immutable. If a real-time node fails and recovers, it can simply reload -any indexes that were persisted to disk and continue reading the -message bus from the point the last offset was committed. Periodically committing offsets reduces the number of messages a real-time -node has to rescan after a failure scenario. - -Real-time nodes maintain a consolidated view of the currently updating -index and of all indexes persisted to disk. This unified view allows -all indexes on a node to be queried. On a periodic basis, the nodes will -schedule a background task that searches for all persisted indexes of -a data source. The task merges these indexes together and builds a -historical segment. The nodes will upload the segment to deep storage -and provide a signal for the historical historical nodes to begin serving -the segment. The ingest, persist, merge, and handoff steps are fluid; -there is no data loss as a real-time node converts a real-time segment -to a historical one. Figure~\ref{fig:data-durability} illustrates the process. - -Similar to historical nodes, real-time nodes announce segments in -Zookeeper. Unlike historical segments, real-time segments may -represent a period of time that extends into the future. For example, -a real-time node may announce it is serving a segment that contains -data for the current hour. Before the end of the hour, the real-time -node continues to collect data for the hour. Every 10 minutes (the -persist period is configurable), the node will flush and persist its -in-memory index to disk. At the end of the current hour, the real-time -node prepares to serve data for the next hour by creating a new index -and announcing a new segment for the next hour. The node does not -immediately merge and build a historical segment for the previous hour -until after some window period has passed. Having a window period -allows for straggling data points to come in and minimizes the risk of -data loss. At the end of the window period, the real-time node will -merge all persisted indexes, build a historical segment for the -previous hour, and hand the segment off to historical nodes to -serve. Once the segment is queryable on the historical nodes, the -real-time node flushes all information about the segment and -unannounces it is serving the segment. - -Real-time nodes are highly scalable. If the data volume and ingestion -rates for a given data source exceed the maximum capabilities of a -single node, additional nodes can be added. Multiple nodes can -consume events from the same stream, and every individual node only -holds a portion of the total number of events. This creates natural -partitions across nodes. Each node announces the real-time segment it -is serving and each real-time segment has a partition number. Data -from individual nodes will be merged at the broker level. To our -knowledge, the largest production level real-time Druid cluster is -consuming approximately 500MB/s (150,000 events/s or 2 TB/hour of raw data). - -\begin{figure} -\centering -\includegraphics[width = 2.8in]{data_reading} -\caption{Real-time data ingestion.} -\label{fig:data_reading} -\end{figure} - -\begin{figure} -\centering -\includegraphics[width = 2.8in]{druid_realtime_flow} -\caption{Real-time data durability} -\label{fig:data-durability} -\end{figure} +\subsubsection{Availability} +Historical nodes depend on Zookeeper for segment load and unload instructions. +If Zookeeper becomes unavailable, historical nodes are no longer able to serve +new data and drop outdated data, however, because the queries are served over +HTTP, historical nodes are still be able to respond to query requests for +the data they are currently serving. This means that Zookeeper outages do not +affect data availability on historical nodes. \subsection{Broker Nodes} -Broker nodes act as query routers to other queryable nodes such as -compute and real-time nodes. Broker nodes understand the metadata -published in Zookeeper about what segments exist and on what nodes the -segments are stored. Broker nodes route incoming queries such that the queries hit -the right storage nodes. Broker nodes also merge partial results from -storage nodes before returning a final consolidated result to the -caller. Additionally, brokers provide an extra level of data -durability as they maintain a cache of recent results. In the event -that multiple storage nodes fail and all copies of a segment are -somehow lost, it is still possible that segment results can still be -returned if that information exists in the cache. - -\subsubsection{Timeline} -To determine the correct nodes to forward queries to, brokers -first build a view of the world from information in Zookeeper. Recall -that Druid uses Zookeeper to maintain information about all compute -and real-time nodes in a cluster and the segments those nodes are -serving. For every data source in Zookeeper, the broker node builds a -timeline of segments for the data source and the nodes that serve them. A timeline -consists of segments and represents which segments contain data for -what ranges of time. Druid may have multiple segments where the data -source and interval are the same but versions differ. The timeline -view will always surface segments with the most recent version -identifier for a time range. If two segments intervals overlap, the segment with the more recent -version always has precedence. When queries are received for a specific -data source and interval, the broker node performs a lookup on the -timeline associated with the query data source for the query interval -and retrieves the segments that contain data for the query. The broker -node maps these segments to the storage nodes that serve them and -forwards the query down to the respective nodes. - +Broker nodes act as query routers to historical and real-time nodes. Broker +nodes understand the metadata published in Zookeeper about what segments are +queryable and where those segments are located. Broker nodes route incoming queries +such that the queries hit the right historical or real-time nodes. Broker nodes +also merge partial results from historical and real-time nodes before returning +a final consolidated result to the caller. \subsubsection{Caching} \label{sec:caching} -Broker nodes employ a distributed cache with a LRU \cite{o1993lru, -kim2001lrfu} cache invalidation strategy. The broker cache stores -per segment results. The cache can be local to each broker node or -shared across multiple nodes using an external distributed cache -such as memcached \cite{fitzpatrick2004distributed}. Recall that each time a broker node receives a -query, it first maps the query to a set of segments. A subset of -these segment results may already exist in the cache and the results -can be directly pulled from the cache. For any segment results that -do not exist in the cache, the broker node will forward the query -to the historical nodes. Once the historical nodes return their results, -the broker will store those results in the cache. Real-time segments -are never cached and hence requests for real-time data will always -be forwarded to real-time nodes. Real-time data is perpetually -changing and caching the results would be unreliable. +Broker nodes contain a cache with a LRU \cite{o1993lru, kim2001lrfu} cache +invalidation strategy. The cache can use local heap memory or an external +distributed store such as memcached \cite{fitzpatrick2004distributed}. Each +time a broker node receives a query, it first maps the query to a set of +segments. Results for certain segments may already exist in the cache and there +is no need to recompute them. For any results that do not exist in the cache, +the broker node will forward the query to the historical and real-time nodes. +Once the historical nodes return their results, the broker will cache these +results on a per segment basis for future use. This process is illustrated in +Figure~\ref{fig:caching}. Real-time data is never cached and hence requests for +real-time data will always be forwarded to real-time nodes. Real-time data is +perpetually changing and caching the results would be unreliable. +\begin{figure*} +\centering +\includegraphics[width = 4.5in]{caching} +\caption{Broker nodes cache per segment results. Every Druid query is mapped to +a set of segments. If segment results do not live in the cache, queries are +forwarded down to historical and real-time nodes.} +\label{fig:caching} +\end{figure*} -\subsection{Coordination (Master) Nodes} -The Druid coordination or master nodes are primarily in charge of -segment management and distribution. The Druid master is responsible -for loading new segments, dropping outdated segments, managing segment -replication, and balancing segment load. Druid uses a multi-version -concurrency control swapping protocol for managing segments in order -to maintain stable views. +The cache also acts as an additional level of data durability. In the event +that all historical nodes fail, it is still possible to query results if those +results already exist in the cache. -The Druid master runs periodically to determine the current state of -the cluster. It makes decisions by comparing the expected state of the -cluster with the actual state of the cluster at the time of the -run. As with all Druid nodes, the Druid master maintains a connection -to Zookeeper for current cluster information. The master also -maintains a connection to a MySQL database that contains additional -operational parameters and configurations. One of the key pieces of -information located in the MySQL database is a segment table that -contains a list of historical segments that should be served. This -table can be updated by any service that creates historical -segments. The MySQL database also contains a rule table that governs -how segments are created, destroyed, and replicated in the cluster. +\subsubsection{Availability} +In the event of a total Zookeeper outage, data is still queryable. If broker +nodes are unable to communicate to Zookeeper, they use their last known segment +to node mapping and continue forwarding queries down to real-time and +historical nodes. Broker nodes make the assumption that the structure of the +cluster is the same as it was before the outage. In practice, this availability +model has allowed our Druid cluster to continue serving queries for several +hours while we diagnosed Zookeeper outages. -The master does not directly communicate with a historical node when -assigning it work; instead the master creates an ephemeral znode in -Zookeeper containing information about what the historical node should -do. The historical node maintains a similar connection to Zookeeper to -monitor for new work. +\subsection{Coordinator Nodes} +The Druid coordinator nodes are primarily in charge of data management and +distribution on historical nodes. The coordinator nodes tell historical nodes +to load new data, drop outdated data, replicate data, and move data for load +balancing. Druid uses a multi-version concurrency control swapping protocol for +managing immutable segments in order to maintain stable views. If any +immutable segment contains data that is wholly obseleted by newer segments, the +outdated segment is dropped from the cluster. Coordinator nodes undergo a +leader-election process that determines a single node that runs the coordinator +functionality. The remaining coordinator nodes act as redundant backups. + +A coordinator node runs periodically to determine the current state of the +cluster. It makes decisions by comparing the expected state of the cluster with +the actual state of the cluster at the time of the run. As with all Druid +nodes, coordinator nodes maintains a Zookeeper connection for current cluster +information. The coordinator nodes also maintain a connection to a MySQL +database that contains additional operational parameters and configurations. +One of the key pieces of information located in the MySQL database is a table +that contains a list of all segments that should be served by historical nodes. +This table can be updated by any service that creates segments, for example, +real-time nodes. The MySQL database also contains a rule table that governs how +segments are created, destroyed, and replicated in the cluster. \subsubsection{Rules} -Rules govern how historical segments are loaded and dropped from the cluster. -Rules indicate how segments should be assigned to -different historical node tiers and how many replicates of a segment -should exist in each tier. Rules may also indicate when segments -should be dropped entirely from the cluster. Rules are usually set for a period of time. -For example, a user may use rules to load the most recent one month's worth of segments into a "hot" cluster, -the most recent one year's worth of segments into a "cold" cluster, and drop any segments that are older. +Rules govern how historical segments are loaded and dropped from the cluster. +Rules indicate how segments should be assigned to different historical node +tiers and how many replicates of a segment should exist in each tier. Rules may +also indicate when segments should be dropped entirely from the cluster. Rules +are usually set for a period of time. For example, a user may use rules to +load the most recent one month's worth of segments into a "hot" cluster, the +most recent one year's worth of segments into a "cold" cluster, and drop any +segments that are older. -The master loads a set of -rules from a rule table in the MySQL database. Rules may be specific -to a certain data source and/or a default set of rules may be -configured. The master will cycle through all available segments and -match each segment with the first rule that applies to it. +The coordinator nodes load a set of rules from a rule table in the MySQL +database. Rules may be specific to a certain data source and/or a default set +of rules may be configured. The master will cycle through all available +segments and match each segment with the first rule that applies to it. \subsubsection{Load Balancing} -In a typical production environment, queries often hit dozens or even -hundreds of data segments. Since each historical node has limited -resources, historical segments must be distributed among the cluster -to ensure that the cluster load is not too imbalanced. Determining -optimal load distribution requires some knowledge about query patterns -and speeds. Typically, queries cover recent data spanning contiguous -time intervals for a single data source. On average, queries that +In a typical production environment, queries often hit dozens or even hundreds +of segments. Since each historical node has limited resources, segments must be +distributed among the cluster to ensure that the cluster load is not too +imbalanced. Determining optimal load distribution requires some knowledge about +query patterns and speeds. Typically, queries cover recent segments spanning +contiguous time intervals for a single data source. On average, queries that access smaller segments are faster. -These query patterns suggest replicating recent historical segments at -a higher rate, spreading out large segments that are close in time to -different historical nodes, and co-locating segments from different data -sources. To optimally distribute and balance segments among the -cluster, we developed a cost-based optimization procedure that takes -into account the segment data source, recency, and size. The exact -details of the algorithm are beyond the scope of this paper and may be discussed in future literature. +These query patterns suggest replicating recent historical segments at a higher +rate, spreading out large segments that are close in time to different +historical nodes, and co-locating segments from different data sources. To +optimally distribute and balance segments among the cluster, we developed a +cost-based optimization procedure that takes into account the segment data +source, recency, and size. The exact details of the algorithm are beyond the +scope of this paper and may be discussed in future literature. -\section{Query API} -\label{sec:query-api} -Druid has its own query language and accepts queries as POST requests. All queryable -Druid nodes share the same query API. +\subsubsection{Replication} +Coordinator nodes may tell different historical nodes to load copies of the +same segment. The number of replicates in each tier of the historical compute +cluster is fully configurable. Setups that require high levels of fault +tolerance can be configured to have a high number of replicates. Replicated +segments are treated the same as the originals and follow the same load +distribution algorithms. By replicating segments, single historical node +failures are transparent in the Druid cluster. We use this property to our +advantage for software upgrades. We can seamlessly take a historical node +offline, update it, bring it back up, and repeat the process for every +historical node in a cluster. Over the last two years, we have never taken +downtime in our Druid cluster for software upgrades. -The body of the POST request is -a JSON object containing key-value pairs specifying various query -parameters. A typical query will contain the data source name, the -granularity of the result data, time range of interest, the -type of request, and the metrics to aggregate over. The result will also be a JSON object -containing the aggregated metrics over the time period. +\subsubsection{Availability} +Druid coordinator nodes have two external dependencies: Zookeeper and MySQL. +Coordinator nodes rely on Zookeeper to determine what historical nodes already +exist in the cluster. If Zookeeper becomes unavailable, the coordinator will no +longer be able to assign, balance, and drop segments. These operations do not +affect data availability at all and all data in the historical cluster should +still be queryable. -Most query types will also support a filter set. A filter set is a Boolean expression of dimension name and value -pairs. Any number and combination of dimensions and values may be specified. -When a filter set is provided, only the subset of the data that pertains to the filter set will be scanned. -The ability to handle complex nested filter sets is what enables Druid -to drill into data at any depth. +The design principle for responding to MySQL and Zookeeper failures is the +same: if an external dependency responsible for coordination fails, the cluster +maintains the status quo. Druid uses MySQL to store operational management +information and segment metadata information about what segments should exist +in the cluster. If MySQL goes down, this information becomes unavailable to +coordinator nodes. However, this does not mean data itself is not available. If +coordinator nodes cannot communicate to MySQL, they will cease to assign new +segments and drop outdated ones. Historical and real-time nodes are still +queryable during MySQL outages. -The exact query syntax depends on the query type and the information requested. -A sample time series query is shown below: -\begin{verbatim} -{ - "queryType" : "timeseries", - "dataSource" : "sample_data", - "intervals" : "2013-01-01/2013-01-02", - "filter" : { - "type" : "selector", - "dimension" : "poets", - "value" : "Ke$ha" - }, - "granularity" : "day", - "aggregations" : [ - { - "type" : "count", - "fieldName" : "row", - "name" : "row" - } - ] -} -\end{verbatim} +\section{Storage Format} +\label{sec:storage-format} +Data tables in Druid (called \emph{data sources}) are collections of +timestamped events and partitioned into a set of segments, where each segment +is typically 5--10 million rows. Formally, we define a segment as a collection +of rows of data that span some period in time. Segments represent the +fundamental storage unit in Druid and replication and distribution are done at +a segment level. + +Druid always requires a timestamp column as a method of simplifying data +distribution policies, data retention policies, and first-level query pruning. +Druid partitions its data sources into well-defined time intervals, typically +an hour or a day, and may further partition on values from other columns to +achieve the desired segment size. For example, partitioning the data in +Table~\ref{tab:sample_data} by hour results in two segments for 2011-01-01, and +partitioning the data by day results in a single segment. The time granularity +to partition segments is a function of data volume and time range. A data set +with timestamps spread over a year is better partitioned by day, and a data set +with timestamps spread over a day is better partitioned by hour. -It is beyond the scope of this paper to fully describe the query API. -We are also in the process of extending the Druid API to understand SQL. +Segments are uniquely identified by a data source identifer, the time interval +of the data, and a version string that increases whenever a new segment is +created. The version string indicates the freshness of segment data; segments +with later versions have newer views of data (over some time range) than +segments with older versions. This segment metadata is used by the system for +concurrency control; read operations always access data in a particular time +range from the segments with the latest version identifiers for that time +range. -\section{Storage} -\label{sec:storage} -Druid is a column-oriented data store. When considering aggregates -over a large number of events, the advantages storing data as columns -rather than rows are well documented \cite{cattell2011scalable}. Column storage allows for -more efficient CPU usage as only what is needed is actually loaded and -scanned. In a row oriented data store, all columns associated with a -row must be scanned as part of an aggregation. The additional scan -time can introduce performance degradations as high as 250\% \cite{bear2012vertica}. +Druid segments are stored in a column orientation. Given that Druid is best +used for aggregating event streams (all data going into Druid must have a +timestamp), the advantages storing aggregate information as columns rather than +rows are well documented \cite{abadi2008column}. Column storage allows for more +efficient CPU usage as only what is needed is actually loaded and scanned. In a +row oriented data store, all columns associated with a row must be scanned as +part of an aggregation. The additional scan time can introduce performance +degradations as high as 250\% \cite{bear2012vertica}. -\subsection{Column Types} -Druid has multiple column types to represent the various column value -formats. Depending on the column type, different compression methods -are used to reduce the cost of storing a column in memory and on -disk. In the example given in Table~\ref{tab:sample_data}, the -publisher, advertiser, gender, and country columns only contain -strings. String columns can be dictionary encoded. Dictionary encoding -is a common method to compress data and has been used in other data -stores such as PowerDrill \cite{hall2012processing}. In the example in +Druid has multiple column types to represent various data formats. Depending on +the column type, different compression methods are used to reduce the cost of +storing a column in memory and on disk. In the example given in +Table~\ref{tab:sample_data}, the page, user, gender, and city columns only +contain strings. String columns can be dictionary encoded. Dictionary encoding +is a common method to compress data and has been used in other data stores such +as PowerDrill \cite{hall2012processing}. In the example in Table~\ref{tab:sample_data}, we can map each publisher to an unique integer identifier. \begin{verbatim} -bieberfever.com -> 0 -ultratrimfast.com -> 1 +Justin Bieber -> 0 +Ke$ha -> 1 \end{verbatim} -This mapping allows us to represent the publisher column as an integer +This mapping allows us to represent the page column as an integer array where the array indices correspond to the rows of the original -data set. For the publisher column, we can represent the unique -publishers as follows: +data set. For the page column, we can represent the unique +pages as follows: \begin{verbatim} [0, 0, 1, 1] \end{verbatim} @@ -534,39 +549,42 @@ extremely common in column-stores. Druid uses the LZF \cite{liblzf2013} compress algorithm. Similar compression methods can be applied to numeric -columns. For example, the clicks and revenue columns in +columns. For example, the characters added and characters removed columns in Table~\ref{tab:sample_data} can also be expressed as individual arrays. \begin{verbatim} -Clicks -> [25, 42, 17, 170] -Revenue -> [15.70, 29.18, 17.31, 34.01] +Characters Added -> [1800, 2912, 1953, 3194] +Characters Removed -> [25, 42, 17, 170] \end{verbatim} -In this case we compress the raw values as opposed to their dictionary +In this case, we compress the raw values as opposed to their dictionary representations. -\subsection{Filters} -To support arbitrary filter sets, Druid creates additional lookup -indices for string columns. These lookup indices are compressed and -Druid operates over the indices in their compressed form. Filters can -be expressed as Boolean equations of multiple lookup indices. Boolean -operations of indices in their compressed form is both performance and -space efficient. +\subsection{Inverted Indices} +In most real world data analytic workflows, queries are issued for the +aggregated results for some set of metrics where some set of dimension +specifications are met. For example, "how many Wikipedia edits were done by +users in San Francisco who are also male"? These queries are filtering the data +based on some a boolean expression of dimension values. In many real world data +sets, string columns are typically dimension columns and metric columns are +typically numeric columns. Druid creates additional lookup indices for string +columns such that only those rows that pertain to a particular query filter are +ever scanned. -Let us consider the publisher column in -Table~\ref{tab:sample_data}. For each unique publisher in +Let us consider the page column in +Table~\ref{tab:sample_data}. For each unique page in Table~\ref{tab:sample_data}, we can form some representation -indicating which table rows a particular publisher is seen. We can +indicating in which table rows a particular page is seen. We can store this information in a binary array where the array indices -represent our rows. If a particular publisher is seen in a certain +represent our rows. If a particular page is seen in a certain row, that array index is marked as \texttt{1}. For example: \begin{verbatim} -bieberfever.com -> rows [0, 1] -> [1][1][0][0] -ultratrimfast.com -> rows [2, 3] -> [0][0][1][1] +Justin Bieber -> rows [0, 1] -> [1][1][0][0] +Ke$ha -> rows [2, 3] -> [0][0][1][1] \end{verbatim} -\texttt{\href{http://bieberfever.com}{bieberfever.com}} is seen in rows \texttt{0} and \texttt{1}. This mapping of column values +\texttt{Justin Bieber} is seen in rows \texttt{0} and \texttt{1}. This mapping of column values to row indices forms an inverted index \cite{tomasic1993performance}. To know which -rows contain {\ttfamily bieberfever.com} or {\ttfamily ultratrimfast.com}, we can \texttt{OR} together +rows contain {\ttfamily Justin Bieber} or {\ttfamily Ke\$ha}, we can \texttt{OR} together the two arrays. \begin{verbatim} [0][1][0][1] OR [1][0][1][0] = [1][1][1][1] @@ -579,95 +597,136 @@ the two arrays. \label{fig:concise_plot} \end{figure} -This approach of performing Boolean operations on large bitmap sets is -commonly used in search engines. Bitmap compression algorithms are a -well-defined area of research and often utilize run-length -encoding. Popular algorithms include Byte-aligned Bitmap Code \cite{antoshenkov1995byte}, -Word-Aligned Hybrid (WAH) code \cite{wu2006optimizing}, and Partitioned Word-Aligned -Hybrid (PWAH) compression \cite{van2011memory}. Druid opted to use the Concise -algorithm \cite{colantonio2010concise} as it can outperform WAH by reducing the size of the -compressed bitmaps by up to 50\%. Figure~\ref{fig:concise_plot} illustrates the number of -bytes using Concise compression versus using an integer array. The -results were generated on a cc2.8xlarge system with a single thread, -2G heap, 512m young gen, and a forced GC between each run. The data -set is a single day’s worth of data collected from the Twitter garden -hose \cite{twitter2013} data stream. The data set contains 2,272,295 rows and 12 -dimensions of varying cardinality. As an additional comparison, we -also resorted the data set rows to maximize compression. +This approach of performing Boolean operations on large bitmap sets is commonly +used in search engines. Bitmap compression algorithms are a well-defined area +of research and often utilize run-length encoding. Popular algorithms include +Byte-aligned Bitmap Code \cite{antoshenkov1995byte}, Word-Aligned Hybrid (WAH) +code \cite{wu2006optimizing}, and Partitioned Word-Aligned Hybrid (PWAH) +compression \cite{van2011memory}. Druid opted to use the Concise algorithm +\cite{colantonio2010concise} as it can outperform WAH by reducing the size of +the compressed bitmaps by up to 50\%. Figure~\ref{fig:concise_plot} +illustrates the number of bytes using Concise compression versus using an +integer array. The results were generated on a cc2.8xlarge system with a single +thread, 2G heap, 512m young gen, and a forced GC between each run. The data set +is a single day’s worth of data collected from the Twitter garden hose +\cite{twitter2013} data stream. The data set contains 2,272,295 rows and 12 +dimensions of varying cardinality. As an additional comparison, we also +resorted the data set rows to maximize compression. -In the unsorted case, the total Concise size was -53,451,144 bytes and the total integer array size was 127,248,520 bytes. Overall, -Concise compressed sets are about 42\% smaller than integer arrays. -In the sorted case, the total Concise compressed size was 43,832,884 -bytes and the total integer array size was 127,248,520 bytes. What is -interesting to note is that after sorting, global compression only -increased minimally. The total Concise set size to total integer array -size is 34\%. It is also interesting to note that as the cardinality -of a dimension approaches the total number of rows in a data set, -integer arrays require less space than Concise sets and become a better alternative. +In the unsorted case, the total Concise size was 53,451,144 bytes and the total +integer array size was 127,248,520 bytes. Overall, Concise compressed sets are +about 42\% smaller than integer arrays. In the sorted case, the total Concise +compressed size was 43,832,884 bytes and the total integer array size was +127,248,520 bytes. What is interesting to note is that after sorting, global +compression only increased minimally. The total Concise set size to total +integer array size is 34\%. It is also interesting to note that as the +cardinality of a dimension approaches the total number of rows in a data set, +integer arrays require less space than Concise sets and become a better +alternative. \subsection{Storage Engine} -Druid’s persistence components allows for different storage engines to -be plugged in, similar to Dynamo \cite{decandia2007dynamo}. These storage engines may store -data in in-memory structures such as the JVM heap or in memory-mapped +Druid’s persistence components allows for different storage engines to be +plugged in, similar to Dynamo \cite{decandia2007dynamo}. These storage engines +may store data in in-memory structures such as the JVM heap or in memory-mapped structures. The ability to swap storage engines allows for Druid to be -configured depending on a particular application’s specifications. An -in-memory storage engine may be operationally more expensive than a -memory-mapped storage engine but could be a better alternative if -performance is critical. At Metamarkets, we commonly use a -memory-mapped storage engine. +configured depending on a particular application’s specifications. An in-memory +storage engine may be operationally more expensive than a memory-mapped storage +engine but could be a better alternative if performance is critical. By +default, a memory-mapped storage engine is used. -\section{Robustness} -\label{sec:robustness} -To achieve high system availability and data durability, Druid employs -several fault recovery techniques. Druid has no single point of -failure. +Druid relies on the operating system to page segments in and out of memory. +Given that segments can only be scanned if they are loaded in memory, a +memory-mapped storage engine allows recent segments to retain in memory whereas +segments that are never queried are paged out of memory. The main drawback with +using the memory-mapped storage engine is in the event a query requires more +segments to be paged into memory than a given node has capacity for. In this +case, query performance will suffer from the cost of paging segments in and out +of memory. -\subsection{Replication} -Druid replicates historical segments on multiple hosts. The number of -replicates in each tier of the historical compute cluster is fully -configurable. Setups that require high levels of fault tolerance can -be configured to have a high number of replicates. Replicates are -assigned to historical nodes by coordination nodes using the same load -distribution algorithm discussed in Section~\ref{sec:caching}. Broker nodes forward queries to the first node they find that contain a segment required for the query. +\section{Query API} +\label{sec:query-api} +Druid has its own query language and accepts queries as POST requests. Broker, +historical, and real-time nodes all share the same query API. -Real-time segments follow a different replication model as real-time -segments are mutable. Multiple real-time nodes can read from the same message -bus and event stream if each node maintains a unique offset and consumer id, hence creating multiple copies -of a real-time segment. This is conceptually different than multiple -nodes reading from the same event stream and sharing the same offset and consumer id, doing so would create -multiple segment partitions. If a real-time node fails and recovers, it can -reload any indexes that were persisted to disk and read from the -message bus from the point it last committed an offset. +The body of the POST request is a JSON object containing key-value pairs +specifying various query parameters. A typical query will contain the data +source name, the granularity of the result data, time range of interest, the +type of request, and the metrics to aggregate over. The result will also be a +JSON object containing the aggregated metrics over the time period. -\subsection{Failure Detection} -If a historical node completely fails and becomes unavailable, the -ephemeral Zookeeper znodes it created are deleted. The master node -will notice that certain segments are insufficiently replicated or -missing altogether. Additional replicates will be created and -redistributed throughout the cluster. +Most query types will also support a filter set. A filter set is a Boolean +expression of dimension name and value pairs. Any number and combination of +dimensions and values may be specified. When a filter set is provided, only +the subset of the data that pertains to the filter set will be scanned. The +ability to handle complex nested filter sets is what enables Druid to drill +into data at any depth. -We are moving towards building out infrastructure to support -programmatic creation of real-time nodes. In the near future, the -master node or a similar service will notice if real-time segments are insufficiently -replicated and automatically create additional real-time nodes as -redundant backups. +The exact query syntax depends on the query type and the information requested. +A sample count query over a week of data is shown below: +\begin{verbatim} +{ + "queryType" : "timeseries", + "dataSource" : "wikipedia", + "intervals" : "2013-01-01/2013-01-08", + "filter" : { + "type" : "selector", + "dimension" : "page", + "value" : "Ke$ha" + }, + "granularity" : "day", + "aggregations" : [ + { + "type" : "count", + "name" : "rows" + } + ] +} +\end{verbatim} -Coordination and broker nodes always have redundant backup nodes in the event -the primary fails. The backup nodes are usually idle until Zookeeper changes alert -them to assume the responsibilities of their primary counterparts. +The query shown above will return a count of the number of rows in the \emph{wikipedia} datasource +from 2013-01-01 to 2013-01-08, filtered for only those rows where the value of the "page" dimension is +equal to "Ke\$ha". The results will be bucketed by day and will be a JSON array of the following form: +\begin{verbatim} +[ + { + "timestamp": "2012-01-01T00:00:00.000Z", + "result": { + "rows": 393298 + } + }, + { + "timestamp": "2012-01-02T00:00:00.000Z", + "result": { + "rows": 382932 + } + }, + ... + { + "timestamp": "2012-01-07T00:00:00.000Z", + "result": { + "rows": 1337 + } + } +] +\end{verbatim} -\subsection{Adding and Removing Nodes} -Starting and removing Druid nodes is done by starting and stopping Java processes. There is minimal -operational overhead with adding nodes in batches. Scaling down the -cluster is usually done one node at a time with some time lapse -between shutdowns. This allows the master to have ample time to -redistribute load and create additional replicates. Shutting down -nodes in batches is not recommended as it may destroy all -copies of a segment, which would lead to data loss. +Druid supports many types of aggregations including double sums, long sums, +minimums, maximums, and several others. Druid also supports complex aggregations +such as cardinality estimation and approxmiate quantile estimation. The +results of aggregations can be combined in mathematical expressions to form +other aggregations. The query API is highly customizable and can be extended to +filter and group results based on almost any arbitrary condition. It is beyond +the scope of this paper to fully describe the query API but more information +can be found +online\footnote{\href{http://druid.io/docs/latest/Querying.html}{http://druid.io/docs/latest/Querying.html}}. +We are also in the process of extending the Druid API to understand SQL. \section{Performance Benchmarks} \label{sec:benchmarks} +To illustrate Druid's performance, we conducted a series of experiments that +focused on measuring Druid's query and data ingestion capabilities. + +\subsection{Query Performance} \begin{figure} \centering \includegraphics[width = 2.8in]{cluster_scan_rate} @@ -675,21 +734,24 @@ copies of a segment, which would lead to data loss. from 25 nodes.} \label{fig:cluster_scan_rate} \end{figure} -To benchmark Druid performance, we created a large test cluster with -6TB of uncompressed data, representing tens of billions of fact -rows. The data set contained more than a dozen dimensions, with -cardinalities ranging from the double digits to tens of millions. We computed -four metrics for each row (counts, sums, and averages). The data was -sharded first on timestamp then on dimension values, creating -thousands of shards roughly 8 million fact rows apiece. +To benchmark Druid query performance, we created a large test cluster with 6TB +of uncompressed data, representing tens of billions of fact rows. The data set +contained more than a dozen dimensions, with cardinalities ranging from the +double digits to tens of millions. We computed four metrics for each row +(counts, sums, and averages). The data was sharded first on timestamp and then +on dimension values, creating thousands of shards roughly 8 million fact rows +apiece. -The cluster used in the benchmark consisted of 100 historical compute -nodes, each with 16 cores, 60GB of RAM, 10 GigE Ethernet, and 1TB of -disk space. Collectively, the cluster comprised of 1600 cores, 6TB or -RAM, sufficiently fast Ethernet and more than enough disk space. +The cluster used in the benchmark consisted of 100 historical nodes, each with +16 cores, 60GB of RAM, 10 GigE Ethernet, and 1TB of disk space. Collectively, +the cluster comprised of 1600 cores, 6TB or RAM, sufficiently fast Ethernet and +more than enough disk space. -SQL statements are included in Table~\ref{tab:sql_queries} to describe the -purpose of each of the queries. Please note: +SQL statements are included in Table~\ref{tab:sql_queries}. These queries are +meant to represent some common queries that are made against Druid for typical data +analysis workflows. Although Druid has its own query language, we choose to +translate the queries into SQL to better describe what the queries are doing. +Please note: \begin{itemize} \item The timestamp range of the queries encompassed all data. \item Each machine was a 16-core machine with 60GB RAM and 1TB of local @@ -724,18 +786,16 @@ purpose of each of the queries. Please note: Figure~\ref{fig:cluster_scan_rate} shows the cluster scan rate and Figure~\ref{fig:core_scan_rate} shows the core scan rate. In -Figure~\ref{fig:cluster_scan_rate} we also include projected linear -scaling based on the results of the 25 core cluster. In particular, -we observe diminishing marginal returns to performance in the size of -the cluster. Under linear scaling, SQL query 1 would have achieved a -speed of 37 billion rows per second on our 75 node cluster. In fact, -the speed was 26 billion rows per second. However, queries 2-6 maintain -a near-linear speedup up to 50 nodes: the core scan rates in -Figure~\ref{fig:core_scan_rate} remain nearly constant. -The increase in speed of a parallel -computing system is often limited by the time needed for the -sequential operations of the system, in accordance with Amdahl's law -\cite{amdahl1967validity}. +Figure~\ref{fig:cluster_scan_rate} we also include projected linear scaling +based on the results of the 25 core cluster. In particular, we observe +diminishing marginal returns to performance in the size of the cluster. Under +linear scaling, the first SQL count query (query 1) would have achieved a speed +of 37 billion rows per second on our 75 node cluster. In fact, the speed was +26 billion rows per second. However, queries 2-6 maintain a near-linear +speedup up to 50 nodes: the core scan rates in Figure~\ref{fig:core_scan_rate} +remain nearly constant. The increase in speed of a parallel computing system +is often limited by the time needed for the sequential operations of the +system, in accordance with Amdahl's law \cite{amdahl1967validity}. The first query listed in Table~\ref{tab:sql_queries} is a simple count, achieving scan rates of 33M rows/second/core. We believe @@ -752,36 +812,87 @@ because of the column-oriented storage format Druid employs. For the the ``where'' clause. As we add metrics, it has to also load those metric values and scan over them, increasing the amount of memory scanned. +\subsection{Data Ingestion Performance} +To measure Druid's data latency latency, we spun up a single real-time node +with the following configurations: +\begin{itemize} +\item JVM arguments: -Xmx2g -Duser.timezone=UTC -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError +\item CPU: 2.3 GHz Intel Core i7 +\end{itemize} + +Druid's data ingestion latency is heavily dependent on the complexity of the data set +being ingested. The data complexity is determined by the number of dimensions +in each event, the number of metrics in each event, and the types of +aggregations we want to perform as we roll up data to a certain time +granularity. With the most basic data set (one that only has a timestamp +column), our setup can ingest data at a rate of 800k events/sec/node, which is +really just a measurement of how fast we can deserialize events. Real world +data sets are never this simple. To simulate more real-world ingestion rates, +we created a data set with 5 dimensions and a single metric. 4 out of the 5 +dimensions have a cardinality less than 100, and we varied the cardinality of +the final dimension. The results of varying the cardinality of a dimension is +shown in Figure~\ref{fig:cardinality_vs_throughput}. +\begin{figure} +\centering +\includegraphics[width = 2.8in]{cardinality_vs_throughput} +\caption{Varying the cardinality of a single dimension, we can see the impact on throughput.} +\label{fig:cardinality_vs_throughput} +\end{figure} + +In Figure~\ref{fig:throughput_vs_num_dims}, we instead vary the number of +dimensions in our data set. Each dimension has a cardinality less than 100. We +can see a similar decline in ingestion throughput as the number of dimensions +increases. +\begin{figure} +\centering +\includegraphics[width = 2.8in]{throughput_vs_num_dims} +\caption{Increasing the number of dimensions of our data set, we see a similar decline in throughput.} +\label{fig:throughput_vs_num_dims} +\end{figure} + +Finally, keeping our number of dimensions constant at 5, with each dimension +having a cardinality in the 0-100 range, we can see a similar decline in +throughput when we increase the number of metrics in the data set. For most +real world data sets, the number of metrics tends to be less than the number of +dimensions. Hence, we can see that adding a few new metrics does not +substantially impact the ingestion latency. +\begin{figure} +\centering +\includegraphics[width = 2.8in]{ingestion_latency_vs_num_metrics} +\caption{Adding new metrics to a data set decreases ingestion latency, however, in most real world data sets, the number of metrics in a data set tends to be low and the impact of adding them is overly substantial.} +\label{fig:ingestion_latency_vs_num_metrics} +\end{figure} + \section{Related Work} \label{sec:related} -Cattell \cite{cattell2011scalable} maintains a great summary about existing Scalable SQL and -NoSQL data stores. Druid -feature-wise sits somewhere between Google’s Dremel \cite{melnik2010dremel} and PowerDrill -\cite{hall2012processing}. Druid has most of the features implemented in Dremel (Dremel -handles arbitrary nested data structures while Druid only allows for a -single level of array-based nesting) and many of the interesting -compression algorithms mentioned in PowerDrill. +Cattell \cite{cattell2011scalable} maintains a great summary about existing +Scalable SQL and NoSQL data stores. Hu \cite{hu2011stream} contributed another +great summary for streaming databases. Druid feature-wise sits somewhere +between Google’s Dremel \cite{melnik2010dremel} and PowerDrill +\cite{hall2012processing}. Druid has most of the features implemented in Dremel +(Dremel handles arbitrary nested data structures while Druid only allows for a +single level of array-based nesting) and many of the interesting compression +algorithms mentioned in PowerDrill. -Although Druid builds on many of the same principles as other -distributed columnar data stores \cite{fink2012distributed}, most existing data -stores are designed to be key-value stores \cite{lerner2010redis}, or -document/extensible record stores \cite{stonebraker2005c}. Such data stores are great -solutions for traditional data warehouse needs and general -back-office/reporting usage. Typically, analysts will query these data -stores and build reports from the results. In-memory databases such as -SAP’s HANA \cite{farber2012sap} and VoltDB \cite{voltdb2010voltdb} are examples of other data stores that -are highly suited for traditional data warehousing needs. Druid is a -front-office system designed such that user-facing dashboards can be -built on top of it. Similar to \cite{paraccel2013}, Druid has analytical features -built in. The main features Druid offers over traditional data -warehousing solutions are real-time data ingestion, interactive -queries and interactive query latencies. In terms of real-time -ingestion and processing of data, Trident/Storm \cite{marz2013storm} and Streaming -Spark \cite{zaharia2012discretized} are other popular real-time computation systems, although -they lack the data storage capabilities of Druid. Spark/Shark \cite{engle2012shark} are -also doing similar work in the area of fast data analysis on large -scale data sets. Cloudera Impala \cite{cloudera2013} is another system focused on -optimizing querying performance, but more so in Hadoop environments. +Although Druid builds on many of the same principles as other distributed +columnar data stores \cite{fink2012distributed}, many of these data stores are +designed to be more generic key-value stores \cite{stonebraker2005c} and do not +support computation directly in the storage layer. These data stores remain +popular solutions in the traditional data warehousing space. Other popular +systems designed for some of the same use cases that Druid is designed to solve +include in-memory databases such as SAP’s HANA \cite{farber2012sap} and VoltDB +\cite{voltdb2010voltdb}. Druid is a front-office system designed such that +user-facing dashboards can be built on top of it. Similar to +\cite{paraccel2013}, Druid has analytical features built in. The main features +Druid offers over traditional data warehousing solutions are real-time data +ingestion, interactive queries and interactive query latencies. In terms of +real-time ingestion and processing of data, Trident/Storm \cite{marz2013storm} +and Streaming Spark \cite{zaharia2012discretized} are other popular real-time +computation systems, although they lack the data storage capabilities of Druid. +Spark/Shark \cite{engle2012shark} are also doing similar work in the area of +fast data analysis on large scale data sets. Cloudera Impala +\cite{cloudera2013} is another system focused on optimizing querying +performance, but more so in Hadoop environments. Druid leverages a unique combination of algorithms in its architecture. Although we believe no other data store has the same set @@ -791,25 +902,23 @@ stores \cite{macnicol2004sybase}. \section{Conclusions} \label{sec:conclusions} -In this paper, we presented Druid, a distributed, column-oriented, -real-time analytical data store. Druid is a highly customizable -solution that is optimized for fast query latencies. Druid ingests -data in real-time and is fault-tolerant. We discussed the performance -of Druid on billion row data sets. We summarized key Druid architecture -aspects such as the storage format, query language and general -execution. In the future, we plan to cover more in depth the different -algorithms we’ve developed for Druid and how other systems may plug -into Druid to achieve powerful use cases. +In this paper, we presented Druid, a distributed, column-oriented, real-time +analytical data store. Druid is designed to power high performance applications +and is optimized for low query latencies. Druid ingests data in real-time and +is fault-tolerant. We discussed Druid performance benchmarks on billion row +data sets. We summarized key architecture aspects such as the storage format, +query language, and general execution. In the future, we plan to cover the +different algorithms we’ve developed for Druid and how other systems may plug +into Druid in greater detail. \balance \section{Acknowledgements} \label{sec:acknowledgements} -We want to thank Steve Harris for his feedback on improving this paper, Adam Smith for giving us the chance to write this paper, and Katherine Chu for -helping to create all the images in this paper. Druid could not have been built without the help of many great -engineers at Metamarkets and in the community. We want to thank Danny Yuan, Jae Hyeon Bae, Paul Baclace, Dave -Nielsen, and Dhruv Parthasarathy for their -contributions to Druid. +Druid could not have been built without the help of many great engineers at +Metamarkets and in the community. We want to thank everyone that has +contributed to the Druid codebase for their invaluable support. In particular +we want to thank Steve Harris for providing feedback on improving this paper. % The following two commands are all you need in the % initial runs of your .tex file to diff --git a/publications/whitepaper/figures/caching.png b/publications/whitepaper/figures/caching.png new file mode 100644 index 0000000000000000000000000000000000000000..e3ee4dd94df22a91d0a6b49cf2c4da153efcce67 GIT binary patch literal 36103 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 JWt~$(6990=t)2h? literal 0 HcmV?d00001 diff --git a/publications/whitepaper/figures/cardinality_vs_throughput.png b/publications/whitepaper/figures/cardinality_vs_throughput.png new file mode 100644 index 0000000000000000000000000000000000000000..6ef18cbfd199883789104352fedcf1ac791c8648 GIT binary patch literal 80455 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 literal 0 HcmV?d00001 diff --git a/publications/whitepaper/figures/cluster.png b/publications/whitepaper/figures/cluster.png new file mode 100644 index 0000000000000000000000000000000000000000..9dba85135383044f4d9efdef0552d1bf6f26e8ff GIT binary patch literal 53735 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 BMsENB literal 0 HcmV?d00001 diff --git a/publications/whitepaper/figures/historical_download.png b/publications/whitepaper/figures/historical_download.png new file mode 100644 index 0000000000000000000000000000000000000000..416d44bfc6c5f2d301323b4e2923d703c6e33db3 GIT binary patch literal 28917 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 z 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

    >VPNB?SG);Q7d@Y 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

    Jp*g8SsBmR`^#@Q?zKh0e0=-mZ)*g>}tC2 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 literal 0 HcmV?d00001 diff --git a/publications/whitepaper/figures/throughput_vs_num_dims.png b/publications/whitepaper/figures/throughput_vs_num_dims.png new file mode 100644 index 0000000000000000000000000000000000000000..60f4842a3cc3e35f1a0265630abcfac4c6abf8eb GIT binary patch literal 74606 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 Date: Thu, 5 Dec 2013 13:37:44 -0800 Subject: [PATCH 02/49] working pagination maybe --- .../io/druid/query/select/EventHolder.java | 68 +++++++++++++------ .../io/druid/query/select/PagingSpec.java | 47 ++++++++----- .../io/druid/query/select/SelectQuery.java | 5 +- .../druid/query/select/SelectQueryEngine.java | 38 +++++++++-- .../select/SelectQueryQueryToolChest.java | 11 +-- .../select/SelectQueryRunnerFactory.java | 11 +-- .../druid/query/select/SelectResultValue.java | 53 +++++++-------- .../select/SelectResultValueBuilder.java | 27 ++++++-- .../main/java/io/druid/segment/Cursor.java | 2 + .../segment/QueryableIndexStorageAdapter.java | 26 +++++-- .../IncrementalIndexStorageAdapter.java | 10 +++ .../io/druid/guice/QueryToolChestModule.java | 3 + 12 files changed, 205 insertions(+), 96 deletions(-) diff --git a/processing/src/main/java/io/druid/query/select/EventHolder.java b/processing/src/main/java/io/druid/query/select/EventHolder.java index d468e02281c..86a898a5d84 100644 --- a/processing/src/main/java/io/druid/query/select/EventHolder.java +++ b/processing/src/main/java/io/druid/query/select/EventHolder.java @@ -1,6 +1,26 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.query.select; -import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.Maps; import org.joda.time.DateTime; @@ -10,40 +30,44 @@ import java.util.Map; */ public class EventHolder { - private final long timestamp; - private final Map entries = Maps.newLinkedHashMap(); + public static final String timestampKey = "timestamp"; - public EventHolder(long timestamp) + private final String segmentId; + private final int offset; + private final Map event; + + @JsonCreator + public EventHolder( + @JsonProperty("segmentId") String segmentId, + @JsonProperty("offset") int offset, + @JsonProperty("event") Map event + ) { - this.timestamp = timestamp; + this.segmentId = segmentId; + this.offset = offset; + this.event = event; } - public void put(String key, Object val) + public DateTime getTimestamp() { - entries.put(key, val); + return (DateTime) event.get(timestampKey); } - public void putAll(Map data) + @JsonProperty + public String getSegmentId() { - entries.putAll(data); + return segmentId; } - public Object get(String key) + @JsonProperty + public int getOffset() { - return entries.get(key); + return offset; } - public long getTimestamp() + @JsonProperty + public Map getEvent() { - return timestamp; - } - - @JsonValue - public Map getBaseObject() - { - Map retVal = Maps.newLinkedHashMap(); - retVal.put("timestamp", new DateTime(timestamp)); - retVal.putAll(entries); - return retVal; + return event; } } diff --git a/processing/src/main/java/io/druid/query/select/PagingSpec.java b/processing/src/main/java/io/druid/query/select/PagingSpec.java index d831d68c140..f5596bd112c 100644 --- a/processing/src/main/java/io/druid/query/select/PagingSpec.java +++ b/processing/src/main/java/io/druid/query/select/PagingSpec.java @@ -1,42 +1,55 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.query.select; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.base.Preconditions; + +import java.util.Map; /** */ public class PagingSpec { - private final int start; - private final int end; + private final Map pagingIdentifiers; + private final int threshold; @JsonCreator public PagingSpec( - @JsonProperty("start") int start, - @JsonProperty("end") int end + @JsonProperty("pagingIdentifiers") Map pagingIdentifiers, + @JsonProperty("threshold") int threshold ) { - Preconditions.checkArgument(end > start, "end must be greater than start"); - - this.start = start; - this.end = end; + this.pagingIdentifiers = pagingIdentifiers; + this.threshold = threshold; } @JsonProperty - public int getStart() + public Map getPagingIdentifiers() { - return start; + return pagingIdentifiers; } @JsonProperty - public int getEnd() - { - return end; - } - public int getThreshold() { - return end - start; + return threshold; } } diff --git a/processing/src/main/java/io/druid/query/select/SelectQuery.java b/processing/src/main/java/io/druid/query/select/SelectQuery.java index 50b61e9466b..a4c924d6459 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQuery.java +++ b/processing/src/main/java/io/druid/query/select/SelectQuery.java @@ -37,7 +37,8 @@ import java.util.Map; @JsonTypeName("select") public class SelectQuery extends BaseQuery> { - private static final PagingSpec defaultPagingSpec = new PagingSpec(0, 10); + // TODO: remove this + private static final PagingSpec defaultPagingSpec = new PagingSpec(null, 5); private final DimFilter dimFilter; private final QueryGranularity granularity; @@ -148,6 +149,4 @@ public class SelectQuery extends BaseQuery> ", pagingSpec=" + pagingSpec + '}'; } - - } diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java index 44b9e4d5df1..8c7ab5d218b 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java +++ b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java @@ -29,10 +29,13 @@ import io.druid.query.Result; import io.druid.segment.Cursor; import io.druid.segment.DimensionSelector; import io.druid.segment.ObjectColumnSelector; +import io.druid.segment.QueryableIndex; +import io.druid.segment.Segment; import io.druid.segment.StorageAdapter; import io.druid.segment.TimestampColumnSelector; import io.druid.segment.data.IndexedInts; import io.druid.segment.filter.Filters; +import org.joda.time.DateTime; import java.util.Iterator; import java.util.List; @@ -42,7 +45,7 @@ import java.util.Map; */ public class SelectQueryEngine { - public Sequence> process(final SelectQuery query, final StorageAdapter adapter) + public Sequence> process(final SelectQuery query, final Segment segment) { return new BaseSequence<>( new BaseSequence.IteratorMaker, Iterator>>() @@ -50,6 +53,8 @@ public class SelectQueryEngine @Override public Iterator> make() { + final StorageAdapter adapter = segment.asStorageAdapter(); + final Iterable dims; if (query.getDimensions() == null || query.getDimensions().isEmpty()) { dims = adapter.getAvailableDimensions(); @@ -75,7 +80,11 @@ public class SelectQueryEngine public Result apply(Cursor cursor) { final TimestampColumnSelector timestampColumnSelector = cursor.makeTimestampColumnSelector(); - final SelectResultValueBuilder builder = new SelectResultValueBuilder(cursor.getTime(), query.getPagingSpec().getThreshold()); + final SelectResultValueBuilder builder = new SelectResultValueBuilder( + cursor.getTime(), + query.getPagingSpec() + .getThreshold() + ); final Map dimSelectors = Maps.newHashMap(); for (String dim : dims) { @@ -89,8 +98,20 @@ public class SelectQueryEngine metSelectors.put(metric, metricSelector); } - while (!cursor.isDone()) { - final EventHolder theEvent = new EventHolder(timestampColumnSelector.getTimestamp()); + int startOffset; + if (query.getPagingSpec().getPagingIdentifiers() == null) { + startOffset = 0; + } else { + Integer offset = query.getPagingSpec().getPagingIdentifiers().get(segment.getIdentifier()); + startOffset = (offset == null) ? 0 : offset; + } + + cursor.advanceTo(startOffset); + + int offset = 0; + while (!cursor.isDone() && offset < query.getPagingSpec().getThreshold()) { + final Map theEvent = Maps.newLinkedHashMap(); + theEvent.put(EventHolder.timestampKey, new DateTime(timestampColumnSelector.getTimestamp())); for (Map.Entry dimSelector : dimSelectors.entrySet()) { final String dim = dimSelector.getKey(); @@ -115,8 +136,15 @@ public class SelectQueryEngine theEvent.put(metric, selector.get()); } - builder.addEntry(theEvent); + builder.addEntry( + new EventHolder( + segment.getIdentifier(), + startOffset + offset, + theEvent + ) + ); cursor.advance(); + offset++; } return builder.build(); diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java b/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java index 1b810b30f73..181af647428 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java +++ b/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java @@ -24,7 +24,6 @@ import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Joiner; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.google.common.collect.Ordering; import com.google.inject.Inject; import com.metamx.common.guava.MergeSequence; @@ -42,7 +41,6 @@ import io.druid.query.QueryToolChest; import io.druid.query.Result; import io.druid.query.ResultGranularTimestampComparator; import io.druid.query.ResultMergeQueryRunner; -import io.druid.query.aggregation.AggregatorFactory; import io.druid.query.aggregation.MetricManipulationFn; import io.druid.query.filter.DimFilter; import org.joda.time.DateTime; @@ -53,7 +51,6 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Iterator; import java.util.List; -import java.util.Map; /** */ @@ -179,7 +176,11 @@ public class SelectQueryQueryToolChest extends QueryToolChest input) { - return Arrays.asList(input.getTimestamp().getMillis(), input.getValue().getBaseObject()); + return Arrays.asList( + input.getTimestamp().getMillis(), + input.getValue().getPagingIdentifiers(), + input.getValue().getEvents() + ); } }; } @@ -201,7 +202,7 @@ public class SelectQueryQueryToolChest extends QueryToolChest( timestamp, - new SelectResultValue(Lists.newArrayList(resultIter)) + new SelectResultValue(resultIter.next(), Lists.newArrayList(resultIter.next())) ); } }; diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java b/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java index 7e0c4905fd9..c4e50358b3e 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java +++ b/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java @@ -29,6 +29,7 @@ import io.druid.query.QueryRunner; import io.druid.query.QueryRunnerFactory; import io.druid.query.QueryToolChest; import io.druid.query.Result; +import io.druid.segment.QueryableIndex; import io.druid.segment.Segment; import io.druid.segment.StorageAdapter; @@ -63,7 +64,7 @@ public class SelectQueryRunnerFactory @Override public QueryRunner> createRunner(final Segment segment) { - return new SelectQueryRunner(engine, segment.asStorageAdapter()); + return new SelectQueryRunner(engine, segment); } @Override @@ -85,12 +86,12 @@ public class SelectQueryRunnerFactory private static class SelectQueryRunner implements QueryRunner> { private final SelectQueryEngine engine; - private final StorageAdapter adapter; + private final Segment segment; - private SelectQueryRunner(SelectQueryEngine engine, StorageAdapter adapter) + private SelectQueryRunner(SelectQueryEngine engine, Segment segment) { this.engine = engine; - this.adapter = adapter; + this.segment = segment; } @Override @@ -100,7 +101,7 @@ public class SelectQueryRunnerFactory throw new ISE("Got a [%s] which isn't a %s", input.getClass(), SelectQuery.class); } - return engine.process((SelectQuery) input, adapter); + return engine.process((SelectQuery) input, segment); } } } diff --git a/processing/src/main/java/io/druid/query/select/SelectResultValue.java b/processing/src/main/java/io/druid/query/select/SelectResultValue.java index a78c74ba123..a5910a89a15 100644 --- a/processing/src/main/java/io/druid/query/select/SelectResultValue.java +++ b/processing/src/main/java/io/druid/query/select/SelectResultValue.java @@ -20,6 +20,7 @@ package io.druid.query.select; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; import com.google.common.base.Function; import com.google.common.collect.Lists; @@ -33,44 +34,42 @@ import java.util.Map; */ public class SelectResultValue implements Iterable { - private final List value; + private final Map pagingIdentifiers; + private final List events; @JsonCreator public SelectResultValue( - List value - ) + @JsonProperty("pagingIdentifiers") Map pagingIdentifiers, + @JsonProperty("events") List events) { - this.value = (value == null) ? Lists.newArrayList() : Lists.transform( - value, - new Function() - { - @Override - public EventHolder apply(Object input) - { - if (input instanceof EventHolder) { - return (EventHolder) input; - } else if (input instanceof Map) { - long timestamp = (long) ((Map) input).remove("timestamp"); - EventHolder retVal = new EventHolder(timestamp); - retVal.putAll((Map) input); - return retVal; - } else { - throw new ISE("Unknown type : %s", input.getClass()); - } - } - } - ); + this.pagingIdentifiers = pagingIdentifiers; + this.events = events; } - @JsonValue - public List getBaseObject() + public SelectResultValue( + Object pagingIdentifiers, + List events + ) { - return value; + this.pagingIdentifiers = null; + this.events = null; + } + + @JsonProperty + public Map getPagingIdentifiers() + { + return pagingIdentifiers; + } + + @JsonProperty + public List getEvents() + { + return events; } @Override public Iterator iterator() { - return value.iterator(); + return events.iterator(); } } diff --git a/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java b/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java index a6f41e4a4c8..fe3ba09a946 100644 --- a/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java +++ b/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java @@ -20,6 +20,7 @@ package io.druid.query.select; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.MinMaxPriorityQueue; import com.google.common.primitives.Longs; import io.druid.query.Result; @@ -27,6 +28,7 @@ import org.joda.time.DateTime; import java.util.Comparator; import java.util.List; +import java.util.Map; /** */ @@ -37,7 +39,17 @@ public class SelectResultValueBuilder @Override public int compare(EventHolder o1, EventHolder o2) { - return Longs.compare(o1.getTimestamp(), o2.getTimestamp()); + int retVal = Longs.compare(o1.getTimestamp().getMillis(), o2.getTimestamp().getMillis()); + + if (retVal == 0) { + retVal = o1.getSegmentId().compareTo(o2.getSegmentId()); + } + + if (retVal == 0) { + retVal = Integer.compare(o1.getOffset(), o2.getOffset()); + } + + return retVal; } }; @@ -55,26 +67,27 @@ public class SelectResultValueBuilder instantiatePQueue(threshold, comparator); } - public SelectResultValueBuilder addEntry( + public void addEntry( EventHolder event ) { pQueue.add(event); - - return this; } public Result build() { - // Pull out top aggregated values + // Pull out top aggregated values List values = Lists.newArrayListWithCapacity(pQueue.size()); + Map pagingIdentifiers = Maps.newHashMap(); while (!pQueue.isEmpty()) { - values.add(pQueue.remove()); + EventHolder event = pQueue.remove(); + pagingIdentifiers.put(event.getSegmentId(), event.getOffset()); + values.add(event); } return new Result( timestamp, - new SelectResultValue(values) + new SelectResultValue(pagingIdentifiers, values) ); } diff --git a/processing/src/main/java/io/druid/segment/Cursor.java b/processing/src/main/java/io/druid/segment/Cursor.java index 42ed6b337af..34070e3f15d 100644 --- a/processing/src/main/java/io/druid/segment/Cursor.java +++ b/processing/src/main/java/io/druid/segment/Cursor.java @@ -21,10 +21,12 @@ package io.druid.segment;import org.joda.time.DateTime; /** */ + public interface Cursor extends ColumnSelectorFactory { public DateTime getTime(); public void advance(); + public void advanceTo(int offset); public boolean isDone(); public void reset(); } diff --git a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java index 4e06e4abd4c..eb73fa559f3 100644 --- a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java @@ -231,6 +231,16 @@ public class QueryableIndexStorageAdapter implements StorageAdapter cursorOffset.increment(); } + @Override + public void advanceTo(int offset) + { + int count = 0; + while (count < offset && !isDone()) { + advance(); + count++; + } + } + @Override public boolean isDone() { @@ -251,7 +261,9 @@ public class QueryableIndexStorageAdapter implements StorageAdapter @Override public long getTimestamp() { - return index.getTimeColumn().getGenericColumn().getLongSingleValueRow(cursorOffset.getOffset()); + return index.getTimeColumn() + .getGenericColumn() + .getLongSingleValueRow(cursorOffset.getOffset()); } }; } @@ -269,8 +281,7 @@ public class QueryableIndexStorageAdapter implements StorageAdapter if (column == null) { return null; - } - else if (columnDesc.getCapabilities().hasMultipleValues()) { + } else if (columnDesc.getCapabilities().hasMultipleValues()) { return new DimensionSelector() { @Override @@ -628,6 +639,12 @@ public class QueryableIndexStorageAdapter implements StorageAdapter ++currRow; } + @Override + public void advanceTo(int offset) + { + currRow += offset; + } + @Override public boolean isDone() { @@ -666,8 +683,7 @@ public class QueryableIndexStorageAdapter implements StorageAdapter if (dict == null) { return null; - } - else if (column.getCapabilities().hasMultipleValues()) { + } else if (column.getCapabilities().hasMultipleValues()) { return new DimensionSelector() { @Override diff --git a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java index b4d6460dba2..d0243f39123 100644 --- a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java @@ -213,6 +213,16 @@ public class IncrementalIndexStorageAdapter implements StorageAdapter } } + @Override + public void advanceTo(int offset) + { + int count = 0; + while (count < offset && !isDone()) { + advance(); + count++; + } + } + @Override public boolean isDone() { diff --git a/server/src/main/java/io/druid/guice/QueryToolChestModule.java b/server/src/main/java/io/druid/guice/QueryToolChestModule.java index 7c4981560d8..96625d4e9ed 100644 --- a/server/src/main/java/io/druid/guice/QueryToolChestModule.java +++ b/server/src/main/java/io/druid/guice/QueryToolChestModule.java @@ -34,6 +34,8 @@ import io.druid.query.metadata.metadata.SegmentMetadataQuery; import io.druid.query.search.SearchQueryQueryToolChest; import io.druid.query.search.search.SearchQuery; import io.druid.query.search.search.SearchQueryConfig; +import io.druid.query.select.SelectQuery; +import io.druid.query.select.SelectQueryQueryToolChest; import io.druid.query.timeboundary.TimeBoundaryQuery; import io.druid.query.timeboundary.TimeBoundaryQueryQueryToolChest; import io.druid.query.timeseries.TimeseriesQuery; @@ -52,6 +54,7 @@ public class QueryToolChestModule implements Module .put(TimeBoundaryQuery.class, TimeBoundaryQueryQueryToolChest.class) .put(SegmentMetadataQuery.class, SegmentMetadataQueryQueryToolChest.class) .put(GroupByQuery.class, GroupByQueryQueryToolChest.class) + .put(SelectQuery.class, SelectQueryQueryToolChest.class) .build(); @Override From 60d72a0fd33cc8a6d8d44f33c63a36e1f8887f04 Mon Sep 17 00:00:00 2001 From: fjy Date: Thu, 5 Dec 2013 16:24:54 -0800 Subject: [PATCH 03/49] add flushing plumber --- .../realtime/plumber/FlushingPlumber.java | 97 +++ .../plumber/FlushingPlumberSchool.java | 126 ++++ .../realtime/plumber/PlumberSchool.java | 7 +- .../realtime/plumber/RealtimePlumber.java | 706 ++++++++++++++++++ .../plumber/RealtimePlumberSchool.java | 632 +--------------- 5 files changed, 949 insertions(+), 619 deletions(-) create mode 100644 server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java create mode 100644 server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumberSchool.java create mode 100644 server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java new file mode 100644 index 00000000000..37c7b842fc8 --- /dev/null +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -0,0 +1,97 @@ +package io.druid.segment.realtime.plumber; + +import com.metamx.common.concurrent.ScheduledExecutors; +import com.metamx.emitter.EmittingLogger; +import com.metamx.emitter.service.ServiceEmitter; +import io.druid.query.QueryRunnerFactoryConglomerate; +import io.druid.segment.IndexGranularity; +import io.druid.segment.realtime.FireDepartmentMetrics; +import io.druid.segment.realtime.Schema; +import io.druid.server.coordination.DataSegmentAnnouncer; +import org.joda.time.Duration; +import org.joda.time.Period; + +import java.io.File; +import java.util.Map; +import java.util.concurrent.ExecutorService; + +/** + */ +public class FlushingPlumber extends RealtimePlumber +{ + private static final EmittingLogger log = new EmittingLogger(FlushingPlumber.class); + + private final Duration flushDuration; + + public FlushingPlumber( + Duration flushDuration, + Period windowPeriod, + File basePersistDirectory, + IndexGranularity segmentGranularity, + Schema schema, + FireDepartmentMetrics metrics, + RejectionPolicy rejectionPolicy, + ServiceEmitter emitter, + QueryRunnerFactoryConglomerate conglomerate, + DataSegmentAnnouncer segmentAnnouncer, + ExecutorService queryExecutorService, + VersioningPolicy versioningPolicy + ) + { + super( + windowPeriod, + basePersistDirectory, + segmentGranularity, + schema, + metrics, + rejectionPolicy, + emitter, + conglomerate, + segmentAnnouncer, + queryExecutorService, + versioningPolicy, + null, + null, + null + ); + + this.flushDuration = flushDuration; + } + + @Override + public void startJob() + { + computeBaseDir(getSchema()).mkdirs(); + initializeExecutors(); + bootstrapSinksFromDisk(); + startPersistThread(); + } + + protected void flushAfterDuration(final long truncatedTime, final Sink sink) + { + ScheduledExecutors.scheduleWithFixedDelay( + getScheduledExecutor(), + flushDuration, + new Runnable() + { + @Override + public void run() + { + abandonSegment(truncatedTime, sink); + } + } + + ); + } + + @Override + public void finishJob() + { + log.info("Shutting down..."); + + for (final Map.Entry entry : getSinks().entrySet()) { + flushAfterDuration(entry.getKey(), entry.getValue()); + } + shutdownScheduledExecutor(); + } +} diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumberSchool.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumberSchool.java new file mode 100644 index 00000000000..6e9e74260fa --- /dev/null +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumberSchool.java @@ -0,0 +1,126 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.segment.realtime.plumber; + +import com.fasterxml.jackson.annotation.JacksonInject; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Preconditions; +import com.metamx.emitter.EmittingLogger; +import com.metamx.emitter.service.ServiceEmitter; +import io.druid.guice.annotations.Processing; +import io.druid.query.QueryRunnerFactoryConglomerate; +import io.druid.segment.IndexGranularity; +import io.druid.segment.realtime.FireDepartmentMetrics; +import io.druid.segment.realtime.Schema; +import io.druid.server.coordination.DataSegmentAnnouncer; +import org.joda.time.Duration; +import org.joda.time.Period; + +import javax.validation.constraints.NotNull; +import java.io.File; +import java.util.concurrent.ExecutorService; + +/** + * This plumber just drops segments at the end of a flush duration instead of handing them off. It is only useful if you want to run + * a real time node without the rest of the Druid cluster. + */ +public class FlushingPlumberSchool implements PlumberSchool +{ + private static final EmittingLogger log = new EmittingLogger(FlushingPlumberSchool.class); + + private final Duration flushDuration; + private final Period windowPeriod; + private final File basePersistDirectory; + private final IndexGranularity segmentGranularity; + + @JacksonInject + @NotNull + private volatile ServiceEmitter emitter; + + @JacksonInject + @NotNull + private volatile QueryRunnerFactoryConglomerate conglomerate = null; + + @JacksonInject + @NotNull + private volatile DataSegmentAnnouncer segmentAnnouncer = null; + + @JacksonInject + @NotNull + @Processing + private volatile ExecutorService queryExecutorService = null; + + private volatile VersioningPolicy versioningPolicy = null; + private volatile RejectionPolicyFactory rejectionPolicyFactory = null; + + @JsonCreator + public FlushingPlumberSchool( + @JsonProperty("flushDuration") Duration flushDuration, + @JsonProperty("windowPeriod") Period windowPeriod, + @JsonProperty("basePersistDirectory") File basePersistDirectory, + @JsonProperty("segmentGranularity") IndexGranularity segmentGranularity + ) + { + this.flushDuration = flushDuration; + this.windowPeriod = windowPeriod; + this.basePersistDirectory = basePersistDirectory; + this.segmentGranularity = segmentGranularity; + this.versioningPolicy = new IntervalStartVersioningPolicy(); + this.rejectionPolicyFactory = new ServerTimeRejectionPolicyFactory(); + + Preconditions.checkNotNull(flushDuration, "FlushingPlumberSchool requires a flushDuration."); + Preconditions.checkNotNull(windowPeriod, "FlushingPlumberSchool requires a windowPeriod."); + Preconditions.checkNotNull(basePersistDirectory, "FlushingPlumberSchool requires a basePersistDirectory."); + Preconditions.checkNotNull(segmentGranularity, "FlushingPlumberSchool requires a segmentGranularity."); + } + + @Override + + public Plumber findPlumber(final Schema schema, final FireDepartmentMetrics metrics) + { + verifyState(); + + final RejectionPolicy rejectionPolicy = rejectionPolicyFactory.create(windowPeriod); + log.info("Creating plumber using rejectionPolicy[%s]", rejectionPolicy); + + return new FlushingPlumber( + flushDuration, + windowPeriod, + basePersistDirectory, + segmentGranularity, + schema, + metrics, + rejectionPolicy, + emitter, + conglomerate, + segmentAnnouncer, + queryExecutorService, + versioningPolicy + ); + } + + private void verifyState() + { + Preconditions.checkNotNull(conglomerate, "must specify a queryRunnerFactoryConglomerate to do this action."); + Preconditions.checkNotNull(segmentAnnouncer, "must specify a segmentAnnouncer to do this action."); + Preconditions.checkNotNull(emitter, "must specify a serviceEmitter to do this action."); + } +} diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/PlumberSchool.java b/server/src/main/java/io/druid/segment/realtime/plumber/PlumberSchool.java index f1e186011da..a2495fba178 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/PlumberSchool.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/PlumberSchool.java @@ -27,9 +27,10 @@ import io.druid.segment.realtime.Schema; /** */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") -@JsonSubTypes( - @JsonSubTypes.Type(name = "realtime", value = RealtimePlumberSchool.class) -) +@JsonSubTypes(value = { + @JsonSubTypes.Type(name = "realtime", value = RealtimePlumberSchool.class), + @JsonSubTypes.Type(name = "flushing", value = FlushingPlumberSchool.class) +}) public interface PlumberSchool { /** diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java new file mode 100644 index 00000000000..ef9d0b6ba0b --- /dev/null +++ b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java @@ -0,0 +1,706 @@ +package io.druid.segment.realtime.plumber; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.base.Throwables; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.primitives.Ints; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.metamx.common.Pair; +import com.metamx.common.concurrent.ScheduledExecutors; +import com.metamx.common.guava.FunctionalIterable; +import com.metamx.emitter.EmittingLogger; +import com.metamx.emitter.service.ServiceEmitter; +import com.metamx.emitter.service.ServiceMetricEvent; +import io.druid.client.DruidServer; +import io.druid.client.ServerView; +import io.druid.common.guava.ThreadRenamingCallable; +import io.druid.common.guava.ThreadRenamingRunnable; +import io.druid.query.MetricsEmittingQueryRunner; +import io.druid.query.Query; +import io.druid.query.QueryRunner; +import io.druid.query.QueryRunnerFactory; +import io.druid.query.QueryRunnerFactoryConglomerate; +import io.druid.query.QueryToolChest; +import io.druid.query.SegmentDescriptor; +import io.druid.query.spec.SpecificSegmentQueryRunner; +import io.druid.query.spec.SpecificSegmentSpec; +import io.druid.segment.IndexGranularity; +import io.druid.segment.IndexIO; +import io.druid.segment.IndexMerger; +import io.druid.segment.QueryableIndex; +import io.druid.segment.QueryableIndexSegment; +import io.druid.segment.Segment; +import io.druid.segment.loading.DataSegmentPusher; +import io.druid.segment.realtime.FireDepartmentMetrics; +import io.druid.segment.realtime.FireHydrant; +import io.druid.segment.realtime.Schema; +import io.druid.segment.realtime.SegmentPublisher; +import io.druid.server.coordination.DataSegmentAnnouncer; +import io.druid.timeline.DataSegment; +import io.druid.timeline.TimelineObjectHolder; +import io.druid.timeline.VersionedIntervalTimeline; +import io.druid.timeline.partition.SingleElementPartitionChunk; +import org.apache.commons.io.FileUtils; +import org.joda.time.DateTime; +import org.joda.time.Duration; +import org.joda.time.Interval; +import org.joda.time.Period; + +import javax.annotation.Nullable; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +/** + */ +public class RealtimePlumber implements Plumber +{ + private static final EmittingLogger log = new EmittingLogger(RealtimePlumber.class); + + private final Period windowPeriod; + private final File basePersistDirectory; + private final IndexGranularity segmentGranularity; + private final Schema schema; + private final FireDepartmentMetrics metrics; + private final RejectionPolicy rejectionPolicy; + private final ServiceEmitter emitter; + private final QueryRunnerFactoryConglomerate conglomerate; + private final DataSegmentAnnouncer segmentAnnouncer; + private final ExecutorService queryExecutorService; + private final VersioningPolicy versioningPolicy; + private final DataSegmentPusher dataSegmentPusher; + private final SegmentPublisher segmentPublisher; + private final ServerView serverView; + + + private final Object handoffCondition = new Object(); + private final Map sinks = Maps.newConcurrentMap(); + private final VersionedIntervalTimeline sinkTimeline = new VersionedIntervalTimeline( + String.CASE_INSENSITIVE_ORDER + ); + + private volatile boolean shuttingDown = false; + private volatile boolean stopped = false; + private volatile ExecutorService persistExecutor = null; + private volatile ScheduledExecutorService scheduledExecutor = null; + + public RealtimePlumber( + Period windowPeriod, + File basePersistDirectory, + IndexGranularity segmentGranularity, + Schema schema, + FireDepartmentMetrics metrics, + RejectionPolicy rejectionPolicy, + ServiceEmitter emitter, + QueryRunnerFactoryConglomerate conglomerate, + DataSegmentAnnouncer segmentAnnouncer, + ExecutorService queryExecutorService, + VersioningPolicy versioningPolicy, + DataSegmentPusher dataSegmentPusher, + SegmentPublisher segmentPublisher, + ServerView serverView + ) + { + this.windowPeriod = windowPeriod; + this.basePersistDirectory = basePersistDirectory; + this.segmentGranularity = segmentGranularity; + this.schema = schema; + this.metrics = metrics; + this.rejectionPolicy = rejectionPolicy; + this.emitter = emitter; + this.conglomerate = conglomerate; + this.segmentAnnouncer = segmentAnnouncer; + this.queryExecutorService = queryExecutorService; + this.versioningPolicy = versioningPolicy; + this.dataSegmentPusher = dataSegmentPusher; + this.segmentPublisher = segmentPublisher; + this.serverView = serverView; + } + + public Schema getSchema() + { + return schema; + } + + public ScheduledExecutorService getScheduledExecutor() + { + return scheduledExecutor; + } + + public Map getSinks() + { + return sinks; + } + + @Override + public void startJob() + { + computeBaseDir(schema).mkdirs(); + initializeExecutors(); + bootstrapSinksFromDisk(); + registerServerViewCallback(); + startPersistThread(); + } + + @Override + public Sink getSink(long timestamp) + { + if (!rejectionPolicy.accept(timestamp)) { + return null; + } + + final long truncatedTime = segmentGranularity.truncate(timestamp); + + Sink retVal = sinks.get(truncatedTime); + + if (retVal == null) { + final Interval sinkInterval = new Interval( + new DateTime(truncatedTime), + segmentGranularity.increment(new DateTime(truncatedTime)) + ); + + retVal = new Sink(sinkInterval, schema, versioningPolicy.getVersion(sinkInterval)); + + try { + segmentAnnouncer.announceSegment(retVal.getSegment()); + sinks.put(truncatedTime, retVal); + sinkTimeline.add(retVal.getInterval(), retVal.getVersion(), new SingleElementPartitionChunk(retVal)); + } + catch (IOException e) { + log.makeAlert(e, "Failed to announce new segment[%s]", schema.getDataSource()) + .addData("interval", retVal.getInterval()) + .emit(); + } + } + + return retVal; + } + + @Override + public QueryRunner getQueryRunner(final Query query) + { + final QueryRunnerFactory> factory = conglomerate.findFactory(query); + final QueryToolChest> toolchest = factory.getToolchest(); + + final Function, ServiceMetricEvent.Builder> builderFn = + new Function, ServiceMetricEvent.Builder>() + { + + @Override + public ServiceMetricEvent.Builder apply(@Nullable Query input) + { + return toolchest.makeMetricBuilder(query); + } + }; + + List> querySinks = Lists.newArrayList(); + for (Interval interval : query.getIntervals()) { + querySinks.addAll(sinkTimeline.lookup(interval)); + } + + return toolchest.mergeResults( + factory.mergeRunners( + queryExecutorService, + FunctionalIterable + .create(querySinks) + .transform( + new Function, QueryRunner>() + { + @Override + public QueryRunner apply(TimelineObjectHolder holder) + { + final Sink theSink = holder.getObject().getChunk(0).getObject(); + return new SpecificSegmentQueryRunner( + new MetricsEmittingQueryRunner( + emitter, + builderFn, + factory.mergeRunners( + MoreExecutors.sameThreadExecutor(), + Iterables.transform( + theSink, + new Function>() + { + @Override + public QueryRunner apply(FireHydrant input) + { + return factory.createRunner(input.getSegment()); + } + } + ) + ) + ), + new SpecificSegmentSpec( + new SegmentDescriptor( + holder.getInterval(), + theSink.getSegment().getVersion(), + theSink.getSegment().getShardSpec().getPartitionNum() + ) + ) + ); + } + } + ) + ) + ); + } + + @Override + public void persist(final Runnable commitRunnable) + { + final List> indexesToPersist = Lists.newArrayList(); + for (Sink sink : sinks.values()) { + if (sink.swappable()) { + indexesToPersist.add(Pair.of(sink.swap(), sink.getInterval())); + } + } + + log.info("Submitting persist runnable for dataSource[%s]", schema.getDataSource()); + + persistExecutor.execute( + new ThreadRenamingRunnable(String.format("%s-incremental-persist", schema.getDataSource())) + { + @Override + public void doRun() + { + for (Pair pair : indexesToPersist) { + metrics.incrementRowOutputCount(persistHydrant(pair.lhs, schema, pair.rhs)); + } + commitRunnable.run(); + } + } + ); + } + + // Submits persist-n-merge task for a Sink to the persistExecutor + private void persistAndMerge(final long truncatedTime, final Sink sink) + { + final String threadName = String.format( + "%s-%s-persist-n-merge", schema.getDataSource(), new DateTime(truncatedTime) + ); + persistExecutor.execute( + new ThreadRenamingRunnable(threadName) + { + @Override + public void doRun() + { + final Interval interval = sink.getInterval(); + + for (FireHydrant hydrant : sink) { + if (!hydrant.hasSwapped()) { + log.info("Hydrant[%s] hasn't swapped yet, swapping. Sink[%s]", hydrant, sink); + final int rowCount = persistHydrant(hydrant, schema, interval); + metrics.incrementRowOutputCount(rowCount); + } + } + + final File mergedTarget = new File(computePersistDir(schema, interval), "merged"); + if (mergedTarget.exists()) { + log.info("Skipping already-merged sink: %s", sink); + return; + } + + File mergedFile = null; + try { + List indexes = Lists.newArrayList(); + for (FireHydrant fireHydrant : sink) { + Segment segment = fireHydrant.getSegment(); + final QueryableIndex queryableIndex = segment.asQueryableIndex(); + log.info("Adding hydrant[%s]", fireHydrant); + indexes.add(queryableIndex); + } + + mergedFile = IndexMerger.mergeQueryableIndex( + indexes, + schema.getAggregators(), + mergedTarget + ); + + QueryableIndex index = IndexIO.loadIndex(mergedFile); + + DataSegment segment = dataSegmentPusher.push( + mergedFile, + sink.getSegment().withDimensions(Lists.newArrayList(index.getAvailableDimensions())) + ); + + segmentPublisher.publishSegment(segment); + } + catch (IOException e) { + log.makeAlert(e, "Failed to persist merged index[%s]", schema.getDataSource()) + .addData("interval", interval) + .emit(); + if (shuttingDown) { + // We're trying to shut down, and this segment failed to push. Let's just get rid of it. + abandonSegment(truncatedTime, sink); + } + } + + if (mergedFile != null) { + try { + log.info("Deleting Index File[%s]", mergedFile); + FileUtils.deleteDirectory(mergedFile); + } + catch (IOException e) { + log.warn(e, "Error deleting directory[%s]", mergedFile); + } + } + } + } + ); + } + + @Override + public void finishJob() + { + log.info("Shutting down..."); + + shuttingDown = true; + + for (final Map.Entry entry : sinks.entrySet()) { + persistAndMerge(entry.getKey(), entry.getValue()); + } + + while (!sinks.isEmpty()) { + try { + log.info( + "Cannot shut down yet! Sinks remaining: %s", + Joiner.on(", ").join( + Iterables.transform( + sinks.values(), + new Function() + { + @Override + public String apply(Sink input) + { + return input.getSegment().getIdentifier(); + } + } + ) + ) + ); + + synchronized (handoffCondition) { + while (!sinks.isEmpty()) { + handoffCondition.wait(); + } + } + } + catch (InterruptedException e) { + throw Throwables.propagate(e); + } + } + + shutdownScheduledExecutor(); + + stopped = true; + } + + protected void initializeExecutors() + { + if (persistExecutor == null) { + persistExecutor = Executors.newFixedThreadPool( + 1, + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("plumber_persist_%d") + .build() + ); + } + if (scheduledExecutor == null) { + scheduledExecutor = Executors.newScheduledThreadPool( + 1, + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("plumber_scheduled_%d") + .build() + ); + } + } + + protected void shutdownScheduledExecutor() + { + // scheduledExecutor is shutdown here, but persistExecutor is shutdown when the + // ServerView sends it a new segment callback + if (scheduledExecutor != null) { + scheduledExecutor.shutdown(); + } + } + + protected void bootstrapSinksFromDisk() + { + File baseDir = computeBaseDir(schema); + if (baseDir == null || !baseDir.exists()) { + return; + } + + File[] files = baseDir.listFiles(); + if (files == null) { + return; + } + + for (File sinkDir : files) { + Interval sinkInterval = new Interval(sinkDir.getName().replace("_", "/")); + + //final File[] sinkFiles = sinkDir.listFiles(); + // To avoid reading and listing of "merged" dir + final File[] sinkFiles = sinkDir.listFiles( + new FilenameFilter() + { + @Override + public boolean accept(File dir, String fileName) + { + return !(Ints.tryParse(fileName) == null); + } + } + ); + Arrays.sort( + sinkFiles, + new Comparator() + { + @Override + public int compare(File o1, File o2) + { + try { + return Ints.compare(Integer.parseInt(o1.getName()), Integer.parseInt(o2.getName())); + } + catch (NumberFormatException e) { + log.error(e, "Couldn't compare as numbers? [%s][%s]", o1, o2); + return o1.compareTo(o2); + } + } + } + ); + + try { + List hydrants = Lists.newArrayList(); + for (File segmentDir : sinkFiles) { + log.info("Loading previously persisted segment at [%s]", segmentDir); + + // Although this has been tackled at start of this method. + // Just a doubly-check added to skip "merged" dir. from being added to hydrants + // If 100% sure that this is not needed, this check can be removed. + if (Ints.tryParse(segmentDir.getName()) == null) { + continue; + } + + hydrants.add( + new FireHydrant( + new QueryableIndexSegment(null, IndexIO.loadIndex(segmentDir)), + Integer.parseInt(segmentDir.getName()) + ) + ); + } + + Sink currSink = new Sink(sinkInterval, schema, versioningPolicy.getVersion(sinkInterval), hydrants); + sinks.put(sinkInterval.getStartMillis(), currSink); + sinkTimeline.add( + currSink.getInterval(), + currSink.getVersion(), + new SingleElementPartitionChunk(currSink) + ); + + segmentAnnouncer.announceSegment(currSink.getSegment()); + } + catch (IOException e) { + log.makeAlert(e, "Problem loading sink[%s] from disk.", schema.getDataSource()) + .addData("interval", sinkInterval) + .emit(); + } + } + } + + protected void startPersistThread() + { + final long truncatedNow = segmentGranularity.truncate(new DateTime()).getMillis(); + final long windowMillis = windowPeriod.toStandardDuration().getMillis(); + + log.info( + "Expect to run at [%s]", + new DateTime().plus( + new Duration(System.currentTimeMillis(), segmentGranularity.increment(truncatedNow) + windowMillis) + ) + ); + + ScheduledExecutors + .scheduleAtFixedRate( + scheduledExecutor, + new Duration(System.currentTimeMillis(), segmentGranularity.increment(truncatedNow) + windowMillis), + new Duration(truncatedNow, segmentGranularity.increment(truncatedNow)), + new ThreadRenamingCallable( + String.format( + "%s-overseer-%d", + schema.getDataSource(), + schema.getShardSpec().getPartitionNum() + ) + ) + { + @Override + public ScheduledExecutors.Signal doCall() + { + if (stopped) { + log.info("Stopping merge-n-push overseer thread"); + return ScheduledExecutors.Signal.STOP; + } + + log.info("Starting merge and push."); + + long minTimestamp = segmentGranularity.truncate( + rejectionPolicy.getCurrMaxTime().minus(windowMillis) + ).getMillis(); + + List> sinksToPush = Lists.newArrayList(); + for (Map.Entry entry : sinks.entrySet()) { + final Long intervalStart = entry.getKey(); + if (intervalStart < minTimestamp) { + log.info("Adding entry[%s] for merge and push.", entry); + sinksToPush.add(entry); + } + } + + for (final Map.Entry entry : sinksToPush) { + persistAndMerge(entry.getKey(), entry.getValue()); + } + + if (stopped) { + log.info("Stopping merge-n-push overseer thread"); + return ScheduledExecutors.Signal.STOP; + } else { + return ScheduledExecutors.Signal.REPEAT; + } + } + } + ); + } + + /** + * Unannounces a given sink and removes all local references to it. + */ + protected void abandonSegment(final long truncatedTime, final Sink sink) + { + try { + segmentAnnouncer.unannounceSegment(sink.getSegment()); + FileUtils.deleteDirectory(computePersistDir(schema, sink.getInterval())); + log.info("Removing sinkKey %d for segment %s", truncatedTime, sink.getSegment().getIdentifier()); + sinks.remove(truncatedTime); + sinkTimeline.remove( + sink.getInterval(), + sink.getVersion(), + new SingleElementPartitionChunk<>(sink) + ); + synchronized (handoffCondition) { + handoffCondition.notifyAll(); + } + } + catch (IOException e) { + log.makeAlert(e, "Unable to abandon old segment for dataSource[%s]", schema.getDataSource()) + .addData("interval", sink.getInterval()) + .emit(); + } + } + + protected File computeBaseDir(Schema schema) + { + return new File(basePersistDirectory, schema.getDataSource()); + } + + protected File computePersistDir(Schema schema, Interval interval) + { + return new File(computeBaseDir(schema), interval.toString().replace("/", "_")); + } + + /** + * Persists the given hydrant and returns the number of rows persisted + * + * @param indexToPersist + * @param schema + * @param interval + * + * @return the number of rows persisted + */ + protected int persistHydrant(FireHydrant indexToPersist, Schema schema, Interval interval) + { + if (indexToPersist.hasSwapped()) { + log.info( + "DataSource[%s], Interval[%s], Hydrant[%s] already swapped. Ignoring request to persist.", + schema.getDataSource(), interval, indexToPersist + ); + return 0; + } + + log.info("DataSource[%s], Interval[%s], persisting Hydrant[%s]", schema.getDataSource(), interval, indexToPersist); + try { + int numRows = indexToPersist.getIndex().size(); + + File persistedFile = IndexMerger.persist( + indexToPersist.getIndex(), + new File(computePersistDir(schema, interval), String.valueOf(indexToPersist.getCount())) + ); + + indexToPersist.swapSegment(new QueryableIndexSegment(null, IndexIO.loadIndex(persistedFile))); + + return numRows; + } + catch (IOException e) { + log.makeAlert("dataSource[%s] -- incremental persist failed", schema.getDataSource()) + .addData("interval", interval) + .addData("count", indexToPersist.getCount()) + .emit(); + + throw Throwables.propagate(e); + } + } + + private void registerServerViewCallback() + { + serverView.registerSegmentCallback( + persistExecutor, + new ServerView.BaseSegmentCallback() + { + @Override + public ServerView.CallbackAction segmentAdded(DruidServer server, DataSegment segment) + { + if (stopped) { + log.info("Unregistering ServerViewCallback"); + persistExecutor.shutdown(); + return ServerView.CallbackAction.UNREGISTER; + } + + if ("realtime".equals(server.getType())) { + return ServerView.CallbackAction.CONTINUE; + } + + log.debug("Checking segment[%s] on server[%s]", segment, server); + if (schema.getDataSource().equals(segment.getDataSource())) { + final Interval interval = segment.getInterval(); + for (Map.Entry entry : sinks.entrySet()) { + final Long sinkKey = entry.getKey(); + if (interval.contains(sinkKey)) { + final Sink sink = entry.getValue(); + log.info("Segment[%s] matches sink[%s] on server[%s]", segment, sink, server); + + final String segmentVersion = segment.getVersion(); + final String sinkVersion = sink.getSegment().getVersion(); + if (segmentVersion.compareTo(sinkVersion) >= 0) { + log.info("Segment version[%s] >= sink version[%s]", segmentVersion, sinkVersion); + abandonSegment(sinkKey, sink); + } + } + } + } + + return ServerView.CallbackAction.CONTINUE; + } + } + ); + } +} diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumberSchool.java b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumberSchool.java index 35abfcaf866..ecaf10e3e4b 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumberSchool.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumberSchool.java @@ -22,70 +22,23 @@ package io.druid.segment.realtime.plumber; import com.fasterxml.jackson.annotation.JacksonInject; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.base.Function; -import com.google.common.base.Joiner; import com.google.common.base.Preconditions; -import com.google.common.base.Throwables; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.primitives.Ints; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.metamx.common.Pair; -import com.metamx.common.concurrent.ScheduledExecutors; -import com.metamx.common.guava.FunctionalIterable; import com.metamx.emitter.EmittingLogger; import com.metamx.emitter.service.ServiceEmitter; -import com.metamx.emitter.service.ServiceMetricEvent; -import io.druid.client.DruidServer; import io.druid.client.ServerView; -import io.druid.common.guava.ThreadRenamingCallable; -import io.druid.common.guava.ThreadRenamingRunnable; import io.druid.guice.annotations.Processing; -import io.druid.query.MetricsEmittingQueryRunner; -import io.druid.query.Query; -import io.druid.query.QueryRunner; -import io.druid.query.QueryRunnerFactory; import io.druid.query.QueryRunnerFactoryConglomerate; -import io.druid.query.QueryToolChest; -import io.druid.query.SegmentDescriptor; -import io.druid.query.spec.SpecificSegmentQueryRunner; -import io.druid.query.spec.SpecificSegmentSpec; import io.druid.segment.IndexGranularity; -import io.druid.segment.IndexIO; -import io.druid.segment.IndexMerger; -import io.druid.segment.QueryableIndex; -import io.druid.segment.QueryableIndexSegment; -import io.druid.segment.Segment; import io.druid.segment.loading.DataSegmentPusher; import io.druid.segment.realtime.FireDepartmentMetrics; -import io.druid.segment.realtime.FireHydrant; import io.druid.segment.realtime.Schema; import io.druid.segment.realtime.SegmentPublisher; import io.druid.server.coordination.DataSegmentAnnouncer; -import io.druid.timeline.DataSegment; -import io.druid.timeline.TimelineObjectHolder; -import io.druid.timeline.VersionedIntervalTimeline; -import io.druid.timeline.partition.SingleElementPartitionChunk; -import org.apache.commons.io.FileUtils; -import org.joda.time.DateTime; -import org.joda.time.Duration; -import org.joda.time.Interval; import org.joda.time.Period; -import javax.annotation.Nullable; import javax.validation.constraints.NotNull; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; /** */ @@ -96,9 +49,6 @@ public class RealtimePlumberSchool implements PlumberSchool private final Period windowPeriod; private final File basePersistDirectory; private final IndexGranularity segmentGranularity; - private final Object handoffCondition = new Object(); - - private volatile boolean shuttingDown = false; @JacksonInject @NotNull @@ -205,572 +155,22 @@ public class RealtimePlumberSchool implements PlumberSchool final RejectionPolicy rejectionPolicy = rejectionPolicyFactory.create(windowPeriod); log.info("Creating plumber using rejectionPolicy[%s]", rejectionPolicy); - return new Plumber() - { - private volatile boolean stopped = false; - private volatile ExecutorService persistExecutor = null; - private volatile ScheduledExecutorService scheduledExecutor = null; - - private final Map sinks = Maps.newConcurrentMap(); - private final VersionedIntervalTimeline sinkTimeline = new VersionedIntervalTimeline( - String.CASE_INSENSITIVE_ORDER - ); - - @Override - public void startJob() - { - computeBaseDir(schema).mkdirs(); - initializeExecutors(); - bootstrapSinksFromDisk(); - registerServerViewCallback(); - startPersistThread(); - } - - @Override - public Sink getSink(long timestamp) - { - if (!rejectionPolicy.accept(timestamp)) { - return null; - } - - final long truncatedTime = segmentGranularity.truncate(timestamp); - - Sink retVal = sinks.get(truncatedTime); - - if (retVal == null) { - final Interval sinkInterval = new Interval( - new DateTime(truncatedTime), - segmentGranularity.increment(new DateTime(truncatedTime)) - ); - - retVal = new Sink(sinkInterval, schema, versioningPolicy.getVersion(sinkInterval)); - - try { - segmentAnnouncer.announceSegment(retVal.getSegment()); - sinks.put(truncatedTime, retVal); - sinkTimeline.add(retVal.getInterval(), retVal.getVersion(), new SingleElementPartitionChunk(retVal)); - } - catch (IOException e) { - log.makeAlert(e, "Failed to announce new segment[%s]", schema.getDataSource()) - .addData("interval", retVal.getInterval()) - .emit(); - } - } - - return retVal; - } - - @Override - public QueryRunner getQueryRunner(final Query query) - { - final QueryRunnerFactory> factory = conglomerate.findFactory(query); - final QueryToolChest> toolchest = factory.getToolchest(); - - final Function, ServiceMetricEvent.Builder> builderFn = - new Function, ServiceMetricEvent.Builder>() - { - - @Override - public ServiceMetricEvent.Builder apply(@Nullable Query input) - { - return toolchest.makeMetricBuilder(query); - } - }; - - List> querySinks = Lists.newArrayList(); - for (Interval interval : query.getIntervals()) { - querySinks.addAll(sinkTimeline.lookup(interval)); - } - - return toolchest.mergeResults( - factory.mergeRunners( - queryExecutorService, - FunctionalIterable - .create(querySinks) - .transform( - new Function, QueryRunner>() - { - @Override - public QueryRunner apply(TimelineObjectHolder holder) - { - final Sink theSink = holder.getObject().getChunk(0).getObject(); - return new SpecificSegmentQueryRunner( - new MetricsEmittingQueryRunner( - emitter, - builderFn, - factory.mergeRunners( - MoreExecutors.sameThreadExecutor(), - Iterables.transform( - theSink, - new Function>() - { - @Override - public QueryRunner apply(FireHydrant input) - { - return factory.createRunner(input.getSegment()); - } - } - ) - ) - ), - new SpecificSegmentSpec( - new SegmentDescriptor( - holder.getInterval(), - theSink.getSegment().getVersion(), - theSink.getSegment().getShardSpec().getPartitionNum() - ) - ) - ); - } - } - ) - ) - ); - } - - @Override - public void persist(final Runnable commitRunnable) - { - final List> indexesToPersist = Lists.newArrayList(); - for (Sink sink : sinks.values()) { - if (sink.swappable()) { - indexesToPersist.add(Pair.of(sink.swap(), sink.getInterval())); - } - } - - log.info("Submitting persist runnable for dataSource[%s]", schema.getDataSource()); - - persistExecutor.execute( - new ThreadRenamingRunnable(String.format("%s-incremental-persist", schema.getDataSource())) - { - @Override - public void doRun() - { - for (Pair pair : indexesToPersist) { - metrics.incrementRowOutputCount(persistHydrant(pair.lhs, schema, pair.rhs)); - } - commitRunnable.run(); - } - } - ); - } - - // Submits persist-n-merge task for a Sink to the persistExecutor - private void persistAndMerge(final long truncatedTime, final Sink sink) - { - final String threadName = String.format( - "%s-%s-persist-n-merge", schema.getDataSource(), new DateTime(truncatedTime) - ); - persistExecutor.execute( - new ThreadRenamingRunnable(threadName) - { - @Override - public void doRun() - { - final Interval interval = sink.getInterval(); - - for (FireHydrant hydrant : sink) { - if (!hydrant.hasSwapped()) { - log.info("Hydrant[%s] hasn't swapped yet, swapping. Sink[%s]", hydrant, sink); - final int rowCount = persistHydrant(hydrant, schema, interval); - metrics.incrementRowOutputCount(rowCount); - } - } - - final File mergedTarget = new File(computePersistDir(schema, interval), "merged"); - if (mergedTarget.exists()) { - log.info("Skipping already-merged sink: %s", sink); - return; - } - - File mergedFile = null; - try { - List indexes = Lists.newArrayList(); - for (FireHydrant fireHydrant : sink) { - Segment segment = fireHydrant.getSegment(); - final QueryableIndex queryableIndex = segment.asQueryableIndex(); - log.info("Adding hydrant[%s]", fireHydrant); - indexes.add(queryableIndex); - } - - mergedFile = IndexMerger.mergeQueryableIndex( - indexes, - schema.getAggregators(), - mergedTarget - ); - - QueryableIndex index = IndexIO.loadIndex(mergedFile); - - DataSegment segment = dataSegmentPusher.push( - mergedFile, - sink.getSegment().withDimensions(Lists.newArrayList(index.getAvailableDimensions())) - ); - - segmentPublisher.publishSegment(segment); - } - catch (IOException e) { - log.makeAlert(e, "Failed to persist merged index[%s]", schema.getDataSource()) - .addData("interval", interval) - .emit(); - if (shuttingDown) { - // We're trying to shut down, and this segment failed to push. Let's just get rid of it. - abandonSegment(truncatedTime, sink); - } - } - - if (mergedFile != null) { - try { - log.info("Deleting Index File[%s]", mergedFile); - FileUtils.deleteDirectory(mergedFile); - } - catch (IOException e) { - log.warn(e, "Error deleting directory[%s]", mergedFile); - } - } - } - } - ); - } - - @Override - public void finishJob() - { - log.info("Shutting down..."); - - shuttingDown = true; - - for (final Map.Entry entry : sinks.entrySet()) { - persistAndMerge(entry.getKey(), entry.getValue()); - } - - while (!sinks.isEmpty()) { - try { - log.info( - "Cannot shut down yet! Sinks remaining: %s", - Joiner.on(", ").join( - Iterables.transform( - sinks.values(), - new Function() - { - @Override - public String apply(Sink input) - { - return input.getSegment().getIdentifier(); - } - } - ) - ) - ); - - synchronized (handoffCondition) { - while (!sinks.isEmpty()) { - handoffCondition.wait(); - } - } - } - catch (InterruptedException e) { - throw Throwables.propagate(e); - } - } - - // scheduledExecutor is shutdown here, but persistExecutor is shutdown when the - // ServerView sends it a new segment callback - if (scheduledExecutor != null) { - scheduledExecutor.shutdown(); - } - - stopped = true; - } - - private void initializeExecutors() - { - if (persistExecutor == null) { - persistExecutor = Executors.newFixedThreadPool( - 1, - new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("plumber_persist_%d") - .build() - ); - } - if (scheduledExecutor == null) { - scheduledExecutor = Executors.newScheduledThreadPool( - 1, - new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("plumber_scheduled_%d") - .build() - ); - } - } - - private void bootstrapSinksFromDisk() - { - File baseDir = computeBaseDir(schema); - if (baseDir == null || !baseDir.exists()) { - return; - } - - File[] files = baseDir.listFiles(); - if (files == null) { - return; - } - - for (File sinkDir : files) { - Interval sinkInterval = new Interval(sinkDir.getName().replace("_", "/")); - - //final File[] sinkFiles = sinkDir.listFiles(); - // To avoid reading and listing of "merged" dir - final File[] sinkFiles = sinkDir.listFiles( - new FilenameFilter() - { - @Override - public boolean accept(File dir, String fileName) - { - return !(Ints.tryParse(fileName) == null); - } - } - ); - Arrays.sort( - sinkFiles, - new Comparator() - { - @Override - public int compare(File o1, File o2) - { - try { - return Ints.compare(Integer.parseInt(o1.getName()), Integer.parseInt(o2.getName())); - } - catch (NumberFormatException e) { - log.error(e, "Couldn't compare as numbers? [%s][%s]", o1, o2); - return o1.compareTo(o2); - } - } - } - ); - - try { - List hydrants = Lists.newArrayList(); - for (File segmentDir : sinkFiles) { - log.info("Loading previously persisted segment at [%s]", segmentDir); - - // Although this has been tackled at start of this method. - // Just a doubly-check added to skip "merged" dir. from being added to hydrants - // If 100% sure that this is not needed, this check can be removed. - if (Ints.tryParse(segmentDir.getName()) == null) { - continue; - } - - hydrants.add( - new FireHydrant( - new QueryableIndexSegment(null, IndexIO.loadIndex(segmentDir)), - Integer.parseInt(segmentDir.getName()) - ) - ); - } - - Sink currSink = new Sink(sinkInterval, schema, versioningPolicy.getVersion(sinkInterval), hydrants); - sinks.put(sinkInterval.getStartMillis(), currSink); - sinkTimeline.add( - currSink.getInterval(), - currSink.getVersion(), - new SingleElementPartitionChunk(currSink) - ); - - segmentAnnouncer.announceSegment(currSink.getSegment()); - } - catch (IOException e) { - log.makeAlert(e, "Problem loading sink[%s] from disk.", schema.getDataSource()) - .addData("interval", sinkInterval) - .emit(); - } - } - } - - private void registerServerViewCallback() - { - serverView.registerSegmentCallback( - persistExecutor, - new ServerView.BaseSegmentCallback() - { - @Override - public ServerView.CallbackAction segmentAdded(DruidServer server, DataSegment segment) - { - if (stopped) { - log.info("Unregistering ServerViewCallback"); - persistExecutor.shutdown(); - return ServerView.CallbackAction.UNREGISTER; - } - - if ("realtime".equals(server.getType())) { - return ServerView.CallbackAction.CONTINUE; - } - - log.debug("Checking segment[%s] on server[%s]", segment, server); - if (schema.getDataSource().equals(segment.getDataSource())) { - final Interval interval = segment.getInterval(); - for (Map.Entry entry : sinks.entrySet()) { - final Long sinkKey = entry.getKey(); - if (interval.contains(sinkKey)) { - final Sink sink = entry.getValue(); - log.info("Segment[%s] matches sink[%s] on server[%s]", segment, sink, server); - - final String segmentVersion = segment.getVersion(); - final String sinkVersion = sink.getSegment().getVersion(); - if (segmentVersion.compareTo(sinkVersion) >= 0) { - log.info("Segment version[%s] >= sink version[%s]", segmentVersion, sinkVersion); - abandonSegment(sinkKey, sink); - } - } - } - } - - return ServerView.CallbackAction.CONTINUE; - } - } - ); - } - - private void startPersistThread() - { - final long truncatedNow = segmentGranularity.truncate(new DateTime()).getMillis(); - final long windowMillis = windowPeriod.toStandardDuration().getMillis(); - - log.info( - "Expect to run at [%s]", - new DateTime().plus( - new Duration(System.currentTimeMillis(), segmentGranularity.increment(truncatedNow) + windowMillis) - ) - ); - - ScheduledExecutors - .scheduleAtFixedRate( - scheduledExecutor, - new Duration(System.currentTimeMillis(), segmentGranularity.increment(truncatedNow) + windowMillis), - new Duration(truncatedNow, segmentGranularity.increment(truncatedNow)), - new ThreadRenamingCallable( - String.format( - "%s-overseer-%d", - schema.getDataSource(), - schema.getShardSpec().getPartitionNum() - ) - ) - { - @Override - public ScheduledExecutors.Signal doCall() - { - if (stopped) { - log.info("Stopping merge-n-push overseer thread"); - return ScheduledExecutors.Signal.STOP; - } - - log.info("Starting merge and push."); - - long minTimestamp = segmentGranularity.truncate( - rejectionPolicy.getCurrMaxTime().minus(windowMillis) - ).getMillis(); - - List> sinksToPush = Lists.newArrayList(); - for (Map.Entry entry : sinks.entrySet()) { - final Long intervalStart = entry.getKey(); - if (intervalStart < minTimestamp) { - log.info("Adding entry[%s] for merge and push.", entry); - sinksToPush.add(entry); - } - } - - for (final Map.Entry entry : sinksToPush) { - persistAndMerge(entry.getKey(), entry.getValue()); - } - - if (stopped) { - log.info("Stopping merge-n-push overseer thread"); - return ScheduledExecutors.Signal.STOP; - } else { - return ScheduledExecutors.Signal.REPEAT; - } - } - } - ); - } - - /** - * Unannounces a given sink and removes all local references to it. - */ - private void abandonSegment(final long truncatedTime, final Sink sink) { - try { - segmentAnnouncer.unannounceSegment(sink.getSegment()); - FileUtils.deleteDirectory(computePersistDir(schema, sink.getInterval())); - log.info("Removing sinkKey %d for segment %s", truncatedTime, sink.getSegment().getIdentifier()); - sinks.remove(truncatedTime); - sinkTimeline.remove( - sink.getInterval(), - sink.getVersion(), - new SingleElementPartitionChunk<>(sink) - ); - synchronized (handoffCondition) { - handoffCondition.notifyAll(); - } - } - catch (IOException e) { - log.makeAlert(e, "Unable to abandon old segment for dataSource[%s]", schema.getDataSource()) - .addData("interval", sink.getInterval()) - .emit(); - } - } - }; - } - - private File computeBaseDir(Schema schema) - { - return new File(basePersistDirectory, schema.getDataSource()); - } - - private File computePersistDir(Schema schema, Interval interval) - { - return new File(computeBaseDir(schema), interval.toString().replace("/", "_")); - } - - /** - * Persists the given hydrant and returns the number of rows persisted - * - * @param indexToPersist - * @param schema - * @param interval - * - * @return the number of rows persisted - */ - private int persistHydrant(FireHydrant indexToPersist, Schema schema, Interval interval) - { - if (indexToPersist.hasSwapped()) { - log.info( - "DataSource[%s], Interval[%s], Hydrant[%s] already swapped. Ignoring request to persist.", - schema.getDataSource(), interval, indexToPersist - ); - return 0; - } - - log.info("DataSource[%s], Interval[%s], persisting Hydrant[%s]", schema.getDataSource(), interval, indexToPersist); - try { - int numRows = indexToPersist.getIndex().size(); - - File persistedFile = IndexMerger.persist( - indexToPersist.getIndex(), - new File(computePersistDir(schema, interval), String.valueOf(indexToPersist.getCount())) - ); - - indexToPersist.swapSegment(new QueryableIndexSegment(null, IndexIO.loadIndex(persistedFile))); - - return numRows; - } - catch (IOException e) { - log.makeAlert("dataSource[%s] -- incremental persist failed", schema.getDataSource()) - .addData("interval", interval) - .addData("count", indexToPersist.getCount()) - .emit(); - - throw Throwables.propagate(e); - } + return new RealtimePlumber( + windowPeriod, + basePersistDirectory, + segmentGranularity, + schema, + metrics, + rejectionPolicy, + emitter, + conglomerate, + segmentAnnouncer, + queryExecutorService, + versioningPolicy, + dataSegmentPusher, + segmentPublisher, + serverView + ); } private void verifyState() From ae5a4ff54ceaa6d28a305f057cfecd62b067461a Mon Sep 17 00:00:00 2001 From: fjy Date: Thu, 5 Dec 2013 16:47:28 -0800 Subject: [PATCH 04/49] add versions to incremental index segment --- .../java/io/druid/segment/IncrementalIndexSegment.java | 7 +++++-- .../main/java/io/druid/segment/realtime/FireHydrant.java | 5 +++-- .../main/java/io/druid/segment/realtime/plumber/Sink.java | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java b/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java index 9e04e2af836..f21f7f1fa09 100644 --- a/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java +++ b/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java @@ -30,18 +30,21 @@ import java.io.IOException; public class IncrementalIndexSegment implements Segment { private final IncrementalIndex index; + private final String segmentIdentifier; public IncrementalIndexSegment( - IncrementalIndex index + IncrementalIndex index, + String segmentIdentifier ) { this.index = index; + this.segmentIdentifier = segmentIdentifier; } @Override public String getIdentifier() { - throw new UnsupportedOperationException(); + return segmentIdentifier; } @Override diff --git a/server/src/main/java/io/druid/segment/realtime/FireHydrant.java b/server/src/main/java/io/druid/segment/realtime/FireHydrant.java index d7c82dbf95b..db99ff45719 100644 --- a/server/src/main/java/io/druid/segment/realtime/FireHydrant.java +++ b/server/src/main/java/io/druid/segment/realtime/FireHydrant.java @@ -33,11 +33,12 @@ public class FireHydrant public FireHydrant( IncrementalIndex index, - int count + int count, + String segmentIdentifier ) { this.index = index; - this.adapter = new IncrementalIndexSegment(index); + this.adapter = new IncrementalIndexSegment(index, segmentIdentifier); this.count = count; } diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java b/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java index ee6b50e27d0..91edc45e266 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java @@ -178,12 +178,12 @@ public class Sink implements Iterable FireHydrant old; if (currIndex == null) { // Only happens on initialization, cannot synchronize on null old = currIndex; - currIndex = new FireHydrant(newIndex, hydrants.size()); + currIndex = new FireHydrant(newIndex, hydrants.size(), version); hydrants.add(currIndex); } else { synchronized (currIndex) { old = currIndex; - currIndex = new FireHydrant(newIndex, hydrants.size()); + currIndex = new FireHydrant(newIndex, hydrants.size(), version); hydrants.add(currIndex); } } From b78919c729be298474c00bd8a3504160408dcfc2 Mon Sep 17 00:00:00 2001 From: fjy Date: Thu, 5 Dec 2013 16:49:28 -0800 Subject: [PATCH 05/49] fix NPEs --- .../src/test/java/io/druid/query/QueryRunnerTestHelper.java | 2 +- .../test/java/io/druid/query/metadata/SegmentAnalyzerTest.java | 2 +- .../druid/query/timeseries/TimeseriesQueryRunnerBonusTest.java | 2 +- .../java/io/druid/segment/filter/SpatialFilterBonusTest.java | 2 +- .../test/java/io/druid/segment/filter/SpatialFilterTest.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java b/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java index 58c1e97034c..747ab090da5 100644 --- a/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java +++ b/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java @@ -110,7 +110,7 @@ public class QueryRunnerTestHelper return Arrays.asList( new Object[][]{ { - makeQueryRunner(factory, new IncrementalIndexSegment(rtIndex)) + makeQueryRunner(factory, new IncrementalIndexSegment(rtIndex, null)) }, { makeQueryRunner(factory, new QueryableIndexSegment(null, mMappedTestIndex)) diff --git a/processing/src/test/java/io/druid/query/metadata/SegmentAnalyzerTest.java b/processing/src/test/java/io/druid/query/metadata/SegmentAnalyzerTest.java index 55ed5887480..e1bc774ebfd 100644 --- a/processing/src/test/java/io/druid/query/metadata/SegmentAnalyzerTest.java +++ b/processing/src/test/java/io/druid/query/metadata/SegmentAnalyzerTest.java @@ -47,7 +47,7 @@ public class SegmentAnalyzerTest public void testIncrementalDoesNotWork() throws Exception { final List results = getSegmentAnalysises( - new IncrementalIndexSegment(TestIndex.getIncrementalTestIndex()) + new IncrementalIndexSegment(TestIndex.getIncrementalTestIndex(), null) ); Assert.assertEquals(0, results.size()); diff --git a/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerBonusTest.java b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerBonusTest.java index b31ff2bf1ea..d1497a19026 100644 --- a/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerBonusTest.java +++ b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerBonusTest.java @@ -90,7 +90,7 @@ public class TimeseriesQueryRunnerBonusTest final QueryRunnerFactory factory = TimeseriesQueryRunnerFactory.create(); final QueryRunner> runner = makeQueryRunner( factory, - new IncrementalIndexSegment(index) + new IncrementalIndexSegment(index, null) ); TimeseriesQuery query = Druids.newTimeseriesQueryBuilder() diff --git a/processing/src/test/java/io/druid/segment/filter/SpatialFilterBonusTest.java b/processing/src/test/java/io/druid/segment/filter/SpatialFilterBonusTest.java index 8e423dfcb47..0eb327972ee 100644 --- a/processing/src/test/java/io/druid/segment/filter/SpatialFilterBonusTest.java +++ b/processing/src/test/java/io/druid/segment/filter/SpatialFilterBonusTest.java @@ -83,7 +83,7 @@ public class SpatialFilterBonusTest return Arrays.asList( new Object[][]{ { - new IncrementalIndexSegment(rtIndex) + new IncrementalIndexSegment(rtIndex, null) }, { new QueryableIndexSegment(null, mMappedTestIndex) diff --git a/processing/src/test/java/io/druid/segment/filter/SpatialFilterTest.java b/processing/src/test/java/io/druid/segment/filter/SpatialFilterTest.java index b59d4a3d59f..d342c12c577 100644 --- a/processing/src/test/java/io/druid/segment/filter/SpatialFilterTest.java +++ b/processing/src/test/java/io/druid/segment/filter/SpatialFilterTest.java @@ -83,7 +83,7 @@ public class SpatialFilterTest return Arrays.asList( new Object[][]{ { - new IncrementalIndexSegment(rtIndex) + new IncrementalIndexSegment(rtIndex, null) }, { new QueryableIndexSegment(null, mMappedTestIndex) From 6f079bcc8faebac9bc699c61a155d8b3219f5146 Mon Sep 17 00:00:00 2001 From: fjy Date: Thu, 5 Dec 2013 17:01:55 -0800 Subject: [PATCH 06/49] fix segment id for ii --- .../src/main/java/io/druid/segment/realtime/plumber/Sink.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java b/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java index 91edc45e266..e2759406eef 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/Sink.java @@ -178,12 +178,12 @@ public class Sink implements Iterable FireHydrant old; if (currIndex == null) { // Only happens on initialization, cannot synchronize on null old = currIndex; - currIndex = new FireHydrant(newIndex, hydrants.size(), version); + currIndex = new FireHydrant(newIndex, hydrants.size(), getSegment().getIdentifier()); hydrants.add(currIndex); } else { synchronized (currIndex) { old = currIndex; - currIndex = new FireHydrant(newIndex, hydrants.size(), version); + currIndex = new FireHydrant(newIndex, hydrants.size(), getSegment().getIdentifier()); hydrants.add(currIndex); } } From 5ba05a46f6d3894438479cc8053758312b118ea7 Mon Sep 17 00:00:00 2001 From: fjy Date: Thu, 5 Dec 2013 17:59:02 -0800 Subject: [PATCH 07/49] fix nulls in realtime persist --- .../io/druid/query/select/PagingSpec.java | 9 +++++++++ .../druid/query/select/SelectQueryEngine.java | 4 +++- .../realtime/plumber/RealtimePlumber.java | 19 +++++++++++++++++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/processing/src/main/java/io/druid/query/select/PagingSpec.java b/processing/src/main/java/io/druid/query/select/PagingSpec.java index f5596bd112c..d57afb1589f 100644 --- a/processing/src/main/java/io/druid/query/select/PagingSpec.java +++ b/processing/src/main/java/io/druid/query/select/PagingSpec.java @@ -52,4 +52,13 @@ public class PagingSpec { return threshold; } + + @Override + public String toString() + { + return "PagingSpec{" + + "pagingIdentifiers=" + pagingIdentifiers + + ", threshold=" + threshold + + '}'; + } } diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java index 8c7ab5d218b..bc957c25983 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java +++ b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java @@ -118,7 +118,9 @@ public class SelectQueryEngine final DimensionSelector selector = dimSelector.getValue(); final IndexedInts vals = selector.getRow(); - if (vals.size() <= 1) { + if (vals.size() == 0) { + continue; + } else if (vals.size() <= 1) { final String dimVal = selector.lookupName(vals.get(0)); theEvent.put(dim, dimVal); } else { diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java index ef9d0b6ba0b..71ce2c5689d 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java @@ -43,6 +43,7 @@ import io.druid.server.coordination.DataSegmentAnnouncer; import io.druid.timeline.DataSegment; import io.druid.timeline.TimelineObjectHolder; import io.druid.timeline.VersionedIntervalTimeline; +import io.druid.timeline.partition.NoneShardSpec; import io.druid.timeline.partition.SingleElementPartitionChunk; import org.apache.commons.io.FileUtils; import org.joda.time.DateTime; @@ -495,7 +496,16 @@ public class RealtimePlumber implements Plumber hydrants.add( new FireHydrant( - new QueryableIndexSegment(null, IndexIO.loadIndex(segmentDir)), + new QueryableIndexSegment( + DataSegment.makeDataSegmentIdentifier( + schema.getDataSource(), + sinkInterval.getStart(), + sinkInterval.getEnd(), + versioningPolicy.getVersion(sinkInterval), + new NoneShardSpec() + ), + IndexIO.loadIndex(segmentDir) + ), Integer.parseInt(segmentDir.getName()) ) ); @@ -646,7 +656,12 @@ public class RealtimePlumber implements Plumber new File(computePersistDir(schema, interval), String.valueOf(indexToPersist.getCount())) ); - indexToPersist.swapSegment(new QueryableIndexSegment(null, IndexIO.loadIndex(persistedFile))); + indexToPersist.swapSegment( + new QueryableIndexSegment( + indexToPersist.getSegment().getIdentifier(), + IndexIO.loadIndex(persistedFile) + ) + ); return numRows; } From e7b6b5c2af6834cf5bc76f831241a07dc1e17015 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 09:51:43 -0800 Subject: [PATCH 08/49] fix persist with flushing plumber --- .../realtime/plumber/FlushingPlumber.java | 27 ++++++++++++++----- .../realtime/plumber/RealtimePlumber.java | 4 +-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index 37c7b842fc8..4d8adc497fb 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -1,5 +1,6 @@ package io.druid.segment.realtime.plumber; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.metamx.common.concurrent.ScheduledExecutors; import com.metamx.emitter.EmittingLogger; import com.metamx.emitter.service.ServiceEmitter; @@ -13,7 +14,10 @@ import org.joda.time.Period; import java.io.File; import java.util.Map; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; /** */ @@ -23,6 +27,14 @@ public class FlushingPlumber extends RealtimePlumber private final Duration flushDuration; + private final ScheduledExecutorService flushScheduledExec = Executors.newScheduledThreadPool( + 1, + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("flushing_scheduled_%d") + .build() + ); + public FlushingPlumber( Duration flushDuration, Period windowPeriod, @@ -61,6 +73,8 @@ public class FlushingPlumber extends RealtimePlumber @Override public void startJob() { + log.info("Starting job"); + computeBaseDir(getSchema()).mkdirs(); initializeExecutors(); bootstrapSinksFromDisk(); @@ -70,28 +84,29 @@ public class FlushingPlumber extends RealtimePlumber protected void flushAfterDuration(final long truncatedTime, final Sink sink) { ScheduledExecutors.scheduleWithFixedDelay( - getScheduledExecutor(), + flushScheduledExec, flushDuration, - new Runnable() + new Callable() { @Override - public void run() + public ScheduledExecutors.Signal call() throws Exception { + log.info("Abandoning segment %s", sink.getSegment().getIdentifier()); abandonSegment(truncatedTime, sink); + return ScheduledExecutors.Signal.STOP; } } - ); } @Override public void finishJob() { - log.info("Shutting down..."); + log.info("Stopping job"); for (final Map.Entry entry : getSinks().entrySet()) { flushAfterDuration(entry.getKey(), entry.getValue()); } - shutdownScheduledExecutor(); + shutdownExecutors(); } } diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java index 71ce2c5689d..104316c0c01 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java @@ -401,7 +401,7 @@ public class RealtimePlumber implements Plumber } } - shutdownScheduledExecutor(); + shutdownExecutors(); stopped = true; } @@ -428,7 +428,7 @@ public class RealtimePlumber implements Plumber } } - protected void shutdownScheduledExecutor() + protected void shutdownExecutors() { // scheduledExecutor is shutdown here, but persistExecutor is shutdown when the // ServerView sends it a new segment callback From c4b990bb270242a29ad0c6078b33c213a5470987 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 09:56:23 -0800 Subject: [PATCH 09/49] more logging --- .../io/druid/segment/realtime/plumber/FlushingPlumber.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index 4d8adc497fb..e8d89f2fca5 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -9,6 +9,7 @@ import io.druid.segment.IndexGranularity; import io.druid.segment.realtime.FireDepartmentMetrics; import io.druid.segment.realtime.Schema; import io.druid.server.coordination.DataSegmentAnnouncer; +import org.joda.time.DateTime; import org.joda.time.Duration; import org.joda.time.Period; @@ -83,6 +84,8 @@ public class FlushingPlumber extends RealtimePlumber protected void flushAfterDuration(final long truncatedTime, final Sink sink) { + log.info("Abandoning segment at %s", new DateTime().plusMillis(flushDuration.toPeriod().getMillis())); + ScheduledExecutors.scheduleWithFixedDelay( flushScheduledExec, flushDuration, From 986223a49d3da761a2b9a449c63b6faf70f69569 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 09:56:47 -0800 Subject: [PATCH 10/49] more logs --- .../druid/segment/realtime/plumber/FlushingPlumber.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index e8d89f2fca5..0d5ab7c3386 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -84,8 +84,12 @@ public class FlushingPlumber extends RealtimePlumber protected void flushAfterDuration(final long truncatedTime, final Sink sink) { - log.info("Abandoning segment at %s", new DateTime().plusMillis(flushDuration.toPeriod().getMillis())); - + log.info( + "Abandoning segment %s at %s", + sink.getSegment().getIdentifier(), + new DateTime().plusMillis(flushDuration.toPeriod().getMillis()) + ); + ScheduledExecutors.scheduleWithFixedDelay( flushScheduledExec, flushDuration, From 90aa9eca478d12befc1636f6eb0fab5b9a60ec7f Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 09:57:07 -0800 Subject: [PATCH 11/49] more logs --- .../java/io/druid/segment/realtime/plumber/FlushingPlumber.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index 0d5ab7c3386..a369deaa3b9 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -74,7 +74,7 @@ public class FlushingPlumber extends RealtimePlumber @Override public void startJob() { - log.info("Starting job"); + log.info("Starting job for %s", getSchema().getDataSource()); computeBaseDir(getSchema()).mkdirs(); initializeExecutors(); From 932d6880220e29f45c7a69a0162cceec72e23a85 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 10:15:18 -0800 Subject: [PATCH 12/49] remove unneccessary merge n persist start --- .../java/io/druid/segment/realtime/plumber/FlushingPlumber.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index a369deaa3b9..68aa23577ff 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -79,7 +79,6 @@ public class FlushingPlumber extends RealtimePlumber computeBaseDir(getSchema()).mkdirs(); initializeExecutors(); bootstrapSinksFromDisk(); - startPersistThread(); } protected void flushAfterDuration(final long truncatedTime, final Sink sink) From 767663af92aa95bdeb1c2f263a24710e730c820f Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 10:25:50 -0800 Subject: [PATCH 13/49] fix how flushing plumber flushes --- .../realtime/plumber/FlushingPlumber.java | 91 +++++++++++++++++-- .../realtime/plumber/RealtimePlumber.java | 19 +++- 2 files changed, 101 insertions(+), 9 deletions(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index 68aa23577ff..9f6e4c41acc 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -1,9 +1,11 @@ package io.druid.segment.realtime.plumber; +import com.google.common.collect.Lists; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.metamx.common.concurrent.ScheduledExecutors; import com.metamx.emitter.EmittingLogger; import com.metamx.emitter.service.ServiceEmitter; +import io.druid.common.guava.ThreadRenamingCallable; import io.druid.query.QueryRunnerFactoryConglomerate; import io.druid.segment.IndexGranularity; import io.druid.segment.realtime.FireDepartmentMetrics; @@ -14,6 +16,7 @@ import org.joda.time.Duration; import org.joda.time.Period; import java.io.File; +import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -28,13 +31,8 @@ public class FlushingPlumber extends RealtimePlumber private final Duration flushDuration; - private final ScheduledExecutorService flushScheduledExec = Executors.newScheduledThreadPool( - 1, - new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("flushing_scheduled_%d") - .build() - ); + private volatile ScheduledExecutorService flushScheduledExec = null; + private volatile boolean stopped = false; public FlushingPlumber( Duration flushDuration, @@ -78,7 +76,19 @@ public class FlushingPlumber extends RealtimePlumber computeBaseDir(getSchema()).mkdirs(); initializeExecutors(); + + if (flushScheduledExec == null) { + flushScheduledExec = Executors.newScheduledThreadPool( + 1, + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("flushing_scheduled_%d") + .build() + ); + } + bootstrapSinksFromDisk(); + startFlushThread(); } protected void flushAfterDuration(final long truncatedTime, final Sink sink) @@ -105,6 +115,67 @@ public class FlushingPlumber extends RealtimePlumber ); } + private void startFlushThread() + { + final long truncatedNow = getSegmentGranularity().truncate(new DateTime()).getMillis(); + final long windowMillis = getWindowPeriod().toStandardDuration().getMillis(); + + log.info( + "Expect to run at [%s]", + new DateTime().plus( + new Duration(System.currentTimeMillis(), getSegmentGranularity().increment(truncatedNow) + windowMillis) + ) + ); + + ScheduledExecutors + .scheduleAtFixedRate( + flushScheduledExec, + new Duration(System.currentTimeMillis(), getSegmentGranularity().increment(truncatedNow) + windowMillis), + new Duration(truncatedNow, getSegmentGranularity().increment(truncatedNow)), + new ThreadRenamingCallable( + String.format( + "%s-flusher-%d", + getSchema().getDataSource(), + getSchema().getShardSpec().getPartitionNum() + ) + ) + { + @Override + public ScheduledExecutors.Signal doCall() + { + if (stopped) { + log.info("Stopping flusher thread"); + return ScheduledExecutors.Signal.STOP; + } + + long minTimestamp = getSegmentGranularity().truncate( + getRejectionPolicy().getCurrMaxTime().minus(windowMillis) + ).getMillis(); + + List> sinksToPush = Lists.newArrayList(); + for (Map.Entry entry : getSinks().entrySet()) { + final Long intervalStart = entry.getKey(); + if (intervalStart < minTimestamp) { + log.info("Adding entry[%s] for merge and push.", entry); + sinksToPush.add(entry); + } + } + + for (final Map.Entry entry : sinksToPush) { + flushAfterDuration(entry.getKey(), entry.getValue()); + } + + if (stopped) { + log.info("Stopping merge-n-push overseer thread"); + return ScheduledExecutors.Signal.STOP; + } else { + return ScheduledExecutors.Signal.REPEAT; + } + } + } + ); + } + @Override public void finishJob() { @@ -114,5 +185,11 @@ public class FlushingPlumber extends RealtimePlumber flushAfterDuration(entry.getKey(), entry.getValue()); } shutdownExecutors(); + + if (flushScheduledExec != null) { + flushScheduledExec.shutdown(); + } + + stopped = true; } } diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java index 104316c0c01..e7a09df689a 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java @@ -134,9 +134,24 @@ public class RealtimePlumber implements Plumber return schema; } - public ScheduledExecutorService getScheduledExecutor() + public Period getWindowPeriod() { - return scheduledExecutor; + return windowPeriod; + } + + public IndexGranularity getSegmentGranularity() + { + return segmentGranularity; + } + + public VersioningPolicy getVersioningPolicy() + { + return versioningPolicy; + } + + public RejectionPolicy getRejectionPolicy() + { + return rejectionPolicy; } public Map getSinks() From f8ff9296bc4bab175379d7235b1cf53f9ea36c35 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 10:26:35 -0800 Subject: [PATCH 14/49] fix logs --- .../io/druid/segment/realtime/plumber/FlushingPlumber.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index 9f6e4c41acc..a69d4bef4f9 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -156,7 +156,7 @@ public class FlushingPlumber extends RealtimePlumber for (Map.Entry entry : getSinks().entrySet()) { final Long intervalStart = entry.getKey(); if (intervalStart < minTimestamp) { - log.info("Adding entry[%s] for merge and push.", entry); + log.info("Adding entry[%s] to flush.", entry); sinksToPush.add(entry); } } @@ -166,7 +166,7 @@ public class FlushingPlumber extends RealtimePlumber } if (stopped) { - log.info("Stopping merge-n-push overseer thread"); + log.info("Stopping flusher thread"); return ScheduledExecutors.Signal.STOP; } else { return ScheduledExecutors.Signal.REPEAT; From 2c5562b6ff2d202cbab2ffbe4836296bc55eac46 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 10:29:22 -0800 Subject: [PATCH 15/49] fix wrong shard spec --- .../java/io/druid/segment/realtime/plumber/RealtimePlumber.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java index e7a09df689a..dabf462d418 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/RealtimePlumber.java @@ -517,7 +517,7 @@ public class RealtimePlumber implements Plumber sinkInterval.getStart(), sinkInterval.getEnd(), versioningPolicy.getVersion(sinkInterval), - new NoneShardSpec() + schema.getShardSpec() ), IndexIO.loadIndex(segmentDir) ), From 1fcbbc8262b25db647cd63c7ae24d4dcb1b0bac3 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 11:14:39 -0800 Subject: [PATCH 16/49] fix logging --- .../java/io/druid/segment/realtime/plumber/FlushingPlumber.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index a69d4bef4f9..07308a071e0 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -96,7 +96,7 @@ public class FlushingPlumber extends RealtimePlumber log.info( "Abandoning segment %s at %s", sink.getSegment().getIdentifier(), - new DateTime().plusMillis(flushDuration.toPeriod().getMillis()) + new DateTime().plusMillis(flushDuration.getMillis()) ); ScheduledExecutors.scheduleWithFixedDelay( From 5fe0a8f2fb6546dda4d90abc834d9367ad13456a Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 11:16:27 -0800 Subject: [PATCH 17/49] fix casting --- .../java/io/druid/segment/realtime/plumber/FlushingPlumber.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index 07308a071e0..da27418eb70 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -96,7 +96,7 @@ public class FlushingPlumber extends RealtimePlumber log.info( "Abandoning segment %s at %s", sink.getSegment().getIdentifier(), - new DateTime().plusMillis(flushDuration.getMillis()) + new DateTime().plusMillis((int) flushDuration.getMillis()) ); ScheduledExecutors.scheduleWithFixedDelay( From d9762ac9bd5c578bc9b975dd1233cfea917134b2 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 11:17:19 -0800 Subject: [PATCH 18/49] fix shutdown --- .../java/io/druid/segment/realtime/plumber/FlushingPlumber.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java index da27418eb70..e2120b1c7ce 100644 --- a/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java +++ b/server/src/main/java/io/druid/segment/realtime/plumber/FlushingPlumber.java @@ -182,7 +182,7 @@ public class FlushingPlumber extends RealtimePlumber log.info("Stopping job"); for (final Map.Entry entry : getSinks().entrySet()) { - flushAfterDuration(entry.getKey(), entry.getValue()); + abandonSegment(entry.getKey(), entry.getValue()); } shutdownExecutors(); From 414c17c8b286e7f59a61ae572d1542ac71d7afce Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 6 Dec 2013 16:13:30 -0800 Subject: [PATCH 19/49] dont need to allocate so much mem --- .../java/io/druid/segment/QueryableIndexStorageAdapter.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java index eb73fa559f3..575a5adec39 100644 --- a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java @@ -261,9 +261,7 @@ public class QueryableIndexStorageAdapter implements StorageAdapter @Override public long getTimestamp() { - return index.getTimeColumn() - .getGenericColumn() - .getLongSingleValueRow(cursorOffset.getOffset()); + return timestamps.getLongSingleValueRow(cursorOffset.getOffset()); } }; } From 1fb5fc6707ae63f436b79ae3b3963dfe5994c38d Mon Sep 17 00:00:00 2001 From: fjy Date: Mon, 9 Dec 2013 14:59:44 -0800 Subject: [PATCH 20/49] tests --- .../io/druid/query/select/EventHolder.java | 44 ++ .../io/druid/query/select/PagingSpec.java | 40 +- .../io/druid/query/select/SelectQuery.java | 5 +- .../druid/query/select/SelectQueryEngine.java | 8 +- .../select/SelectQueryQueryToolChest.java | 74 +++- .../select/SelectQueryRunnerFactory.java | 7 +- .../druid/query/select/SelectResultValue.java | 51 ++- .../select/SelectResultValueBuilder.java | 2 +- .../io/druid/query/QueryRunnerTestHelper.java | 8 +- .../query/select/SelectBinaryFnTest.java | 224 ++++++++++ .../query/select/SelectQueryRunnerTest.java | 403 ++++++++++++++++++ 11 files changed, 832 insertions(+), 34 deletions(-) create mode 100644 processing/src/test/java/io/druid/query/select/SelectBinaryFnTest.java create mode 100644 processing/src/test/java/io/druid/query/select/SelectQueryRunnerTest.java diff --git a/processing/src/main/java/io/druid/query/select/EventHolder.java b/processing/src/main/java/io/druid/query/select/EventHolder.java index 86a898a5d84..1ac3661d1f5 100644 --- a/processing/src/main/java/io/druid/query/select/EventHolder.java +++ b/processing/src/main/java/io/druid/query/select/EventHolder.java @@ -70,4 +70,48 @@ public class EventHolder { return event; } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + EventHolder that = (EventHolder) o; + + if (offset != that.offset) { + return false; + } + if (!Maps.difference(event, ((EventHolder) o).event).areEqual()) { + return false; + } + if (segmentId != null ? !segmentId.equals(that.segmentId) : that.segmentId != null) { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = segmentId != null ? segmentId.hashCode() : 0; + result = 31 * result + offset; + result = 31 * result + (event != null ? event.hashCode() : 0); + return result; + } + + @Override + public String toString() + { + return "EventHolder{" + + "segmentId='" + segmentId + '\'' + + ", offset=" + offset + + ", event=" + event + + '}'; + } } diff --git a/processing/src/main/java/io/druid/query/select/PagingSpec.java b/processing/src/main/java/io/druid/query/select/PagingSpec.java index d57afb1589f..7be4cf62746 100644 --- a/processing/src/main/java/io/druid/query/select/PagingSpec.java +++ b/processing/src/main/java/io/druid/query/select/PagingSpec.java @@ -21,19 +21,22 @@ package io.druid.query.select; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.primitives.Ints; +import java.nio.ByteBuffer; +import java.util.LinkedHashMap; import java.util.Map; /** */ public class PagingSpec { - private final Map pagingIdentifiers; + private final LinkedHashMap pagingIdentifiers; private final int threshold; @JsonCreator public PagingSpec( - @JsonProperty("pagingIdentifiers") Map pagingIdentifiers, + @JsonProperty("pagingIdentifiers") LinkedHashMap pagingIdentifiers, @JsonProperty("threshold") int threshold ) { @@ -53,6 +56,39 @@ public class PagingSpec return threshold; } + public byte[] getCacheKey() + { + final byte[][] pagingKeys = new byte[pagingIdentifiers.size()][]; + final byte[][] pagingValues = new byte[pagingIdentifiers.size()][]; + + int index = 0; + int pagingKeysSize = 0; + int pagingValuesSize = 0; + for (Map.Entry entry : pagingIdentifiers.entrySet()) { + pagingKeys[index] = entry.getKey().getBytes(); + pagingValues[index] = ByteBuffer.allocate(Ints.BYTES).putInt(entry.getValue()).array(); + pagingKeysSize += pagingKeys[index].length; + pagingValuesSize += Ints.BYTES; + index++; + } + + final byte[] thresholdBytes = ByteBuffer.allocate(Ints.BYTES).putInt(threshold).array(); + + final ByteBuffer queryCacheKey = ByteBuffer.allocate(pagingKeysSize + pagingValuesSize + thresholdBytes.length); + + for (byte[] pagingKey : pagingKeys) { + queryCacheKey.put(pagingKey); + } + + for (byte[] pagingValue : pagingValues) { + queryCacheKey.put(pagingValue); + } + + queryCacheKey.put(thresholdBytes); + + return queryCacheKey.array(); + } + @Override public String toString() { diff --git a/processing/src/main/java/io/druid/query/select/SelectQuery.java b/processing/src/main/java/io/druid/query/select/SelectQuery.java index a4c924d6459..8c5eb2ba59f 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQuery.java +++ b/processing/src/main/java/io/druid/query/select/SelectQuery.java @@ -37,9 +37,6 @@ import java.util.Map; @JsonTypeName("select") public class SelectQuery extends BaseQuery> { - // TODO: remove this - private static final PagingSpec defaultPagingSpec = new PagingSpec(null, 5); - private final DimFilter dimFilter; private final QueryGranularity granularity; private final List dimensions; @@ -63,7 +60,7 @@ public class SelectQuery extends BaseQuery> this.granularity = granularity; this.dimensions = dimensions; this.metrics = metrics; - this.pagingSpec = pagingSpec == null ? defaultPagingSpec : pagingSpec; + this.pagingSpec = pagingSpec; } @Override diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java index bc957c25983..3238ac01f7a 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java +++ b/processing/src/main/java/io/druid/query/select/SelectQueryEngine.java @@ -29,7 +29,6 @@ import io.druid.query.Result; import io.druid.segment.Cursor; import io.druid.segment.DimensionSelector; import io.druid.segment.ObjectColumnSelector; -import io.druid.segment.QueryableIndex; import io.druid.segment.Segment; import io.druid.segment.StorageAdapter; import io.druid.segment.TimestampColumnSelector; @@ -79,13 +78,14 @@ public class SelectQueryEngine @Override public Result apply(Cursor cursor) { - final TimestampColumnSelector timestampColumnSelector = cursor.makeTimestampColumnSelector(); final SelectResultValueBuilder builder = new SelectResultValueBuilder( cursor.getTime(), query.getPagingSpec() .getThreshold() ); + final TimestampColumnSelector timestampColumnSelector = cursor.makeTimestampColumnSelector(); + final Map dimSelectors = Maps.newHashMap(); for (String dim : dims) { final DimensionSelector dimSelector = cursor.makeDimensionSelector(dim); @@ -118,9 +118,7 @@ public class SelectQueryEngine final DimensionSelector selector = dimSelector.getValue(); final IndexedInts vals = selector.getRow(); - if (vals.size() == 0) { - continue; - } else if (vals.size() <= 1) { + if (vals.size() == 1) { final String dimVal = selector.lookupName(vals.get(0)); theEvent.put(dim, dimVal); } else { diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java b/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java index 181af647428..9e5a365479c 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java +++ b/processing/src/main/java/io/druid/query/select/SelectQueryQueryToolChest.java @@ -20,11 +20,12 @@ package io.druid.query.select; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Joiner; -import com.google.common.collect.Lists; import com.google.common.collect.Ordering; +import com.google.common.collect.Sets; import com.google.inject.Inject; import com.metamx.common.guava.MergeSequence; import com.metamx.common.guava.Sequence; @@ -51,6 +52,8 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Set; /** */ @@ -70,11 +73,13 @@ public class SelectQueryQueryToolChest extends QueryToolChest dimensions = Sets.newTreeSet(); + if (query.getDimensions() != null) { + dimensions.addAll(query.getDimensions()); + } + + final byte[][] dimensionsBytes = new byte[dimensions.size()][]; + int dimensionsBytesSize = 0; + int index = 0; + for (String dimension : dimensions) { + dimensionsBytes[index] = dimension.getBytes(); + dimensionsBytesSize += dimensionsBytes[index].length; + ++index; + } + + + final Set metrics = Sets.newTreeSet(); + if (query.getMetrics() != null) { + dimensions.addAll(query.getMetrics()); + } + + final byte[][] metricBytes = new byte[metrics.size()][]; + int metricBytesSize = 0; + index = 0; + for (String metric : metrics) { + metricBytes[index] = metric.getBytes(); + metricBytesSize += metricBytes[index].length; + ++index; + } + + final ByteBuffer queryCacheKey = ByteBuffer + .allocate( + 1 + + granularityBytes.length + + filterBytes.length + + query.getPagingSpec().getCacheKey().length + + dimensionsBytesSize + + metricBytesSize + ) .put(SELECT_QUERY) .put(granularityBytes) .put(filterBytes) - .array(); + .put(query.getPagingSpec().getCacheKey()); + + for (byte[] dimensionsByte : dimensionsBytes) { + queryCacheKey.put(dimensionsByte); + } + + for (byte[] metricByte : metricBytes) { + queryCacheKey.put(metricByte); + } + + return queryCacheKey.array(); } @Override @@ -202,7 +253,18 @@ public class SelectQueryQueryToolChest extends QueryToolChest( timestamp, - new SelectResultValue(resultIter.next(), Lists.newArrayList(resultIter.next())) + new SelectResultValue( + (Map) jsonMapper.convertValue( + resultIter.next(), new TypeReference>() + { + } + ), + (List) jsonMapper.convertValue( + resultIter.next(), new TypeReference>() + { + } + ) + ) ); } }; diff --git a/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java b/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java index c4e50358b3e..6e995b15f44 100644 --- a/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java +++ b/processing/src/main/java/io/druid/query/select/SelectQueryRunnerFactory.java @@ -19,6 +19,7 @@ package io.druid.query.select; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; import com.metamx.common.ISE; import com.metamx.common.guava.Sequence; @@ -29,9 +30,7 @@ import io.druid.query.QueryRunner; import io.druid.query.QueryRunnerFactory; import io.druid.query.QueryToolChest; import io.druid.query.Result; -import io.druid.segment.QueryableIndex; import io.druid.segment.Segment; -import io.druid.segment.StorageAdapter; import java.util.concurrent.ExecutorService; @@ -40,10 +39,10 @@ import java.util.concurrent.ExecutorService; public class SelectQueryRunnerFactory implements QueryRunnerFactory, SelectQuery> { - public static SelectQueryRunnerFactory create() + public static SelectQueryRunnerFactory create(ObjectMapper jsonMapper) { return new SelectQueryRunnerFactory( - new SelectQueryQueryToolChest(new QueryConfig()), + new SelectQueryQueryToolChest(new QueryConfig(), jsonMapper), new SelectQueryEngine() ); } diff --git a/processing/src/main/java/io/druid/query/select/SelectResultValue.java b/processing/src/main/java/io/druid/query/select/SelectResultValue.java index a5910a89a15..d3ce5d6ef68 100644 --- a/processing/src/main/java/io/druid/query/select/SelectResultValue.java +++ b/processing/src/main/java/io/druid/query/select/SelectResultValue.java @@ -26,6 +26,7 @@ import com.google.common.base.Function; import com.google.common.collect.Lists; import com.metamx.common.ISE; +import javax.annotation.Nullable; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -46,15 +47,6 @@ public class SelectResultValue implements Iterable this.events = events; } - public SelectResultValue( - Object pagingIdentifiers, - List events - ) - { - this.pagingIdentifiers = null; - this.events = null; - } - @JsonProperty public Map getPagingIdentifiers() { @@ -72,4 +64,45 @@ public class SelectResultValue implements Iterable { return events.iterator(); } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + SelectResultValue that = (SelectResultValue) o; + + if (events != null ? !events.equals(that.events) : that.events != null) { + return false; + } + if (pagingIdentifiers != null + ? !pagingIdentifiers.equals(that.pagingIdentifiers) + : that.pagingIdentifiers != null) { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = pagingIdentifiers != null ? pagingIdentifiers.hashCode() : 0; + result = 31 * result + (events != null ? events.hashCode() : 0); + return result; + } + + @Override + public String toString() + { + return "SelectResultValue{" + + "pagingIdentifiers=" + pagingIdentifiers + + ", events=" + events + + '}'; + } } diff --git a/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java b/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java index fe3ba09a946..d417bddae8e 100644 --- a/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java +++ b/processing/src/main/java/io/druid/query/select/SelectResultValueBuilder.java @@ -78,7 +78,7 @@ public class SelectResultValueBuilder { // Pull out top aggregated values List values = Lists.newArrayListWithCapacity(pQueue.size()); - Map pagingIdentifiers = Maps.newHashMap(); + Map pagingIdentifiers = Maps.newLinkedHashMap(); while (!pQueue.isEmpty()) { EventHolder event = pQueue.remove(); pagingIdentifiers.put(event.getSegmentId(), event.getOffset()); diff --git a/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java b/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java index 747ab090da5..2f51162f076 100644 --- a/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java +++ b/processing/src/test/java/io/druid/query/QueryRunnerTestHelper.java @@ -48,11 +48,13 @@ import java.util.List; */ public class QueryRunnerTestHelper { + public static final String segmentId= "testSegment"; public static final String dataSource = "testing"; public static final QueryGranularity dayGran = QueryGranularity.DAY; public static final QueryGranularity allGran = QueryGranularity.ALL; public static final String providerDimension = "proVider"; public static final String qualityDimension = "quality"; + public static final String placementDimension = "placement"; public static final String placementishDimension = "placementish"; public static final String indexMetric = "index"; public static final CountAggregatorFactory rowsCount = new CountAggregatorFactory("rows"); @@ -110,13 +112,13 @@ public class QueryRunnerTestHelper return Arrays.asList( new Object[][]{ { - makeQueryRunner(factory, new IncrementalIndexSegment(rtIndex, null)) + makeQueryRunner(factory, new IncrementalIndexSegment(rtIndex, segmentId)) }, { - makeQueryRunner(factory, new QueryableIndexSegment(null, mMappedTestIndex)) + makeQueryRunner(factory, new QueryableIndexSegment(segmentId, mMappedTestIndex)) }, { - makeQueryRunner(factory, new QueryableIndexSegment(null, mergedRealtimeIndex)) + makeQueryRunner(factory, new QueryableIndexSegment(segmentId, mergedRealtimeIndex)) } } ); diff --git a/processing/src/test/java/io/druid/query/select/SelectBinaryFnTest.java b/processing/src/test/java/io/druid/query/select/SelectBinaryFnTest.java new file mode 100644 index 00000000000..5eb059deb30 --- /dev/null +++ b/processing/src/test/java/io/druid/query/select/SelectBinaryFnTest.java @@ -0,0 +1,224 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.metamx.common.ISE; +import io.druid.granularity.QueryGranularity; +import io.druid.query.Result; +import junit.framework.Assert; +import org.joda.time.DateTime; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +/** + */ +public class SelectBinaryFnTest +{ + private static final String segmentId1 = "testSegment"; + + private static final String segmentId2 = "testSegment"; + + @Test + public void testApply() throws Exception + { + SelectBinaryFn binaryFn = new SelectBinaryFn(QueryGranularity.ALL, new PagingSpec(null, 5)); + + Result res1 = new Result<>( + new DateTime("2013-01-01"), + new SelectResultValue( + ImmutableMap.of(), + Arrays.asList( + new EventHolder( + segmentId1, + 0, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T00"), + "dim", + "first" + ) + ), + new EventHolder( + segmentId1, + 1, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T03"), + "dim", + "fourth" + ) + ), + new EventHolder( + segmentId1, + 2, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T05"), + "dim", + "sixth" + ) + ) + ) + ) + ); + + + Result res2 = new Result<>( + new DateTime("2013-01-01"), + new SelectResultValue( + ImmutableMap.of(), + Arrays.asList( + new EventHolder( + segmentId2, + 0, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T00"), + "dim", + "second" + ) + ), + new EventHolder( + segmentId2, + 1, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T02"), + "dim", + "third" + ) + ), + new EventHolder( + segmentId2, + 2, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T04"), + "dim", + "fifth" + ) + ) + ) + ) + ); + + Result merged = binaryFn.apply(res1, res2); + + Assert.assertEquals(res1.getTimestamp(), merged.getTimestamp()); + + LinkedHashMap expectedPageIds = Maps.newLinkedHashMap(); + expectedPageIds.put(segmentId1, 0); + expectedPageIds.put(segmentId2, 0); + expectedPageIds.put(segmentId2, 1); + expectedPageIds.put(segmentId1, 1); + expectedPageIds.put(segmentId2, 2); + + Iterator exSegmentIter = expectedPageIds.keySet().iterator(); + Iterator acSegmentIter = merged.getValue().getPagingIdentifiers().keySet().iterator(); + + verifyIters(exSegmentIter, acSegmentIter); + + Iterator exOffsetIter = expectedPageIds.values().iterator(); + Iterator acOffsetIter = merged.getValue().getPagingIdentifiers().values().iterator(); + + verifyIters(exOffsetIter, acOffsetIter); + + List exEvents = Arrays.asList( + new EventHolder( + segmentId1, + 0, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T00"), "dim", "first" + ) + ), + new EventHolder( + segmentId2, + 0, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T00"), + "dim", + "second" + ) + ), + new EventHolder( + segmentId2, + 1, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T02"), + "dim", + "third" + ) + ), + new EventHolder( + segmentId1, + 1, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T03"), + "dim", + "fourth" + ) + ), + new EventHolder( + segmentId2, + 2, + ImmutableMap.of( + EventHolder.timestampKey, + new DateTime("2013-01-01T04"), + "dim", + "fifth" + ) + ) + ); + + List acEvents = merged.getValue().getEvents(); + + + verifyEvents(exEvents, acEvents); + } + + private void verifyIters(Iterator iter1, Iterator iter2) + { + while (iter1.hasNext()) { + Assert.assertEquals(iter1.next(), iter2.next()); + } + + if (iter2.hasNext()) { + throw new ISE("This should be empty!"); + } + } + + private void verifyEvents(List events1, List events2) + { + Iterator ex = events1.iterator(); + Iterator ac = events2.iterator(); + + verifyIters(ex, ac); + } +} diff --git a/processing/src/test/java/io/druid/query/select/SelectQueryRunnerTest.java b/processing/src/test/java/io/druid/query/select/SelectQueryRunnerTest.java new file mode 100644 index 00000000000..6c7b26d6059 --- /dev/null +++ b/processing/src/test/java/io/druid/query/select/SelectQueryRunnerTest.java @@ -0,0 +1,403 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.query.select; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.metamx.common.ISE; +import com.metamx.common.guava.Sequences; +import io.druid.jackson.DefaultObjectMapper; +import io.druid.query.QueryRunner; +import io.druid.query.QueryRunnerTestHelper; +import io.druid.query.Result; +import io.druid.query.filter.SelectorDimFilter; +import io.druid.query.spec.LegacySegmentSpec; +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + */ +@RunWith(Parameterized.class) +public class SelectQueryRunnerTest +{ + @Parameterized.Parameters + public static Collection constructorFeeder() throws IOException + { + return QueryRunnerTestHelper.makeQueryRunners( + SelectQueryRunnerFactory.create(new DefaultObjectMapper()) + ); + } + + private static final String providerLowercase = "provider"; + + private final QueryRunner runner; + + public SelectQueryRunnerTest( + QueryRunner runner + ) + { + this.runner = runner; + } + + @Test + public void testFullOnSelect() + { + SelectQuery query = new SelectQuery( + QueryRunnerTestHelper.dataSource, + QueryRunnerTestHelper.fullOnInterval, + null, + QueryRunnerTestHelper.allGran, + Lists.newArrayList(), + Lists.newArrayList(), + new PagingSpec(null, 3), + null + ); + + Iterable> results = Sequences.toList( + runner.run(query), + Lists.>newArrayList() + ); + + List> expectedResults = Arrays.asList( + new Result( + new DateTime("2011-01-12T00:00:00.000Z"), + new SelectResultValue( + ImmutableMap.of(QueryRunnerTestHelper.segmentId, 2), + Arrays.asList( + new EventHolder( + QueryRunnerTestHelper.segmentId, + 0, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(providerLowercase, "spot") + .put(QueryRunnerTestHelper.qualityDimension, "automotive") + .put(QueryRunnerTestHelper.placementDimension, "preferred") + .put(QueryRunnerTestHelper.placementishDimension, Lists.newArrayList("a", "preferred")) + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 1, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(providerLowercase, "spot") + .put(QueryRunnerTestHelper.qualityDimension, "business") + .put(QueryRunnerTestHelper.placementDimension, "preferred") + .put(QueryRunnerTestHelper.placementishDimension, Lists.newArrayList("b", "preferred")) + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 2, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(providerLowercase, "spot") + .put(QueryRunnerTestHelper.qualityDimension, "entertainment") + .put(QueryRunnerTestHelper.placementDimension, "preferred") + .put(QueryRunnerTestHelper.placementishDimension, Lists.newArrayList("e", "preferred")) + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ) + ) + ) + ) + ); + + verify(expectedResults, results); + } + + @Test + public void testSelectWithDimsAndMets() + { + SelectQuery query = new SelectQuery( + QueryRunnerTestHelper.dataSource, + QueryRunnerTestHelper.fullOnInterval, + null, + QueryRunnerTestHelper.allGran, + Lists.newArrayList(providerLowercase), + Lists.newArrayList(QueryRunnerTestHelper.indexMetric), + new PagingSpec(null, 3), + null + ); + + Iterable> results = Sequences.toList( + runner.run(query), + Lists.>newArrayList() + ); + + List> expectedResults = Arrays.asList( + new Result( + new DateTime("2011-01-12T00:00:00.000Z"), + new SelectResultValue( + ImmutableMap.of(QueryRunnerTestHelper.segmentId, 2), + Arrays.asList( + new EventHolder( + QueryRunnerTestHelper.segmentId, + 0, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(providerLowercase, "spot") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 1, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(providerLowercase, "spot") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 2, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(providerLowercase, "spot") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ) + ) + ) + ) + ); + + verify(expectedResults, results); + } + + @Test + public void testSelectPagination() + { + SelectQuery query = new SelectQuery( + QueryRunnerTestHelper.dataSource, + QueryRunnerTestHelper.fullOnInterval, + null, + QueryRunnerTestHelper.allGran, + Lists.newArrayList(QueryRunnerTestHelper.qualityDimension), + Lists.newArrayList(QueryRunnerTestHelper.indexMetric), + new PagingSpec(Maps.newLinkedHashMap(ImmutableMap.of(QueryRunnerTestHelper.segmentId, 3)), 3), + null + ); + + Iterable> results = Sequences.toList( + runner.run(query), + Lists.>newArrayList() + ); + + List> expectedResults = Arrays.asList( + new Result( + new DateTime("2011-01-12T00:00:00.000Z"), + new SelectResultValue( + ImmutableMap.of(QueryRunnerTestHelper.segmentId, 5), + Arrays.asList( + new EventHolder( + QueryRunnerTestHelper.segmentId, + 3, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "health") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 4, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "mezzanine") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 5, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "news") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ) + ) + ) + ) + ); + + verify(expectedResults, results); + } + + @Test + public void testFullOnSelectWithFilter() + { + SelectQuery query = new SelectQuery( + QueryRunnerTestHelper.dataSource, + new LegacySegmentSpec(new Interval("2011-01-12/2011-01-14")), + new SelectorDimFilter(QueryRunnerTestHelper.providerDimension, "spot"), + QueryRunnerTestHelper.dayGran, + Lists.newArrayList(QueryRunnerTestHelper.qualityDimension), + Lists.newArrayList(QueryRunnerTestHelper.indexMetric), + new PagingSpec(Maps.newLinkedHashMap(ImmutableMap.of(QueryRunnerTestHelper.segmentId, 3)), 3), + null + ); + + Iterable> results = Sequences.toList( + runner.run(query), + Lists.>newArrayList() + ); + + List> expectedResults = Arrays.asList( + new Result( + new DateTime("2011-01-12T00:00:00.000Z"), + new SelectResultValue( + ImmutableMap.of(QueryRunnerTestHelper.segmentId, 5), + Arrays.asList( + new EventHolder( + QueryRunnerTestHelper.segmentId, + 3, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "health") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 4, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "mezzanine") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 5, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-12T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "news") + .put(QueryRunnerTestHelper.indexMetric, 100.000000F) + .build() + ) + ) + ) + ), + new Result( + new DateTime("2011-01-13T00:00:00.000Z"), + new SelectResultValue( + ImmutableMap.of(QueryRunnerTestHelper.segmentId, 5), + Arrays.asList( + new EventHolder( + QueryRunnerTestHelper.segmentId, + 3, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-13T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "health") + .put(QueryRunnerTestHelper.indexMetric, 114.947403F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 4, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-13T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "mezzanine") + .put(QueryRunnerTestHelper.indexMetric, 104.465767F) + .build() + ), + new EventHolder( + QueryRunnerTestHelper.segmentId, + 5, + new ImmutableMap.Builder() + .put(EventHolder.timestampKey, new DateTime("2011-01-13T00:00:00.000Z")) + .put(QueryRunnerTestHelper.qualityDimension, "news") + .put(QueryRunnerTestHelper.indexMetric, 102.851683F) + .build() + ) + ) + ) + ) + ); + + verify(expectedResults, results); + } + + private static void verify( + Iterable> expectedResults, + Iterable> actualResults + ) + { + Iterator> expectedIter = expectedResults.iterator(); + Iterator> actualIter = actualResults.iterator(); + + while (expectedIter.hasNext()) { + Result expected = expectedIter.next(); + Result actual = actualIter.next(); + + Assert.assertEquals(expected.getTimestamp(), actual.getTimestamp()); + + for (Map.Entry entry : expected.getValue().getPagingIdentifiers().entrySet()) { + Assert.assertEquals(entry.getValue(), actual.getValue().getPagingIdentifiers().get(entry.getKey())); + } + + Iterator expectedEvts = expected.getValue().getEvents().iterator(); + Iterator actualEvts = actual.getValue().getEvents().iterator(); + + while (expectedEvts.hasNext()) { + EventHolder exHolder = expectedEvts.next(); + EventHolder acHolder = actualEvts.next(); + + Assert.assertEquals(exHolder.getTimestamp(), acHolder.getTimestamp()); + Assert.assertEquals(exHolder.getOffset(), acHolder.getOffset()); + + for (Map.Entry ex : exHolder.getEvent().entrySet()) { + Object actVal = acHolder.getEvent().get(ex.getKey()); + + // work around for current II limitations + if (acHolder.getEvent().get(ex.getKey()) instanceof Double) { + actVal = ((Double) actVal).floatValue(); + } + Assert.assertEquals(ex.getValue(), actVal); + } + } + + if (actualEvts.hasNext()) { + throw new ISE("This event iterator should be exhausted!"); + } + } + + if (actualIter.hasNext()) { + throw new ISE("This iterator should be exhausted!"); + } + } +} From ca7335f45fa6e8f1b95c770e63ef56939a5c6937 Mon Sep 17 00:00:00 2001 From: fjy Date: Fri, 13 Dec 2013 13:35:22 -0800 Subject: [PATCH 21/49] things dont work --- .../Tutorial:-Loading-Your-Data-Part-1.md | 6 +- .../java/io/druid/client/DruidServer.java | 2 + .../io/druid/client/DruidServerConfig.java | 9 ++- .../java/io/druid/db/DatabaseRuleManager.java | 9 ++- .../server/coordinator/DruidCoordinator.java | 9 ++- .../server/coordinator/LoadPeonCallback.java | 4 +- .../DruidCoordinatorBalancer.java | 12 ++- .../{ => helper}/DruidCoordinatorCleanup.java | 12 ++- .../{ => helper}/DruidCoordinatorHelper.java | 4 +- .../{ => helper}/DruidCoordinatorLogger.java | 7 +- .../DruidCoordinatorRuleRunner.java | 7 +- .../DruidCoordinatorSegmentInfoLoader.java | 4 +- .../DruidCoordinatorSegmentMerger.java | 5 +- .../DruidCoordinatorVersionConverter.java | 66 +++++++++++++++++ .../coordinator/rules/ForeverDropRule.java | 40 ++++++++++ .../coordinator/rules/ForeverLoadRule.java | 73 +++++++++++++++++++ .../server/coordinator/rules/LoadRule.java | 4 +- .../druid/server/coordinator/rules/Rule.java | 1 + .../server/http/CoordinatorResource.java | 4 +- .../DruidCoordinatorBalancerProfiler.java | 1 + .../DruidCoordinatorBalancerTester.java | 3 +- .../DruidCoordinatorRuleRunnerTest.java | 1 + .../DruidCoordinatorSegmentMergerTest.java | 1 + 23 files changed, 259 insertions(+), 25 deletions(-) rename server/src/main/java/io/druid/server/coordinator/{ => helper}/DruidCoordinatorBalancer.java (92%) rename server/src/main/java/io/druid/server/coordinator/{ => helper}/DruidCoordinatorCleanup.java (89%) rename server/src/main/java/io/druid/server/coordinator/{ => helper}/DruidCoordinatorHelper.java (89%) rename server/src/main/java/io/druid/server/coordinator/{ => helper}/DruidCoordinatorLogger.java (96%) rename server/src/main/java/io/druid/server/coordinator/{ => helper}/DruidCoordinatorRuleRunner.java (92%) rename server/src/main/java/io/druid/server/coordinator/{ => helper}/DruidCoordinatorSegmentInfoLoader.java (91%) rename server/src/main/java/io/druid/server/coordinator/{ => helper}/DruidCoordinatorSegmentMerger.java (98%) create mode 100644 server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorVersionConverter.java create mode 100644 server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java create mode 100644 server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java diff --git a/docs/content/Tutorial:-Loading-Your-Data-Part-1.md b/docs/content/Tutorial:-Loading-Your-Data-Part-1.md index 2c56c81a839..8c77aba0d07 100644 --- a/docs/content/Tutorial:-Loading-Your-Data-Part-1.md +++ b/docs/content/Tutorial:-Loading-Your-Data-Part-1.md @@ -218,9 +218,9 @@ Congratulations! The segment has completed building. Once a segment is built, a You should see the following logs on the coordinator: ```bash -2013-10-09 21:41:54,368 INFO [Coordinator-Exec--0] io.druid.server.coordinator.DruidCoordinatorLogger - [_default_tier] : Assigned 1 segments among 1 servers -2013-10-09 21:41:54,369 INFO [Coordinator-Exec--0] io.druid.server.coordinator.DruidCoordinatorLogger - Load Queues: -2013-10-09 21:41:54,369 INFO [Coordinator-Exec--0] io.druid.server.coordinator.DruidCoordinatorLogger - Server[localhost:8081, historical, _default_tier] has 1 left to load, 0 left to drop, 4,477 bytes queued, 4,477 bytes served. +2013-10-09 21:41:54,368 INFO [Coordinator-Exec--0] io.druid.server.coordinator.helper.DruidCoordinatorLogger - [_default_tier] : Assigned 1 segments among 1 servers +2013-10-09 21:41:54,369 INFO [Coordinator-Exec--0] io.druid.server.coordinator.helper.DruidCoordinatorLogger - Load Queues: +2013-10-09 21:41:54,369 INFO [Coordinator-Exec--0] io.druid.server.coordinator.helper.DruidCoordinatorLogger - Server[localhost:8081, historical, _default_tier] has 1 left to load, 0 left to drop, 4,477 bytes queued, 4,477 bytes served. ``` These logs indicate that the coordinator has assigned our new segment to the historical node to download and serve. If you look at the historical node logs, you should see: diff --git a/server/src/main/java/io/druid/client/DruidServer.java b/server/src/main/java/io/druid/client/DruidServer.java index 53acc501513..23876497548 100644 --- a/server/src/main/java/io/druid/client/DruidServer.java +++ b/server/src/main/java/io/druid/client/DruidServer.java @@ -36,7 +36,9 @@ import java.util.concurrent.ConcurrentMap; */ public class DruidServer implements Comparable { + public static final int DEFAULT_NUM_REPLICANTS = 2; public static final String DEFAULT_TIER = "_default_tier"; + private static final Logger log = new Logger(DruidServer.class); private final Object lock = new Object(); diff --git a/server/src/main/java/io/druid/client/DruidServerConfig.java b/server/src/main/java/io/druid/client/DruidServerConfig.java index 089c05ff021..a990d56ef15 100644 --- a/server/src/main/java/io/druid/client/DruidServerConfig.java +++ b/server/src/main/java/io/druid/client/DruidServerConfig.java @@ -32,7 +32,10 @@ public class DruidServerConfig private long maxSize = 0; @JsonProperty - private String tier = "_default_tier"; + private String tier = DruidServer.DEFAULT_TIER; + + @JsonProperty + private String zone = DruidServer.DEFAULT_ZONE; public long getMaxSize() { @@ -43,4 +46,8 @@ public class DruidServerConfig { return tier; } + + public String getZone() { + return zone; + } } diff --git a/server/src/main/java/io/druid/db/DatabaseRuleManager.java b/server/src/main/java/io/druid/db/DatabaseRuleManager.java index 0ba44c52c85..9c5efde4fcd 100644 --- a/server/src/main/java/io/druid/db/DatabaseRuleManager.java +++ b/server/src/main/java/io/druid/db/DatabaseRuleManager.java @@ -31,9 +31,11 @@ import com.metamx.common.concurrent.ScheduledExecutors; import com.metamx.common.lifecycle.LifecycleStart; import com.metamx.common.lifecycle.LifecycleStop; import com.metamx.common.logger.Logger; +import io.druid.client.DruidServer; import io.druid.concurrent.Execs; import io.druid.guice.ManageLifecycle; import io.druid.guice.annotations.Json; +import io.druid.server.coordinator.rules.ForeverLoadRule; import io.druid.server.coordinator.rules.PeriodLoadRule; import io.druid.server.coordinator.rules.Rule; import org.joda.time.DateTime; @@ -86,10 +88,9 @@ public class DatabaseRuleManager } final List defaultRules = Arrays.asList( - new PeriodLoadRule( - new Period("P5000Y"), - 2, - "_default_tier" + new ForeverLoadRule( + DruidServer.DEFAULT_NUM_REPLICANTS, + DruidServer.DEFAULT_TIER ) ); final String version = new DateTime().toString(); diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java b/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java index 0ae18185015..993843a0a27 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java +++ b/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java @@ -50,6 +50,13 @@ import io.druid.db.DatabaseRuleManager; import io.druid.db.DatabaseSegmentManager; import io.druid.guice.ManageLifecycle; import io.druid.segment.IndexIO; +import io.druid.server.coordinator.helper.DruidCoordinatorBalancer; +import io.druid.server.coordinator.helper.DruidCoordinatorCleanup; +import io.druid.server.coordinator.helper.DruidCoordinatorHelper; +import io.druid.server.coordinator.helper.DruidCoordinatorLogger; +import io.druid.server.coordinator.helper.DruidCoordinatorRuleRunner; +import io.druid.server.coordinator.helper.DruidCoordinatorSegmentInfoLoader; +import io.druid.server.coordinator.helper.DruidCoordinatorSegmentMerger; import io.druid.server.initialization.ZkPathsConfig; import io.druid.timeline.DataSegment; import org.apache.curator.framework.CuratorFramework; @@ -310,7 +317,7 @@ public class DruidCoordinator new LoadPeonCallback() { @Override - protected void execute() + public void execute() { try { if (curator.checkExists().forPath(toServedSegPath) != null && diff --git a/server/src/main/java/io/druid/server/coordinator/LoadPeonCallback.java b/server/src/main/java/io/druid/server/coordinator/LoadPeonCallback.java index ff0cea085ca..eaf3b0267d7 100644 --- a/server/src/main/java/io/druid/server/coordinator/LoadPeonCallback.java +++ b/server/src/main/java/io/druid/server/coordinator/LoadPeonCallback.java @@ -21,7 +21,7 @@ package io.druid.server.coordinator; /** */ -public abstract class LoadPeonCallback +public interface LoadPeonCallback { - protected abstract void execute(); + public void execute(); } diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorBalancer.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorBalancer.java similarity index 92% rename from server/src/main/java/io/druid/server/coordinator/DruidCoordinatorBalancer.java rename to server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorBalancer.java index 0ca4ff32fe8..bc960258400 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorBalancer.java +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorBalancer.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.server.coordinator; +package io.druid.server.coordinator.helper; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -25,6 +25,14 @@ import com.google.common.collect.MinMaxPriorityQueue; import com.metamx.common.guava.Comparators; import com.metamx.emitter.EmittingLogger; import io.druid.client.DruidServer; +import io.druid.server.coordinator.BalancerSegmentHolder; +import io.druid.server.coordinator.BalancerStrategy; +import io.druid.server.coordinator.CoordinatorStats; +import io.druid.server.coordinator.DruidCoordinator; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; +import io.druid.server.coordinator.LoadPeonCallback; +import io.druid.server.coordinator.LoadQueuePeon; +import io.druid.server.coordinator.ServerHolder; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; @@ -163,7 +171,7 @@ public class DruidCoordinatorBalancer implements DruidCoordinatorHelper callback = new LoadPeonCallback() { @Override - protected void execute() + public void execute() { Map movingSegments = currentlyMovingSegments.get(toServer.getTier()); if (movingSegments != null) { diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorCleanup.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorCleanup.java similarity index 89% rename from server/src/main/java/io/druid/server/coordinator/DruidCoordinatorCleanup.java rename to server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorCleanup.java index 659391514aa..33438e204e1 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorCleanup.java +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorCleanup.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.server.coordinator; +package io.druid.server.coordinator.helper; import com.google.common.collect.Maps; import com.google.common.collect.MinMaxPriorityQueue; @@ -25,6 +25,14 @@ import com.metamx.common.guava.Comparators; import com.metamx.common.logger.Logger; import io.druid.client.DruidDataSource; import io.druid.client.DruidServer; +import io.druid.server.coordinator.CoordinatorStats; +import io.druid.server.coordinator.DruidCluster; +import io.druid.server.coordinator.DruidCoordinator; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; +import io.druid.server.coordinator.LoadPeonCallback; +import io.druid.server.coordinator.LoadQueuePeon; +import io.druid.server.coordinator.ServerHolder; +import io.druid.server.coordinator.helper.DruidCoordinatorHelper; import io.druid.timeline.DataSegment; import io.druid.timeline.TimelineObjectHolder; import io.druid.timeline.VersionedIntervalTimeline; @@ -69,7 +77,7 @@ public class DruidCoordinatorCleanup implements DruidCoordinatorHelper segment, new LoadPeonCallback() { @Override - protected void execute() + public void execute() { } } diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorHelper.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorHelper.java similarity index 89% rename from server/src/main/java/io/druid/server/coordinator/DruidCoordinatorHelper.java rename to server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorHelper.java index e6eb7bb3997..26709744ab9 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorHelper.java +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorHelper.java @@ -17,7 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.server.coordinator; +package io.druid.server.coordinator.helper; + +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; /** */ diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorLogger.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorLogger.java similarity index 96% rename from server/src/main/java/io/druid/server/coordinator/DruidCoordinatorLogger.java rename to server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorLogger.java index b6c8bb8c240..aa03e808f17 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorLogger.java +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorLogger.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.server.coordinator; +package io.druid.server.coordinator.helper; import com.google.common.collect.Maps; import com.google.common.collect.MinMaxPriorityQueue; @@ -27,6 +27,11 @@ import com.metamx.emitter.service.ServiceMetricEvent; import io.druid.client.DruidDataSource; import io.druid.client.DruidServer; import io.druid.collections.CountingMap; +import io.druid.server.coordinator.CoordinatorStats; +import io.druid.server.coordinator.DruidCluster; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; +import io.druid.server.coordinator.LoadQueuePeon; +import io.druid.server.coordinator.ServerHolder; import io.druid.timeline.DataSegment; import java.util.Map; diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorRuleRunner.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorRuleRunner.java similarity index 92% rename from server/src/main/java/io/druid/server/coordinator/DruidCoordinatorRuleRunner.java rename to server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorRuleRunner.java index 594889201cf..15edf27d428 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorRuleRunner.java +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorRuleRunner.java @@ -17,10 +17,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.server.coordinator; +package io.druid.server.coordinator.helper; import com.metamx.emitter.EmittingLogger; import io.druid.db.DatabaseRuleManager; +import io.druid.server.coordinator.CoordinatorStats; +import io.druid.server.coordinator.DruidCluster; +import io.druid.server.coordinator.DruidCoordinator; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; +import io.druid.server.coordinator.ReplicationThrottler; import io.druid.server.coordinator.rules.Rule; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorSegmentInfoLoader.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorSegmentInfoLoader.java similarity index 91% rename from server/src/main/java/io/druid/server/coordinator/DruidCoordinatorSegmentInfoLoader.java rename to server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorSegmentInfoLoader.java index 69f8ccdbc43..8980bfded90 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorSegmentInfoLoader.java +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorSegmentInfoLoader.java @@ -17,9 +17,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.server.coordinator; +package io.druid.server.coordinator.helper; import com.metamx.common.logger.Logger; +import io.druid.server.coordinator.DruidCoordinator; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; import io.druid.timeline.DataSegment; import java.util.Set; diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorSegmentMerger.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorSegmentMerger.java similarity index 98% rename from server/src/main/java/io/druid/server/coordinator/DruidCoordinatorSegmentMerger.java rename to server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorSegmentMerger.java index 839cda93563..d39d1bbaac9 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinatorSegmentMerger.java +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorSegmentMerger.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.druid.server.coordinator; +package io.druid.server.coordinator.helper; import com.google.common.base.Function; import com.google.common.base.Preconditions; @@ -33,6 +33,9 @@ import com.metamx.common.Pair; import com.metamx.common.guava.FunctionalIterable; import com.metamx.common.logger.Logger; import io.druid.client.indexing.IndexingServiceClient; +import io.druid.server.coordinator.CoordinatorStats; +import io.druid.server.coordinator.DatasourceWhitelist; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; import io.druid.timeline.DataSegment; import io.druid.timeline.TimelineObjectHolder; import io.druid.timeline.VersionedIntervalTimeline; diff --git a/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorVersionConverter.java b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorVersionConverter.java new file mode 100644 index 00000000000..70bef7c2216 --- /dev/null +++ b/server/src/main/java/io/druid/server/coordinator/helper/DruidCoordinatorVersionConverter.java @@ -0,0 +1,66 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.server.coordinator.helper; + +import com.metamx.emitter.EmittingLogger; +import io.druid.client.indexing.IndexingServiceClient; +import io.druid.segment.IndexIO; +import io.druid.server.coordinator.DatasourceWhitelist; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; +import io.druid.timeline.DataSegment; + +import java.util.concurrent.atomic.AtomicReference; + +public class DruidCoordinatorVersionConverter implements DruidCoordinatorHelper +{ + private static final EmittingLogger log = new EmittingLogger(DruidCoordinatorVersionConverter.class); + + + private final IndexingServiceClient indexingServiceClient; + private final AtomicReference whitelistRef; + + public DruidCoordinatorVersionConverter( + IndexingServiceClient indexingServiceClient, + AtomicReference whitelistRef + ) + { + this.indexingServiceClient = indexingServiceClient; + this.whitelistRef = whitelistRef; + } + + @Override + public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) + { + DatasourceWhitelist whitelist = whitelistRef.get(); + + for (DataSegment dataSegment : params.getAvailableSegments()) { + if (whitelist == null || whitelist.contains(dataSegment.getDataSource())) { + final Integer binaryVersion = dataSegment.getBinaryVersion(); + + if (binaryVersion == null || binaryVersion < IndexIO.CURRENT_VERSION_ID) { + log.info("Upgrading version on segment[%s]", dataSegment.getIdentifier()); + indexingServiceClient.upgradeSegment(dataSegment); + } + } + } + + return params; + } +} diff --git a/server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java b/server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java new file mode 100644 index 00000000000..fe86a602055 --- /dev/null +++ b/server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java @@ -0,0 +1,40 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.server.coordinator.rules; + +import io.druid.timeline.DataSegment; +import org.joda.time.DateTime; + +/** + */ +public class ForeverDropRule extends DropRule +{ + @Override + public String getType() + { + return "dropForever"; + } + + @Override + public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) + { + return true; + } +} diff --git a/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java new file mode 100644 index 00000000000..d826c572ad0 --- /dev/null +++ b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java @@ -0,0 +1,73 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.server.coordinator.rules; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.druid.timeline.DataSegment; +import org.joda.time.DateTime; + +/** + */ +public class ForeverLoadRule extends LoadRule +{ + private final Integer replicants; + private final String tier; + + @JsonCreator + public ForeverLoadRule( + @JsonProperty("replicants") Integer replicants, + @JsonProperty("tier") String tier + ) + { + this.replicants = (replicants == null) ? 2 : replicants; + this.tier = tier; + } + + @Override + public int getReplicants() + { + return replicants; + } + + @Override + public int getReplicants(String tier) + { + return (this.tier.equalsIgnoreCase(tier)) ? replicants : 0; + } + + @Override + public String getTier() + { + return null; + } + + @Override + public String getType() + { + return "loadForever"; + } + + @Override + public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) + { + return true; + } +} diff --git a/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java index 792d76d01b2..98ee7cfb206 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java @@ -120,7 +120,7 @@ public abstract class LoadRule implements Rule new LoadPeonCallback() { @Override - protected void execute() + public void execute() { replicationManager.unregisterReplicantCreation( getTier(), @@ -197,7 +197,7 @@ public abstract class LoadRule implements Rule new LoadPeonCallback() { @Override - protected void execute() + public void execute() { replicationManager.unregisterReplicantTermination( getTier(), diff --git a/server/src/main/java/io/druid/server/coordinator/rules/Rule.java b/server/src/main/java/io/druid/server/coordinator/rules/Rule.java index 7c720e1aa2f..e8be9a81102 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/Rule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/Rule.java @@ -33,6 +33,7 @@ import org.joda.time.DateTime; @JsonSubTypes(value = { @JsonSubTypes.Type(name = "loadByPeriod", value = PeriodLoadRule.class), @JsonSubTypes.Type(name = "loadByInterval", value = IntervalLoadRule.class), + @JsonSubTypes.Type(name = "loadForever", value = ForeverLoadRule.class), @JsonSubTypes.Type(name = "dropByPeriod", value = PeriodDropRule.class), @JsonSubTypes.Type(name = "dropByInterval", value = IntervalDropRule.class), @JsonSubTypes.Type(name = "loadBySize", value = SizeLoadRule.class), diff --git a/server/src/main/java/io/druid/server/http/CoordinatorResource.java b/server/src/main/java/io/druid/server/http/CoordinatorResource.java index 1c70dd39c8c..5946a57d385 100644 --- a/server/src/main/java/io/druid/server/http/CoordinatorResource.java +++ b/server/src/main/java/io/druid/server/http/CoordinatorResource.java @@ -61,7 +61,7 @@ public class CoordinatorResource new LoadPeonCallback() { @Override - protected void execute() + public void execute() { return; } @@ -91,7 +91,7 @@ public class CoordinatorResource segmentToDrop.getFromServer(), segmentToDrop.getSegmentName(), new LoadPeonCallback() { @Override - protected void execute() + public void execute() { return; } diff --git a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java index 2d95fec765b..6f931c286ff 100644 --- a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java +++ b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java @@ -29,6 +29,7 @@ import com.metamx.emitter.EmittingLogger; import com.metamx.emitter.service.ServiceEmitter; import io.druid.client.DruidServer; import io.druid.db.DatabaseRuleManager; +import io.druid.server.coordinator.helper.DruidCoordinatorRuleRunner; import io.druid.server.coordinator.rules.PeriodLoadRule; import io.druid.server.coordinator.rules.Rule; import io.druid.timeline.DataSegment; diff --git a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerTester.java b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerTester.java index 77808f2fe86..06af063897d 100644 --- a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerTester.java +++ b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerTester.java @@ -20,6 +20,7 @@ package io.druid.server.coordinator; import io.druid.client.DruidServer; +import io.druid.server.coordinator.helper.DruidCoordinatorBalancer; import io.druid.timeline.DataSegment; public class DruidCoordinatorBalancerTester extends DruidCoordinatorBalancer @@ -59,7 +60,7 @@ public class DruidCoordinatorBalancerTester extends DruidCoordinatorBalancer loadPeon.loadSegment(segment.getSegment(), new LoadPeonCallback() { @Override - protected void execute() + public void execute() { } }); diff --git a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java index 9c8fdf0de2a..72693e65103 100644 --- a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java +++ b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java @@ -31,6 +31,7 @@ import com.metamx.emitter.service.ServiceEventBuilder; import io.druid.client.DruidServer; import io.druid.db.DatabaseRuleManager; import io.druid.segment.IndexIO; +import io.druid.server.coordinator.helper.DruidCoordinatorRuleRunner; import io.druid.server.coordinator.rules.IntervalLoadRule; import io.druid.server.coordinator.rules.IntervalDropRule; import io.druid.server.coordinator.rules.Rule; diff --git a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorSegmentMergerTest.java b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorSegmentMergerTest.java index 72aeb40ab46..b6cc82cd354 100644 --- a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorSegmentMergerTest.java +++ b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorSegmentMergerTest.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import io.druid.client.indexing.IndexingServiceClient; +import io.druid.server.coordinator.helper.DruidCoordinatorSegmentMerger; import io.druid.timeline.DataSegment; import io.druid.timeline.partition.LinearShardSpec; import junit.framework.Assert; From 27bba22e6fa8d2c19f770cd2af3cf1fd98647adc Mon Sep 17 00:00:00 2001 From: fjy Date: Mon, 16 Dec 2013 15:54:42 -0800 Subject: [PATCH 22/49] make rules assignable across tiers --- .../Tutorial:-A-First-Look-at-Druid.md | 2 +- .../java/io/druid/db/DatabaseRuleManager.java | 9 +- .../server/coordinator/DruidCoordinator.java | 1 + .../coordinator/rules/ForeverLoadRule.java | 42 +++---- .../coordinator/rules/IntervalLoadRule.java | 33 +++--- .../server/coordinator/rules/LoadRule.java | 106 ++++++++++-------- .../coordinator/rules/PeriodLoadRule.java | 31 ++--- .../coordinator/rules/SizeLoadRule.java | 30 +---- 8 files changed, 122 insertions(+), 132 deletions(-) diff --git a/docs/content/Tutorial:-A-First-Look-at-Druid.md b/docs/content/Tutorial:-A-First-Look-at-Druid.md index e3fe41c51c6..1d5cf883267 100644 --- a/docs/content/Tutorial:-A-First-Look-at-Druid.md +++ b/docs/content/Tutorial:-A-First-Look-at-Druid.md @@ -205,7 +205,7 @@ You are probably wondering, what are these [Granularities](Granularities.html) a To issue the query and get some results, run the following in your command line: ``` -curl -X POST 'http://localhost:8083/druid/v2/?pretty' -H 'content-type: application/json' -d ````timeseries_query.body +curl -X POST 'http://localhost:8083/druid/v2/?pretty' -H 'content-type: application/json' -d @timeseries_query.body ``` Once again, you should get a JSON blob of text back with your results, that looks something like this: diff --git a/server/src/main/java/io/druid/db/DatabaseRuleManager.java b/server/src/main/java/io/druid/db/DatabaseRuleManager.java index 9c5efde4fcd..f205542ba41 100644 --- a/server/src/main/java/io/druid/db/DatabaseRuleManager.java +++ b/server/src/main/java/io/druid/db/DatabaseRuleManager.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Supplier; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.inject.Inject; @@ -36,11 +37,9 @@ import io.druid.concurrent.Execs; import io.druid.guice.ManageLifecycle; import io.druid.guice.annotations.Json; import io.druid.server.coordinator.rules.ForeverLoadRule; -import io.druid.server.coordinator.rules.PeriodLoadRule; import io.druid.server.coordinator.rules.Rule; import org.joda.time.DateTime; import org.joda.time.Duration; -import org.joda.time.Period; import org.skife.jdbi.v2.FoldController; import org.skife.jdbi.v2.Folder3; import org.skife.jdbi.v2.Handle; @@ -89,8 +88,10 @@ public class DatabaseRuleManager final List defaultRules = Arrays.asList( new ForeverLoadRule( - DruidServer.DEFAULT_NUM_REPLICANTS, - DruidServer.DEFAULT_TIER + ImmutableMap.of( + DruidServer.DEFAULT_TIER, + DruidServer.DEFAULT_NUM_REPLICANTS + ) ) ); final String version = new DateTime().toString(); diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java b/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java index 26e736ee3bf..41da48a9ed3 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java +++ b/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java @@ -58,6 +58,7 @@ import io.druid.server.coordinator.helper.DruidCoordinatorCleanup; import io.druid.server.coordinator.helper.DruidCoordinatorHelper; import io.druid.server.coordinator.helper.DruidCoordinatorLogger; import io.druid.server.coordinator.helper.DruidCoordinatorRuleRunner; +import io.druid.server.coordinator.helper.DruidCoordinatorSegmentInfoLoader; import io.druid.server.coordinator.helper.DruidCoordinatorSegmentMerger; import io.druid.server.initialization.ZkPathsConfig; import io.druid.timeline.DataSegment; diff --git a/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java index d826c572ad0..9c3c5095066 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java @@ -24,39 +24,20 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; +import java.util.Map; + /** */ public class ForeverLoadRule extends LoadRule { - private final Integer replicants; - private final String tier; + private final Map tieredReplicants; @JsonCreator public ForeverLoadRule( - @JsonProperty("replicants") Integer replicants, - @JsonProperty("tier") String tier + @JsonProperty("tieredReplicants") Map tieredReplicants ) { - this.replicants = (replicants == null) ? 2 : replicants; - this.tier = tier; - } - - @Override - public int getReplicants() - { - return replicants; - } - - @Override - public int getReplicants(String tier) - { - return (this.tier.equalsIgnoreCase(tier)) ? replicants : 0; - } - - @Override - public String getTier() - { - return null; + this.tieredReplicants = tieredReplicants; } @Override @@ -65,6 +46,19 @@ public class ForeverLoadRule extends LoadRule return "loadForever"; } + @Override + @JsonProperty + public Map getTieredReplicants() + { + return tieredReplicants; + } + + @Override + public int getNumReplicants(String tier) + { + return tieredReplicants.get(tier); + } + @Override public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) { diff --git a/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java index 4fe01521e66..ea3a36587d0 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java @@ -21,11 +21,14 @@ package io.druid.server.coordinator.rules; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableMap; import com.metamx.common.logger.Logger; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; import org.joda.time.Interval; +import java.util.Map; + /** */ public class IntervalLoadRule extends LoadRule @@ -33,19 +36,25 @@ public class IntervalLoadRule extends LoadRule private static final Logger log = new Logger(IntervalLoadRule.class); private final Interval interval; - private final Integer replicants; - private final String tier; + private final Map tieredReplicants; @JsonCreator public IntervalLoadRule( @JsonProperty("interval") Interval interval, + @JsonProperty("load") Map tieredReplicants, + // Replicants and tier are deprecated @JsonProperty("replicants") Integer replicants, @JsonProperty("tier") String tier ) { this.interval = interval; - this.replicants = (replicants == null) ? 2 : replicants; - this.tier = tier; + + + if (tieredReplicants != null) { + this.tieredReplicants = tieredReplicants; + } else { // Backwards compatible + this.tieredReplicants = ImmutableMap.of(tier, replicants); + } } @Override @@ -55,24 +64,16 @@ public class IntervalLoadRule extends LoadRule return "loadByInterval"; } - @Override @JsonProperty - public int getReplicants() + public Map getTieredReplicants() { - return replicants; + return tieredReplicants; } @Override - public int getReplicants(String tier) + public int getNumReplicants(String tier) { - return (this.tier.equalsIgnoreCase(tier)) ? replicants : 0; - } - - @Override - @JsonProperty - public String getTier() - { - return tier; + return tieredReplicants.get(tier); } @JsonProperty diff --git a/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java index 98ee7cfb206..7127c9af98c 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java @@ -22,17 +22,16 @@ package io.druid.server.coordinator.rules; import com.google.common.collect.Lists; import com.google.common.collect.MinMaxPriorityQueue; import com.metamx.emitter.EmittingLogger; +import io.druid.server.coordinator.BalancerStrategy; import io.druid.server.coordinator.CoordinatorStats; import io.druid.server.coordinator.DruidCoordinator; import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; import io.druid.server.coordinator.LoadPeonCallback; -import io.druid.server.coordinator.BalancerStrategy; import io.druid.server.coordinator.ReplicationThrottler; import io.druid.server.coordinator.ServerHolder; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -48,39 +47,46 @@ public abstract class LoadRule implements Rule { CoordinatorStats stats = new CoordinatorStats(); - int expectedReplicants = getReplicants(); - int totalReplicants = params.getSegmentReplicantLookup().getTotalReplicants(segment.getIdentifier(), getTier()); - int clusterReplicants = params.getSegmentReplicantLookup().getClusterReplicants(segment.getIdentifier(), getTier()); + for (Map.Entry entry : getTieredReplicants().entrySet()) { + final String tier = entry.getKey(); + final int expectedReplicants = entry.getValue(); - MinMaxPriorityQueue serverQueue = params.getDruidCluster().getServersByTier(getTier()); - if (serverQueue == null) { - log.makeAlert("Tier[%s] has no servers! Check your cluster configuration!", getTier()).emit(); - return stats; + int totalReplicants = params.getSegmentReplicantLookup().getTotalReplicants(segment.getIdentifier(), tier); + int clusterReplicants = params.getSegmentReplicantLookup() + .getClusterReplicants(segment.getIdentifier(), tier); + + MinMaxPriorityQueue serverQueue = params.getDruidCluster().getServersByTier(tier); + if (serverQueue == null) { + log.makeAlert("Tier[%s] has no servers! Check your cluster configuration!", tier).emit(); + return stats; + } + + final List serverHolderList = Lists.newArrayList(serverQueue); + final DateTime referenceTimestamp = params.getBalancerReferenceTimestamp(); + final BalancerStrategy strategy = params.getBalancerStrategyFactory().createBalancerStrategy(referenceTimestamp); + if (params.getAvailableSegments().contains(segment)) { + stats.accumulate( + assign( + params.getReplicationManager(), + tier, + expectedReplicants, + totalReplicants, + strategy, + serverHolderList, + segment + ) + ); + } + + stats.accumulate(drop(expectedReplicants, clusterReplicants, segment, params)); } - final List serverHolderList = new ArrayList(serverQueue); - final DateTime referenceTimestamp = params.getBalancerReferenceTimestamp(); - final BalancerStrategy strategy = params.getBalancerStrategyFactory().createBalancerStrategy(referenceTimestamp); - if (params.getAvailableSegments().contains(segment)) { - stats.accumulate( - assign( - params.getReplicationManager(), - expectedReplicants, - totalReplicants, - strategy, - serverHolderList, - segment - ) - ); - } - - stats.accumulate(drop(expectedReplicants, clusterReplicants, segment, params)); - return stats; } private CoordinatorStats assign( final ReplicationThrottler replicationManager, + final String tier, final int expectedReplicants, int totalReplicants, final BalancerStrategy strategy, @@ -89,11 +95,12 @@ public abstract class LoadRule implements Rule ) { final CoordinatorStats stats = new CoordinatorStats(); + stats.addToTieredStat("assignedCount", tier, 0); while (totalReplicants < expectedReplicants) { boolean replicate = totalReplicants > 0; - if (replicate && !replicationManager.canCreateReplicant(getTier())) { + if (replicate && !replicationManager.canCreateReplicant(tier)) { break; } @@ -101,8 +108,8 @@ public abstract class LoadRule implements Rule if (holder == null) { log.warn( - "Not enough %s servers or node capacity to assign segment[%s]! Expected Replicants[%d]", - getTier(), + "Not enough [%s] servers or node capacity to assign segment[%s]! Expected Replicants[%d]", + tier, segment.getIdentifier(), expectedReplicants ); @@ -111,7 +118,7 @@ public abstract class LoadRule implements Rule if (replicate) { replicationManager.registerReplicantCreation( - getTier(), segment.getIdentifier(), holder.getServer().getHost() + tier, segment.getIdentifier(), holder.getServer().getHost() ); } @@ -123,7 +130,7 @@ public abstract class LoadRule implements Rule public void execute() { replicationManager.unregisterReplicantCreation( - getTier(), + tier, segment.getIdentifier(), holder.getServer().getHost() ); @@ -131,7 +138,7 @@ public abstract class LoadRule implements Rule } ); - stats.addToTieredStat("assignedCount", getTier(), 1); + stats.addToTieredStat("assignedCount", tier, 1); ++totalReplicants; } @@ -152,17 +159,20 @@ public abstract class LoadRule implements Rule return stats; } - // Make sure we have enough actual replicants in the cluster before doing anything + // Make sure we have enough actual replicants in the correct tier in the cluster before doing anything if (clusterReplicants < expectedReplicants) { return stats; } - Map replicantsByType = params.getSegmentReplicantLookup().getClusterTiers(segment.getIdentifier()); + // Find all instances of this segment across tiers + Map replicantsByTier = params.getSegmentReplicantLookup().getClusterTiers(segment.getIdentifier()); - for (Map.Entry entry : replicantsByType.entrySet()) { - String tier = entry.getKey(); - int actualNumReplicantsForType = entry.getValue(); - int expectedNumReplicantsForType = getReplicants(tier); + for (Map.Entry entry : replicantsByTier.entrySet()) { + final String tier = entry.getKey(); + int actualNumReplicantsForTier = entry.getValue(); + int expectedNumReplicantsForTier = getNumReplicants(tier); + + stats.addToTieredStat("droppedCount", tier, 0); MinMaxPriorityQueue serverQueue = params.getDruidCluster().get(tier); if (serverQueue == null) { @@ -171,7 +181,7 @@ public abstract class LoadRule implements Rule } List droppedServers = Lists.newArrayList(); - while (actualNumReplicantsForType > expectedNumReplicantsForType) { + while (actualNumReplicantsForTier > expectedNumReplicantsForTier) { final ServerHolder holder = serverQueue.pollLast(); if (holder == null) { log.warn("Wtf, holder was null? I have no servers serving [%s]?", segment.getIdentifier()); @@ -179,14 +189,14 @@ public abstract class LoadRule implements Rule } if (holder.isServingSegment(segment)) { - if (expectedNumReplicantsForType > 0) { // don't throttle unless we are removing extra replicants - if (!replicationManager.canDestroyReplicant(getTier())) { + if (expectedNumReplicantsForTier > 0) { // don't throttle unless we are removing extra replicants + if (!replicationManager.canDestroyReplicant(tier)) { serverQueue.add(holder); break; } replicationManager.registerReplicantTermination( - getTier(), + tier, segment.getIdentifier(), holder.getServer().getHost() ); @@ -200,14 +210,14 @@ public abstract class LoadRule implements Rule public void execute() { replicationManager.unregisterReplicantTermination( - getTier(), + tier, segment.getIdentifier(), holder.getServer().getHost() ); } } ); - --actualNumReplicantsForType; + --actualNumReplicantsForTier; stats.addToTieredStat("droppedCount", tier, 1); } droppedServers.add(holder); @@ -218,9 +228,7 @@ public abstract class LoadRule implements Rule return stats; } - public abstract int getReplicants(); + public abstract Map getTieredReplicants(); - public abstract int getReplicants(String tier); - - public abstract String getTier(); + public abstract int getNumReplicants(String tier); } diff --git a/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java index a2048756894..a8b47e35aef 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java @@ -21,12 +21,15 @@ package io.druid.server.coordinator.rules; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableMap; import com.metamx.common.logger.Logger; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; import org.joda.time.Interval; import org.joda.time.Period; +import java.util.Map; + /** */ public class PeriodLoadRule extends LoadRule @@ -34,19 +37,24 @@ public class PeriodLoadRule extends LoadRule private static final Logger log = new Logger(PeriodLoadRule.class); private final Period period; - private final Integer replicants; - private final String tier; + private final Map tieredReplicants; @JsonCreator public PeriodLoadRule( @JsonProperty("period") Period period, + @JsonProperty("tieredReplicants") Map tieredReplicants, + // The following two vars need to be deprecated @JsonProperty("replicants") Integer replicants, @JsonProperty("tier") String tier ) { this.period = period; - this.replicants = (replicants == null) ? 2 : replicants; - this.tier = tier; + + if (tieredReplicants != null) { + this.tieredReplicants = tieredReplicants; + } else { // Backwards compatible + this.tieredReplicants = ImmutableMap.of(tier, replicants); + } } @Override @@ -62,22 +70,17 @@ public class PeriodLoadRule extends LoadRule return period; } + @Override @JsonProperty - public int getReplicants() + public Map getTieredReplicants() { - return replicants; + return tieredReplicants; } @Override - public int getReplicants(String tier) + public int getNumReplicants(String tier) { - return (this.tier.equalsIgnoreCase(tier)) ? replicants : 0; - } - - @JsonProperty - public String getTier() - { - return tier; + return tieredReplicants.get(tier); } @Override diff --git a/server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java index 6fdc10f822c..e1f0942958c 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java @@ -25,6 +25,8 @@ import com.google.common.collect.Range; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; +import java.util.Map; + /** */ public class SizeLoadRule extends LoadRule @@ -51,23 +53,15 @@ public class SizeLoadRule extends LoadRule } @Override - @JsonProperty - public int getReplicants() + public Map getTieredReplicants() { - return replicants; + return null; } @Override - public int getReplicants(String tier) + public int getNumReplicants(String tier) { - return (this.tier.equalsIgnoreCase(tier)) ? replicants : 0; - } - - @Override - @JsonProperty - public String getTier() - { - return tier; + return 0; } @Override @@ -76,18 +70,6 @@ public class SizeLoadRule extends LoadRule return "loadBySize"; } - @JsonProperty - public long getLow() - { - return low; - } - - @JsonProperty - public long getHigh() - { - return high; - } - @Override public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) { From 2d3c4812e52e17a4284948d03f3c8e518d835e0e Mon Sep 17 00:00:00 2001 From: fjy Date: Thu, 2 Jan 2014 11:33:05 -0800 Subject: [PATCH 23/49] passing tests from loading across tiers --- .../io/druid/client/DruidServerConfig.java | 7 - .../coordinator/rules/IntervalLoadRule.java | 3 +- .../server/coordinator/rules/LoadRule.java | 25 +- .../coordinator/rules/PeriodLoadRule.java | 5 +- .../DruidCoordinatorBalancerProfiler.java | 2 +- .../DruidCoordinatorRuleRunnerTest.java | 34 +-- .../coordinator/rules/LoadRuleTest.java | 270 ++++++++++++++++++ .../coordinator/rules/PeriodLoadRuleTest.java | 2 + 8 files changed, 311 insertions(+), 37 deletions(-) create mode 100644 server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java diff --git a/server/src/main/java/io/druid/client/DruidServerConfig.java b/server/src/main/java/io/druid/client/DruidServerConfig.java index a990d56ef15..096269b02e8 100644 --- a/server/src/main/java/io/druid/client/DruidServerConfig.java +++ b/server/src/main/java/io/druid/client/DruidServerConfig.java @@ -34,9 +34,6 @@ public class DruidServerConfig @JsonProperty private String tier = DruidServer.DEFAULT_TIER; - @JsonProperty - private String zone = DruidServer.DEFAULT_ZONE; - public long getMaxSize() { return maxSize; @@ -46,8 +43,4 @@ public class DruidServerConfig { return tier; } - - public String getZone() { - return zone; - } } diff --git a/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java index ea3a36587d0..6a1599dc4ad 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/IntervalLoadRule.java @@ -73,7 +73,8 @@ public class IntervalLoadRule extends LoadRule @Override public int getNumReplicants(String tier) { - return tieredReplicants.get(tier); + final Integer retVal = tieredReplicants.get(tier); + return retVal == null ? 0 : retVal; } @JsonProperty diff --git a/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java index 7127c9af98c..f629318395b 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/LoadRule.java @@ -19,6 +19,7 @@ package io.druid.server.coordinator.rules; +import com.google.api.client.util.Maps; import com.google.common.collect.Lists; import com.google.common.collect.MinMaxPriorityQueue; import com.metamx.emitter.EmittingLogger; @@ -47,13 +48,12 @@ public abstract class LoadRule implements Rule { CoordinatorStats stats = new CoordinatorStats(); + final Map loadStatus = Maps.newHashMap(); for (Map.Entry entry : getTieredReplicants().entrySet()) { final String tier = entry.getKey(); final int expectedReplicants = entry.getValue(); int totalReplicants = params.getSegmentReplicantLookup().getTotalReplicants(segment.getIdentifier(), tier); - int clusterReplicants = params.getSegmentReplicantLookup() - .getClusterReplicants(segment.getIdentifier(), tier); MinMaxPriorityQueue serverQueue = params.getDruidCluster().getServersByTier(tier); if (serverQueue == null) { @@ -78,8 +78,13 @@ public abstract class LoadRule implements Rule ); } - stats.accumulate(drop(expectedReplicants, clusterReplicants, segment, params)); + int clusterReplicants = params.getSegmentReplicantLookup() + .getClusterReplicants(segment.getIdentifier(), tier); + loadStatus.put(tier, expectedReplicants - clusterReplicants); } + // Remove over-replication + stats.accumulate(drop(loadStatus, segment, params)); + return stats; } @@ -146,24 +151,26 @@ public abstract class LoadRule implements Rule } private CoordinatorStats drop( - int expectedReplicants, - int clusterReplicants, + final Map loadStatus, final DataSegment segment, final DruidCoordinatorRuntimeParams params ) { CoordinatorStats stats = new CoordinatorStats(); - final ReplicationThrottler replicationManager = params.getReplicationManager(); if (!params.hasDeletionWaitTimeElapsed()) { return stats; } - // Make sure we have enough actual replicants in the correct tier in the cluster before doing anything - if (clusterReplicants < expectedReplicants) { - return stats; + // Make sure we have enough actual replicants in the correct tiers in the cluster before doing anything + for (Integer leftToLoad : loadStatus.values()) { + if (leftToLoad > 0) { + return stats; + } } + final ReplicationThrottler replicationManager = params.getReplicationManager(); + // Find all instances of this segment across tiers Map replicantsByTier = params.getSegmentReplicantLookup().getClusterTiers(segment.getIdentifier()); diff --git a/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java index a8b47e35aef..bfad025b4a5 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/PeriodLoadRule.java @@ -44,7 +44,7 @@ public class PeriodLoadRule extends LoadRule @JsonProperty("period") Period period, @JsonProperty("tieredReplicants") Map tieredReplicants, // The following two vars need to be deprecated - @JsonProperty("replicants") Integer replicants, + @JsonProperty("replicants") int replicants, @JsonProperty("tier") String tier ) { @@ -80,7 +80,8 @@ public class PeriodLoadRule extends LoadRule @Override public int getNumReplicants(String tier) { - return tieredReplicants.get(tier); + final Integer retVal = tieredReplicants.get(tier); + return retVal == null ? 0 : retVal; } @Override diff --git a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java index 6f931c286ff..65ae7908198 100644 --- a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java +++ b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java @@ -54,7 +54,7 @@ public class DruidCoordinatorBalancerProfiler Map segments = Maps.newHashMap(); ServiceEmitter emitter; DatabaseRuleManager manager; - PeriodLoadRule loadRule = new PeriodLoadRule(new Period("P5000Y"), 3, "normal"); + PeriodLoadRule loadRule = new PeriodLoadRule(new Period("P5000Y"), null, 3, "normal"); List rules = ImmutableList.of(loadRule); @Before diff --git a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java index 72693e65103..02d690b1a17 100644 --- a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java +++ b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java @@ -115,9 +115,9 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T06:00:00.000Z"), 1, "hot"), - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), 1, "normal"), - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), 1, "cold") + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T06:00:00.000Z"), null, 1, "hot"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), null, 1, "normal"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), null, 1, "cold") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); @@ -211,8 +211,8 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T06:00:00.000Z"), 2, "hot"), - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), 1, "cold") + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T06:00:00.000Z"), null, 2, "hot"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), null, 1, "cold") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); @@ -300,8 +300,8 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), 1, "hot"), - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), 1, "normal") + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), null, 1, "hot"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), null, 1, "normal") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); @@ -383,8 +383,8 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), 1, "hot"), - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), 1, "normal") + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), null, 1, "hot"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z"), null, 1, "normal") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); @@ -434,7 +434,7 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-02T00:00:00.000Z/2012-01-03T00:00:00.000Z"), 1, "normal") + new IntervalLoadRule(new Interval("2012-01-02T00:00:00.000Z/2012-01-03T00:00:00.000Z"), null, 1, "normal") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); @@ -488,7 +488,7 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), 1, "normal"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), null, 1, "normal"), new IntervalDropRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z")) ) ).atLeastOnce(); @@ -549,7 +549,7 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), 1, "normal"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), null, 1, "normal"), new IntervalDropRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z")) ) ).atLeastOnce(); @@ -626,7 +626,7 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), 1, "hot"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), null, 1, "hot"), new IntervalDropRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z")) ) ).atLeastOnce(); @@ -705,7 +705,7 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), 1, "hot"), + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T12:00:00.000Z"), null, 1, "hot"), new IntervalDropRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-02T00:00:00.000Z")) ) ).atLeastOnce(); @@ -776,7 +776,7 @@ public class DruidCoordinatorRuleRunnerTest { EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T01:00:00.000Z"), 0, "normal") + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2012-01-01T01:00:00.000Z"), null, 0, "normal") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); @@ -877,7 +877,7 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2013-01-01T00:00:00.000Z"), 2, "hot") + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2013-01-01T00:00:00.000Z"), null, 2, "hot") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); @@ -968,7 +968,7 @@ public class DruidCoordinatorRuleRunnerTest EasyMock.expect(databaseRuleManager.getRulesWithDefault(EasyMock.anyObject())).andReturn( Lists.newArrayList( - new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2013-01-02T00:00:00.000Z"), 1, "normal") + new IntervalLoadRule(new Interval("2012-01-01T00:00:00.000Z/2013-01-02T00:00:00.000Z"), null, 1, "normal") ) ).atLeastOnce(); EasyMock.replay(databaseRuleManager); diff --git a/server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java b/server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java new file mode 100644 index 00000000000..60571bb16e9 --- /dev/null +++ b/server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java @@ -0,0 +1,270 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.server.coordinator.rules; + +import com.google.api.client.util.Lists; +import com.google.api.client.util.Maps; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.MinMaxPriorityQueue; +import com.google.common.collect.Ordering; +import com.google.common.collect.Sets; +import io.druid.client.DruidServer; +import io.druid.server.coordinator.CoordinatorStats; +import io.druid.server.coordinator.DruidCluster; +import io.druid.server.coordinator.DruidCoordinatorRuntimeParams; +import io.druid.server.coordinator.LoadPeonCallback; +import io.druid.server.coordinator.LoadQueuePeon; +import io.druid.server.coordinator.ReplicationThrottler; +import io.druid.server.coordinator.SegmentReplicantLookup; +import io.druid.server.coordinator.ServerHolder; +import io.druid.timeline.DataSegment; +import io.druid.timeline.partition.NoneShardSpec; +import org.easymock.EasyMock; +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Map; + +/** + */ +public class LoadRuleTest +{ + private LoadQueuePeon mockPeon; + private ReplicationThrottler throttler; + private DataSegment segment; + + @Before + public void setUp() throws Exception + { + mockPeon = EasyMock.createMock(LoadQueuePeon.class); + throttler = new ReplicationThrottler(1, 1); + for (String tier : Arrays.asList("hot", DruidServer.DEFAULT_TIER)) { + throttler.updateReplicationState(tier); + throttler.updateTerminationState(tier); + } + segment = new DataSegment( + "foo", + new Interval("0/3000"), + new DateTime().toString(), + Maps.newHashMap(), + Lists.newArrayList(), + Lists.newArrayList(), + new NoneShardSpec(), + 0, + 0 + ); + } + + @After + public void tearDown() throws Exception + { + EasyMock.verify(mockPeon); + } + + @Test + public void testLoad() throws Exception + { + mockPeon.loadSegment(EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.expect(mockPeon.getSegmentsToLoad()).andReturn(Sets.newHashSet()).atLeastOnce(); + EasyMock.expect(mockPeon.getLoadQueueSize()).andReturn(0L).atLeastOnce(); + EasyMock.replay(mockPeon); + + LoadRule rule = new LoadRule() + { + private final Map tiers = ImmutableMap.of( + "hot", 1, + DruidServer.DEFAULT_TIER, 2 + ); + + @Override + public Map getTieredReplicants() + { + return tiers; + } + + @Override + public int getNumReplicants(String tier) + { + return tiers.get(tier); + } + + @Override + public String getType() + { + return "test"; + } + + @Override + public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) + { + return true; + } + }; + + DruidCluster druidCluster = new DruidCluster( + ImmutableMap.of( + "hot", + MinMaxPriorityQueue.orderedBy(Ordering.natural().reverse()).create( + Arrays.asList( + new ServerHolder( + new DruidServer( + "serverHot", + "hostHot", + 1000, + "historical", + "hot" + ), + mockPeon + ) + ) + ), + DruidServer.DEFAULT_TIER, + MinMaxPriorityQueue.orderedBy(Ordering.natural().reverse()).create( + Arrays.asList( + new ServerHolder( + new DruidServer( + "serverNorm", + "hostNorm", + 1000, + "historical", + DruidServer.DEFAULT_TIER + ), + mockPeon + ) + ) + ) + ) + ); + + CoordinatorStats stats = rule.run( + null, + DruidCoordinatorRuntimeParams.newBuilder() + .withDruidCluster(druidCluster) + .withSegmentReplicantLookup(SegmentReplicantLookup.make(new DruidCluster())) + .withReplicationManager(throttler) + .withAvailableSegments(Arrays.asList(segment)).build(), + segment + ); + + Assert.assertTrue(stats.getPerTierStats().get("assignedCount").get("hot").get() == 1); + Assert.assertTrue(stats.getPerTierStats().get("assignedCount").get(DruidServer.DEFAULT_TIER).get() == 2); + } + + @Test + public void testDrop() throws Exception + { + mockPeon.dropSegment(EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.expect(mockPeon.getSegmentsToLoad()).andReturn(Sets.newHashSet()).atLeastOnce(); + EasyMock.expect(mockPeon.getLoadQueueSize()).andReturn(0L).anyTimes(); + EasyMock.replay(mockPeon); + + LoadRule rule = new LoadRule() + { + private final Map tiers = ImmutableMap.of( + "hot", 0, + DruidServer.DEFAULT_TIER, 0 + ); + + @Override + public Map getTieredReplicants() + { + return tiers; + } + + @Override + public int getNumReplicants(String tier) + { + return tiers.get(tier); + } + + @Override + public String getType() + { + return "test"; + } + + @Override + public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) + { + return true; + } + }; + + DruidServer server1 = new DruidServer( + "serverHot", + "hostHot", + 1000, + "historical", + "hot" + ); + server1.addDataSegment(segment.getIdentifier(), segment); + DruidServer server2 = new DruidServer( + "serverNorm", + "hostNorm", + 1000, + "historical", + DruidServer.DEFAULT_TIER + ); + server2.addDataSegment(segment.getIdentifier(), segment); + DruidCluster druidCluster = new DruidCluster( + ImmutableMap.of( + "hot", + MinMaxPriorityQueue.orderedBy(Ordering.natural().reverse()).create( + Arrays.asList( + new ServerHolder( + server1, + mockPeon + ) + ) + ), + DruidServer.DEFAULT_TIER, + MinMaxPriorityQueue.orderedBy(Ordering.natural().reverse()).create( + Arrays.asList( + new ServerHolder( + server2, + mockPeon + ) + ) + ) + ) + ); + + + CoordinatorStats stats = rule.run( + null, + DruidCoordinatorRuntimeParams.newBuilder() + .withDruidCluster(druidCluster) + .withSegmentReplicantLookup(SegmentReplicantLookup.make(druidCluster)) + .withReplicationManager(throttler) + .withAvailableSegments(Arrays.asList(segment)).build(), + segment + ); + + Assert.assertTrue(stats.getPerTierStats().get("droppedCount").get("hot").get() == 1); + Assert.assertTrue(stats.getPerTierStats().get("droppedCount").get(DruidServer.DEFAULT_TIER).get() == 1); + } +} diff --git a/server/src/test/java/io/druid/server/coordinator/rules/PeriodLoadRuleTest.java b/server/src/test/java/io/druid/server/coordinator/rules/PeriodLoadRuleTest.java index 6c172af1081..afd255111eb 100644 --- a/server/src/test/java/io/druid/server/coordinator/rules/PeriodLoadRuleTest.java +++ b/server/src/test/java/io/druid/server/coordinator/rules/PeriodLoadRuleTest.java @@ -42,6 +42,7 @@ public class PeriodLoadRuleTest DateTime now = new DateTime("2013-01-01"); PeriodLoadRule rule = new PeriodLoadRule( new Period("P5000Y"), + null, 0, "" ); @@ -57,6 +58,7 @@ public class PeriodLoadRuleTest DateTime now = new DateTime("2012-12-31T01:00:00"); PeriodLoadRule rule = new PeriodLoadRule( new Period("P1M"), + null, 0, "" ); From e11952f3b6ae1a4c1041fc8bff4564c983f43d18 Mon Sep 17 00:00:00 2001 From: fjy Date: Mon, 6 Jan 2014 17:01:50 -0800 Subject: [PATCH 24/49] bridge is kinda working for mastery stuff right now, tests pass --- docs/content/Realtime.md | 1 - .../druid/curator/announcement/Announcer.java | 15 + .../io/druid/db/DatabaseSegmentManager.java | 47 ++- .../java/io/druid/server/bridge/Bridge.java | 17 + .../server/bridge/BridgeCuratorConfig.java | 12 + .../bridge/BridgeJettyServerInitializer.java | 38 ++ .../server/bridge/BridgeZkCoordinator.java | 121 +++++++ .../server/bridge/DruidClusterBridge.java | 334 ++++++++++++++++++ .../bridge/DruidClusterBridgeConfig.java | 25 ++ .../coordination/BaseZkCoordinator.java | 181 ++++++++++ .../DataSegmentChangeCallback.java | 8 + .../DataSegmentChangeHandler.java | 4 +- .../DataSegmentChangeRequest.java | 2 +- .../SegmentChangeRequestDrop.java | 4 +- .../SegmentChangeRequestLoad.java | 4 +- .../SegmentChangeRequestNoop.java | 4 +- .../server/coordination/ZkCoordinator.java | 198 +++-------- .../server/coordinator/DruidCoordinator.java | 15 +- .../coordinator/rules/ForeverDropRule.java | 2 + .../coordinator/rules/ForeverLoadRule.java | 1 + .../server/initialization/ZkPathsConfig.java | 6 + .../src/main/java/io/druid/cli/CliBridge.java | 158 +++++++++ services/src/main/java/io/druid/cli/Main.java | 3 +- 23 files changed, 1022 insertions(+), 178 deletions(-) create mode 100644 server/src/main/java/io/druid/server/bridge/Bridge.java create mode 100644 server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java create mode 100644 server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java create mode 100644 server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java create mode 100644 server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java create mode 100644 server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java create mode 100644 server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java create mode 100644 server/src/main/java/io/druid/server/coordination/DataSegmentChangeCallback.java create mode 100644 services/src/main/java/io/druid/cli/CliBridge.java diff --git a/docs/content/Realtime.md b/docs/content/Realtime.md index a6111a8734b..511a3995627 100644 --- a/docs/content/Realtime.md +++ b/docs/content/Realtime.md @@ -129,7 +129,6 @@ This describes the data schema for the output Druid segment. More information ab |aggregators|Array of Objects|The list of aggregators to use to aggregate colliding rows together.|yes| |dataSource|String|The name of the dataSource that the segment belongs to.|yes| |indexGranularity|String|The granularity of the data inside the segment. E.g. a value of "minute" will mean that data is aggregated at minutely granularity. That is, if there are collisions in the tuple (minute(timestamp), dimensions), then it will aggregate values together using the aggregators instead of storing individual rows.|yes| -|segmentGranularity|String|The granularity of the segment as a whole. This is generally larger than the index granularity and describes the rate at which the realtime server will push segments out for historical servers to take over.|yes| |shardSpec|Object|This describes the shard that is represented by this server. This must be specified properly in order to have multiple realtime nodes indexing the same data stream in a sharded fashion.|no| ### Config diff --git a/server/src/main/java/io/druid/curator/announcement/Announcer.java b/server/src/main/java/io/druid/curator/announcement/Announcer.java index 8b017c41a24..b5beb44f3c1 100644 --- a/server/src/main/java/io/druid/curator/announcement/Announcer.java +++ b/server/src/main/java/io/druid/curator/announcement/Announcer.java @@ -63,6 +63,7 @@ public class Announcer private final PathChildrenCacheFactory factory; private final List> toAnnounce = Lists.newArrayList(); + private final List> toUpdate = Lists.newArrayList(); private final ConcurrentMap listeners = new MapMaker().makeMap(); private final ConcurrentMap> announcements = new MapMaker().makeMap(); private final List parentsIBuilt = new CopyOnWriteArrayList(); @@ -92,6 +93,11 @@ public class Announcer announce(pair.lhs, pair.rhs); } toAnnounce.clear(); + + for (Pair pair : toUpdate) { + update(pair.lhs, pair.rhs); + } + toUpdate.clear(); } } @@ -144,6 +150,8 @@ public class Announcer } } + log.info("Announcing with Curator %s", curator); // TODO + final ZKPaths.PathAndNode pathAndNode = ZKPaths.getPathAndNode(path); final String parentPath = pathAndNode.getPath(); @@ -268,6 +276,13 @@ public class Announcer public void update(final String path, final byte[] bytes) { + synchronized (toAnnounce) { + if (!started) { + toUpdate.add(Pair.of(path, bytes)); + return; + } + } + final ZKPaths.PathAndNode pathAndNode = ZKPaths.getPathAndNode(path); final String parentPath = pathAndNode.getPath(); diff --git a/server/src/main/java/io/druid/db/DatabaseSegmentManager.java b/server/src/main/java/io/druid/db/DatabaseSegmentManager.java index 3d68ad46978..eee1b0db360 100644 --- a/server/src/main/java/io/druid/db/DatabaseSegmentManager.java +++ b/server/src/main/java/io/druid/db/DatabaseSegmentManager.java @@ -339,6 +339,50 @@ public class DatabaseSegmentManager return true; } + public boolean deleteSegment(final DataSegment segment) + { + try { + final String ds = segment.getDataSource(); + + dbi.withHandle( + new HandleCallback() + { + @Override + public Void withHandle(Handle handle) throws Exception + { + handle.createStatement( + String.format("DELETE from %s WHERE id = :id", getSegmentsTable()) + ) + .bind("id", segment.getIdentifier()) + .execute(); + + return null; + } + } + ); + + ConcurrentHashMap dataSourceMap = dataSources.get(); + + if (!dataSourceMap.containsKey(ds)) { + log.warn("Cannot find datasource %s", ds); + return false; + } + + DruidDataSource dataSource = dataSourceMap.get(ds); + dataSource.removePartition(segment.getIdentifier()); + + if (dataSource.isEmpty()) { + dataSourceMap.remove(ds); + } + } + catch (Exception e) { + log.error(e, e.toString()); + return false; + } + + return true; + } + public boolean isStarted() { return started; @@ -462,7 +506,8 @@ public class DatabaseSegmentManager } } - private String getSegmentsTable() { + private String getSegmentsTable() + { return dbTables.get().getSegmentsTable(); } } diff --git a/server/src/main/java/io/druid/server/bridge/Bridge.java b/server/src/main/java/io/druid/server/bridge/Bridge.java new file mode 100644 index 00000000000..108cac07629 --- /dev/null +++ b/server/src/main/java/io/druid/server/bridge/Bridge.java @@ -0,0 +1,17 @@ +package io.druid.server.bridge; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + */ +@BindingAnnotation +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Bridge +{ +} diff --git a/server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java b/server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java new file mode 100644 index 00000000000..f60ce5f0132 --- /dev/null +++ b/server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java @@ -0,0 +1,12 @@ +package io.druid.server.bridge; + +import io.druid.curator.CuratorConfig; +import org.skife.config.Config; + +/** + */ +public abstract class BridgeCuratorConfig extends CuratorConfig +{ + @Config("druid.bridge.zk.service.host") + public abstract String getParentZkHosts(); +} diff --git a/server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java b/server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java new file mode 100644 index 00000000000..e07f979bb22 --- /dev/null +++ b/server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java @@ -0,0 +1,38 @@ +package io.druid.server.bridge; + +import com.google.inject.Injector; +import com.google.inject.servlet.GuiceFilter; +import io.druid.server.initialization.JettyServerInitializer; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlets.GzipFilter; + +/** + */ +public class BridgeJettyServerInitializer implements JettyServerInitializer +{ + @Override + public void initialize(Server server, Injector injector) + { + final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS); + + ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class); + + root.addServlet(holderPwd, "/"); + //root.addFilter(new FilterHolder(injector.getInstance(RedirectFilter.class)), "/*", null); + root.addFilter(GzipFilter.class, "/*", null); + + // Can't use '/*' here because of Guice and Jetty static content conflicts + // The coordinator really needs a standarized api path + root.addFilter(GuiceFilter.class, "/status/*", null); + + HandlerList handlerList = new HandlerList(); + handlerList.setHandlers(new Handler[]{root}); + + server.setHandler(handlerList); + } +} diff --git a/server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java b/server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java new file mode 100644 index 00000000000..fb9ec911bd3 --- /dev/null +++ b/server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java @@ -0,0 +1,121 @@ +package io.druid.server.bridge; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Throwables; +import com.google.inject.Inject; +import com.metamx.common.logger.Logger; +import io.druid.client.DruidServer; +import io.druid.client.ServerView; +import io.druid.concurrent.Execs; +import io.druid.db.DatabaseSegmentManager; +import io.druid.segment.loading.SegmentLoaderConfig; +import io.druid.segment.realtime.DbSegmentPublisher; +import io.druid.server.coordination.BaseZkCoordinator; +import io.druid.server.coordination.DataSegmentChangeCallback; +import io.druid.server.coordination.DataSegmentChangeHandler; +import io.druid.server.coordination.DruidServerMetadata; +import io.druid.server.initialization.ZkPathsConfig; +import io.druid.timeline.DataSegment; +import org.apache.curator.framework.CuratorFramework; + +import java.util.concurrent.ExecutorService; + +/** + */ +public class BridgeZkCoordinator extends BaseZkCoordinator +{ + private static final Logger log = new Logger(BaseZkCoordinator.class); + + private final DbSegmentPublisher dbSegmentPublisher; + private final DatabaseSegmentManager databaseSegmentManager; + private final ServerView serverView; + + private final ExecutorService exec = Execs.singleThreaded("BridgeZkCoordinatorServerView-%s"); + + @Inject + public BridgeZkCoordinator( + ObjectMapper jsonMapper, + ZkPathsConfig zkPaths, + DruidServerMetadata me, + @Bridge CuratorFramework curator, + DbSegmentPublisher dbSegmentPublisher, + DatabaseSegmentManager databaseSegmentManager, + ServerView serverView + ) + { + super(jsonMapper, zkPaths, me, curator); + + this.dbSegmentPublisher = dbSegmentPublisher; + this.databaseSegmentManager = databaseSegmentManager; + this.serverView = serverView; + } + + @Override + public void createCacheDir() + { + // do nothing + } + + @Override + public void loadCache() + { + // do nothing + } + + @Override + public DataSegmentChangeHandler getDataSegmentChangeHandler() + { + return BridgeZkCoordinator.this; + } + + @Override + public void addSegment(final DataSegment segment, final DataSegmentChangeCallback callback) + { + try { + log.info("Publishing segment %s", segment.getIdentifier()); + dbSegmentPublisher.publishSegment(segment); + serverView.registerSegmentCallback( + exec, + new ServerView.BaseSegmentCallback() + { + @Override + public ServerView.CallbackAction segmentAdded( + DruidServer server, DataSegment theSegment + ) + { + if (theSegment.equals(segment)) { + callback.execute(); + log.info("Callback executed"); + } + return ServerView.CallbackAction.CONTINUE; + } + } + ); + } + catch (Exception e) { + throw Throwables.propagate(e); + } + } + + @Override + public void removeSegment(final DataSegment segment, final DataSegmentChangeCallback callback) + { + databaseSegmentManager.removeSegment(segment.getDataSource(), segment.getIdentifier()); + serverView.registerSegmentCallback( + exec, + new ServerView.BaseSegmentCallback() + { + @Override + public ServerView.CallbackAction segmentRemoved( + DruidServer server, DataSegment theSegment + ) + { + if (theSegment.equals(segment)) { + callback.execute(); + } + return ServerView.CallbackAction.CONTINUE; + } + } + ); + } +} diff --git a/server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java b/server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java new file mode 100644 index 00000000000..8a824fc702b --- /dev/null +++ b/server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java @@ -0,0 +1,334 @@ +package io.druid.server.bridge; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Predicate; +import com.google.common.base.Throwables; +import com.google.common.collect.Maps; +import com.google.common.io.Closeables; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.inject.Inject; +import com.metamx.common.concurrent.ScheduledExecutorFactory; +import com.metamx.common.concurrent.ScheduledExecutors; +import com.metamx.common.guava.FunctionalIterable; +import com.metamx.common.lifecycle.LifecycleStart; +import com.metamx.common.lifecycle.LifecycleStop; +import com.metamx.emitter.EmittingLogger; +import io.druid.client.DruidServer; +import io.druid.client.ServerInventoryView; +import io.druid.client.ServerView; +import io.druid.concurrent.Execs; +import io.druid.curator.announcement.Announcer; +import io.druid.guice.ManageLifecycle; +import io.druid.guice.annotations.Self; +import io.druid.server.DruidNode; +import io.druid.server.coordination.AbstractDataSegmentAnnouncer; +import io.druid.server.coordination.DruidServerMetadata; +import io.druid.timeline.DataSegment; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.recipes.leader.LeaderLatch; +import org.apache.curator.framework.recipes.leader.LeaderLatchListener; +import org.apache.curator.utils.ZKPaths; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicReference; + +/** + */ +@ManageLifecycle +public class DruidClusterBridge +{ + public static final String CONNECTOR_OWNER_NODE = "_CONNECTOR"; + public static final String NODE_TYPE = "bridge"; + + private static final EmittingLogger log = new EmittingLogger(DruidClusterBridge.class); + + private final ObjectMapper jsonMapper; + private final DruidClusterBridgeConfig config; + private final BridgeZkCoordinator bridgeZkCoordinator; // watches for assignments from main cluster + private final Announcer announcer; //announce self to main cluster + private final ServerInventoryView serverInventoryView; + private final CuratorFramework curator; + private final ScheduledExecutorService exec; + private final AtomicReference leaderLatch; + private final DruidNode self; + + private final Map segments = Maps.newHashMap(); + private final Object lock = new Object(); + + private volatile boolean started = false; + private volatile boolean leader = false; + + @Inject + public DruidClusterBridge( + ObjectMapper jsonMapper, + DruidClusterBridgeConfig config, + BridgeZkCoordinator bridgeZkCoordinator, + @Bridge Announcer announcer, + @Bridge final AbstractDataSegmentAnnouncer dataSegmentAnnouncer, + ServerInventoryView serverInventoryView, + CuratorFramework curator, + ScheduledExecutorFactory scheduledExecutorFactory, + AtomicReference leaderLatch, + @Self DruidNode self + ) + { + this.jsonMapper = jsonMapper; + this.config = config; + this.bridgeZkCoordinator = bridgeZkCoordinator; + this.announcer = announcer; + this.serverInventoryView = serverInventoryView; + this.curator = curator; + this.leaderLatch = leaderLatch; + + this.exec = scheduledExecutorFactory.create(1, "Coordinator-Exec--%d"); + this.self = self; + + log.info("Local curator: [%s]", curator); // TODO + + serverInventoryView.registerSegmentCallback( + Executors.newFixedThreadPool( + 1, + new ThreadFactoryBuilder().setDaemon(true) + .setNameFormat("DruidClusterBridge-ServerInventoryView-%d") + .build() + ), + new ServerView.BaseSegmentCallback() + { + @Override + public ServerView.CallbackAction segmentAdded( + DruidServer server, DataSegment segment + ) + { + try { + synchronized (lock) { + Integer count = segments.get(segment); + if (count == null) { + segments.put(segment, 1); + dataSegmentAnnouncer.announceSegment(segment); + } else { + segments.put(segment, count + 1); + } + } + } + catch (Exception e) { + throw Throwables.propagate(e); + } + + return ServerView.CallbackAction.CONTINUE; + } + + @Override + public ServerView.CallbackAction segmentRemoved(DruidServer server, DataSegment segment) + { + try { + synchronized (lock) { + Integer count = segments.get(segment); + if (count != null) { + if (count == 0) { + dataSegmentAnnouncer.unannounceSegment(segment); + segments.remove(segment); + } else { + segments.put(segment, count - 1); + } + } + } + } + catch (Exception e) { + throw Throwables.propagate(e); + } + + return ServerView.CallbackAction.CONTINUE; + } + } + ); + } + + public boolean isLeader() + { + return leader; + } + + @LifecycleStart + public void start() + { + synchronized (lock) { + if (started) { + return; + } + started = true; + + createNewLeaderLatch(); + try { + leaderLatch.get().start(); + } + catch (Exception e) { + throw Throwables.propagate(e); + } + } + } + + private LeaderLatch createNewLeaderLatch() + { + final LeaderLatch newLeaderLatch = new LeaderLatch( + curator, ZKPaths.makePath(config.getConnectorPath(), CONNECTOR_OWNER_NODE), self.getHost() + ); + + newLeaderLatch.addListener( + new LeaderLatchListener() + { + @Override + public void isLeader() + { + becomeLeader(); + } + + @Override + public void notLeader() + { + stopBeingLeader(); + } + }, + Execs.singleThreaded("CoordinatorLeader-%s") + ); + + return leaderLatch.getAndSet(newLeaderLatch); + } + + @LifecycleStop + public void stop() + { + synchronized (lock) { + if (!started) { + return; + } + + stopBeingLeader(); + + try { + leaderLatch.get().close(); + } + catch (IOException e) { + log.warn(e, "Unable to close leaderLatch, ignoring"); + } + + exec.shutdownNow(); + + started = false; + } + } + + private void becomeLeader() + { + synchronized (lock) { + if (!started) { + return; + } + + log.info("Go-Go Gadgetmobile! Starting bridge in %s", config.getStartDelay()); + try { + bridgeZkCoordinator.start(); + serverInventoryView.start(); + + ScheduledExecutors.scheduleWithFixedDelay( + exec, + config.getStartDelay(), + config.getPeriod(), + new Callable() + { + @Override + public ScheduledExecutors.Signal call() + { + if (leader) { + Iterable servers = FunctionalIterable + .create(serverInventoryView.getInventory()) + .filter( + new Predicate() + { + @Override + public boolean apply( + DruidServer input + ) + { + return !input.getType().equalsIgnoreCase("realtime"); + } + } + ); + + long totalMaxSize = 0; + for (DruidServer server : servers) { + totalMaxSize += server.getMaxSize(); + } + + if (totalMaxSize == 0) { + log.warn("No servers founds!"); + } else { + + DruidServerMetadata me = new DruidServerMetadata( + self.getHost(), + self.getHost(), + totalMaxSize, + NODE_TYPE, + config.getTier() + ); + + try { + final String path = ZKPaths.makePath(config.getAnnouncementsPath(), self.getHost()); + log.info("Updating [%s] to have a maxSize of[%,d] bytes", self.getHost(), totalMaxSize); + announcer.update(path, jsonMapper.writeValueAsBytes(me)); + } + catch (Exception e) { + throw Throwables.propagate(e); + } + } + } + if (leader) { // (We might no longer be coordinator) + return ScheduledExecutors.Signal.REPEAT; + } else { + return ScheduledExecutors.Signal.STOP; + } + } + } + ); + + leader = true; + } + catch (Exception e) { + log.makeAlert(e, "Exception becoming leader") + .emit(); + final LeaderLatch oldLatch = createNewLeaderLatch(); + Closeables.closeQuietly(oldLatch); + try { + leaderLatch.get().start(); + } + catch (Exception e1) { + // If an exception gets thrown out here, then the coordinator will zombie out 'cause it won't be looking for + // the latch anymore. I don't believe it's actually possible for an Exception to throw out here, but + // Curator likes to have "throws Exception" on methods so it might happen... + log.makeAlert(e1, "I am a zombie") + .emit(); + } + } + } + } + + private void stopBeingLeader() + { + synchronized (lock) { + try { + log.info("I'll get you next time, Gadget. Next time!"); + + bridgeZkCoordinator.stop(); + serverInventoryView.stop(); + + leader = false; + } + catch (Exception e) { + log.makeAlert(e, "Unable to stopBeingLeader").emit(); + } + } + } +} diff --git a/server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java b/server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java new file mode 100644 index 00000000000..cd9398a6572 --- /dev/null +++ b/server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java @@ -0,0 +1,25 @@ +package io.druid.server.bridge; + +import io.druid.client.DruidServer; +import io.druid.server.initialization.ZkPathsConfig; +import org.joda.time.Duration; +import org.skife.config.Config; +import org.skife.config.Default; + +/** + */ +// TODO: make sure that this uses sub cluster zk paths +public abstract class DruidClusterBridgeConfig extends ZkPathsConfig +{ + @Config("druid.server.tier") + @Default(DruidServer.DEFAULT_TIER) + public abstract String getTier(); + + @Config("druid.bridge.startDelay") + @Default("PT300s") + public abstract Duration getStartDelay(); + + @Config("druid.bridge.period") + @Default("PT60s") + public abstract Duration getPeriod(); +} diff --git a/server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java b/server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java new file mode 100644 index 00000000000..db5fb693462 --- /dev/null +++ b/server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java @@ -0,0 +1,181 @@ +package io.druid.server.coordination; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Throwables; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.metamx.common.lifecycle.LifecycleStart; +import com.metamx.common.lifecycle.LifecycleStop; +import com.metamx.emitter.EmittingLogger; +import io.druid.server.initialization.ZkPathsConfig; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.recipes.cache.ChildData; +import org.apache.curator.framework.recipes.cache.PathChildrenCache; +import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; +import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; +import org.apache.curator.utils.ZKPaths; + +import java.io.IOException; + +/** + */ +public abstract class BaseZkCoordinator implements DataSegmentChangeHandler +{ + private static final EmittingLogger log = new EmittingLogger(ZkCoordinator.class); + + private final Object lock = new Object(); + + private final ObjectMapper jsonMapper; + private final ZkPathsConfig zkPaths; + private final DruidServerMetadata me; + private final CuratorFramework curator; + + private volatile PathChildrenCache loadQueueCache; + private volatile boolean started; + + public BaseZkCoordinator( + ObjectMapper jsonMapper, + ZkPathsConfig zkPaths, + DruidServerMetadata me, + CuratorFramework curator + ) + { + this.jsonMapper = jsonMapper; + this.zkPaths = zkPaths; + this.me = me; + this.curator = curator; + } + + @LifecycleStart + public void start() throws IOException + { + log.info("Starting zkCoordinator for server[%s]", me); + synchronized (lock) { + if (started) { + return; + } + + final String loadQueueLocation = ZKPaths.makePath(zkPaths.getLoadQueuePath(), me.getName()); + final String servedSegmentsLocation = ZKPaths.makePath(zkPaths.getServedSegmentsPath(), me.getName()); + final String liveSegmentsLocation = ZKPaths.makePath(zkPaths.getLiveSegmentsPath(), me.getName()); + + loadQueueCache = new PathChildrenCache( + curator, + loadQueueLocation, + true, + true, + new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ZkCoordinator-%s").build() + ); + + try { + createCacheDir(); + + log.info("Remote Curator[%s]", curator); // TODO + curator.newNamespaceAwareEnsurePath(loadQueueLocation).ensure(curator.getZookeeperClient()); + curator.newNamespaceAwareEnsurePath(servedSegmentsLocation).ensure(curator.getZookeeperClient()); + curator.newNamespaceAwareEnsurePath(liveSegmentsLocation).ensure(curator.getZookeeperClient()); + + loadCache(); + + loadQueueCache.getListenable().addListener( + new PathChildrenCacheListener() + { + @Override + public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception + { + final ChildData child = event.getData(); + switch (event.getType()) { + case CHILD_ADDED: + final String path = child.getPath(); + final DataSegmentChangeRequest segment = jsonMapper.readValue( + child.getData(), DataSegmentChangeRequest.class + ); + + log.info("New node[%s] with segmentClass[%s]", path, segment.getClass()); + + try { + segment.go( + getDataSegmentChangeHandler(), + new DataSegmentChangeCallback() + { + boolean hasRun = false; + + @Override + public void execute() + { + try { + if (!hasRun) { + curator.delete().guaranteed().forPath(path); + log.info("Completed processing for node[%s]", path); + hasRun = true; + } + } + catch (Exception e) { + throw Throwables.propagate(e); + } + } + } + ); + } + catch (Exception e) { + try { + curator.delete().guaranteed().forPath(path); + } + catch (Exception e1) { + log.info(e1, "Failed to delete node[%s], but ignoring exception.", path); + } + + log.makeAlert(e, "Segment load/unload: uncaught exception.") + .addData("node", path) + .addData("nodeProperties", segment) + .emit(); + } + + break; + case CHILD_REMOVED: + log.info("%s was removed", event.getData().getPath()); + break; + default: + log.info("Ignoring event[%s]", event); + } + } + } + ); + loadQueueCache.start(); + } + catch (Exception e) { + Throwables.propagateIfPossible(e, IOException.class); + throw Throwables.propagate(e); + } + + started = true; + } + } + + @LifecycleStop + public void stop() + { + log.info("Stopping ZkCoordinator for [%s]", me); + synchronized (lock) { + if (!started) { + return; + } + + try { + loadQueueCache.close(); + } + catch (Exception e) { + throw Throwables.propagate(e); + } + finally { + loadQueueCache = null; + started = false; + } + } + } + + public abstract void createCacheDir(); + + public abstract void loadCache(); + + public abstract DataSegmentChangeHandler getDataSegmentChangeHandler(); +} diff --git a/server/src/main/java/io/druid/server/coordination/DataSegmentChangeCallback.java b/server/src/main/java/io/druid/server/coordination/DataSegmentChangeCallback.java new file mode 100644 index 00000000000..fe0cd038b7d --- /dev/null +++ b/server/src/main/java/io/druid/server/coordination/DataSegmentChangeCallback.java @@ -0,0 +1,8 @@ +package io.druid.server.coordination; + +/** + */ +public interface DataSegmentChangeCallback +{ + public void execute(); +} diff --git a/server/src/main/java/io/druid/server/coordination/DataSegmentChangeHandler.java b/server/src/main/java/io/druid/server/coordination/DataSegmentChangeHandler.java index 460e4b4256f..98f2bcd7b47 100644 --- a/server/src/main/java/io/druid/server/coordination/DataSegmentChangeHandler.java +++ b/server/src/main/java/io/druid/server/coordination/DataSegmentChangeHandler.java @@ -25,6 +25,6 @@ import io.druid.timeline.DataSegment; */ public interface DataSegmentChangeHandler { - public void addSegment(DataSegment segment); - public void removeSegment(DataSegment segment); + public void addSegment(DataSegment segment, DataSegmentChangeCallback callback); + public void removeSegment(DataSegment segment, DataSegmentChangeCallback callback); } diff --git a/server/src/main/java/io/druid/server/coordination/DataSegmentChangeRequest.java b/server/src/main/java/io/druid/server/coordination/DataSegmentChangeRequest.java index 0c29d1e1c75..c5fa72e6bc0 100644 --- a/server/src/main/java/io/druid/server/coordination/DataSegmentChangeRequest.java +++ b/server/src/main/java/io/druid/server/coordination/DataSegmentChangeRequest.java @@ -32,5 +32,5 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; }) public interface DataSegmentChangeRequest { - public void go(DataSegmentChangeHandler handler); + public void go(DataSegmentChangeHandler handler, DataSegmentChangeCallback callback); } diff --git a/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestDrop.java b/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestDrop.java index 9b0fc755fb3..2514f22871e 100644 --- a/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestDrop.java +++ b/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestDrop.java @@ -46,9 +46,9 @@ public class SegmentChangeRequestDrop implements DataSegmentChangeRequest } @Override - public void go(DataSegmentChangeHandler handler) + public void go(DataSegmentChangeHandler handler, DataSegmentChangeCallback callback) { - handler.removeSegment(segment); + handler.removeSegment(segment, callback); } @Override diff --git a/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestLoad.java b/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestLoad.java index 2a66693b66f..11eba9684c0 100644 --- a/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestLoad.java +++ b/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestLoad.java @@ -39,9 +39,9 @@ public class SegmentChangeRequestLoad implements DataSegmentChangeRequest } @Override - public void go(DataSegmentChangeHandler handler) + public void go(DataSegmentChangeHandler handler, DataSegmentChangeCallback callback) { - handler.addSegment(segment); + handler.addSegment(segment, callback); } @JsonProperty diff --git a/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestNoop.java b/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestNoop.java index e713278b47c..7c51f3f0b6f 100644 --- a/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestNoop.java +++ b/server/src/main/java/io/druid/server/coordination/SegmentChangeRequestNoop.java @@ -24,8 +24,8 @@ package io.druid.server.coordination; public class SegmentChangeRequestNoop implements DataSegmentChangeRequest { @Override - public void go(DataSegmentChangeHandler handler) + public void go(DataSegmentChangeHandler handler, DataSegmentChangeCallback callback) { - + // do nothing } } diff --git a/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java b/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java index 246415f57d0..72993173cd5 100644 --- a/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java +++ b/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java @@ -20,23 +20,14 @@ package io.druid.server.coordination; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Throwables; import com.google.common.collect.Lists; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.inject.Inject; -import com.metamx.common.lifecycle.LifecycleStart; -import com.metamx.common.lifecycle.LifecycleStop; import com.metamx.emitter.EmittingLogger; import io.druid.segment.loading.SegmentLoaderConfig; import io.druid.segment.loading.SegmentLoadingException; import io.druid.server.initialization.ZkPathsConfig; import io.druid.timeline.DataSegment; import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; -import org.apache.curator.utils.ZKPaths; import java.io.File; import java.io.IOException; @@ -44,23 +35,15 @@ import java.util.List; /** */ -public class ZkCoordinator implements DataSegmentChangeHandler +public class ZkCoordinator extends BaseZkCoordinator { private static final EmittingLogger log = new EmittingLogger(ZkCoordinator.class); - private final Object lock = new Object(); - private final ObjectMapper jsonMapper; private final SegmentLoaderConfig config; - private final ZkPathsConfig zkPaths; - private final DruidServerMetadata me; private final DataSegmentAnnouncer announcer; - private final CuratorFramework curator; private final ServerManager serverManager; - private volatile PathChildrenCache loadQueueCache; - private volatile boolean started; - @Inject public ZkCoordinator( ObjectMapper jsonMapper, @@ -72,126 +55,22 @@ public class ZkCoordinator implements DataSegmentChangeHandler ServerManager serverManager ) { + super(jsonMapper, zkPaths, me, curator); + this.jsonMapper = jsonMapper; this.config = config; - this.zkPaths = zkPaths; - this.me = me; this.announcer = announcer; - this.curator = curator; this.serverManager = serverManager; } - @LifecycleStart - public void start() throws IOException + @Override + public void createCacheDir() { - log.info("Starting zkCoordinator for server[%s]", me); - synchronized (lock) { - if (started) { - return; - } - - final String loadQueueLocation = ZKPaths.makePath(zkPaths.getLoadQueuePath(), me.getName()); - final String servedSegmentsLocation = ZKPaths.makePath(zkPaths.getServedSegmentsPath(), me.getName()); - final String liveSegmentsLocation = ZKPaths.makePath(zkPaths.getLiveSegmentsPath(), me.getName()); - - loadQueueCache = new PathChildrenCache( - curator, - loadQueueLocation, - true, - true, - new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ZkCoordinator-%s").build() - ); - - try { - config.getInfoDir().mkdirs(); - - curator.newNamespaceAwareEnsurePath(loadQueueLocation).ensure(curator.getZookeeperClient()); - curator.newNamespaceAwareEnsurePath(servedSegmentsLocation).ensure(curator.getZookeeperClient()); - curator.newNamespaceAwareEnsurePath(liveSegmentsLocation).ensure(curator.getZookeeperClient()); - - loadCache(); - - loadQueueCache.getListenable().addListener( - new PathChildrenCacheListener() - { - @Override - public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception - { - final ChildData child = event.getData(); - switch (event.getType()) { - case CHILD_ADDED: - final String path = child.getPath(); - final DataSegmentChangeRequest segment = jsonMapper.readValue( - child.getData(), DataSegmentChangeRequest.class - ); - - log.info("New node[%s] with segmentClass[%s]", path, segment.getClass()); - - try { - segment.go(ZkCoordinator.this); - curator.delete().guaranteed().forPath(path); - - log.info("Completed processing for node[%s]", path); - } - catch (Exception e) { - try { - curator.delete().guaranteed().forPath(path); - } - catch (Exception e1) { - log.info(e1, "Failed to delete node[%s], but ignoring exception.", path); - } - - log.makeAlert(e, "Segment load/unload: uncaught exception.") - .addData("node", path) - .addData("nodeProperties", segment) - .emit(); - } - - break; - case CHILD_REMOVED: - log.info("%s was removed", event.getData().getPath()); - break; - default: - log.info("Ignoring event[%s]", event); - } - } - } - ); - loadQueueCache.start(); - } - catch (Exception e) { - Throwables.propagateIfPossible(e, IOException.class); - throw Throwables.propagate(e); - } - - started = true; - } + config.getInfoDir().mkdirs(); } - @LifecycleStop - public void stop() - { - log.info("Stopping ZkCoordinator with config[%s]", config); - synchronized (lock) { - if (!started) { - return; - } - - - try { - loadQueueCache.close(); - } - catch (Exception e) { - throw Throwables.propagate(e); - } - finally { - loadQueueCache = null; - started = false; - } - } - } - - private void loadCache() + @Override + public void loadCache() { File baseDir = config.getInfoDir(); if (!baseDir.exists()) { @@ -221,11 +100,27 @@ public class ZkCoordinator implements DataSegmentChangeHandler } } - addSegments(cachedSegments); + addSegments( + cachedSegments, + new DataSegmentChangeCallback() + { + @Override + public void execute() + { + // do nothing + } + } + ); } @Override - public void addSegment(DataSegment segment) + public DataSegmentChangeHandler getDataSegmentChangeHandler() + { + return ZkCoordinator.this; + } + + @Override + public void addSegment(DataSegment segment, DataSegmentChangeCallback callback) { try { log.info("Loading segment %s", segment.getIdentifier()); @@ -235,7 +130,7 @@ public class ZkCoordinator implements DataSegmentChangeHandler loaded = serverManager.loadSegment(segment); } catch (Exception e) { - removeSegment(segment); + removeSegment(segment, callback); throw new SegmentLoadingException(e, "Exception loading segment[%s]", segment.getIdentifier()); } @@ -246,7 +141,7 @@ public class ZkCoordinator implements DataSegmentChangeHandler jsonMapper.writeValue(segmentInfoCacheFile, segment); } catch (IOException e) { - removeSegment(segment); + removeSegment(segment, callback); throw new SegmentLoadingException( e, "Failed to write to disk segment info cache file[%s]", segmentInfoCacheFile ); @@ -260,16 +155,18 @@ public class ZkCoordinator implements DataSegmentChangeHandler throw new SegmentLoadingException(e, "Failed to announce segment[%s]", segment.getIdentifier()); } } - } catch (SegmentLoadingException e) { log.makeAlert(e, "Failed to load segment for dataSource") .addData("segment", segment) .emit(); } + finally { + callback.execute(); + } } - public void addSegments(Iterable segments) + public void addSegments(Iterable segments, DataSegmentChangeCallback callback) { try { final List segmentFailures = Lists.newArrayList(); @@ -284,7 +181,7 @@ public class ZkCoordinator implements DataSegmentChangeHandler } catch (Exception e) { log.error(e, "Exception loading segment[%s]", segment.getIdentifier()); - removeSegment(segment); + removeSegment(segment, callback); segmentFailures.add(segment.getIdentifier()); continue; } @@ -297,7 +194,7 @@ public class ZkCoordinator implements DataSegmentChangeHandler } catch (IOException e) { log.error(e, "Failed to write to disk segment info cache file[%s]", segmentInfoCacheFile); - removeSegment(segment); + removeSegment(segment, callback); segmentFailures.add(segment.getIdentifier()); continue; } @@ -326,11 +223,14 @@ public class ZkCoordinator implements DataSegmentChangeHandler .addData("segments", segments) .emit(); } + finally { + callback.execute(); + } } @Override - public void removeSegment(DataSegment segment) + public void removeSegment(DataSegment segment, DataSegmentChangeCallback callback) { try { serverManager.dropSegment(segment); @@ -347,26 +247,8 @@ public class ZkCoordinator implements DataSegmentChangeHandler .addData("segment", segment) .emit(); } - } - - public void removeSegments(Iterable segments) - { - try { - for (DataSegment segment : segments) { - serverManager.dropSegment(segment); - - File segmentInfoCacheFile = new File(config.getInfoDir(), segment.getIdentifier()); - if (!segmentInfoCacheFile.delete()) { - log.warn("Unable to delete segmentInfoCacheFile[%s]", segmentInfoCacheFile); - } - } - - announcer.unannounceSegments(segments); - } - catch (Exception e) { - log.makeAlert(e, "Failed to remove segments") - .addData("segments", segments) - .emit(); + finally { + callback.execute(); } } } diff --git a/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java b/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java index 41da48a9ed3..4aef292297b 100644 --- a/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java +++ b/server/src/main/java/io/druid/server/coordinator/DruidCoordinator.java @@ -70,7 +70,6 @@ import org.apache.curator.utils.ZKPaths; import org.joda.time.DateTime; import org.joda.time.Duration; -import javax.annotation.Nullable; import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -694,11 +693,11 @@ public class DruidCoordinator // Do coordinator stuff. DruidCoordinatorRuntimeParams params = DruidCoordinatorRuntimeParams.newBuilder() - .withStartTime(startTime) - .withDatasources(databaseSegmentManager.getInventory()) - .withDynamicConfigs(dynamicConfigs.get()) - .withEmitter(emitter) - .build(); + .withStartTime(startTime) + .withDatasources(databaseSegmentManager.getInventory()) + .withDynamicConfigs(dynamicConfigs.get()) + .withEmitter(emitter) + .build(); for (DruidCoordinatorHelper helper : helpers) { @@ -731,10 +730,10 @@ public class DruidCoordinator { @Override public boolean apply( - @Nullable DruidServer input + DruidServer input ) { - return input.getType().equalsIgnoreCase("historical"); + return !input.getType().equalsIgnoreCase("realtime"); } } ); diff --git a/server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java b/server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java index fe86a602055..510cb29c55a 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/ForeverDropRule.java @@ -19,6 +19,7 @@ package io.druid.server.coordinator.rules; +import com.fasterxml.jackson.annotation.JsonProperty; import io.druid.timeline.DataSegment; import org.joda.time.DateTime; @@ -27,6 +28,7 @@ import org.joda.time.DateTime; public class ForeverDropRule extends DropRule { @Override + @JsonProperty public String getType() { return "dropForever"; diff --git a/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java index 9c3c5095066..70e482764f8 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java @@ -41,6 +41,7 @@ public class ForeverLoadRule extends LoadRule } @Override + @JsonProperty public String getType() { return "loadForever"; diff --git a/server/src/main/java/io/druid/server/initialization/ZkPathsConfig.java b/server/src/main/java/io/druid/server/initialization/ZkPathsConfig.java index ab296698548..8494b45e257 100644 --- a/server/src/main/java/io/druid/server/initialization/ZkPathsConfig.java +++ b/server/src/main/java/io/druid/server/initialization/ZkPathsConfig.java @@ -66,6 +66,12 @@ public abstract class ZkPathsConfig return defaultPath("coordinator"); } + @Config("druid.zk.paths.connectorPath") + public String getConnectorPath() + { + return defaultPath("connector"); + } + @Config("druid.zk.paths.indexer.announcementsPath") public String getIndexerAnnouncementPath() { diff --git a/services/src/main/java/io/druid/cli/CliBridge.java b/services/src/main/java/io/druid/cli/CliBridge.java new file mode 100644 index 00000000000..262b94d0534 --- /dev/null +++ b/services/src/main/java/io/druid/cli/CliBridge.java @@ -0,0 +1,158 @@ +package io.druid.cli; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; +import com.google.inject.Binder; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.metamx.common.lifecycle.Lifecycle; +import com.metamx.common.logger.Logger; +import io.airlift.command.Command; +import io.druid.concurrent.Execs; +import io.druid.curator.PotentiallyGzippedCompressionProvider; +import io.druid.curator.announcement.Announcer; +import io.druid.db.DatabaseSegmentManager; +import io.druid.db.DatabaseSegmentManagerConfig; +import io.druid.db.DatabaseSegmentManagerProvider; +import io.druid.guice.ConfigProvider; +import io.druid.guice.JsonConfigProvider; +import io.druid.guice.LazySingleton; +import io.druid.guice.LifecycleModule; +import io.druid.guice.ManageLifecycle; +import io.druid.guice.ManageLifecycleLast; +import io.druid.guice.NodeTypeConfig; +import io.druid.server.bridge.Bridge; +import io.druid.server.bridge.BridgeCuratorConfig; +import io.druid.server.bridge.BridgeJettyServerInitializer; +import io.druid.server.bridge.BridgeZkCoordinator; +import io.druid.server.bridge.DruidClusterBridge; +import io.druid.server.bridge.DruidClusterBridgeConfig; +import io.druid.server.coordination.AbstractDataSegmentAnnouncer; +import io.druid.server.coordination.BatchDataSegmentAnnouncer; +import io.druid.server.coordination.DruidServerMetadata; +import io.druid.server.initialization.BatchDataSegmentAnnouncerConfig; +import io.druid.server.initialization.JettyServerInitializer; +import io.druid.server.initialization.ZkPathsConfig; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.BoundedExponentialBackoffRetry; +import org.eclipse.jetty.server.Server; + +import java.util.List; + +/** + */ +@Command( + name = "bridge", + description = "Runs a bridge node, see http://druid.io/docs/0.6.46/Bridge.html for a description." // TODO +) +public class CliBridge extends ServerRunnable +{ + private static final Logger log = new Logger(CliBridge.class); + + public CliBridge() + { + super(log); + } + + @Override + protected List getModules() + { + return ImmutableList.of( + new Module() + { + @Override + public void configure(Binder binder) + { + ConfigProvider.bind(binder, BridgeCuratorConfig.class); + + binder.bind(BridgeZkCoordinator.class).in(ManageLifecycle.class); + binder.bind(NodeTypeConfig.class).toInstance(new NodeTypeConfig("bridge")); + + JsonConfigProvider.bind(binder, "druid.manager.segments", DatabaseSegmentManagerConfig.class); + binder.bind(DatabaseSegmentManager.class) + .toProvider(DatabaseSegmentManagerProvider.class) + .in(ManageLifecycle.class); + + ConfigProvider.bind(binder, DruidClusterBridgeConfig.class); + binder.bind(DruidClusterBridge.class); + LifecycleModule.register(binder, DruidClusterBridge.class); + + binder.bind(JettyServerInitializer.class).toInstance(new BridgeJettyServerInitializer()); + LifecycleModule.register(binder, BridgeZkCoordinator.class); + + LifecycleModule.register(binder, Server.class); + } + + @Provides + @LazySingleton + @Bridge + public CuratorFramework getBridgeCurator(final BridgeCuratorConfig bridgeCuratorConfig, Lifecycle lifecycle) + { + final CuratorFramework framework = + CuratorFrameworkFactory.builder() + .connectString(bridgeCuratorConfig.getParentZkHosts()) + .sessionTimeoutMs(bridgeCuratorConfig.getZkSessionTimeoutMs()) + .retryPolicy(new BoundedExponentialBackoffRetry(1000, 45000, 30)) + .compressionProvider( + new PotentiallyGzippedCompressionProvider( + bridgeCuratorConfig.enableCompression() + ) + ) + .build(); + + lifecycle.addHandler( + new Lifecycle.Handler() + { + @Override + public void start() throws Exception + { + log.info("Starting Curator for %s", bridgeCuratorConfig.getParentZkHosts()); + framework.start(); + } + + @Override + public void stop() + { + log.info("Stopping Curator"); + framework.close(); + } + } + ); + + return framework; + } + + @Provides + @ManageLifecycle + @Bridge + public Announcer getBridgeAnnouncer( + @Bridge CuratorFramework curator + ) + { + return new Announcer(curator, Execs.singleThreaded("BridgeAnnouncer-%s")); + } + + @Provides + @ManageLifecycleLast + @Bridge + public AbstractDataSegmentAnnouncer getBridgeDataSegmentAnnouncer( + DruidServerMetadata metadata, + BatchDataSegmentAnnouncerConfig config, + ZkPathsConfig zkPathsConfig, + @Bridge Announcer announcer, + ObjectMapper jsonMapper + ) + { + return new BatchDataSegmentAnnouncer( + metadata, + config, + zkPathsConfig, + announcer, + jsonMapper + ); + } + } + ); + } +} diff --git a/services/src/main/java/io/druid/cli/Main.java b/services/src/main/java/io/druid/cli/Main.java index 8fc06ffcdc5..7012e3a3f79 100644 --- a/services/src/main/java/io/druid/cli/Main.java +++ b/services/src/main/java/io/druid/cli/Main.java @@ -51,7 +51,8 @@ public class Main .withDefaultCommand(Help.class) .withCommands( CliCoordinator.class, CliHistorical.class, CliBroker.class, - CliRealtime.class, CliOverlord.class, CliMiddleManager.class + CliRealtime.class, CliOverlord.class, CliMiddleManager.class, + CliBridge.class ); builder.withGroup("example") From f44509b5306a2ac6146f5b857109a43179b9db6d Mon Sep 17 00:00:00 2001 From: fjy Date: Tue, 7 Jan 2014 16:24:53 -0800 Subject: [PATCH 25/49] queries working at this point, tests pass, still need more tests and fix rules interface --- .../java/io/druid/client/DruidServer.java | 14 +- .../io/druid/client/DruidServerConfig.java | 8 ++ .../druid/client/selector/ServerSelector.java | 16 ++- .../druid/curator/announcement/Announcer.java | 2 - .../io/druid/guice/StorageNodeModule.java | 3 +- .../java/io/druid/server/bridge/Bridge.java | 19 +++ .../server/bridge/BridgeCuratorConfig.java | 19 +++ .../bridge/BridgeJettyServerInitializer.java | 38 ------ .../bridge/BridgeQuerySegmentWalker.java | 121 ++++++++++++++++++ .../server/bridge/BridgeZkCoordinator.java | 29 +++-- .../server/bridge/DruidClusterBridge.java | 55 +++++--- .../bridge/DruidClusterBridgeConfig.java | 27 +++- .../coordination/BaseZkCoordinator.java | 31 +++-- .../coordination/DruidServerMetadata.java | 12 +- .../server/coordination/ZkCoordinator.java | 13 +- .../druid/server/coordinator/rules/Rule.java | 5 +- .../coordinator/rules/SizeDropRule.java | 71 ---------- .../coordinator/rules/SizeLoadRule.java | 78 ----------- .../main/resources/static/js/rules-0.0.1.js | 14 ++ .../client/BatchServerInventoryViewTest.java | 3 +- .../client/selector/ServerSelectorTest.java | 5 +- .../coordination/ZkCoordinatorTest.java | 2 +- .../BatchDataSegmentAnnouncerTest.java | 3 +- .../DruidCoordinatorRuleRunnerTest.java | 72 +++++++---- .../coordinator/rules/LoadRuleTest.java | 12 +- .../src/main/java/io/druid/cli/CliBridge.java | 26 +++- 26 files changed, 416 insertions(+), 282 deletions(-) delete mode 100644 server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java create mode 100644 server/src/main/java/io/druid/server/bridge/BridgeQuerySegmentWalker.java delete mode 100644 server/src/main/java/io/druid/server/coordinator/rules/SizeDropRule.java delete mode 100644 server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java diff --git a/server/src/main/java/io/druid/client/DruidServer.java b/server/src/main/java/io/druid/client/DruidServer.java index 23876497548..a8599fab820 100644 --- a/server/src/main/java/io/druid/client/DruidServer.java +++ b/server/src/main/java/io/druid/client/DruidServer.java @@ -61,7 +61,8 @@ public class DruidServer implements Comparable node.getHost(), config.getMaxSize(), type, - config.getTier() + config.getTier(), + 0 ); } @@ -71,10 +72,11 @@ public class DruidServer implements Comparable @JsonProperty("host") String host, @JsonProperty("maxSize") long maxSize, @JsonProperty("type") String type, - @JsonProperty("tier") String tier + @JsonProperty("tier") String tier, + @JsonProperty("priority") int priority ) { - this.metadata = new DruidServerMetadata(name, host, maxSize, type, tier); + this.metadata = new DruidServerMetadata(name, host, maxSize, type, tier, priority); this.dataSources = new ConcurrentHashMap(); this.segments = new ConcurrentHashMap(); @@ -120,6 +122,12 @@ public class DruidServer implements Comparable return metadata.getTier(); } + @JsonProperty + public int getPriority() + { + return metadata.getPriority(); + } + @JsonProperty public Map getSegments() { diff --git a/server/src/main/java/io/druid/client/DruidServerConfig.java b/server/src/main/java/io/druid/client/DruidServerConfig.java index 096269b02e8..420596ff65e 100644 --- a/server/src/main/java/io/druid/client/DruidServerConfig.java +++ b/server/src/main/java/io/druid/client/DruidServerConfig.java @@ -34,6 +34,9 @@ public class DruidServerConfig @JsonProperty private String tier = DruidServer.DEFAULT_TIER; + @JsonProperty + private int priority = 0; + public long getMaxSize() { return maxSize; @@ -43,4 +46,9 @@ public class DruidServerConfig { return tier; } + + public int getPriority() + { + return priority; + } } diff --git a/server/src/main/java/io/druid/client/selector/ServerSelector.java b/server/src/main/java/io/druid/client/selector/ServerSelector.java index d10c561c72d..68d0368ed4a 100644 --- a/server/src/main/java/io/druid/client/selector/ServerSelector.java +++ b/server/src/main/java/io/druid/client/selector/ServerSelector.java @@ -36,7 +36,12 @@ public class ServerSelector implements DiscoverySelector @Override public int compare(QueryableDruidServer left, QueryableDruidServer right) { - return Ints.compare(left.getClient().getNumOpenConnections(), right.getClient().getNumOpenConnections()); + int retVal = -Ints.compare(left.getServer().getPriority(), right.getServer().getPriority()); + if (retVal == 0) { + retVal = Ints.compare(left.getClient().getNumOpenConnections(), right.getClient().getNumOpenConnections()); + } + + return retVal; } }; @@ -84,9 +89,12 @@ public class ServerSelector implements DiscoverySelector synchronized (this) { final int size = servers.size(); switch (size) { - case 0: return null; - case 1: return servers.iterator().next(); - default: return Collections.min(servers, comparator); + case 0: + return null; + case 1: + return servers.iterator().next(); + default: + return Collections.min(servers, comparator); } } } diff --git a/server/src/main/java/io/druid/curator/announcement/Announcer.java b/server/src/main/java/io/druid/curator/announcement/Announcer.java index b5beb44f3c1..3471ea60d87 100644 --- a/server/src/main/java/io/druid/curator/announcement/Announcer.java +++ b/server/src/main/java/io/druid/curator/announcement/Announcer.java @@ -150,8 +150,6 @@ public class Announcer } } - log.info("Announcing with Curator %s", curator); // TODO - final ZKPaths.PathAndNode pathAndNode = ZKPaths.getPathAndNode(path); final String parentPath = pathAndNode.getPath(); diff --git a/server/src/main/java/io/druid/guice/StorageNodeModule.java b/server/src/main/java/io/druid/guice/StorageNodeModule.java index f50ab39bbb7..01f9563c7d5 100644 --- a/server/src/main/java/io/druid/guice/StorageNodeModule.java +++ b/server/src/main/java/io/druid/guice/StorageNodeModule.java @@ -67,7 +67,8 @@ public class StorageNodeModule implements Module node.getHost(), config.getMaxSize(), nodeType.getNodeType(), - config.getTier() + config.getTier(), + config.getPriority() ); } } diff --git a/server/src/main/java/io/druid/server/bridge/Bridge.java b/server/src/main/java/io/druid/server/bridge/Bridge.java index 108cac07629..8509221c564 100644 --- a/server/src/main/java/io/druid/server/bridge/Bridge.java +++ b/server/src/main/java/io/druid/server/bridge/Bridge.java @@ -1,3 +1,22 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.server.bridge; import com.google.inject.BindingAnnotation; diff --git a/server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java b/server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java index f60ce5f0132..5f616eb49a1 100644 --- a/server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java +++ b/server/src/main/java/io/druid/server/bridge/BridgeCuratorConfig.java @@ -1,3 +1,22 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.server.bridge; import io.druid.curator.CuratorConfig; diff --git a/server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java b/server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java deleted file mode 100644 index e07f979bb22..00000000000 --- a/server/src/main/java/io/druid/server/bridge/BridgeJettyServerInitializer.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.druid.server.bridge; - -import com.google.inject.Injector; -import com.google.inject.servlet.GuiceFilter; -import io.druid.server.initialization.JettyServerInitializer; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.HandlerList; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.servlets.GzipFilter; - -/** - */ -public class BridgeJettyServerInitializer implements JettyServerInitializer -{ - @Override - public void initialize(Server server, Injector injector) - { - final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS); - - ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class); - - root.addServlet(holderPwd, "/"); - //root.addFilter(new FilterHolder(injector.getInstance(RedirectFilter.class)), "/*", null); - root.addFilter(GzipFilter.class, "/*", null); - - // Can't use '/*' here because of Guice and Jetty static content conflicts - // The coordinator really needs a standarized api path - root.addFilter(GuiceFilter.class, "/status/*", null); - - HandlerList handlerList = new HandlerList(); - handlerList.setHandlers(new Handler[]{root}); - - server.setHandler(handlerList); - } -} diff --git a/server/src/main/java/io/druid/server/bridge/BridgeQuerySegmentWalker.java b/server/src/main/java/io/druid/server/bridge/BridgeQuerySegmentWalker.java new file mode 100644 index 00000000000..c892989ab15 --- /dev/null +++ b/server/src/main/java/io/druid/server/bridge/BridgeQuerySegmentWalker.java @@ -0,0 +1,121 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.server.bridge; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Charsets; +import com.google.inject.Inject; +import com.metamx.common.guava.Sequence; +import com.metamx.common.guava.Sequences; +import com.metamx.http.client.HttpClient; +import com.metamx.http.client.response.StatusResponseHandler; +import com.metamx.http.client.response.StatusResponseHolder; +import io.druid.client.selector.Server; +import io.druid.curator.discovery.ServerDiscoverySelector; +import io.druid.guice.annotations.Global; +import io.druid.query.Query; +import io.druid.query.QueryRunner; +import io.druid.query.QuerySegmentWalker; +import io.druid.query.SegmentDescriptor; +import org.joda.time.Interval; + +import java.net.URL; +import java.util.List; + +/** + */ +public class BridgeQuerySegmentWalker implements QuerySegmentWalker +{ + private final ServerDiscoverySelector brokerSelector; + private final HttpClient httpClient; + private final ObjectMapper jsonMapper; + private final StatusResponseHandler responseHandler; + + @Inject + public BridgeQuerySegmentWalker( + ServerDiscoverySelector brokerSelector, + @Global HttpClient httpClient, + ObjectMapper jsonMapper + ) + { + this.brokerSelector = brokerSelector; + this.httpClient = httpClient; + this.jsonMapper = jsonMapper; + this.responseHandler = new StatusResponseHandler(Charsets.UTF_8); + } + + @Override + public QueryRunner getQueryRunnerForIntervals( + Query query, Iterable intervals + ) + { + return makeRunner(); + } + + @Override + public QueryRunner getQueryRunnerForSegments( + Query query, Iterable specs + ) + { + return makeRunner(); + } + + private QueryRunner makeRunner() + { + return new QueryRunner() + { + @Override + public Sequence run(Query query) + { + try { + Server instance = brokerSelector.pick(); + if (instance == null) { + return Sequences.empty(); + } + + final String url = String.format( + "http://%s/druid/v2/", + brokerSelector.pick().getHost() + ); + + StatusResponseHolder response = httpClient.post(new URL(url)) + .setContent( + "application/json", + jsonMapper.writeValueAsBytes(query) + ) + .go(responseHandler) + .get(); + + List results = jsonMapper.readValue( + response.getContent(), new TypeReference>() + { + } + ); + + return Sequences.simple(results); + } + catch (Exception e) { + return Sequences.empty(); + } + } + }; + } +} diff --git a/server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java b/server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java index fb9ec911bd3..400b270779c 100644 --- a/server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java +++ b/server/src/main/java/io/druid/server/bridge/BridgeZkCoordinator.java @@ -1,3 +1,22 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.server.bridge; import com.fasterxml.jackson.databind.ObjectMapper; @@ -8,7 +27,6 @@ import io.druid.client.DruidServer; import io.druid.client.ServerView; import io.druid.concurrent.Execs; import io.druid.db.DatabaseSegmentManager; -import io.druid.segment.loading.SegmentLoaderConfig; import io.druid.segment.realtime.DbSegmentPublisher; import io.druid.server.coordination.BaseZkCoordinator; import io.druid.server.coordination.DataSegmentChangeCallback; @@ -51,13 +69,7 @@ public class BridgeZkCoordinator extends BaseZkCoordinator } @Override - public void createCacheDir() - { - // do nothing - } - - @Override - public void loadCache() + public void loadLocalCache() { // do nothing } @@ -85,7 +97,6 @@ public class BridgeZkCoordinator extends BaseZkCoordinator { if (theSegment.equals(segment)) { callback.execute(); - log.info("Callback executed"); } return ServerView.CallbackAction.CONTINUE; } diff --git a/server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java b/server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java index 8a824fc702b..b0e9af83f68 100644 --- a/server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java +++ b/server/src/main/java/io/druid/server/bridge/DruidClusterBridge.java @@ -1,3 +1,22 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.server.bridge; import com.fasterxml.jackson.databind.ObjectMapper; @@ -41,21 +60,25 @@ import java.util.concurrent.atomic.AtomicReference; @ManageLifecycle public class DruidClusterBridge { - public static final String CONNECTOR_OWNER_NODE = "_CONNECTOR"; + public static final String BRIDGE_OWNER_NODE = "_BRIDGE"; public static final String NODE_TYPE = "bridge"; private static final EmittingLogger log = new EmittingLogger(DruidClusterBridge.class); private final ObjectMapper jsonMapper; private final DruidClusterBridgeConfig config; - private final BridgeZkCoordinator bridgeZkCoordinator; // watches for assignments from main cluster - private final Announcer announcer; //announce self to main cluster - private final ServerInventoryView serverInventoryView; - private final CuratorFramework curator; private final ScheduledExecutorService exec; - private final AtomicReference leaderLatch; private final DruidNode self; + // Communicates to the ZK cluster that this bridge node is deployed at + private final CuratorFramework curator; + private final AtomicReference leaderLatch; + + // Communicates to the remote (parent) ZK cluster + private final BridgeZkCoordinator bridgeZkCoordinator; + private final Announcer announcer; + private final ServerInventoryView serverInventoryView; + private final Map segments = Maps.newHashMap(); private final Object lock = new Object(); @@ -66,14 +89,14 @@ public class DruidClusterBridge public DruidClusterBridge( ObjectMapper jsonMapper, DruidClusterBridgeConfig config, + ScheduledExecutorFactory scheduledExecutorFactory, + @Self DruidNode self, + CuratorFramework curator, + AtomicReference leaderLatch, BridgeZkCoordinator bridgeZkCoordinator, @Bridge Announcer announcer, @Bridge final AbstractDataSegmentAnnouncer dataSegmentAnnouncer, - ServerInventoryView serverInventoryView, - CuratorFramework curator, - ScheduledExecutorFactory scheduledExecutorFactory, - AtomicReference leaderLatch, - @Self DruidNode self + ServerInventoryView serverInventoryView ) { this.jsonMapper = jsonMapper; @@ -87,8 +110,6 @@ public class DruidClusterBridge this.exec = scheduledExecutorFactory.create(1, "Coordinator-Exec--%d"); this.self = self; - log.info("Local curator: [%s]", curator); // TODO - serverInventoryView.registerSegmentCallback( Executors.newFixedThreadPool( 1, @@ -128,7 +149,7 @@ public class DruidClusterBridge synchronized (lock) { Integer count = segments.get(segment); if (count != null) { - if (count == 0) { + if (count == 1) { dataSegmentAnnouncer.unannounceSegment(segment); segments.remove(segment); } else { @@ -174,7 +195,7 @@ public class DruidClusterBridge private LeaderLatch createNewLeaderLatch() { final LeaderLatch newLeaderLatch = new LeaderLatch( - curator, ZKPaths.makePath(config.getConnectorPath(), CONNECTOR_OWNER_NODE), self.getHost() + curator, ZKPaths.makePath(config.getConnectorPath(), BRIDGE_OWNER_NODE), self.getHost() ); newLeaderLatch.addListener( @@ -266,13 +287,13 @@ public class DruidClusterBridge if (totalMaxSize == 0) { log.warn("No servers founds!"); } else { - DruidServerMetadata me = new DruidServerMetadata( self.getHost(), self.getHost(), totalMaxSize, NODE_TYPE, - config.getTier() + config.getTier(), + config.getPriority() ); try { diff --git a/server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java b/server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java index cd9398a6572..8a98e3bb593 100644 --- a/server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java +++ b/server/src/main/java/io/druid/server/bridge/DruidClusterBridgeConfig.java @@ -1,3 +1,22 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.server.bridge; import io.druid.client.DruidServer; @@ -8,7 +27,6 @@ import org.skife.config.Default; /** */ -// TODO: make sure that this uses sub cluster zk paths public abstract class DruidClusterBridgeConfig extends ZkPathsConfig { @Config("druid.server.tier") @@ -22,4 +40,11 @@ public abstract class DruidClusterBridgeConfig extends ZkPathsConfig @Config("druid.bridge.period") @Default("PT60s") public abstract Duration getPeriod(); + + @Config("druid.bridge.broker.serviceName") + public abstract String getBrokerServiceName(); + + @Config("druid.server.priority") + @Default("0") + public abstract int getPriority(); } diff --git a/server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java b/server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java index db5fb693462..33d3118e304 100644 --- a/server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java +++ b/server/src/main/java/io/druid/server/coordination/BaseZkCoordinator.java @@ -1,3 +1,22 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + package io.druid.server.coordination; import com.fasterxml.jackson.databind.ObjectMapper; @@ -48,12 +67,13 @@ public abstract class BaseZkCoordinator implements DataSegmentChangeHandler @LifecycleStart public void start() throws IOException { - log.info("Starting zkCoordinator for server[%s]", me); synchronized (lock) { if (started) { return; } + log.info("Starting zkCoordinator for server[%s]", me); + final String loadQueueLocation = ZKPaths.makePath(zkPaths.getLoadQueuePath(), me.getName()); final String servedSegmentsLocation = ZKPaths.makePath(zkPaths.getServedSegmentsPath(), me.getName()); final String liveSegmentsLocation = ZKPaths.makePath(zkPaths.getLiveSegmentsPath(), me.getName()); @@ -67,14 +87,11 @@ public abstract class BaseZkCoordinator implements DataSegmentChangeHandler ); try { - createCacheDir(); - - log.info("Remote Curator[%s]", curator); // TODO curator.newNamespaceAwareEnsurePath(loadQueueLocation).ensure(curator.getZookeeperClient()); curator.newNamespaceAwareEnsurePath(servedSegmentsLocation).ensure(curator.getZookeeperClient()); curator.newNamespaceAwareEnsurePath(liveSegmentsLocation).ensure(curator.getZookeeperClient()); - loadCache(); + loadLocalCache(); loadQueueCache.getListenable().addListener( new PathChildrenCacheListener() @@ -173,9 +190,7 @@ public abstract class BaseZkCoordinator implements DataSegmentChangeHandler } } - public abstract void createCacheDir(); - - public abstract void loadCache(); + public abstract void loadLocalCache(); public abstract DataSegmentChangeHandler getDataSegmentChangeHandler(); } diff --git a/server/src/main/java/io/druid/server/coordination/DruidServerMetadata.java b/server/src/main/java/io/druid/server/coordination/DruidServerMetadata.java index ecb7f33b2ea..6e564734c8c 100644 --- a/server/src/main/java/io/druid/server/coordination/DruidServerMetadata.java +++ b/server/src/main/java/io/druid/server/coordination/DruidServerMetadata.java @@ -31,6 +31,7 @@ public class DruidServerMetadata private final long maxSize; private final String tier; private final String type; + private final int priority; @JsonCreator public DruidServerMetadata( @@ -38,7 +39,8 @@ public class DruidServerMetadata @JsonProperty("host") String host, @JsonProperty("maxSize") long maxSize, @JsonProperty("type") String type, - @JsonProperty("tier") String tier + @JsonProperty("tier") String tier, + @JsonProperty("priority") int priority ) { this.name = name; @@ -46,6 +48,7 @@ public class DruidServerMetadata this.maxSize = maxSize; this.tier = tier; this.type = type; + this.priority = priority; } @JsonProperty @@ -78,6 +81,12 @@ public class DruidServerMetadata return type; } + @JsonProperty + public int getPriority() + { + return priority; + } + @Override public String toString() { @@ -87,6 +96,7 @@ public class DruidServerMetadata ", maxSize=" + maxSize + ", tier='" + tier + '\'' + ", type='" + type + '\'' + + ", priority='" + priority + '\'' + '}'; } } diff --git a/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java b/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java index 72993173cd5..28edb8ddca2 100644 --- a/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java +++ b/server/src/main/java/io/druid/server/coordination/ZkCoordinator.java @@ -64,16 +64,11 @@ public class ZkCoordinator extends BaseZkCoordinator } @Override - public void createCacheDir() - { - config.getInfoDir().mkdirs(); - } - - @Override - public void loadCache() + public void loadLocalCache() { + final long start = System.currentTimeMillis(); File baseDir = config.getInfoDir(); - if (!baseDir.exists()) { + if (!baseDir.exists() && !config.getInfoDir().mkdirs()) { return; } @@ -107,7 +102,7 @@ public class ZkCoordinator extends BaseZkCoordinator @Override public void execute() { - // do nothing + log.info("Cache load took %,d ms", System.currentTimeMillis() - start); } } ); diff --git a/server/src/main/java/io/druid/server/coordinator/rules/Rule.java b/server/src/main/java/io/druid/server/coordinator/rules/Rule.java index e8be9a81102..255c31b4f67 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/Rule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/Rule.java @@ -35,11 +35,8 @@ import org.joda.time.DateTime; @JsonSubTypes.Type(name = "loadByInterval", value = IntervalLoadRule.class), @JsonSubTypes.Type(name = "loadForever", value = ForeverLoadRule.class), @JsonSubTypes.Type(name = "dropByPeriod", value = PeriodDropRule.class), - @JsonSubTypes.Type(name = "dropByInterval", value = IntervalDropRule.class), - @JsonSubTypes.Type(name = "loadBySize", value = SizeLoadRule.class), - @JsonSubTypes.Type(name = "dropBySize", value = SizeDropRule.class) + @JsonSubTypes.Type(name = "dropByInterval", value = IntervalDropRule.class) }) - public interface Rule { public String getType(); diff --git a/server/src/main/java/io/druid/server/coordinator/rules/SizeDropRule.java b/server/src/main/java/io/druid/server/coordinator/rules/SizeDropRule.java deleted file mode 100644 index 219d5559b69..00000000000 --- a/server/src/main/java/io/druid/server/coordinator/rules/SizeDropRule.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Druid - a distributed column store. - * Copyright (C) 2012, 2013 Metamarkets Group Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.druid.server.coordinator.rules; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.collect.Range; -import io.druid.timeline.DataSegment; -import org.joda.time.DateTime; - -/** - */ -public class SizeDropRule extends DropRule -{ - private final long low; - private final long high; - private final Range range; - - @JsonCreator - public SizeDropRule( - @JsonProperty("low") long low, - @JsonProperty("high") long high - ) - { - this.low = low; - this.high = high; - this.range = Range.closedOpen(low, high); - } - - @Override - @JsonProperty - public String getType() - { - return "dropBySize"; - } - - @JsonProperty - public long getLow() - { - return low; - } - - @JsonProperty - public long getHigh() - { - return high; - } - - @Override - public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) - { - return range.contains(segment.getSize()); - } -} diff --git a/server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java deleted file mode 100644 index e1f0942958c..00000000000 --- a/server/src/main/java/io/druid/server/coordinator/rules/SizeLoadRule.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Druid - a distributed column store. - * Copyright (C) 2012, 2013 Metamarkets Group Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.druid.server.coordinator.rules; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.collect.Range; -import io.druid.timeline.DataSegment; -import org.joda.time.DateTime; - -import java.util.Map; - -/** - */ -public class SizeLoadRule extends LoadRule -{ - private final long low; - private final long high; - private final Integer replicants; - private final String tier; - private final Range range; - - @JsonCreator - public SizeLoadRule( - @JsonProperty("low") long low, - @JsonProperty("high") long high, - @JsonProperty("replicants") Integer replicants, - @JsonProperty("tier") String tier - ) - { - this.low = low; - this.high = high; - this.replicants = replicants; - this.tier = tier; - this.range = Range.closedOpen(low, high); - } - - @Override - public Map getTieredReplicants() - { - return null; - } - - @Override - public int getNumReplicants(String tier) - { - return 0; - } - - @Override - public String getType() - { - return "loadBySize"; - } - - @Override - public boolean appliesTo(DataSegment segment, DateTime referenceTimestamp) - { - return range.contains(segment.getSize()); - } -} diff --git a/server/src/main/resources/static/js/rules-0.0.1.js b/server/src/main/resources/static/js/rules-0.0.1.js index fbe782b34c2..79ae691b2c6 100644 --- a/server/src/main/resources/static/js/rules-0.0.1.js +++ b/server/src/main/resources/static/js/rules-0.0.1.js @@ -6,6 +6,8 @@ var ruleTypes = [ "loadByPeriod", "dropByInterval", "dropByPeriod", + "loadForever", + "dropForever", "JSON" ]; @@ -60,6 +62,12 @@ function makeRuleBody(rule) { case "dropByPeriod": retVal += makeDropByPeriod(rule); break; + case "loadForever": + retVal += makeLoadForever(rule); + break; + case "dropForever": + retVal += ""; + break; case "JSON": retVal += makeJSON(); break; @@ -93,6 +101,12 @@ function makeDropByPeriod(rule) { return "period"; } +function makeLoadForever(rule) { + return "replicants" + + makeTiersDropdown(rule) + ; +} + function makeJSON() { return "JSON"; } diff --git a/server/src/test/java/io/druid/client/client/BatchServerInventoryViewTest.java b/server/src/test/java/io/druid/client/client/BatchServerInventoryViewTest.java index a777222efe1..934d9d959ff 100644 --- a/server/src/test/java/io/druid/client/client/BatchServerInventoryViewTest.java +++ b/server/src/test/java/io/druid/client/client/BatchServerInventoryViewTest.java @@ -93,7 +93,8 @@ public class BatchServerInventoryViewTest "host", Long.MAX_VALUE, "type", - "tier" + "tier", + 0 ), new BatchDataSegmentAnnouncerConfig() { diff --git a/server/src/test/java/io/druid/client/selector/ServerSelectorTest.java b/server/src/test/java/io/druid/client/selector/ServerSelectorTest.java index d66648beb68..22eb98807e6 100644 --- a/server/src/test/java/io/druid/client/selector/ServerSelectorTest.java +++ b/server/src/test/java/io/druid/client/selector/ServerSelectorTest.java @@ -27,6 +27,7 @@ import com.metamx.http.client.HttpClient; import com.metamx.http.client.Request; import com.metamx.http.client.RequestBuilder; import io.druid.client.DirectDruidClient; +import io.druid.client.DruidServer; import io.druid.jackson.DefaultObjectMapper; import io.druid.query.Druids; import io.druid.query.ReflectionQueryToolChestWarehouse; @@ -91,12 +92,12 @@ public class ServerSelectorTest ); QueryableDruidServer queryableDruidServer1 = new QueryableDruidServer( - null, + new DruidServer("test1", "localhost", 0, "historical", DruidServer.DEFAULT_TIER, 0), client1 ); serverSelector.addServer(queryableDruidServer1); QueryableDruidServer queryableDruidServer2 = new QueryableDruidServer( - null, + new DruidServer("test1", "localhost", 0, "historical", DruidServer.DEFAULT_TIER, 0), client2 ); serverSelector.addServer(queryableDruidServer2); diff --git a/server/src/test/java/io/druid/server/coordination/ZkCoordinatorTest.java b/server/src/test/java/io/druid/server/coordination/ZkCoordinatorTest.java index e1d78741b7c..77b4c9f8144 100644 --- a/server/src/test/java/io/druid/server/coordination/ZkCoordinatorTest.java +++ b/server/src/test/java/io/druid/server/coordination/ZkCoordinatorTest.java @@ -83,7 +83,7 @@ public class ZkCoordinatorTest extends CuratorTestBase MoreExecutors.sameThreadExecutor() ); - final DruidServerMetadata me = new DruidServerMetadata("dummyServer", "dummyHost", 0, "dummyType", "normal"); + final DruidServerMetadata me = new DruidServerMetadata("dummyServer", "dummyHost", 0, "dummyType", "normal", 0); final ZkPathsConfig zkPaths = new ZkPathsConfig() { diff --git a/server/src/test/java/io/druid/server/coordination/coordination/BatchDataSegmentAnnouncerTest.java b/server/src/test/java/io/druid/server/coordination/coordination/BatchDataSegmentAnnouncerTest.java index 245a3573c5f..d4d2f8d7aaa 100644 --- a/server/src/test/java/io/druid/server/coordination/coordination/BatchDataSegmentAnnouncerTest.java +++ b/server/src/test/java/io/druid/server/coordination/coordination/BatchDataSegmentAnnouncerTest.java @@ -93,7 +93,8 @@ public class BatchDataSegmentAnnouncerTest "host", Long.MAX_VALUE, "type", - "tier" + "tier", + 0 ), new BatchDataSegmentAnnouncerConfig() { diff --git a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java index 02d690b1a17..2663a4a94e4 100644 --- a/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java +++ b/server/src/test/java/io/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java @@ -133,7 +133,8 @@ public class DruidCoordinatorRuleRunnerTest "hostHot", 1000, "historical", - "hot" + "hot", + 0 ), mockPeon ) @@ -148,7 +149,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm", 1000, "historical", - "normal" + "normal", + 0 ), mockPeon ) @@ -163,7 +165,8 @@ public class DruidCoordinatorRuleRunnerTest "hostCold", 1000, "historical", - "cold" + "cold", + 0 ), mockPeon ) @@ -228,7 +231,8 @@ public class DruidCoordinatorRuleRunnerTest "hostHot", 1000, "historical", - "hot" + "hot", + 0 ), mockPeon ), @@ -238,7 +242,8 @@ public class DruidCoordinatorRuleRunnerTest "hostHot2", 1000, "historical", - "hot" + "hot", + 0 ), mockPeon ) @@ -253,7 +258,8 @@ public class DruidCoordinatorRuleRunnerTest "hostCold", 1000, "historical", - "cold" + "cold", + 0 ), mockPeon ) @@ -311,7 +317,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm", 1000, "historical", - "normal" + "normal", + 0 ); for (DataSegment availableSegment : availableSegments) { normServer.addDataSegment(availableSegment.getIdentifier(), availableSegment); @@ -328,7 +335,8 @@ public class DruidCoordinatorRuleRunnerTest "hostHot", 1000, "historical", - "hot" + "hot", + 0 ), mockPeon ) @@ -400,7 +408,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm", 1000, "historical", - "normal" + "normal", + 0 ), mockPeon ) @@ -450,7 +459,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm", 1000, "historical", - "normal" + "normal", + 0 ), mockPeon ) @@ -499,7 +509,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm", 1000, "historical", - "normal" + "normal", + 0 ); for (DataSegment segment : availableSegments) { server.addDataSegment(segment.getIdentifier(), segment); @@ -560,7 +571,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm", 1000, "historical", - "normal" + "normal", + 0 ); server1.addDataSegment(availableSegments.get(0).getIdentifier(), availableSegments.get(0)); @@ -569,7 +581,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm2", 1000, "historical", - "normal" + "normal", + 0 ); for (DataSegment segment : availableSegments) { server2.addDataSegment(segment.getIdentifier(), segment); @@ -637,7 +650,8 @@ public class DruidCoordinatorRuleRunnerTest "host1", 1000, "historical", - "hot" + "hot", + 0 ); server1.addDataSegment(availableSegments.get(0).getIdentifier(), availableSegments.get(0)); DruidServer server2 = new DruidServer( @@ -645,7 +659,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm2", 1000, "historical", - "normal" + "normal", + 0 ); for (DataSegment segment : availableSegments) { server2.addDataSegment(segment.getIdentifier(), segment); @@ -716,14 +731,16 @@ public class DruidCoordinatorRuleRunnerTest "host1", 1000, "historical", - "hot" + "hot", + 0 ); DruidServer server2 = new DruidServer( "serverNorm2", "hostNorm2", 1000, "historical", - "normal" + "normal", + 0 ); for (DataSegment segment : availableSegments) { server2.addDataSegment(segment.getIdentifier(), segment); @@ -786,7 +803,8 @@ public class DruidCoordinatorRuleRunnerTest "host1", 1000, "historical", - "normal" + "normal", + 0 ); server1.addDataSegment(availableSegments.get(0).getIdentifier(), availableSegments.get(0)); DruidServer server2 = new DruidServer( @@ -794,7 +812,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm2", 1000, "historical", - "normal" + "normal", + 0 ); server2.addDataSegment(availableSegments.get(1).getIdentifier(), availableSegments.get(1)); DruidServer server3 = new DruidServer( @@ -802,7 +821,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm3", 1000, "historical", - "normal" + "normal", + 0 ); server3.addDataSegment(availableSegments.get(1).getIdentifier(), availableSegments.get(1)); server3.addDataSegment(availableSegments.get(2).getIdentifier(), availableSegments.get(2)); @@ -893,7 +913,8 @@ public class DruidCoordinatorRuleRunnerTest "hostHot", 1000, "historical", - "hot" + "hot", + 0 ), mockPeon ), @@ -903,7 +924,8 @@ public class DruidCoordinatorRuleRunnerTest "hostHot2", 1000, "historical", - "hot" + "hot", + 0 ), mockPeon ) @@ -992,7 +1014,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm1", 1000, "historical", - "normal" + "normal", + 0 ); for (DataSegment availableSegment : longerAvailableSegments) { server1.addDataSegment(availableSegment.getIdentifier(), availableSegment); @@ -1002,7 +1025,8 @@ public class DruidCoordinatorRuleRunnerTest "hostNorm2", 1000, "historical", - "normal" + "normal", + 0 ); for (DataSegment availableSegment : longerAvailableSegments) { server2.addDataSegment(availableSegment.getIdentifier(), availableSegment); diff --git a/server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java b/server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java index 60571bb16e9..a52927d0b7d 100644 --- a/server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java +++ b/server/src/test/java/io/druid/server/coordinator/rules/LoadRuleTest.java @@ -135,7 +135,8 @@ public class LoadRuleTest "hostHot", 1000, "historical", - "hot" + "hot", + 0 ), mockPeon ) @@ -150,7 +151,8 @@ public class LoadRuleTest "hostNorm", 1000, "historical", - DruidServer.DEFAULT_TIER + DruidServer.DEFAULT_TIER, + 0 ), mockPeon ) @@ -219,7 +221,8 @@ public class LoadRuleTest "hostHot", 1000, "historical", - "hot" + "hot", + 0 ); server1.addDataSegment(segment.getIdentifier(), segment); DruidServer server2 = new DruidServer( @@ -227,7 +230,8 @@ public class LoadRuleTest "hostNorm", 1000, "historical", - DruidServer.DEFAULT_TIER + DruidServer.DEFAULT_TIER, + 0 ); server2.addDataSegment(segment.getIdentifier(), segment); DruidCluster druidCluster = new DruidCluster( diff --git a/services/src/main/java/io/druid/cli/CliBridge.java b/services/src/main/java/io/druid/cli/CliBridge.java index 262b94d0534..13bac634422 100644 --- a/services/src/main/java/io/druid/cli/CliBridge.java +++ b/services/src/main/java/io/druid/cli/CliBridge.java @@ -11,19 +11,24 @@ import io.airlift.command.Command; import io.druid.concurrent.Execs; import io.druid.curator.PotentiallyGzippedCompressionProvider; import io.druid.curator.announcement.Announcer; +import io.druid.curator.discovery.ServerDiscoveryFactory; +import io.druid.curator.discovery.ServerDiscoverySelector; import io.druid.db.DatabaseSegmentManager; import io.druid.db.DatabaseSegmentManagerConfig; import io.druid.db.DatabaseSegmentManagerProvider; import io.druid.guice.ConfigProvider; +import io.druid.guice.Jerseys; import io.druid.guice.JsonConfigProvider; import io.druid.guice.LazySingleton; import io.druid.guice.LifecycleModule; import io.druid.guice.ManageLifecycle; import io.druid.guice.ManageLifecycleLast; import io.druid.guice.NodeTypeConfig; +import io.druid.query.QuerySegmentWalker; +import io.druid.server.QueryResource; import io.druid.server.bridge.Bridge; import io.druid.server.bridge.BridgeCuratorConfig; -import io.druid.server.bridge.BridgeJettyServerInitializer; +import io.druid.server.bridge.BridgeQuerySegmentWalker; import io.druid.server.bridge.BridgeZkCoordinator; import io.druid.server.bridge.DruidClusterBridge; import io.druid.server.bridge.DruidClusterBridgeConfig; @@ -44,7 +49,7 @@ import java.util.List; */ @Command( name = "bridge", - description = "Runs a bridge node, see http://druid.io/docs/0.6.46/Bridge.html for a description." // TODO + description = "Runs a bridge node, see http://druid.io/docs/0.6.46/Bridge.html for a description." ) public class CliBridge extends ServerRunnable { @@ -74,11 +79,15 @@ public class CliBridge extends ServerRunnable .toProvider(DatabaseSegmentManagerProvider.class) .in(ManageLifecycle.class); + binder.bind(QuerySegmentWalker.class).to(BridgeQuerySegmentWalker.class).in(LazySingleton.class); + binder.bind(JettyServerInitializer.class).to(QueryJettyServerInitializer.class).in(LazySingleton.class); + Jerseys.addResource(binder, QueryResource.class); + LifecycleModule.register(binder, QueryResource.class); + ConfigProvider.bind(binder, DruidClusterBridgeConfig.class); binder.bind(DruidClusterBridge.class); LifecycleModule.register(binder, DruidClusterBridge.class); - binder.bind(JettyServerInitializer.class).toInstance(new BridgeJettyServerInitializer()); LifecycleModule.register(binder, BridgeZkCoordinator.class); LifecycleModule.register(binder, Server.class); @@ -123,6 +132,17 @@ public class CliBridge extends ServerRunnable return framework; } + @Provides + @ManageLifecycle + public ServerDiscoverySelector getServerDiscoverySelector( + DruidClusterBridgeConfig config, + ServerDiscoveryFactory factory + + ) + { + return factory.createSelector(config.getBrokerServiceName()); + } + @Provides @ManageLifecycle @Bridge From 306f4b8fa2cb8f976bbfe128228f0f75aa30f673 Mon Sep 17 00:00:00 2001 From: fjy Date: Wed, 8 Jan 2014 14:08:41 -0800 Subject: [PATCH 26/49] more tests --- .../server/bridge/DruidClusterBridgeTest.java | 230 ++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 server/src/test/java/io/druid/server/bridge/DruidClusterBridgeTest.java diff --git a/server/src/test/java/io/druid/server/bridge/DruidClusterBridgeTest.java b/server/src/test/java/io/druid/server/bridge/DruidClusterBridgeTest.java new file mode 100644 index 00000000000..a8d9dd69b55 --- /dev/null +++ b/server/src/test/java/io/druid/server/bridge/DruidClusterBridgeTest.java @@ -0,0 +1,230 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.druid.server.bridge; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.metamx.common.ISE; +import com.metamx.common.concurrent.ScheduledExecutorFactory; +import com.metamx.common.concurrent.ScheduledExecutors; +import com.metamx.common.lifecycle.Lifecycle; +import io.druid.client.BatchServerInventoryView; +import io.druid.client.DruidServer; +import io.druid.client.ServerView; +import io.druid.curator.PotentiallyGzippedCompressionProvider; +import io.druid.curator.announcement.Announcer; +import io.druid.db.DatabaseSegmentManager; +import io.druid.jackson.DefaultObjectMapper; +import io.druid.segment.realtime.DbSegmentPublisher; +import io.druid.server.DruidNode; +import io.druid.server.coordination.BatchDataSegmentAnnouncer; +import io.druid.server.coordination.DruidServerMetadata; +import io.druid.server.initialization.ZkPathsConfig; +import junit.framework.Assert; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.framework.recipes.leader.LeaderLatch; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.curator.test.TestingCluster; +import org.easymock.EasyMock; +import org.joda.time.Duration; +import org.junit.Test; + +import java.util.Arrays; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +/** + */ +public class DruidClusterBridgeTest +{ + @Test + public void testRun() throws Exception + { + TestingCluster localCluster = new TestingCluster(1); + localCluster.start(); + + CuratorFramework localCf = CuratorFrameworkFactory.builder() + .connectString(localCluster.getConnectString()) + .retryPolicy(new ExponentialBackoffRetry(1, 10)) + .compressionProvider( + new PotentiallyGzippedCompressionProvider( + false + ) + ) + .build(); + localCf.start(); + + + TestingCluster remoteCluster = new TestingCluster(1); + remoteCluster.start(); + + CuratorFramework remoteCf = CuratorFrameworkFactory.builder() + .connectString(remoteCluster.getConnectString()) + .retryPolicy(new ExponentialBackoffRetry(1, 10)) + .compressionProvider( + new PotentiallyGzippedCompressionProvider( + false + ) + ) + .build(); + remoteCf.start(); + + ObjectMapper jsonMapper = new DefaultObjectMapper(); + DruidClusterBridgeConfig config = new DruidClusterBridgeConfig() + { + @Override + public String getTier() + { + return DruidServer.DEFAULT_TIER; + } + + @Override + public Duration getStartDelay() + { + return new Duration(0); + } + + @Override + public Duration getPeriod() + { + return new Duration(Long.MAX_VALUE); + } + + @Override + public String getBrokerServiceName() + { + return "testz0rz"; + } + + @Override + public int getPriority() + { + return 0; + } + }; + + ScheduledExecutorFactory factory = ScheduledExecutors.createFactory(new Lifecycle()); + + DruidNode me = new DruidNode( + "me", + "localhost", + 8080 + ); + + AtomicReference leaderLatch = new AtomicReference<>(new LeaderLatch(localCf, "test")); + + ZkPathsConfig zkPathsConfig = new ZkPathsConfig() + { + @Override + public String getZkBasePath() + { + return "/druid"; + } + }; + DruidServerMetadata metadata = new DruidServerMetadata( + "test", + "localhost", + 1000, + "bridge", + DruidServer.DEFAULT_TIER, + 0 + ); + DbSegmentPublisher dbSegmentPublisher = EasyMock.createMock(DbSegmentPublisher.class); + DatabaseSegmentManager databaseSegmentManager = EasyMock.createMock(DatabaseSegmentManager.class); + ServerView serverView = EasyMock.createMock(ServerView.class); + BridgeZkCoordinator bridgeZkCoordinator = new BridgeZkCoordinator( + jsonMapper, + zkPathsConfig, + metadata, + remoteCf, + dbSegmentPublisher, + databaseSegmentManager, + serverView + ); + + Announcer announcer = new Announcer(remoteCf, Executors.newSingleThreadExecutor()); + announcer.start(); + announcer.announce(zkPathsConfig.getAnnouncementsPath() + "/" + me.getHost(), jsonMapper.writeValueAsBytes(me)); + BatchDataSegmentAnnouncer batchDataSegmentAnnouncer = EasyMock.createMock(BatchDataSegmentAnnouncer.class); + BatchServerInventoryView batchServerInventoryView = EasyMock.createMock(BatchServerInventoryView.class); + + EasyMock.expect(batchServerInventoryView.getInventory()).andReturn( + Arrays.asList( + new DruidServer("1", "localhost", 117, "historical", DruidServer.DEFAULT_TIER, 0), + new DruidServer("2", "localhost", 1, "historical", DruidServer.DEFAULT_TIER, 0) + ) + ); + batchServerInventoryView.registerSegmentCallback( + EasyMock.anyObject(), + EasyMock.anyObject() + ); + EasyMock.expectLastCall(); + batchServerInventoryView.start(); + EasyMock.expectLastCall(); + EasyMock.replay(batchServerInventoryView); + + + DruidClusterBridge bridge = new DruidClusterBridge( + jsonMapper, + config, + factory, + me, + localCf, + leaderLatch, + bridgeZkCoordinator, + announcer, + batchDataSegmentAnnouncer, + batchServerInventoryView + ); + + bridge.start(); + + int retry = 0; + while (!bridge.isLeader()) { + if (retry > 5) { + throw new ISE("Unable to become leader"); + } + + Thread.sleep(100); + retry++; + } + + String path = "/druid/announcements/localhost:8080"; + retry = 0; + while (remoteCf.checkExists().forPath(path) == null) { + if (retry > 5) { + throw new ISE("Unable to announce"); + } + + Thread.sleep(100); + retry++; + } + + DruidServerMetadata announced = jsonMapper.readValue( + remoteCf.getData().forPath(path), + DruidServerMetadata.class + ); + + Assert.assertEquals(118, announced.getMaxSize()); + + EasyMock.verify(batchServerInventoryView); + } +} From f3d6bdc76d5a80dcbdc7a0635ea51c3d64255425 Mon Sep 17 00:00:00 2001 From: fjy Date: Thu, 9 Jan 2014 16:42:23 -0800 Subject: [PATCH 27/49] fix GUI --- .../coordinator/rules/ForeverLoadRule.java | 3 +- .../src/main/resources/static/css/rules.css | 3 +- .../main/resources/static/js/rules-0.0.1.js | 91 ++++++++++++++----- 3 files changed, 70 insertions(+), 27 deletions(-) diff --git a/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java index 70e482764f8..2150150cb03 100644 --- a/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java +++ b/server/src/main/java/io/druid/server/coordinator/rules/ForeverLoadRule.java @@ -57,7 +57,8 @@ public class ForeverLoadRule extends LoadRule @Override public int getNumReplicants(String tier) { - return tieredReplicants.get(tier); + Integer retVal = tieredReplicants.get(tier); + return (retVal == null) ? 0 : retVal; } @Override diff --git a/server/src/main/resources/static/css/rules.css b/server/src/main/resources/static/css/rules.css index 384f312181e..dcd52e2706e 100644 --- a/server/src/main/resources/static/css/rules.css +++ b/server/src/main/resources/static/css/rules.css @@ -36,8 +36,9 @@ margin: 0 10px 0 10px; } -.delete_rule { +.delete_rule, .add_tier { border-style : none; color:#555; background-color:#eee; + cursor: pointer; } \ No newline at end of file diff --git a/server/src/main/resources/static/js/rules-0.0.1.js b/server/src/main/resources/static/js/rules-0.0.1.js index 79ae691b2c6..8ffdd085808 100644 --- a/server/src/main/resources/static/js/rules-0.0.1.js +++ b/server/src/main/resources/static/js/rules-0.0.1.js @@ -19,6 +19,7 @@ function makeRuleDiv(rule) { } else { retVal += makeRuleComponents(rule.type) + makeRuleBody(rule); } + retVal += ""; return retVal; } @@ -56,15 +57,15 @@ function makeRuleBody(rule) { case "loadByPeriod": retVal += makeLoadByPeriod(rule); break; + case "loadForever": + retVal += makeLoadForever(rule); + break; case "dropByInterval": retVal += makeDropByInterval(rule); break; case "dropByPeriod": retVal += makeDropByPeriod(rule); break; - case "loadForever": - retVal += makeLoadForever(rule); - break; case "dropForever": retVal += ""; break; @@ -80,42 +81,67 @@ function makeRuleBody(rule) { } function makeLoadByInterval(rule) { - return "interval" + - "replicants" + - makeTiersDropdown(rule) - ; + var retVal = ""; + retVal += "interval"; + retVal += ""; + if (rule.tieredReplicants === undefined) { + retVal += makeTierLoad(null, 0); + } + for (var tier in rule.tieredReplicants) { + retVal += makeTierLoad(tier, rule.tieredReplicants[tier]); + } + return retVal; } function makeLoadByPeriod(rule) { - return "period" + - "replicants" + - makeTiersDropdown(rule) - ; -} - -function makeDropByInterval(rule) { - return "interval"; -} - -function makeDropByPeriod(rule) { - return "period"; + var retVal = ""; + retVal += "period"; + retVal += ""; + if (rule.tieredReplicants === undefined) { + retVal += makeTierLoad(null, 0); + } + for (var tier in rule.tieredReplicants) { + retVal += makeTierLoad(tier, rule.tieredReplicants[tier]); + } + return retVal; } function makeLoadForever(rule) { - return "replicants" + - makeTiersDropdown(rule) - ; + var retVal = ""; + retVal += ""; + if (rule.tieredReplicants === undefined) { + retVal += makeTierLoad(null, 0); + } + for (var tier in rule.tieredReplicants) { + retVal += makeTierLoad(tier, rule.tieredReplicants[tier]); + } + return retVal; +} + +function makeTierLoad(tier, val) { + return "
    " + + "replicants" + + makeTiersDropdown(tier) + + "
    "; +} + +function makeDropByInterval(rule) { + return "interval"; +} + +function makeDropByPeriod(rule) { + return "period"; } function makeJSON() { return "JSON"; } -function makeTiersDropdown(rule) { +function makeTiersDropdown(selTier) { var retVal = "tier