131.1。内置工具

131.1.1。主 Web 界面

Master 默认在端口 16010 上启动 Web 界面。

Master Web UI 列出了创建的表及其定义(例如,ColumnFamilies,blocksize 等)。此外,还会列出群集中可用的 RegionServers 以及选定的高级度量标准(请求,区域数,usedHeap,maxHeap)。 Master Web UI 允许导航到每个 RegionServer 的 Web UI。

131.1.2。 RegionServer Web 界面

默认情况下,RegionServers 在端口 16030 上启动 Web 界面。

RegionServer Web UI 列出了在线区域及其开始/结束键,以及时间点 RegionServer 度量(请求,区域,storeFileIndexSize,compactionQueueSize 等)。

有关度量标准定义的更多信息,请参见 HBase 度量标准

131.1.3。 zkcli

zkcli是一个非常有用的工具,用于调查与 ZooKeeper 相关的问题。要调用:

./hbase zkcli -server host:port <cmd> <args> 

命令(和参数)是:

 connect host:port
  get path [watch]
  ls path [watch]
  set path data [version]
  delquota [-n|-b] path
  quit
  printwatches on|off
  create [-s] [-e] path data acl
  stat path [watch]
  close
  ls2 path [watch]
  history
  listquota path
  setAcl path acl
  getAcl path
  sync path
  redo cmdno
  addauth scheme auth
  delete path [version]
  setquota -n|-b val path 

131.1.4。维护模式

如果群集在某种状态下卡住并且标准技术没有取得进展,则可以在“维护模式”下重新启动群集。此模式具有显着降低的功能和表面积,使得更容易实现非常低级别的更改,例如修复/恢复hbase:meta表。

要进入维护模式,请在hbase-site.xml中将hbase.master.maintenance_mode设置为true,或在启动主过程(-D…​=true)时通过系统配置。进入和退出此模式需要重新启动服务,但典型的用途是 HBase Master 已经面临启动困难。

启用维护模式后,主服务器将托管所有系统表 - 确保它有足够的内存来执行此操作。不会从用户空间表中为 RegionServers 分配任何区域;事实上,在维护模式下,它们将完全未使用。此外,主服务器不会加载任何协处理器,不会运行任何规范化或合并/拆分操作,也不会强制执行配额。

131.2。外部工具

131.2.1。尾巴

tail是命令行工具,可以让您查看文件的结尾。添加-f选项,当新数据可用时,它将刷新。当你想知道发生了什么时,这很有用,例如,当一个集群需要很长时间才能关闭或启动时,因为你可以触发一个新的终端并拖尾主日志(可能还有一些 RegionServers)。

131.2.2。最佳

top可能是首次尝试查看计算机上运行的内容以及如何使用资源时最重要的工具之一。这是生产系统的一个例子:

top - 14:46:59 up 39 days, 11:55,  1 user,  load average: 3.75, 3.57, 3.84
Tasks: 309 total,   1 running, 308 sleeping,   0 stopped,   0 zombie
Cpu(s):  4.5%us,  1.6%sy,  0.0%ni, 91.7%id,  1.4%wa,  0.1%hi,  0.6%si,  0.0%st
Mem:  24414432k total, 24296956k used,   117476k free,     7196k buffers
Swap: 16008732k total,        14348k used, 15994384k free, 11106908k cached

  PID USER          PR  NI  VIRT  RES  SHR S %CPU %MEM        TIME+  COMMAND
15558 hadoop        18  -2 3292m 2.4g 3556 S   79 10.4   6523:52 java
13268 hadoop        18  -2 8967m 8.2g 4104 S   21 35.1   5170:30 java
 8895 hadoop        18  -2 1581m 497m 3420 S   11  2.1   4002:32 java
… 

在这里我们可以看到最后五分钟内的系统平均负载是 3.75,这大致意味着在这 5 分钟内平均有 3.75 个线程在等待 CPU 时间。通常,_ 完美 _ 利用率等于核心数量,在该数量下机器未被利用并且机器被过度利用。这是一个重要的概念,请参阅本文以了解更多: http://www.linuxjournal.com/article/9001

