|
29 | 29 | import org.apache.druid.query.DefaultQueryMetrics; |
30 | 30 | import org.apache.druid.query.DruidProcessingConfigTest; |
31 | 31 | import org.apache.druid.server.metrics.LatchableEmitter; |
| 32 | +import org.apache.druid.server.metrics.StorageMonitor; |
32 | 33 | import org.apache.druid.sql.calcite.planner.Calcites; |
33 | 34 | import org.apache.druid.testing.embedded.EmbeddedBroker; |
34 | 35 | import org.apache.druid.testing.embedded.EmbeddedCoordinator; |
|
51 | 52 | import java.io.IOException; |
52 | 53 | import java.nio.file.Files; |
53 | 54 | import java.util.Collections; |
54 | | -import java.util.List; |
55 | 55 | import java.util.concurrent.ThreadLocalRandom; |
56 | 56 |
|
57 | 57 | /** |
@@ -102,6 +102,11 @@ public EmbeddedDruidCluster createCluster() |
102 | 102 | .useDefaultTimeoutForLatchableEmitter(20) |
103 | 103 | .addResource(storageResource) |
104 | 104 | .addCommonProperty("druid.storage.zip", "false") |
| 105 | + .addCommonProperty("druid.monitoring.emissionPeriod", "PT1s") |
| 106 | + .addCommonProperty( |
| 107 | + "druid.monitoring.monitors", |
| 108 | + "[\"org.apache.druid.server.metrics.StorageMonitor\"]" |
| 109 | + ) |
105 | 110 | .addServer(coordinator) |
106 | 111 | .addServer(overlord) |
107 | 112 | .addServer(indexer) |
@@ -152,90 +157,123 @@ void testQueryPartials() |
152 | 157 | "select count(*) from \"%s\" WHERE __time >= TIMESTAMP '2015-09-12 14:00:00' and __time < TIMESTAMP '2015-09-12 19:00:00'", |
153 | 158 | "select count(*) from \"%s\" WHERE __time >= TIMESTAMP '2015-09-12 19:00:00' and __time < TIMESTAMP '2015-09-13 00:00:00'" |
154 | 159 | }; |
155 | | - final long[] expectedResults = new long[] { |
156 | | - 9770, |
157 | | - 10524, |
158 | | - 10267, |
159 | | - 8683 |
160 | | - }; |
| 160 | + final long[] expectedResults = new long[]{9770, 10524, 10267, 8683}; |
| 161 | + final long[] expectedLoads = new long[]{8L, 6L, 5L, 5L}; |
| 162 | + |
| 163 | + |
| 164 | + LatchableEmitter emitter = historical.latchableEmitter(); |
| 165 | + // clear out the pipe to get zerod out storage monitor metrics |
| 166 | + ServiceMetricEvent monitorEvent = emitter.waitForNextEvent(event -> event.hasMetricName(StorageMonitor.VSF_LOAD_COUNT)); |
| 167 | + while (monitorEvent != null && monitorEvent.getValue().longValue() > 0) { |
| 168 | + monitorEvent = emitter.waitForNextEvent(event -> event.hasMetricName(StorageMonitor.VSF_LOAD_COUNT)); |
| 169 | + } |
| 170 | + // then flush (which clears out the internal events stores in test emitter) so we can do clean sums across them |
| 171 | + emitter.flush(); |
| 172 | + |
| 173 | + emitter.waitForNextEvent(event -> event.hasMetricName(StorageMonitor.VSF_LOAD_COUNT)); |
| 174 | + long beforeLoads = emitter.getMetricEventLongSum(StorageMonitor.VSF_LOAD_COUNT); |
| 175 | + // confirm flushed |
| 176 | + Assertions.assertEquals(0, beforeLoads); |
161 | 177 |
|
| 178 | + // run the queries in order |
162 | 179 | Assertions.assertEquals(expectedResults[0], Long.parseLong(cluster.runSql(queries[0], dataSource))); |
163 | | - assertMetrics(1, 8L); |
| 180 | + assertQueryMetrics(1, expectedLoads[0]); |
164 | 181 | Assertions.assertEquals(expectedResults[1], Long.parseLong(cluster.runSql(queries[1], dataSource))); |
165 | | - assertMetrics(2, 6L); |
| 182 | + assertQueryMetrics(2, expectedLoads[1]); |
166 | 183 | Assertions.assertEquals(expectedResults[2], Long.parseLong(cluster.runSql(queries[2], dataSource))); |
167 | | - assertMetrics(3, 5L); |
| 184 | + assertQueryMetrics(3, expectedLoads[2]); |
168 | 185 | Assertions.assertEquals(expectedResults[3], Long.parseLong(cluster.runSql(queries[3], dataSource))); |
169 | | - assertMetrics(4, 5L); |
| 186 | + assertQueryMetrics(4, expectedLoads[3]); |
170 | 187 |
|
| 188 | + emitter.waitForNextEvent(event -> event.hasMetricName(StorageMonitor.VSF_LOAD_COUNT)); |
| 189 | + long firstLoads = emitter.getMetricEventLongSum(StorageMonitor.VSF_LOAD_COUNT); |
| 190 | + Assertions.assertTrue(firstLoads >= 24, "expected " + 24 + " but only got " + firstLoads); |
| 191 | + |
| 192 | + long expectedTotalHits = 0; |
| 193 | + long expectedTotalLoad = 0; |
171 | 194 | for (int i = 0; i < 1000; i++) { |
172 | 195 | int nextQuery = ThreadLocalRandom.current().nextInt(queries.length); |
173 | 196 | Assertions.assertEquals(expectedResults[nextQuery], Long.parseLong(cluster.runSql(queries[nextQuery], dataSource))); |
174 | | - assertMetrics(i + 5, null); |
| 197 | + assertQueryMetrics(i + 5, null); |
| 198 | + long actualLoads = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_COUNT, i + 5); |
| 199 | + expectedTotalLoad += actualLoads; |
| 200 | + expectedTotalHits += (expectedLoads[nextQuery] - actualLoads); |
175 | 201 | } |
| 202 | + |
| 203 | + emitter.waitForNextEvent(event -> event.hasMetricName(StorageMonitor.VSF_HIT_COUNT)); |
| 204 | + long hits = emitter.getMetricEventLongSum(StorageMonitor.VSF_HIT_COUNT); |
| 205 | + Assertions.assertTrue(hits >= expectedTotalHits, "expected " + expectedTotalHits + " but only got " + hits); |
| 206 | + emitter.waitForNextEvent(event -> event.hasMetricName(StorageMonitor.VSF_LOAD_COUNT)); |
| 207 | + long loads = emitter.getMetricEventLongSum(StorageMonitor.VSF_LOAD_COUNT); |
| 208 | + Assertions.assertTrue(loads >= expectedTotalLoad, "expected " + expectedTotalLoad + " but only got " + loads); |
| 209 | + Assertions.assertTrue(emitter.getMetricEventLongSum(StorageMonitor.VSF_LOAD_BYTES) > 0); |
| 210 | + emitter.waitForNextEvent(event -> event.hasMetricName(StorageMonitor.VSF_EVICT_COUNT)); |
| 211 | + Assertions.assertTrue(emitter.getMetricEventLongSum(StorageMonitor.VSF_EVICT_COUNT) >= 0); |
| 212 | + Assertions.assertTrue(emitter.getMetricEventLongSum(StorageMonitor.VSF_EVICT_BYTES) > 0); |
| 213 | + Assertions.assertEquals(0, emitter.getMetricEventLongSum(StorageMonitor.VSF_REJECT_COUNT)); |
| 214 | + Assertions.assertTrue(emitter.getLatestMetricEventValue(StorageMonitor.VSF_USED_BYTES, 0).longValue() > 0); |
176 | 215 | } |
177 | 216 |
|
178 | | - private void assertMetrics(int expectedEventCount, @Nullable Long expectedLoadCount) |
| 217 | + |
| 218 | + private void assertQueryMetrics(int expectedEventCount, @Nullable Long expectedLoadCount) |
179 | 219 | { |
180 | 220 | LatchableEmitter emitter = historical.latchableEmitter(); |
181 | | - final int lastIndex = expectedEventCount - 1; |
182 | 221 |
|
183 | | - List<ServiceMetricEvent> countEvents = emitter.getMetricEvents(DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_COUNT); |
184 | | - Assertions.assertEquals(expectedEventCount, countEvents.size()); |
| 222 | + long loadCount = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_COUNT, expectedEventCount); |
185 | 223 | if (expectedLoadCount != null) { |
186 | | - Assertions.assertEquals(expectedLoadCount, countEvents.get(lastIndex).getValue()); |
| 224 | + Assertions.assertEquals(expectedLoadCount, loadCount); |
187 | 225 | } |
188 | | - boolean hasLoads = countEvents.get(lastIndex).getValue().longValue() > 0; |
| 226 | + boolean hasLoads = loadCount > 0; |
189 | 227 |
|
190 | | - List<ServiceMetricEvent> timeEvents = emitter.getMetricEvents(DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_BATCH_TIME); |
191 | | - Assertions.assertEquals(expectedEventCount, timeEvents.size()); |
| 228 | + long time = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_BATCH_TIME, expectedEventCount); |
192 | 229 | if (hasLoads) { |
193 | | - Assertions.assertTrue(timeEvents.get(lastIndex).getValue().longValue() > 0); |
| 230 | + Assertions.assertTrue(time > 0); |
194 | 231 | } else { |
195 | | - Assertions.assertEquals(0, timeEvents.get(lastIndex).getValue().longValue()); |
| 232 | + Assertions.assertEquals(0, time); |
196 | 233 | } |
197 | 234 |
|
198 | | - List<ServiceMetricEvent> timeMaxEvents = emitter.getMetricEvents(DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_TIME_MAX); |
199 | | - Assertions.assertEquals(expectedEventCount, timeMaxEvents.size()); |
| 235 | + long maxTime = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_TIME_MAX, expectedEventCount); |
200 | 236 | if (hasLoads) { |
201 | | - Assertions.assertTrue(timeMaxEvents.get(lastIndex).getValue().longValue() > 0); |
| 237 | + Assertions.assertTrue(maxTime > 0); |
202 | 238 | } else { |
203 | | - Assertions.assertEquals(0, timeMaxEvents.get(lastIndex).getValue().longValue()); |
| 239 | + Assertions.assertEquals(0, maxTime); |
204 | 240 | } |
205 | 241 |
|
206 | | - List<ServiceMetricEvent> timeAvgEvents = emitter.getMetricEvents(DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_TIME_AVG); |
207 | | - Assertions.assertEquals(expectedEventCount, timeAvgEvents.size()); |
| 242 | + long avgTime = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_TIME_AVG, expectedEventCount); |
208 | 243 | if (hasLoads) { |
209 | | - Assertions.assertTrue(timeAvgEvents.get(lastIndex).getValue().longValue() > 0); |
| 244 | + Assertions.assertTrue(avgTime > 0); |
210 | 245 | } else { |
211 | | - Assertions.assertEquals(0, timeAvgEvents.get(lastIndex).getValue().longValue()); |
| 246 | + Assertions.assertEquals(0, avgTime); |
212 | 247 | } |
213 | 248 |
|
214 | | - List<ServiceMetricEvent> waitMaxEvents = emitter.getMetricEvents(DefaultQueryMetrics.QUERY_ON_DEMAND_WAIT_TIME_MAX); |
215 | | - Assertions.assertEquals(expectedEventCount, waitMaxEvents.size()); |
| 249 | + long maxWait = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_WAIT_TIME_MAX, expectedEventCount); |
216 | 250 | if (hasLoads) { |
217 | | - Assertions.assertTrue(waitMaxEvents.get(lastIndex).getValue().longValue() >= 0); |
| 251 | + Assertions.assertTrue(maxWait >= 0); |
218 | 252 | } else { |
219 | | - Assertions.assertEquals(0, waitMaxEvents.get(lastIndex).getValue().longValue()); |
| 253 | + Assertions.assertEquals(0, maxWait); |
220 | 254 | } |
221 | 255 |
|
222 | | - List<ServiceMetricEvent> waitAvgEvents = emitter.getMetricEvents(DefaultQueryMetrics.QUERY_ON_DEMAND_WAIT_TIME_AVG); |
223 | | - Assertions.assertEquals(expectedEventCount, waitAvgEvents.size()); |
| 256 | + long avgWait = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_WAIT_TIME_AVG, expectedEventCount); |
224 | 257 | if (hasLoads) { |
225 | | - Assertions.assertTrue(waitAvgEvents.get(lastIndex).getValue().longValue() >= 0); |
| 258 | + Assertions.assertTrue(avgWait >= 0); |
226 | 259 | } else { |
227 | | - Assertions.assertEquals(0, waitAvgEvents.get(lastIndex).getValue().longValue()); |
| 260 | + Assertions.assertEquals(0, avgWait); |
228 | 261 | } |
229 | 262 |
|
230 | | - List<ServiceMetricEvent> loadSizeEvents = emitter.getMetricEvents(DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_BYTES); |
231 | | - Assertions.assertEquals(expectedEventCount, loadSizeEvents.size()); |
| 263 | + long bytes = getMetricLatestValue(emitter, DefaultQueryMetrics.QUERY_ON_DEMAND_LOAD_BYTES, expectedEventCount); |
232 | 264 | if (hasLoads) { |
233 | | - Assertions.assertTrue(loadSizeEvents.get(lastIndex).getValue().longValue() > 0); |
| 265 | + Assertions.assertTrue(bytes > 0); |
234 | 266 | } else { |
235 | | - Assertions.assertEquals(0, loadSizeEvents.get(lastIndex).getValue().longValue()); |
| 267 | + Assertions.assertEquals(0, bytes); |
236 | 268 | } |
237 | 269 | } |
238 | 270 |
|
| 271 | + private long getMetricLatestValue(LatchableEmitter emitter, String metricName, int expectedCount) |
| 272 | + { |
| 273 | + Assertions.assertEquals(expectedCount, emitter.getMetricEventCount(metricName)); |
| 274 | + return emitter.getLatestMetricEventValue(metricName, 0).longValue(); |
| 275 | + } |
| 276 | + |
239 | 277 | private String createTestDatasourceName() |
240 | 278 | { |
241 | 279 | return "wiki-" + IdUtils.getRandomId(); |
|
0 commit comments