通过zookeeper连接时如何确定选择了哪个Apache Drill钻头?

How to determine which Apache Drill drillbit was selected when connecting via zookeeper?

我正在使用 zookeeper 连接字符串来连接到 drill 集群。我想记录我成功连接到哪个 drillbit(主机名或 IP 地址),但我在 java.sql.Connection class 上找不到任何 属性 或方法来获取此信息。

我试过 connection.getMetaData.getURL,但那只是 returns 我用来获取连接的 zookeeper 连接字符串(下面的 scala 代码):

import java.sql._
Class.forName("com.mapr.drill.jdbc41.Driver")
val con = DriverManager.getConnection("jdbc:drill:zk=<server1>:5181,<server2>:5181/drill/<cluster_name>...")
con.getMetaData().getURL()  // returns "jdbc:drill:zk=<server1>..."
val st  = con.createStatement()
val res = st.executeQuery("select *,'findme' from sys.drillbits")
while(res.next()) { println(res.getString(1)) }

如果我在 findme 的所有 drillbit 服务器上 grep drillbit_queries.json 日志,我可以找到哪个 drillbit 用于执行查询。为了跟踪连接问题,我希望能够从应用程序中记录正在使用的钻头,而不是必须 grep 日志文件。

不要忘记,您可以在 drill 邮件列表或 slack 频道上直接向 Apache Drill 社区提出这些问题。有关详细信息,请参阅 https://drill.apache.org/community-resources/

具体到您的问题,请查看系统 tables (https://drill.apache.org/docs/querying-system-tables/)。尤其是 sys.profiles_json table,它似乎可以为您提供所需的信息。

如果您可以在 Drill 的 Web 界面中看到您需要的信息,那么您也可以在系统 table 中找到该信息,这通常是一个非常安全的赌注。通常,快速浏览文档并进行一些尝试性查询将为您提供所需的信息。由于 Web 界面是开源的,您还可以研究源代码以了解 Web 界面如何为您提供相关信息。

特别是,此查询大致给出了您的要求:

with t1 as (
    select convert_from(x.json, 'JSON') js from sys.profiles_json x
)
select t1.js.queryId id, t1.js.foreman.address foreman, t1.js.query query
from t1
limit 3

我真的找到了我要找的东西: https://github.com/apache/drill/blob/master/exec/java-exec/src/main/java/org/apache/drill/exec/client/DrillClient.java#L462

private void connect(DrillbitEndpoint endpoint) throws RpcException {
   client.connect(endpoint, properties, getUserCredentials());
   logger.info("Foreman drillbit is {}", endpoint.getAddress());
}

所以现在问题变成了(假设 MapR Drill JDBC 驱动程序是相似的),我们的应用程序可以访问那个 DrillbitEndpoint 对象吗?

在 UserClient 代码中(DillClient 是 UserClient 的包装器)我看到了 https://github.com/apache/drill/blob/master/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserClient.java#L109

DrillbitEndpoint endpoint;

是私有实例变量,我没有看到任何 public 方法来公开它。所以我认为我们的应用程序无法访问它。

Ted 建议使用 Java 反射或 and/or Drill 的未来拉取请求来公开此字段。


如果您不介意再次查询,https://drill.apache.org/docs/troubleshooting/#identify-the-foreman 有答案:

SELECT hostname FROM sys.drillbits WHERE `current` = true;

这将 return 为您的会话连接到的钻头(即工头)的主机名。