除了加载之外,我们可以看到系统几乎使用了所有可用的 RAM,但大部分用于 OS 缓存(这很好)。交换只有几 KB,这是想要的,高数字表示交换活动,这是 Java 系统性能的克星。检测交换的另一种方法是当负载平均值通过屋顶时(尽管这也可能是由死亡磁盘等引起的)。

默认情况下,进程列表并不是非常有用,我们所知道的是 3 个 java 进程正在使用大约 111%的 CPU。要知道哪个是哪个,只需输入c并扩展每一行。键入1将为您提供每个 CPU 的使用方式的详细信息,而不是所有 CPU 的平均值,如此处所示。

131.2.3。 JPS

jps随每个 JDK 一起提供,并为当前用户提供 java 进程 ID(如果是 root,则为所有用户提供 id)。例:

hadoop@sv4borg12:~$ jps
1322 TaskTracker
17789 HRegionServer
27862 Child
1158 DataNode
25115 HQuorumPeer
2950 Jps
19750 ThriftServer
18776 jmx 

按顺序,我们看到:

  • Hadoop TaskTracker 管理当地的 Childs

  • HBase RegionServer 服务于区域

  • Child,它的 MapReduce 任务,无法确切地分辨出哪种类型

  • Hadoop TaskTracker, manages the local Childs

  • Hadoop DataNode 服务块

  • HQorumPeer,ZooKeeper 合奏成员

  • Jps,嗯...这是当前的过程

  • ThriftServer,它是一个特殊的将只在 thrift 启动时运行

  • jmx,这是一个本地进程,它是我们监控平台的一部分(可能名字很差)。你可能没有那个。

然后,您可以执行诸如检出启动该过程的完整命令行之类的操作:

hadoop@sv4borg12:~$ ps aux | grep HRegionServer
hadoop   17789  155 35.2 9067824 8604364 ?     S<l  Mar04 9855:48 /usr/java/jdk1.6.0_14/bin/java -Xmx8000m -XX:+DoEscapeAnalysis -XX:+AggressiveOpts -XX:+UseConcMarkSweepGC -XX:NewSize=64m -XX:MaxNewSize=64m -XX:CMSInitiatingOccupancyFraction=88 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/export1/hadoop/logs/gc-hbase.log -Dcom.sun.management.jmxremote.port=10102 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.password.file=/home/hadoop/hbase/conf/jmxremote.password -Dcom.sun.management.jmxremote -Dhbase.log.dir=/export1/hadoop/logs -Dhbase.log.file=hbase-hadoop-regionserver-sv4borg12.log -Dhbase.home.dir=/home/hadoop/hbase -Dhbase.id.str=hadoop -Dhbase.root.logger=INFO,DRFA -Djava.library.path=/home/hadoop/hbase/lib/native/Linux-amd64-64 -classpath /home/hadoop/hbase/bin/../conf:[many jars]:/home/hadoop/hadoop/conf org.apache.hadoop.hbase.regionserver.HRegionServer start 

131.2.4。 jstack

jstack是最重要的工具之一,试图找出除了查看日志之外的 java 进程正在做什么。它必须与 jps 一起使用才能为其提供进程 ID。它显示了一个线程列表,每个线程都有一个名称,它们按照创建的顺序出现(所以最顶层的线程是最新的线程)。以下是一些示例:

RegionServer 的主线程等待主服务器执行的操作:

"regionserver60020" prio=10 tid=0x0000000040ab4000 nid=0x45cf waiting on condition [0x00007f16b6a96000..0x00007f16b6a96a70]
java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00007f16cd5c2f30> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1963)
    at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:395)
    at org.apache.hadoop.hbase.regionserver.HRegionServer.run(HRegionServer.java:647)
    at java.lang.Thread.run(Thread.java:619) 

正在刷新到文件的 MemStore 刷新线程:

