Kubernetes 性能调优
HivePlus 在 Kubernetes 上由于使用 Docker 容器而遭受性能损失。这种性能损失是我们为使用 Kubernetes 的所有好处(如更轻松的部署和更高的安全性)付出的代价。下面我们描述在 Kubernetes 上运行 HivePlus 时如何最小化性能损失。
Docker 容器的页缓存
从 Hadoop 迁移到 Kubernetes 时最显著的变化是页缓存现在是每个 Docker 容器本地的。用户应在选择 ContainerWorker Pod 的内存限制和 ContainerWorker 进程的 Java 堆大小时考虑 Docker 容器的这一特性。
在 Hadoop 的情况下,运行在同一节点上的所有 ContainerWorker 共享由操作系统管理的页缓存。因此,只要页缓存可以充分增长,Java 堆大小就可以接近分配给 ContainerWorker 进程的内存大小。例如,将配置键 hive.mr3.container.max.java.heap.fraction 在 hive-site.xml 中设置甚至为 0.9(从默认值 0.8)可能是可以的。
当 ContainerWorker 作为 Pod 在 Kubernetes 上运行时,情况就不再如此了。操作系统为每个 ContainerWorker Pod 维护页缓存,但通过消耗分配给 ContainerWorker Pod 本身的内存。 由于不同的 ContainerWorker Pod 不经常读取公共文件,我们可以认为每个 ContainerWorker Pod 管理自己的页缓存。因此,根据工作负载的特性,配置键 hive.mr3.container.max.java.heap.fraction 应调整为足够小的值,如 0.7 甚至 0.6,以确保每个 ContainerWorker Pod 有足够大的页缓存。否则,HivePlus 的性能有时会因为抖动而明显变慢。

使用 HDFS 时的位置提示
在与 HDFS 并置的 Kubernetes 集群中,HivePlus可以利用 HDFS 提供的位置提示。具体来说,当调度即将读取 HDFS 块的 mapper 时,MR3 可以检查 HDFS 提供的位置提示,并尝试将其分配给存储 HDFS 块的同一物理节点上运行的 ContainerWorker Pod。
为了利用此功能,用户应在 mr3-site.xml 中将配置键 mr3.k8s.host.aliases 设置为从主机名到 IP 地址的映射。例如,假设一个 HDFS DataNode 和一个 ContainerWorker Pod(分配了 Kubernetes 逻辑 IP 地址 10.1.1.1)在节点 foo 上运行,物理 IP 地址为 192.168.100.1。

对于存储在节点 foo 上的每个 HDFS 块,其位置提示包括主机名 foo,但不包括 IP 地址 192.168.100.1。另一方面,ContainerWorker Pod 可以从 Kubernetes 获取其物理 IP 地址 192.168.100.1,但不知道对应的主机名 foo。我们可以通过将 mr3.k8s.host.aliases 设置为 foo=192.168.100.1 来调和这种不匹配。
在内部,Kubernetes 上的 MR3 尝试将所有位置提示转换为 IP 地址。如果找不到 IP 地址,则丢弃位置提示,因为 ContainerWorker Pod 仅知道其逻辑和物理 IP 地址。为了最好地利用位置提示,在 Kubernetes 外部运行的 MR3Client(如 HiveServer2 和 Spark driver)应提供 IP 地址作为位置提示,因为在 Kubernetes 外部解析为主机名的 IP 地址在 Kubernetes 内部可能无法解析。
删除 Vertex 本地目录
默认情况下,ContainerWorker 在每个查询完成后删除中间数据。这种默认行为在 Hadoop 或独立模式下运行 HivePlus 时是可以接受的,但可能会影响 Kubernetes 上 HivePlus 的稳定性。例如,ContainerWorker Pod 可能没有足够的空间来存放写入中间数据的本地目录,尤其是在运行产生大量中间数据的查询时。由于早期 Vertex 生成的中间数据可能会停留在页缓存中而不再被访问,默认行为也可能负面影响页缓存的利用率。
为了处理此默认行为的潜在问题,MR3 允许用户在一个 Vertex 的所有消费 Vertex 完成后立即删除该 Vertex 生成的中间数据。用户可以将配置键 hive.mr3.delete.vertex.local.directory 设置为 true,既可以在 Beeline 中提交查询之前设置,也可以在 hive-site.xml 中启动 HiveServer2 之前设置。然后 HiveServer2 在内部将 MR3 配置键 mr3.am.notify.destination.vertex.complete 设置为 true,ContainerWorker 会收到每个单独 Vertex 的所有消费 Vertex 完成的通知。
需要注意的是,如果配置键 hive.mr3.delete.vertex.local.directory 设置为 true,fetch 失败可能导致 Vertex 重新运行一直级联到叶子 Vertex,如内存设置中所述。因此,用户应仅在以下情况下谨慎设置 hive.mr3.delete.vertex.local.directory 为 true:1) ContainerWorker Pod 没有足够的空间用于本地目录;2) fetch 失败很少发生。