apache phoenix4.6配置tracing

1.前言

phoenix從4.1.0版本開始就加入了收集每個請求的traces的功能,這可以讓你看到每個重要的步驟(例如查詢操作或者插入操作)。phoenix通過利用cloudera公司的HTrace庫(HTrace是一個用java寫的用於分佈式系統的追蹤框架,源碼託管在github上)實現與Hbase追蹤工具的無縫整合,而更進一步,phoenix還把這些追蹤的指標保存到了phoenix表中(hadoop1不支持把數據寫到phoenix表)。
Tracing Web Application顧名思義是一個web應用,可以跑在jetty服務器上,主要就是將trace的數據可視化,有助於預測和分析查詢信息和系統模型,可分爲幾個功能模塊:

  1. 根據輸入的數據限制,以行列出最近的traces記錄
  2. 根據輸入trace id,以樹型拓撲的形式顯示所有屬於該trace的蹤跡  
  3. 將trace按description進行分類,以餅圖,條形圖等展示各分類比例
  4. 將trace按所在運行主機進行分類,以餅圖,條形圖等展示各分類比例
  5. 以x軸爲時間,顯示同一個trace id的trace耗時

總的來說,trace數據就一個表(9個字段,主要幾個:trace_id,parent_id,description,start_time,end_time等),trace web只是以不同角度對數據進行描述。

2.服務端配置

前提是Hbase已經與phoenix集成,即可以正常使用phoenix的基礎功能(建表,sql查詢等),然後再配置hbase服務端支持phoenix的tracing。hbase已經默認自帶了hadoop-metrics2-hbase.properties配置文件,位於conf目錄下,所以編輯所有節點的文件內容,加入以下配置: 

hbase.sink.tracing.class=org.apache.phoenix.trace.PhoenixMetricsSink
hbase.sink.tracing.writer-class=org.apache.phoenix.trace.PhoenixTableMetricsWriter
hbase.sink.tracing.context=tracing

由於本人使用的是CDH,所以在cloudera manager頁面找到hbase配置項:Hadoop 度量 2 高級配置代碼段(安全閥),並在輸入框中加入以上內容,重啓hbase集羣。

3.客戶端配置

3.1配置hadoop-metrics2-phoenix.properties文件

以sqlline爲例,配置文件位於phoenix發行包的bin目錄下,不用修改,使用默認配置即可。如果在程序中通過jdbc連接,把文件拷貝過去即可,默認的內容爲:

phoenix.sink.tracing.class=org.apache.phoenix.trace.PhoenixMetricsSink
phoenix.sink.tracing.writer-class=org.apache.phoenix.trace.PhoenixTableMetricsWriter
phoenix.sink.tracing.context=tracing

3.2配置phoenix.trace.frequency屬性值

phoenix.trace.frequency有3個可配置的值:

  1. never:默認值
  2. always:對所有請求都進行追蹤
  3. probability:以某種頻率對請求進行追蹤,搭配phoenix.trace.probability.threshold配置進行使用,默認是0.05

注意:probability值可以在進行JDBC連接時作爲一個連接屬性進行配置,示例:

# Enable tracing on every request
Properties props = new Properties();
props.setProperty("phoenix.trace.frequency", "always");
Connection conn = DriverManager.getConnection("jdbc:phoenix:localhost", props);

# Enable tracing on 50% of requests
props.setProperty("phoenix.trace.frequency", "probability");
props.setProperty("phoenix.trace.probability.threshold", 0.5)
Connection conn = DriverManager.getConnection("jdbc:phoenix:localhost", props);

也可以通過在$phoenix_home/bin/hbase-site.xml配置文件中配置phoenix.trace.frequency,但這種方式只支持兩個值:never,always:

<configuration>
  <property>
    <name>phoenix.trace.frequency</name>
    <value>always</value>
  </property>
</configuration>

4.創建trace表

本文開始時已經提及到了,trace數據將會保存在phoenix表中,默認的表爲 SYSTEM.TRACING_STATS,創建表的DDL語句爲:

