# Kudu 故障排除

原文链接 : [http://kudu.apache.org/docs/troubleshooting.html](http://kudu.apache.org/docs/troubleshooting.html)

译文链接 : [http://cwiki.apachecn.org/pages/viewpage.action?pageId=10813626](http://cwiki.apachecn.org/pages/viewpage.action?pageId=10813626)

贡献者 : [小瑶](/display/~chenyao) [ApacheCN](/display/~apachecn) [Apache中文网](/display/~apachechina)

## 启动错误

### Errors During Hole Punching Test ( 穿透测试中的错误 )

**Kudu** 需要 **hole punching capabilities** ( 穿透能力 ) 才能有效。穿透支持取决于您的操作系统内核版本和本地文件系统实现。

*   **RHEL** 或 **CentOS 6.4** 或更高版本，修补到 **2.6.32-358** 或更高版本的内核版本。未配置的 **RHEL** 或 **CentOS 6.4** 不包括支持穿透的内核。
*   **Ubuntu 14.04** 包括 **Linux** 内核的 **3.13** 版本，它支持打孔。
*   较新版本的 **EXT4** 或 **XFS** 文件系统支持穿透，但 **EXT3** 不支持。旧版本的 **XFS** 不支持穿透返回 **EOPNOTSUPP** （操作不支持）错误。不支持穿透的 **EXT4** 或 **XFS** 的较旧版本会导致 **Kudu** 发出以下错误消息，并且无法启动：

穿透试验时出错日志块管理器需要一个具有穿透支持的文件系统，如 **ext4** 或 **xfs** 。在 **el6** 上，内核版本 **2.6.32-358** 或更新版本是必需的。不使用穿透时（以某种效率和可扩展性为代价），重新配置 **Kudu** 与 **--block_manager = file**。有关更多信息，请参阅 **Kudu** 文档细节。原始错误消息如下。

没有穿透支持，日志块管理器不安全使用。它不会删除块，并将消耗更多的磁盘空间。

即使你的环境中无法使用穿透，你仍然可以尝试 **Kudu** 。通过将 **--block_manager = file** 标志添加到用于启动主服务器和**tablet server**的命令，启用文件块管理器而不是日志块管理器。文件块管理器不会与日志块管理器一样缩放。

注意

由于文件块管理器的规模和性能不佳，只能用于小规模的评估和开发。

### NTP Clock Synchronization ( NTP 时钟同步 )

对于主服务器和平板电脑服务器守护程序，必须使用 **NTP** 同步服务器的时钟。另外，最大时钟误差（不要误估为误差）低于可配置的阈值。默认值为 **10** 秒，但可以使用标志 **--max_clock_sync_error_usec** 设置。

如果未安装 **NTP** ，或者如果时钟被报告为不同步，则 **Kudu** 将不会启动，并会发出如下消息：

```
F0924 20:24:36.336809 14550 hybrid_clock.cc:191 Couldn't get the current time: Clock unsynchronized. Status: Service unavailable: Error reading clock. Clock considered unsynchronized.
```

如果 **NTP** 安装并同步，但最大时钟错误太高，用户将看到如下消息：

```
Sep 17, 8:13:09.873 PM FATAL hybrid_clock.cc:196 Couldn't get the current time: Clock synchronized, but error: 11130000, is past the maximum allowable error: 10000000
```

或者

```
Sep 17, 8:32:31.135 PM FATAL tablet_server_main.cc:38 Check failed: _s.ok() Bad status: Service unavailable: Cannot initialize clock: Cannot initialize HybridClock. Clock synchronized but error was too high (11711000 us).
```

重要

如果已安装 **NTP** ，用户可以通过运行 **ntptime** 来监视同步状态。相关值是报告的最大误差。

要安装 **NTP** ，请对您的操作系统使用相应的命令：

| OS ( 操作系统 ) | Command ( 命令 ) |
| --- | --- |
| Debian/Ubuntu | sudo apt-get install ntp |
| RHEL/CentOS | sudo yum install ntp |

如果 **NTP** 已安装但未运行，请使用以下命令之一启动它：

| OS ( 操作系统 ) | Command ( 命令 ) |
| --- | --- |
| Debian/Ubuntu | sudo service ntp restart |
| RHEL/CentOS | sudo /etc/init.d/ntpd restart |

重要

**NTP** 需要网络连接，可能需要几分钟才能同步时钟。 在某些情况下，有点网络连接可能使 **NTP** 将时钟报告为不同步。 一个常见的，虽然临时的解决方法是使用上述命令重新启动 **NTP** 。

如果时钟被 **NTP** 报告为同步，但是最大误差太高，则用户可以通过设置上述标志来将阈值增加到更高的值。 例如，将可能的最大误差增加到 **20** 秒，标志应该如下设置：**--max_clock_sync_error_usec = 20000000**

## 报告 Kudu 崩溃

**Kudu** 在 **Kudu** 遇到崩溃时使用 **[Google Breakpad](https://chromium.googlesource.com/breakpad/breakpad/)** 库来生成 **minidump** 。这些 **minidumps** 的大小通常只有几 **MB** ，即使禁用了核心转储生成也会生成这些。在这个时候，只能在 **Kudu** 的 **Linux** 上生成 **minidumps** 。

**minidump** 文件包含有关崩溃的进程的重要调试信息，包括加载的共享库及其版本，崩溃时运行的线程列表，处理器寄存器的状态和每个线程的堆栈内存副本，以及 **CPU** 和操作系统版本信息。

也可以强制 **Kudu** 通过向 **kudu-tserver** 或 **kudu-master** 进程发送 **USR1** 信号来创建一个 **minidump** ，而不会杀死进程。例如：

```
sudo pkill -USR1 kudu-tserver
```

默认情况下，**Kudu** 将其 **minidum** 存储在其配置的名为 **minidumps** 的 **glog** 目录的子目录中。可以通过设置 **--minidump_path** 标志来定制该位置。在删除最旧的之前， **Kudu** 将只保留一定数量的 **minidumps** ，以避免用 **minidump** 文件填满磁盘。可以通过设置 **--max_minidumps gflag** 来控制将保留的最小数量。

**Minidumps** 包含特定于创建它们的二进制文件的信息，因此在不访问崩溃的确切二进制文件的情况下不可用，或者非常相似的二进制文件。

重要

**Minitump** 可以通过电子邮件发送给 **Kudu** 开发人员或附加到 **JIRA** ，以帮助 **Kudu** 开发人员调试崩溃。为了使其有用，开发人员将需要知道 **Kudu** 的确切版本和发生崩溃的操作系统。请注意，虽然 **minidump** 不包含堆内存转储，但它确实包含堆栈内存，因此可以将应用程序数据显示在**minidump** 中。如果机密或个人信息存储在群集上，请不要共享 **minidump** 文件。

## 性能故障排除

### Kudu追踪

**kudu-master** 和 **kudu-tserver** 守护进程包括基于开源 **Chromium** 跟踪框架的内置跟踪支持。您可以使用跟踪来帮助诊断延迟问题或 **Kudu** 服务器上的其他问题。

#### 访问跟踪界面

每个 **Kudu** 守护进程中，跟踪界面是通过 **Web** 浏览器访问嵌入式 **Web** 服务器的一部分。

表 1\. 跟踪界面 **URL**

| Daemon ( 守护进程 ) | URL |
| --- | --- |
| Tablet Server | [http://tablet-server-1.example.com:8050/tracing.html](http://tablet-server-1.example.com:8050/tracing.html) |
| Master | [http://master-1.example.com:8051/tracing.html](http://master-1.example.com:8051/tracing.html) |

注意

已知跟踪界面适用于最新版本的 **Google Chrome** 。其他浏览器可能无法正常工作。

#### Collecting a trace ( 收集痕迹 )

导航到跟踪界面后，单击屏幕左上角的记录按钮。当开始诊断问题时，首先选择所有类别。单击记录开始记录跟踪。

在跟踪收集期间，事件被收集到内存中的环形缓冲区中。该环形缓冲器的大小固定，最终可以达到100％。但是，在删除旧事件的同时，仍然收集新的事件。记录跟踪时，触发您有兴趣探索的行为或工作负载。

收集数秒后，单击停止。收集的踪迹将被下载并显示。使用 ？键显示有关使用跟踪界面探索跟踪的帮助文本。

#### Saving a trace ( 保存痕迹 )

您可以将收集的痕迹保存为 **JSON** 文件，以便以后分析，然后在收集跟踪后单击“保存”。要加载和分析保存的 **JSON** 文件，请单击加载并选择文件。

### RPC Timeout Traces ( RPC超时跟踪 )

如果客户端应用程序遇到 **RPC** 超时，**Kudu  tablet servers WARNING** 级别日志应包含包含 **RPC** 级别跟踪的日志条目。例如：

```
W0922 00:56:52.313848 10858 inbound_call.cc:193] Call kudu.consensus.ConsensusService.UpdateConsensus
from 192.168.1.102:43499 (request call id 3555909) took 1464ms (client timeout 1000).
W0922 00:56:52.314888 10858 inbound_call.cc:197] Trace:
0922 00:56:50.849505 (+     0us) service_pool.cc:97] Inserting onto call queue
0922 00:56:50.849527 (+    22us) service_pool.cc:158] Handling call
0922 00:56:50.849574 (+    47us) raft_consensus.cc:1008] Updating replica for 2 ops
0922 00:56:50.849628 (+    54us) raft_consensus.cc:1050] Early marking committed up to term: 8 index: 880241
0922 00:56:50.849968 (+   340us) raft_consensus.cc:1056] Triggering prepare for 2 ops
0922 00:56:50.850119 (+   151us) log.cc:420] Serialized 1555 byte log entry
0922 00:56:50.850213 (+    94us) raft_consensus.cc:1131] Marking committed up to term: 8 index: 880241
0922 00:56:50.850218 (+     5us) raft_consensus.cc:1148] Updating last received op as term: 8 index: 880243
0922 00:56:50.850219 (+     1us) raft_consensus.cc:1195] Filling consensus response to leader.
0922 00:56:50.850221 (+     2us) raft_consensus.cc:1169] Waiting on the replicates to finish logging
0922 00:56:52.313763 (+1463542us) raft_consensus.cc:1182] finished
0922 00:56:52.313764 (+     1us) raft_consensus.cc:1190] UpdateReplicas() finished
0922 00:56:52.313788 (+    24us) inbound_call.cc:114] Queueing success response
```

这些跟踪可以指示请求的哪个部分缓慢。 请将它们包含在与 **RPC** 延迟异常值相关的错误报告中。

### Kernel Stack Watchdog Traces ( 内核堆栈看门狗跟踪 )

每个 **Kudu** 服务器进程都有一个称为 **Stack Watchdog** 的后台线程，它监视服务器中的其他线程，以防它们被阻塞超过预期的时间段。 这些跟踪可以指示操作系统问题或瓶颈存储。

当看门狗线程识别线程阻塞的情况时，它会在 **WARNING** 日志中记录一个条目，如下所示：

```
W0921 23:51:54.306350 10912 kernel_stack_watchdog.cc:111] Thread 10937 stuck at /data/kudu/consensus/log.cc:505 for 537ms:
Kernel stack:
[<ffffffffa00b209d>] do_get_write_access+0x29d/0x520 [jbd2]
[<ffffffffa00b2471>] jbd2_journal_get_write_access+0x31/0x50 [jbd2]
[<ffffffffa00fe6d8>] __ext4_journal_get_write_access+0x38/0x80 [ext4]
[<ffffffffa00d9b23>] ext4_reserve_inode_write+0x73/0xa0 [ext4]
[<ffffffffa00d9b9c>] ext4_mark_inode_dirty+0x4c/0x1d0 [ext4]
[<ffffffffa00d9e90>] ext4_dirty_inode+0x40/0x60 [ext4]
[<ffffffff811ac48b>] __mark_inode_dirty+0x3b/0x160
[<ffffffff8119c742>] file_update_time+0xf2/0x170
[<ffffffff8111c1e0>] __generic_file_aio_write+0x230/0x490
[<ffffffff8111c4c8>] generic_file_aio_write+0x88/0x100
[<ffffffffa00d3fb1>] ext4_file_write+0x61/0x1e0 [ext4]
[<ffffffff81180f5b>] do_sync_readv_writev+0xfb/0x140
[<ffffffff81181ee6>] do_readv_writev+0xd6/0x1f0
[<ffffffff81182046>] vfs_writev+0x46/0x60
[<ffffffff81182102>] sys_pwritev+0xa2/0xc0
[<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

User stack:
    @       0x3a1ace10c4  (unknown)
    @          0x1262103  (unknown)
    @          0x12622d4  (unknown)
    @          0x12603df  (unknown)
    @           0x8e7bfb  (unknown)
    @           0x8f478b  (unknown)
    @           0x8f55db  (unknown)
    @          0x12a7b6f  (unknown)
    @       0x3a1b007851  (unknown)
    @       0x3a1ace894d  (unknown)
    @              (nil)  (unknown)
```

这些跟踪可用于诊断根源于延迟问题（由 **Kudu** 以下的系统引起），如磁盘控制器或文件系统。

## 使用 Kudu 的问题

### ClassNotFoundException：com.cloudera.kudu.hive.KuduStorageHandler

尝试通过 **Hive** 使用 **Kudu** 表时，用户将遇到此异常。 这不是一个丢失的 **jar** 的情况，而只是 **Impala** 将 **Hive** 中的 **Kudu** 元数据存储在其他工具（包括 **Hive** 本身和 **Spark** ）中无法读取的格式。  **Hive** 用户没有解决方法。  **Spark** 用户需要创建临时表。