@Override public void run() { byte[] key = new byte[keySize]; byte[] value = new byte[valueSize]; Random rand = new Random(Thread.currentThread().getId()); WAL wal = region.getWAL(); TraceScope threadScope = Trace.startSpan("WALPerfEval." + Thread.currentThread().getName()); try { long startTime = System.currentTimeMillis(); int lastSync = 0; for (int i = 0; i < numIterations; ++i) { assert Trace.currentSpan() == threadScope.getSpan() : "Span leak detected."; TraceScope loopScope = Trace.startSpan("runLoopIter" + i, loopSampler); try { long now = System.nanoTime(); Put put = setupPut(rand, key, value, numFamilies); WALEdit walEdit = new WALEdit(); addFamilyMapToWALEdit(put.getFamilyCellMap(), walEdit); HRegionInfo hri = region.getRegionInfo(); final WALKey logkey = new WALKey(hri.getEncodedNameAsBytes(), hri.getTable(), now); wal.append(htd, hri, logkey, walEdit, region.getSequenceId(), true, null); if (!this.noSync) { if (++lastSync >= this.syncInterval) { wal.sync(); lastSync = 0; } } latencyHistogram.update(System.nanoTime() - now); } finally { loopScope.close(); } } long totalTime = (System.currentTimeMillis() - startTime); logBenchmarkResult(Thread.currentThread().getName(), numIterations, totalTime); } catch (Exception e) { LOG.error(getClass().getSimpleName() + " Thread failed", e); } finally { threadScope.close(); } }
private void readEntries(Opts opts) throws TableNotFoundException, AccumuloException, AccumuloSecurityException { Scanner scanner = opts.getConnector().createScanner(opts.getTableName(), opts.auths); // Trace the read operation. TraceScope readScope = Trace.startSpan("Client Read", Sampler.ALWAYS); System.out.println("TraceID: " + Long.toHexString(readScope.getSpan().getTraceId())); int numberOfEntriesRead = 0; for (Entry<Key, Value> entry : scanner) { System.out.println(entry.getKey().toString() + " -> " + entry.getValue().toString()); ++numberOfEntriesRead; } // You can add additional metadata (key, values) to Spans which will be able to be viewed in the // Monitor readScope .getSpan() .addKVAnnotation( "Number of Entries Read".getBytes(UTF_8), String.valueOf(numberOfEntriesRead).getBytes(UTF_8)); readScope.close(); }
private void createEntries(Opts opts) throws TableNotFoundException, AccumuloException, AccumuloSecurityException { // Trace the write operation. Note, unless you flush the BatchWriter, you will not capture // the write operation as it is occurs asynchronously. You can optionally create additional // Spans // within a given Trace as seen below around the flush TraceScope scope = Trace.startSpan("Client Write", Sampler.ALWAYS); System.out.println("TraceID: " + Long.toHexString(scope.getSpan().getTraceId())); BatchWriter batchWriter = opts.getConnector().createBatchWriter(opts.getTableName(), new BatchWriterConfig()); Mutation m = new Mutation("row"); m.put("cf", "cq", "value"); batchWriter.addMutation(m); // You can add timeline annotations to Spans which will be able to be viewed in the Monitor scope.getSpan().addTimelineAnnotation("Initiating Flush"); batchWriter.flush(); batchWriter.close(); scope.close(); }
@Test public void testTraceCreateTable() throws Exception { TraceScope tableCreationSpan = Trace.startSpan("creating table", Sampler.ALWAYS); Table table; try { table = TEST_UTIL.createTable(TableName.valueOf("table"), FAMILY_BYTES); } finally { tableCreationSpan.close(); } // Some table creation is async. Need to make sure that everything is full in before // checking to see if the spans are there. TEST_UTIL.waitFor( 1000, new Waiter.Predicate<Exception>() { @Override public boolean evaluate() throws Exception { return rcvr.getSpans().size() >= 5; } }); Collection<Span> spans = rcvr.getSpans(); TraceTree traceTree = new TraceTree(spans); Collection<Span> roots = traceTree.getSpansByParent().find(Span.ROOT_SPAN_ID); assertEquals(1, roots.size()); Span createTableRoot = roots.iterator().next(); assertEquals("creating table", createTableRoot.getDescription()); int createTableCount = 0; for (Span s : traceTree.getSpansByParent().find(createTableRoot.getSpanId())) { if (s.getDescription().startsWith("MasterService.CreateTable")) { createTableCount++; } } assertTrue(createTableCount >= 1); assertTrue(traceTree.getSpansByParent().find(createTableRoot.getSpanId()).size() > 3); assertTrue(spans.size() > 5); Put put = new Put("row".getBytes()); put.add(FAMILY_BYTES, "col".getBytes(), "value".getBytes()); TraceScope putSpan = Trace.startSpan("doing put", Sampler.ALWAYS); try { table.put(put); } finally { putSpan.close(); } spans = rcvr.getSpans(); traceTree = new TraceTree(spans); roots = traceTree.getSpansByParent().find(Span.ROOT_SPAN_ID); assertEquals(2, roots.size()); Span putRoot = null; for (Span root : roots) { if (root.getDescription().equals("doing put")) { putRoot = root; } } assertNotNull(putRoot); }
@AfterClass public static void after() throws Exception { TEST_UTIL.shutdownMiniCluster(); Trace.removeReceiver(rcvr); rcvr = null; }
@BeforeClass public static void before() throws Exception { TEST_UTIL.startMiniCluster(2, 3); rcvr = new POJOSpanReceiver(new HBaseHTraceConfiguration(TEST_UTIL.getConfiguration())); Trace.addReceiver(rcvr); }
@Override public int run(String[] args) throws Exception { Path rootRegionDir = null; int numThreads = 1; long numIterations = 1000000; int numFamilies = 1; int syncInterval = 0; boolean noSync = false; boolean verify = false; boolean verbose = false; boolean cleanup = true; boolean noclosefs = false; long roll = Long.MAX_VALUE; boolean compress = false; String cipher = null; int numRegions = 1; String spanReceivers = getConf().get("hbase.trace.spanreceiver.classes"); boolean trace = spanReceivers != null && !spanReceivers.isEmpty(); double traceFreq = 1.0; // Process command line args for (int i = 0; i < args.length; i++) { String cmd = args[i]; try { if (cmd.equals("-threads")) { numThreads = Integer.parseInt(args[++i]); } else if (cmd.equals("-iterations")) { numIterations = Long.parseLong(args[++i]); } else if (cmd.equals("-path")) { rootRegionDir = new Path(args[++i]); } else if (cmd.equals("-families")) { numFamilies = Integer.parseInt(args[++i]); } else if (cmd.equals("-qualifiers")) { numQualifiers = Integer.parseInt(args[++i]); } else if (cmd.equals("-keySize")) { keySize = Integer.parseInt(args[++i]); } else if (cmd.equals("-valueSize")) { valueSize = Integer.parseInt(args[++i]); } else if (cmd.equals("-syncInterval")) { syncInterval = Integer.parseInt(args[++i]); } else if (cmd.equals("-nosync")) { noSync = true; } else if (cmd.equals("-verify")) { verify = true; } else if (cmd.equals("-verbose")) { verbose = true; } else if (cmd.equals("-nocleanup")) { cleanup = false; } else if (cmd.equals("-noclosefs")) { noclosefs = true; } else if (cmd.equals("-roll")) { roll = Long.parseLong(args[++i]); } else if (cmd.equals("-compress")) { compress = true; } else if (cmd.equals("-encryption")) { cipher = args[++i]; } else if (cmd.equals("-regions")) { numRegions = Integer.parseInt(args[++i]); } else if (cmd.equals("-traceFreq")) { traceFreq = Double.parseDouble(args[++i]); } else if (cmd.equals("-h")) { printUsageAndExit(); } else if (cmd.equals("--help")) { printUsageAndExit(); } else { System.err.println("UNEXPECTED: " + cmd); printUsageAndExit(); } } catch (Exception e) { printUsageAndExit(); } } if (compress) { Configuration conf = getConf(); conf.setBoolean(HConstants.ENABLE_WAL_COMPRESSION, true); } if (cipher != null) { // Set up WAL for encryption Configuration conf = getConf(); conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, KeyProviderForTesting.class.getName()); conf.set(HConstants.CRYPTO_MASTERKEY_NAME_CONF_KEY, "hbase"); conf.setClass( "hbase.regionserver.hlog.reader.impl", SecureProtobufLogReader.class, WAL.Reader.class); conf.setClass( "hbase.regionserver.hlog.writer.impl", SecureProtobufLogWriter.class, Writer.class); conf.setBoolean(HConstants.ENABLE_WAL_ENCRYPTION, true); conf.set(HConstants.CRYPTO_WAL_ALGORITHM_CONF_KEY, cipher); } if (numThreads < numRegions) { LOG.warn("Number of threads is less than the number of regions; some regions will sit idle."); } // Internal config. goes off number of threads; if more threads than handlers, stuff breaks. // In regionserver, number of handlers == number of threads. getConf().setInt(HConstants.REGION_SERVER_HANDLER_COUNT, numThreads); // Run WAL Performance Evaluation // First set the fs from configs. In case we are on hadoop1 FSUtils.setFsDefault(getConf(), FSUtils.getRootDir(getConf())); FileSystem fs = FileSystem.get(getConf()); LOG.info("FileSystem: " + fs); SpanReceiverHost receiverHost = trace ? SpanReceiverHost.getInstance(getConf()) : null; TraceScope scope = Trace.startSpan("WALPerfEval", trace ? Sampler.ALWAYS : Sampler.NEVER); try { if (rootRegionDir == null) { rootRegionDir = TEST_UTIL.getDataTestDirOnTestFS("WALPerformanceEvaluation"); } rootRegionDir = rootRegionDir.makeQualified(fs); cleanRegionRootDir(fs, rootRegionDir); FSUtils.setRootDir(getConf(), rootRegionDir); final WALFactory wals = new WALFactory(getConf(), null, "wals"); final HRegion[] regions = new HRegion[numRegions]; final Runnable[] benchmarks = new Runnable[numRegions]; final MockRegionServerServices mockServices = new MockRegionServerServices(getConf()); final LogRoller roller = new LogRoller(mockServices, mockServices); Threads.setDaemonThreadRunning(roller.getThread(), "WALPerfEval.logRoller"); try { for (int i = 0; i < numRegions; i++) { // Initialize Table Descriptor // a table per desired region means we can avoid carving up the key space final HTableDescriptor htd = createHTableDescriptor(i, numFamilies); regions[i] = openRegion(fs, rootRegionDir, htd, wals, roll, roller); benchmarks[i] = Trace.wrap( new WALPutBenchmark( regions[i], htd, numIterations, noSync, syncInterval, traceFreq)); } ConsoleReporter.enable(this.metrics, 30, TimeUnit.SECONDS); long putTime = runBenchmark(benchmarks, numThreads); logBenchmarkResult( "Summary: threads=" + numThreads + ", iterations=" + numIterations + ", syncInterval=" + syncInterval, numIterations * numThreads, putTime); for (int i = 0; i < numRegions; i++) { if (regions[i] != null) { closeRegion(regions[i]); regions[i] = null; } } if (verify) { LOG.info("verifying written log entries."); Path dir = new Path( FSUtils.getRootDir(getConf()), DefaultWALProvider.getWALDirectoryName("wals")); long editCount = 0; FileStatus[] fsss = fs.listStatus(dir); if (fsss.length == 0) throw new IllegalStateException("No WAL found"); for (FileStatus fss : fsss) { Path p = fss.getPath(); if (!fs.exists(p)) throw new IllegalStateException(p.toString()); editCount += verify(wals, p, verbose); } long expected = numIterations * numThreads; if (editCount != expected) { throw new IllegalStateException("Counted=" + editCount + ", expected=" + expected); } } } finally { mockServices.stop("test clean up."); for (int i = 0; i < numRegions; i++) { if (regions[i] != null) { closeRegion(regions[i]); } } if (null != roller) { LOG.info("shutting down log roller."); Threads.shutdown(roller.getThread()); } wals.shutdown(); // Remove the root dir for this test region if (cleanup) cleanRegionRootDir(fs, rootRegionDir); } } finally { // We may be called inside a test that wants to keep on using the fs. if (!noclosefs) fs.close(); scope.close(); if (receiverHost != null) receiverHost.closeReceivers(); } return (0); }