package org.apache.hadoop.hbase.client; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.log4j.Logger; import java.io.*; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; public class HTableStats { Logger LOG = Logger.getLogger(HTableStats.class); AtomicLong maxPutTime = new AtomicLong(0); AtomicLong maxPutListTime = new AtomicLong(0); AtomicLong maxDeleteTime = new AtomicLong(0); AtomicLong maxDeleteListTime = new AtomicLong(0); AtomicLong maxGetTime = new AtomicLong(0); AtomicLong maxGetListTime = new AtomicLong(0); AtomicLong putPrimary = new AtomicLong(0); AtomicLong putFailover = new AtomicLong(0); AtomicLong putListPrimary = new AtomicLong(0); AtomicLong putListFailover = new AtomicLong(0); AtomicLong getPrimary = new AtomicLong(0); AtomicLong getFailover = new AtomicLong(0); AtomicLong getListPrimary = new AtomicLong(0); AtomicLong getListFailover = new AtomicLong(0); AtomicLong deletePrimary = new AtomicLong(0); AtomicLong deleteFailover = new AtomicLong(0); AtomicLong deleteListPrimary = new AtomicLong(0); AtomicLong deleteListFailover = new AtomicLong(0); long lastPutPrimary = 0; long lastPutFailover = 0; long lastPutListPrimary = 0; long lastPutListFailover = 0; long lastGetPrimary = 0; long lastGetFailover = 0; long lastGetListPrimary = 0; long lastGetListFailover = 0; long lastDeletePrimary = 0; long lastDeleteFailover = 0; long lastDeleteListPrimary = 0; long lastDeleteListFailover = 0; static final int ROLLING_AVG_WINDOW = 90; BlockingQueue<Long> putRollingAverage = new LinkedBlockingQueue<Long>(); BlockingQueue<Long> putListRollingAverage = new LinkedBlockingQueue<Long>(); BlockingQueue<Long> getRollingAverage = new LinkedBlockingQueue<Long>(); BlockingQueue<Long> getListRollingAverage = new LinkedBlockingQueue<Long>(); BlockingQueue<Long> deleteRollingAverage = new LinkedBlockingQueue<Long>(); BlockingQueue<Long> deleteListRollingAverage = new LinkedBlockingQueue<Long>(); static final String newLine = System.getProperty("line.separator"); Thread printingThread = null; boolean continuePrinting = false; public HTableStats() { for (int i = 0; i < ROLLING_AVG_WINDOW; i++) { putRollingAverage.add(-1l); putListRollingAverage.add(-1l); getRollingAverage.add(-1l); getListRollingAverage.add(-1l); deleteRollingAverage.add(-1l); deleteListRollingAverage.add(-1l); } } public void printPrettyStats() { LOG.info("Stats: Max Time"); LOG.info(" > maxPutTime: " + maxPutTime); LOG.info(" > maxPutListTime: " + maxPutListTime); LOG.info(" > maxGetTime: " + maxGetTime); LOG.info(" > maxGetListTime: " + maxGetListTime); LOG.info(" > maxDeleteTime: " + maxDeleteTime); LOG.info(" > maxDeleteListTime: " + maxDeleteListTime); LOG.info("Stats: Rolling Avg"); LOG.info(" > put: " + getRollingAvg(putRollingAverage)); LOG.info(" > putList: " + getRollingAvg(putListRollingAverage)); LOG.info(" > get: " + getRollingAvg(getRollingAverage)); LOG.info(" > getList: " + getRollingAvg(getListRollingAverage)); LOG.info(" > delete: " + getRollingAvg(deleteRollingAverage)); LOG.info(" > deleteList: " + getRollingAvg(deleteListRollingAverage)); LOG.info("Stats: Rolling Max"); LOG.info(" > put: " + getRollingMax(putRollingAverage)); LOG.info(" > putList: " + getRollingMax(putListRollingAverage)); LOG.info(" > get: " + getRollingMax(getRollingAverage)); LOG.info(" > getList: " + getRollingMax(getListRollingAverage)); LOG.info(" > delete: " + getRollingMax(deleteRollingAverage)); LOG.info(" > deleteList: " + getRollingMax(deleteListRollingAverage)); LOG.info("Stats: Dst"); LOG.info(" > put: " + putPrimary + "/" + putFailover); LOG.info(" > putList: " + putListPrimary + "/" + putListFailover); LOG.info(" > get: " + getPrimary + "/" + getFailover); LOG.info(" > getList: " + getListPrimary + "/" + getListFailover); LOG.info(" > delete: " + deletePrimary + "/" + deleteFailover); LOG.info(" > deleteList: " + deleteListPrimary + "/" + deleteListFailover); } public void stopPrintingStats() { continuePrinting = false; printingThread = null; } public void printStats(final BufferedWriter writer, final long secondsHeartbeat) { try { writer.append("maxPutTime," + "maxPutListTime + ," + "maxGetTime," + "maxGetListTime," + "maxDeleteTime," + "maxDeleteListTime," + "putRollingAverage," + "putListRollingAverage," + "getRollingAverage," + "getListRollingAverage," + "deleteRollingAverage," + "deleteListRollingAverage," + "putRollingMax," + "putListRollingMax," + "getRollingMax," + "getListRollingMax," + "deleteRollingMax," + "deleteListRollingMax," + "putPrimaryTotalCount," + "putPrimaryRollingCount," + "putFailoverTotalCount," + "putFailoverRollingCount," + "putListPrimaryTotalCount," + "putListPrimaryRollingCount," + "putListFailoverTotalCount," + "putListFailoverRollingCount," + "getPrimaryCount," + "getPrimaryRollingCount," + "getFailoverCount," + "getFailoverRollingCount," + "getListPrimaryCount," + "getListPrimaryRollingCount," + "getListFailoverCount," + "getListFailoverRollingCount," + "deletePrimaryCount," + "deletePrimaryRollingCount," + "deleteFailoverCount," + "deleteFailoverRollingCount," + "deleteListPrimaryCount," + "deleteListPrimaryRollingCount," + "deleteListFailoverCount," + "deleteListFailoverRollingCount," + newLine); } catch (IOException e) { e.printStackTrace(); } Runnable printerRunnable = new Runnable() { @Override public void run() { while(continuePrinting) { try { Thread.sleep(secondsHeartbeat); } catch (InterruptedException e) { e.printStackTrace(); } String statStr = maxPutTime + "," + maxPutListTime + "," + maxGetTime + "," + maxGetListTime + "," + maxDeleteTime + "," + maxDeleteListTime + "," + getRollingAvg(putRollingAverage) + "," + getRollingAvg(putListRollingAverage) + "," + getRollingAvg(getRollingAverage) + "," + getRollingAvg(getListRollingAverage) + "," + getRollingAvg(deleteRollingAverage) + "," + getRollingAvg(deleteListRollingAverage) + "," + getRollingMax(putRollingAverage) + "," + getRollingMax(putListRollingAverage) + "," + getRollingMax(getRollingAverage) + "," + getRollingMax(getListRollingAverage) + "," + getRollingMax(deleteRollingAverage) + "," + getRollingMax(deleteListRollingAverage) + "," + putPrimary + "," + (putPrimary.get() - lastPutPrimary) + "," + putFailover + "," + (putFailover.get() - lastPutFailover) + "," + putListPrimary + "," + (putListPrimary.get() - lastPutListPrimary) + "," + putListFailover + "," + (putListFailover.get() - lastPutListFailover) + "," + getPrimary + "," + (getPrimary.get() - lastGetPrimary) + "," + (getFailover.get()) + "," + (getFailover.get() - lastGetFailover) + "," + (getListPrimary.get()) + "," + (getListPrimary.get() - lastGetListPrimary) + "," + (getListFailover.get()) + "," + (getFailover.get() - lastGetFailover) + "," + (deletePrimary.get()) + "," + (deletePrimary.get() - lastDeletePrimary) + "," + (deleteFailover.get()) + "," + (deleteFailover.get() - lastDeleteFailover) + "," + (deleteListPrimary.get()) + "," + (deleteListPrimary.get() - lastDeleteListPrimary) + "," + (deleteListFailover.get()) + "," + (deleteListFailover.get() - lastDeleteListFailover); try { writer.write(statStr); writer.newLine(); } catch (IOException e) { break; } } System.out.println("---- Stats Stopped ----"); } }; printingThread = new Thread(printerRunnable); continuePrinting = true; printingThread.start(); } public void printStats(final OutputStream outputStream, final long secondsHeartbeat) { final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream)); printStats(writer, secondsHeartbeat); } public static void printCSVHeaders(Writer writer) throws IOException { writer.append("maxPutTime," + "maxPutListTime + ," + "maxGetTime," + "maxGetListTime," + "maxDeleteTime," + "maxDeleteListTime," + "putRollingAverage," + "putListRollingAverage," + "getRollingAverage," + "getListRollingAverage," + "deleteRollingAverage," + "deleteListRollingAverage," + "putRollingMax," + "putListRollingMax," + "getRollingMax," + "getListRollingMax," + "deleteRollingMax," + "deleteListRollingMax," + "putPrimaryTotalCount," + "putPrimaryRollingCount," + "putFailoverTotalCount," + "putFailoverRollingCount," + "putListPrimaryTotalCount," + "putListPrimaryRollingCount," + "putListFailoverTotalCount," + "putListFailoverRollingCount," + "getPrimaryCount," + "getPrimaryRollingCount," + "getFailoverCount," + "getFailoverRollingCount," + "getListPrimaryCount," + "getListPrimaryRollingCount," + "getListFailoverCount," + "getListFailoverRollingCount," + "deletePrimaryCount," + "deletePrimaryRollingCount," + "deleteFailoverCount," + "deleteFailoverRollingCount," + "deleteListPrimaryCount," + "deleteListPrimaryRollingCount," + "deleteListFailoverCount," + "deleteListFailoverRollingCount," + newLine); } public void printCSVStats(Writer writer) throws IOException { writer.append(maxPutTime + "," + maxPutListTime + "," + maxGetTime + "," + maxGetListTime + "," + maxDeleteTime + "," + maxDeleteListTime + "," + getRollingAvg(putRollingAverage) + "," + getRollingAvg(putListRollingAverage) + "," + getRollingAvg(getRollingAverage) + "," + getRollingAvg(getListRollingAverage) + "," + getRollingAvg(deleteRollingAverage) + "," + getRollingAvg(deleteListRollingAverage) + "," + getRollingMax(putRollingAverage) + "," + getRollingMax(putListRollingAverage) + "," + getRollingMax(getRollingAverage) + "," + getRollingMax(getListRollingAverage) + "," + getRollingMax(deleteRollingAverage) + "," + getRollingMax(deleteListRollingAverage) + "," + putPrimary + "," + (putPrimary.get()-lastPutPrimary) + "," + putFailover + "," + (putFailover.get()-lastPutFailover) + "," + putListPrimary + "," + (putListPrimary.get()-lastPutListPrimary) + "," + putListFailover + "," + (putListFailover.get()-lastPutListFailover) + "," + getPrimary + "," + (getPrimary.get()-lastGetPrimary) + "," + (getFailover.get()) + "," + (getFailover.get()-lastGetFailover) + "," + (getListPrimary.get()) + "," + (getListPrimary.get()-lastGetListPrimary) + "," + (getListFailover.get()) + "," + (getListFailover.get()-lastGetListFailover) + "," + (deletePrimary.get()) + "," + (deletePrimary.get()-lastDeletePrimary) + "," + (deleteFailover.get()) + "," + (deleteFailover.get()-lastDeleteFailover) + "," + (deleteListPrimary.get()) + "," + (deleteListPrimary.get()-lastDeleteListPrimary) + "," + (deleteListFailover.get()) + "," + (deleteListFailover.get()-lastDeleteListFailover) + newLine); lastPutPrimary = putPrimary.get(); lastPutFailover = putFailover.get(); lastPutListPrimary = putListPrimary.get(); lastPutListFailover = putListFailover.get(); lastGetPrimary = getPrimary.get(); lastGetFailover = getFailover.get(); lastGetListPrimary = getListPrimary.get(); lastGetListFailover = getListFailover.get(); lastDeletePrimary = deletePrimary.get(); lastDeleteFailover = deleteFailover.get(); lastDeleteListPrimary = deleteListPrimary.get(); lastDeleteListFailover = deleteListFailover.get(); } public static long getRollingAvg(BlockingQueue<Long> queue) { Long[] times = queue.toArray(new Long[0]); long totalTime = 0; long totalCount = 0; for (Long time: times) { if (time > -1) { totalCount++; totalTime += time; } } if (totalCount != 0) { return totalTime/totalCount; } else { return 0; } } public static long getRollingMax(BlockingQueue<Long> queue) { Long[] times = queue.toArray(new Long[0]); long maxTime = 0; for (Long time: times) { if (time > maxTime) { maxTime = time; } } return maxTime; } public void addPut(Boolean isPrimary, long time) { updateStat(isPrimary, time, maxPutTime, putPrimary, putFailover, putRollingAverage); } public void addPutList(Boolean isPrimary, long time) { updateStat(isPrimary, time, maxPutListTime, putListPrimary, putListFailover, putListRollingAverage); } public void addGet(Boolean isPrimary, long time) { updateStat(isPrimary, time, maxGetTime, getPrimary, getFailover, getRollingAverage); } public void addGetList(Boolean isPrimary, long time) { updateStat(isPrimary, time, maxGetListTime, getListPrimary, getListFailover, getListRollingAverage); } public void addDelete(Boolean isPrimary, long time) { updateStat(isPrimary, time, maxDeleteTime, deletePrimary, deleteFailover, deleteRollingAverage); } public void addDeleteList(Boolean isPrimary, long time) { updateStat(isPrimary, time, maxDeleteListTime, deleteListPrimary, deleteListFailover, deleteListRollingAverage); } private static void updateStat(Boolean isPrimary, long time, AtomicLong maxTime, AtomicLong primaryCount, AtomicLong failoverCount, BlockingQueue<Long> rollingAverage) { long max = maxTime.get(); while (time > max) { if (!maxTime.compareAndSet(max, time)) { max = maxTime.get(); } else { break; } } if (isPrimary != null) { if (isPrimary == true) { primaryCount.addAndGet(1); } else { failoverCount.addAndGet(1); } } rollingAverage.add(time); if (rollingAverage.size() > 100) { rollingAverage.poll(); } } }