CREATE TABLE SYSTEM.TRACING_STATS (
      trace_id BIGINT NOT NULL,
      parent_id BIGINT NOT NULL,
      span_id BIGINT NOT NULL,
      description VARCHAR,
      start_time BIGINT,
      end_time BIGINT,
      hostname VARCHAR,
      tags.count SMALLINT,
      annotations.count SMALLINT,
      CONSTRAINT pk PRIMARY KEY (trace_id, parent_id, span_id)
      )

如果想要修改默認表,可以修改hbase的配置,如hbase-site.xml:

<property>
    <name>phoenix.trace.statsTableName</name>
    <value>表名</value>
  </property>

5.啓動Tracing Web Application

通過命令 ./bin/traceserver.py start對web服務進行啓動,正常啓動後可以訪問http://localhost:8864。不過出現了不正常的情況,在執行命令後,查看啓動日誌以現了該錯誤:錯誤: 找不到或無法加載主類 org.apache.phoenix.tracingwebapp.http.Main.經過Google還是沒找到什麼解決方法,倒是找到了兩個比較相近的issues:

https://issues.apache.org/jira/browse/PHOENIX-2186

https://issues.apache.org/jira/browse/PHOENIX-2659

最後懶得浪費時間在上面折騰了,看了一下Phoenix源碼中的phoenix-tracing-webapp模塊,其實就4個類,其它的都是前臺頁面相關的。於是把源碼導入到eclipse裏面,修改一下相關代碼以及環境:

5.1修改phoenix連接配置

找到ConnectionFactory類,修改PHOENIX_HOST屬性(默認是localhost)以及PHOENIX_PORT屬性(默認是2181),使得指向正確集羣,以下的本人的配置:

protected static String PHOENIX_HOST = "master";
protected static int PHOENIX_PORT = 2182;

5.2加入phoenix-core-4.6.0-HBase-1.0.jar依賴包

Trace Web Application會通過jdbc的方式連接trace表獲取數據,所以要加入phoenix-core-4.6.0-HBase-1.0.jar,否則會報找不到的錯誤。

5.3修改TraceServlet類源碼

在進行5.1和5.2步驟的操作後,通過運行Main類已經可以把web服務啓動,也可以訪問到http://localhost:8864/頁面了,但是頁面死活沒有數據顯示,於是在瀏覽器F12進行調試,可以看到頁面是有向後臺發送請求並且後臺也已經正常返回數據到前臺,而報的錯誤則是一些js的錯誤,而且是解析json時出錯:

SyntaxError: Unexpected string in JSON at position 11
    at Object.parse (native)
    at fromJson (http://localhost:8864/js/lib/angular.js:1072:14)
    at defaultHttpResponseTransform (http://localhost:8864/js/lib/angular.js:8618:16)
    at http://localhost:8864/js/lib/angular.js:8703:12
    at forEach (http://localhost:8864/js/lib/angular.js:323:20)
   ........

通過觀察後臺返回的數據,發現數據根本就不是json格式的數據,使用就像這種(注意加紅字體處):[{“count”:2”,”end_time”:147520457138……,不細心看還真看不出個所以然,定位到了問題就容易解決了,經調試知道是TraceServlet類的getJson方法有問題:

protected String getJson(String json) {     #調試過程中發現json已經是標準的json字符中了
    String output = json.toString().replace("_id\":", "_id\":\"")
        .replace(",\"hostname", "\",\"hostname")
        .replace(",\"parent", "\",\"parent")
        .replace(",\"end", "\",\"end");  #想不明白爲什麼還要replace,正是因爲做了該操作才使得前臺拿到錯誤的數據
    return output;
  }

其實傳進來的json參數已經是標準的json字符串了,想不明白,這裏爲什麼要做一堆replace操作,導致了上面本來應該是2的卻變成了2”,稍微修改一下這個方法:

  protected String getJson(String json) {
    return json;   #直接返回行了
  }

並重新啓動web服務,訪問http://localhost:8864/,可以看到已經正常了:

這裏寫圖片描述

6.參考

http://phoenix.apache.org/tracing.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章