"regionserver60020.cacheFlusher" daemon prio=10 tid=0x0000000040f4e000 nid=0x45eb in Object.wait() [0x00007f16b5b86000..0x00007f16b5b87af0]
java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at org.apache.hadoop.ipc.Client.call(Client.java:803)
    - locked <0x00007f16cb14b3a8> (a org.apache.hadoop.ipc.Client$Call)
    at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:221)
    at $Proxy1.complete(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:82)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:59)
    at $Proxy1.complete(Unknown Source)
    at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.closeInternal(DFSClient.java:3390)
    - locked <0x00007f16cb14b470> (a org.apache.hadoop.hdfs.DFSClient$DFSOutputStream)
    at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.close(DFSClient.java:3304)
    at org.apache.hadoop.fs.FSDataOutputStream$PositionCache.close(FSDataOutputStream.java:61)
    at org.apache.hadoop.fs.FSDataOutputStream.close(FSDataOutputStream.java:86)
    at org.apache.hadoop.hbase.io.hfile.HFile$Writer.close(HFile.java:650)
    at org.apache.hadoop.hbase.regionserver.StoreFile$Writer.close(StoreFile.java:853)
    at org.apache.hadoop.hbase.regionserver.Store.internalFlushCache(Store.java:467)
    - locked <0x00007f16d00e6f08> (a java.lang.Object)
    at org.apache.hadoop.hbase.regionserver.Store.flushCache(Store.java:427)
    at org.apache.hadoop.hbase.regionserver.Store.access$100(Store.java:80)
    at org.apache.hadoop.hbase.regionserver.Store$StoreFlusherImpl.flushCache(Store.java:1359)
    at org.apache.hadoop.hbase.regionserver.HRegion.internalFlushcache(HRegion.java:907)
    at org.apache.hadoop.hbase.regionserver.HRegion.internalFlushcache(HRegion.java:834)
    at org.apache.hadoop.hbase.regionserver.HRegion.flushcache(HRegion.java:786)
    at org.apache.hadoop.hbase.regionserver.MemStoreFlusher.flushRegion(MemStoreFlusher.java:250)
    at org.apache.hadoop.hbase.regionserver.MemStoreFlusher.flushRegion(MemStoreFlusher.java:224)
    at org.apache.hadoop.hbase.regionserver.MemStoreFlusher.run(MemStoreFlusher.java:146) 

正在等待处理的处理程序线程(如 put,delete,scan 等):

"IPC Server handler 16 on 60020" daemon prio=10 tid=0x00007f16b011d800 nid=0x4a5e waiting on condition [0x00007f16afefd000..0x00007f16afefd9f0]
   java.lang.Thread.State: WAITING (parking)
          at sun.misc.Unsafe.park(Native Method)
          - parking to wait for  <0x00007f16cd3f8dd8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
          at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
          at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1925)
          at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:358)
          at org.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1013) 

还有一个正在忙着增加一个计数器(它正处于尝试创建扫描器以读取最后一个值的阶段):

"IPC Server handler 66 on 60020" daemon prio=10 tid=0x00007f16b006e800 nid=0x4a90 runnable [0x00007f16acb77000..0x00007f16acb77cf0]
   java.lang.Thread.State: RUNNABLE
          at org.apache.hadoop.hbase.regionserver.KeyValueHeap.<init>(KeyValueHeap.java:56)
          at org.apache.hadoop.hbase.regionserver.StoreScanner.<init>(StoreScanner.java:79)
          at org.apache.hadoop.hbase.regionserver.Store.getScanner(Store.java:1202)
          at org.apache.hadoop.hbase.regionserver.HRegion$RegionScanner.<init>(HRegion.java:2209)
          at org.apache.hadoop.hbase.regionserver.HRegion.instantiateInternalScanner(HRegion.java:1063)
          at org.apache.hadoop.hbase.regionserver.HRegion.getScanner(HRegion.java:1055)
          at org.apache.hadoop.hbase.regionserver.HRegion.getScanner(HRegion.java:1039)
          at org.apache.hadoop.hbase.regionserver.HRegion.getLastIncrement(HRegion.java:2875)
          at org.apache.hadoop.hbase.regionserver.HRegion.incrementColumnValue(HRegion.java:2978)
          at org.apache.hadoop.hbase.regionserver.HRegionServer.incrementColumnValue(HRegionServer.java:2433)
          at sun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:597)
          at org.apache.hadoop.hbase.ipc.HBaseRPC$Server.call(HBaseRPC.java:560)
          at org.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1027) 

从 HDFS 接收数据的线程:

"IPC Client (47) connection to sv4borg9/10.4.24.40:9000 from hadoop" daemon prio=10 tid=0x00007f16a02d0000 nid=0x4fa3 runnable [0x00007f16b517d000..0x00007f16b517dbf0]
   java.lang.Thread.State: RUNNABLE
          at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
          at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:215)
          at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
          at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
          - locked <0x00007f17d5b68c00> (a sun.nio.ch.Util$1)
          - locked <0x00007f17d5b68be8> (a java.util.Collections$UnmodifiableSet)
          - locked <0x00007f1877959b50> (a sun.nio.ch.EPollSelectorImpl)
          at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
          at org.apache.hadoop.net.SocketIOWithTimeout$SelectorPool.select(SocketIOWithTimeout.java:332)
          at org.apache.hadoop.net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:157)
          at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:155)
          at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:128)
          at java.io.FilterInputStream.read(FilterInputStream.java:116)
          at org.apache.hadoop.ipc.Client$Connection$PingInputStream.read(Client.java:304)
          at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
          at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
          - locked <0x00007f1808539178> (a java.io.BufferedInputStream)
          at java.io.DataInputStream.readInt(DataInputStream.java:370)
          at org.apache.hadoop.ipc.Client$Connection.receiveResponse(Client.java:569)
          at org.apache.hadoop.ipc.Client$Connection.run(Client.java:477) 

这是一个主人试图在 RegionServer 死后恢复租约:

"LeaseChecker" daemon prio=10 tid=0x00000000407ef800 nid=0x76cd waiting on condition [0x00007f6d0eae2000..0x00007f6d0eae2a70]
--
   java.lang.Thread.State: WAITING (on object monitor)
          at java.lang.Object.wait(Native Method)
          at java.lang.Object.wait(Object.java:485)
          at org.apache.hadoop.ipc.Client.call(Client.java:726)
          - locked <0x00007f6d1cd28f80> (a org.apache.hadoop.ipc.Client$Call)
          at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:220)
          at $Proxy1.recoverBlock(Unknown Source)
          at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.processDatanodeError(DFSClient.java:2636)
          at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.<init>(DFSClient.java:2832)
          at org.apache.hadoop.hdfs.DFSClient.append(DFSClient.java:529)
          at org.apache.hadoop.hdfs.DistributedFileSystem.append(DistributedFileSystem.java:186)
          at org.apache.hadoop.fs.FileSystem.append(FileSystem.java:530)
          at org.apache.hadoop.hbase.util.FSUtils.recoverFileLease(FSUtils.java:619)
          at org.apache.hadoop.hbase.regionserver.wal.HLog.splitLog(HLog.java:1322)
          at org.apache.hadoop.hbase.regionserver.wal.HLog.splitLog(HLog.java:1210)
          at org.apache.hadoop.hbase.master.HMaster.splitLogAfterStartup(HMaster.java:648)
          at org.apache.hadoop.hbase.master.HMaster.joinCluster(HMaster.java:572)
          at org.apache.hadoop.hbase.master.HMaster.run(HMaster.java:503) 

131.2.5。 OpenTSDB

OpenTSDB 是 Ganglia 的绝佳替代品,因为它使用 Apache HBase 存储所有时间序列而不必下采样。监控托管 OpenTSDB 的 HBase 集群是一个很好的练习。

这是一个集群的例子,这个集群几乎同时发生了数百次压缩,严重影响了 IO 性能:( TODO:插图绘制 compactionQueueSize)

使用每台机器和每个集群的所有重要图表构建仪表板是一个很好的做法,这样就可以通过一次快速查看来完成调试问题。例如,在 StumbleUpon,每个集群有一个仪表板,其中包含来自操作系统和 Apache HBase 的最重要指标。然后,您可以在机器级别下载并获得更详细的指标。

131.2.6。 clusterssh +顶

clusterssh + top,它就像一个穷人的监控系统,当你只有几台机器时,它非常有用,因为它很容易设置。启动 clusterssh 将为每台机器和另一个终端提供一个终端,在该终端中,您输入的任何内容都将在每个窗口中重新输入。这意味着您可以键入top一次,同时为所有计算机启动它,可以全面查看集群的当前状态。您还可以同时拖动所有日志,编辑文件等。