Apache Kylin的安裝和使用

官網    |     GitHub    |     文檔    |     下載

目錄


1 概覽

Apache Kylin™是一個開源的分佈式分析引擎,提供Hadoop/Spark之上的SQL查詢接口及多維分析(OLAP)能力以支持超大規模數據。它能在亞秒內查詢巨大的Hive表,並支持高併發。Apache Kylin最初由eBay Inc.開發並於2014年10月開源貢獻至開源社區,在當年11月成爲Apache孵化項目,它也是第一個由中國團隊完整貢獻到Apache的一個頂級項目。2016年3月其核心開發人員在上海創建Kyligence公司,它採用多維立方體預計算技術,可以將大數據的SQL查詢速度提升到亞秒級別。相對於之前的分鐘乃至小時級別的查詢速度,亞秒級別速度是百倍到千倍的提升,該引擎爲超大規模數據集上的交互式大數據分析打開了大門。

Apache Kylin的使命是超高速的大數據OLAP(Online Analytical Processing),也就是要讓大數據分析像使用數據庫一樣簡單迅速,用戶的查詢請求可以在秒內返回,交互式數據分析將以前所未有的速度釋放大數據裏潛藏的知識和信息,讓我們在面對未來的挑戰時佔得先機。

1.1 Kylin是什麼

  • 可擴展超快的基於大數據的OLAP引擎:Kylin是爲減少在Hadoop/Spark上百億規模數據查詢延遲而設計;
  • Hadoop ANSI SQL 接口:作爲一個OLAP引擎,Kylin爲Hadoop提供標準SQL支持大部分查詢功能;
  • 交互式查詢能力:通過Kylin,用戶可以與Hadoop數據進行亞秒級交互,在同樣的數據集上提供比Hive更好的性能;
  • 多維立方體(MOLAP Cube):用戶能夠在Kylin裏爲百億以上數據集定義數據模型並構建立方體;
  • 實時 OLAP:Kylin可以在數據產生時進行實時處理,用戶可以在秒級延遲下進行實時數據的多維分析;
  • 與BI工具無縫整合:Kylin提供與BI工具的整合能力,如Tableau,PowerBI/Excel,MSTR,QlikSense,Hue和SuperSet。

1.2 Kylin的特性

  • Job管理與監控
  • 壓縮與編碼
  • 增量更新
  • 利用HBase Coprocessor
  • 基於HyperLogLog的Dinstinc Count近似算法
  • 友好的web界面以管理,監控和使用立方體
  • 項目及表級別的訪問控制安全
  • 支持LDAP、SSO

1.3 使用 Apache Kylin 的典型場景

如果用戶有一個巨大的表 (如:超過 1 億行) 與維表進行 JOIN,而且查詢需要在儀表盤、交互式報告、BI (商務智能) 中完成,用戶併發數量爲幾十個或者幾百個,那麼 Kylin 是最好的選擇。Kylin的核心思想是利用空間換時間,將計算好的多維數據結果存入HBase,實現數據的快速查詢。同時,由於Apache Kylin在查詢方面制定了多種靈活的策略,進一步提高空間的利用率,使得這樣的平衡策略在應用中值得采用。

1.4 Kylin 支持多大的數據量表? 性能怎麼樣?

Kylin 可以支持 TB 到 PB 級數據集的亞秒級查詢。 這已經被 eBay,美團,頭條等用戶驗證過。 以美團的案例爲例(至 2018-08),973 個 Cube,每天 380 萬個查詢,原始數據 8.9 萬億,總 Cube 大小 971 TB(原始數據更大),50%查詢在 <0.5 秒內完成,90% 查詢 <1.2秒。

1.5 維度和度量

簡單來講,維度就是觀察數據的角度。比如電商的銷售數據,可以從時間的維度來觀察,也可以進一步細化,從時間和地區的維度來觀察。維度一般是一組離散的值,比如時間維度上的每一個獨立的日期,或者商品維度上的每一件獨立的商品。因此統計時可以把維度值相同的記錄聚合在一起,然後應用聚合函數做累加、平均、去重複計數等聚合計算。

度量就是被聚合的統計值,也是聚合運算的結果,它一般是連續的值,例如在電商銷售數據中的銷售額,抑或是銷售商品的總件數。通過比較和測算度量,分析師可以對數據進行評估,比如今年的銷售額相比去年有多大的增長,增長的速度是否達到預期,不同商品類別的增長比例是否合理等。

1.6 事實表和維表

事實表是用來記錄事件的,包含了每個事件的具體要素,以及具體發生的事情。維表則是對事實表中事件的要素的描述信息。

比如,事實表的一條數據中可能會包含唯一標記符(主鍵)、時間、地點、人物和事件等,也就是記錄了整個事件的信息,但是對地點和人物等只是用關鍵標識符來表示,比如一串數字、字母或者數字字母組成,而這些關鍵標記的具體含義,我們可以從維表中獲取。基於事實表和維表就可以構建出多種維度模型,包括最常見的星型模型、雪花型模型。有的公司還會使用星座模型,這個模型是由星型模型擴展而來的,爲了表示多個事實之間的關係,可以共享多個維度,這些共享維度對每個擁有它的事實表來說都具有相同的意義。

2 部署

本次安裝部署Apache Kylin 版本爲 2.6.3。Kylin的安裝方式有多種,常見的主要有如下幾種:

單實例部署方式。在Hadoop的一個節點上部署,然後啓動Kylin,這種部署方式簡單快捷,但是當併發請求比較多(QPS>50)時將會產生性能瓶頸。

Docker方式部署。這種部署時將Kylin等依賴的服務以容器的方式啓動,部署時需要環境中安裝Docker(關於Docker的安裝可以參考我的博客Spring Cloud 項目中 Docker 的使用),執行Docker命令先拉取一份鏡像,時間長短取決於網絡,當完成鏡像的下載後,執行docker命令啓動容器,它會自動啓動Hadoop、HBase、Kafka、Kylin等服務。這種方式部署比較簡單,但是對硬件有要求,保中容器可用的內存不少於8GB。

集羣方式部署。較單實例部署來說增加了Kylin的節點數,因爲Kylin的元數據存儲在HBase中,只需要在Kylin中配置讓每個節點都能訪問同一個Metadata表(kylin.metadata.url=kylin_metadata@hbase)就可以搭建一個Kylin集羣,如上圖所示,並且Kylin集羣中只有一個Kylin實例運行任務引擎(kylin.server.mode=all),其它實例都是查詢引擎(kylin.server.mode=query)模式,對於有多個查詢引擎爲了實現負載均衡,可以通過Nginx來實現,這方方式搭建稍微複雜些,還要和Nginx進行集成,但是對於一般場景下,這種方式是比較好的選擇,而且也能解決單實例的性能瓶頸問題。
Kylin集羣部署

讀寫分離的Kylin集羣。因爲Kylin的工作負載一般又有兩種,第一種是Cube計算,會產生密集的CPU和IO資源調用,第二種是在線的實時查詢計算,對Cube計算結束後進行的查詢,而且都是隻讀操作,要求相應快速、延遲低。例如我們的義務主要是在夜間執行Cube的計算,而白天上班時間進行查詢分析,就比較適合使用第三種方式。

Staging和Production多環境的部署。這是一種更高級的部署方式,在做開發時,由於生產環境比較重要,一般都是先在測試環境測試,通過後沒有問題了再部署到生產環境,那麼在開發測試時,可以部署到Staging(Production生產環境的一個鏡像,可以理解爲一個測試環境),沒有問題了之後纔會發佈到Production生產環境,這樣可以避免不當的設計導致對生產環境的破壞,Kylin提供了一個工具,幾分鐘就可以將一個Cube從Staging環境遷移到Production環境。

下面我們主要演示Kylin的使用,因此我們的部署採用第一種方式部署。

2.1 軟件要求

  • Hadoop: 2.7+, 3.1+ (since v2.5)
  • Hive: 0.13 - 1.2.1+
  • HBase: 1.1+, 2.0 (since v2.5)
  • Spark (可選) 2.3.0+
  • Kafka (可選) 1.0.0+ (since v2.5)
  • JDK: 1.8+ (since v2.5)
  • OS: Linux only, CentOS 6.5+ or Ubuntu 16.0.4+

這裏我們的環境裏已經安裝了 JDK 1.8、CentOS 7、Hadoop 3.1.2、Hive 3.1.1、Zookeeper 3.4.14、HBase 2.2.1,對於安裝 Kylin 2.6.3 版本這些硬件要求基本都滿足。如果沒有安裝的可以自行安裝這些服務。

Kylin 依賴於 Hadoop 集羣處理大量的數據集。您需要準備一個配置好 HDFS,YARN,MapReduce,,Hive, HBase,Zookeeper 和其他服務的 Hadoop 集羣供 Kylin 運行。Kylin 可以在 Hadoop 集羣的任意節點上啓動。方便起見,您可以在 master 節點上運行 Kylin。但爲了更好的穩定性,我們建議您將 Kylin 部署在一個乾淨的 Hadoop client 節點上,該節點上 Hive,HBase,HDFS 等命令行已安裝好且 client 配置(如 core-site.xml,hive-site.xml,hbase-site.xml及其他)也已經合理的配置且其可以自動和其它節點同步。運行 Kylin 的 Linux 賬戶要有訪問 Hadoop 集羣的權限,包括創建/寫入 HDFS 文件夾,Hive 表, HBase 表和提交 MapReduce 任務的權限。
安裝架構圖

2.2 硬件要求

在正式生產環境運行 Kylin 的服務器的最低配置爲 4 core CPU,16 GB 內存和 100 GB 磁盤。 對於高負載的場景,建議使用 24 core CPU,64 GB 內存或更高的配置。

2.3 下載並解壓

 # 1 下載。可以訪問 https://kylin.apache.org/download/ 下載適合您版本的二級制文件
# 例如因爲前面換進中Hadoop 爲3.1.2 ,所以這裏下載基於Hadoop 3 的二進制包
wget http://mirrors.tuna.tsinghua.edu.cn/apache/kylin/apache-kylin-2.6.3/apache-kylin-2.6.3-bin-hadoop3.tar.gz -P /opt/

# 2 解壓
tar -zxf /opt/apache-kylin-2.6.3-bin-hadoop3.tar.gz -C /opt
cd /opt/apache-kylin-2.6.3-bin-hadoop3

# 3 查看目錄。如果沒有可以使用這個命令安裝:yum -y install tree
# 目錄的詳細說明如下:
#  bin: shell 腳本,用於啓動/停止 Kylin,備份/恢復 Kylin 元數據,以及一些檢查端口、獲取 Hive/HBase 依賴的方法等;
#  conf: Hadoop 任務的 XML 配置文件,這些文件的作用可參考配置頁面
#  lib: 供外面應用使用的 jar 文件,例如 Hadoop 任務 jar, JDBC 驅動, HBase coprocessor 等.
#  meta_backups: 執行 bin/metastore.sh backup 後的默認的備份目錄;
#  sample_cube 用於創建樣例 Cube 和表的文件。
#  tomcat: 自帶的 tomcat,用於啓動 Kylin 服務。
#  tool: 用於執行一些命令行的jar文件。
tree -L 1
 .
 ├── bin
 ├── commit_SHA1 (文件)
 ├── conf
 ├── lib
 ├── LICENSE   (文件)
 ├── NOTICE    (文件)
 ├── README.md (文件)
 ├── sample_cube
 ├── tomcat
 └── tool

2.4 環境變量和 Spark

配置Kylin環境變量 vim /etc/profile,添加如下

export KYLIN_HOME=/opt/apache-kylin-2.6.3-bin-hadoop3

從 v2.6.1 開始,Kylin 不再包含 Spark 二進制包; 我們需要另外下載 Spark,然後設置SPARK_HOME系統變量(一定要設置)到 Spark 安裝目錄:

 # 下載Spark
wget http://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-2.3.4/spark-2.3.4-bin-hadoop2.7.tgz

# 解壓
tar -zxvf spark-2.3.4-bin-hadoop2.7.tgz -C $KYLIN_HOME

# 重命名spark文件
mv $KYLIN_HOME/spark-2.3.4-bin-hadoop2.7 $KYLIN_HOME/spark

# Remove unused components in Spark
rm -rf $KYLIN_HOME/spark/lib/spark-examples-*
rm -rf $KYLIN_HOME/spark/examples
rm -rf $KYLIN_HOME/spark/data
rm -rf $KYLIN_HOME/spark/R

也可以執行Kylin自帶的腳本,這種方式會下載Spark 2.3.2、 Hadoop的版本是Hadoop 2.7,如果網絡有限制或者版本有要求,不推薦用這種方式的。

# 執行腳本下載 spark-2.3.2-bin-hadoop2.7.tgz
# 
# 這種方式會將Spark下載到 /tmp/spark_package
# 會自動訪問  http://archive.apache.org/dist/spark/spark-2.3.2/spark-2.3.2-bin-hadoop2.7.tgz
$KYLIN_HOME/bin/download-spark.sh

2.5 檢查運行環境

Kylin 運行在 Hadoop 集羣上,對各個組件的版本、訪問權限及 CLASSPATH 等都有一定的要求,爲了避免遇到各種環境問題,我們可以運行Kylin自帶的腳本來進行環境檢測,如果我們的環境存在任何的問題,腳本將打印出詳細報錯信息。如果沒有報錯信息,代表我們的環境適合 Kylin 運行。

# 檢查運行環境
$KYLIN_HOME/bin/check-env.sh

# 檢查Kylin依賴的 HBase 是否完整
$KYLIN_HOME/bin/find-hbase-dependency.sh

# 檢查Kylin依賴的 Hive 是否完整
$KYLIN_HOME/bin/find-hive-dependency.sh

2.6 配置Kylin參數

Kylin 會自動從環境中讀取 Hadoop 配置(core-site.xml),Hive 配置(hive-site.xml)和 HBase 配置(hbase-site.xml),另外Kylin 的配置文件在 $KYLIN_HOME/conf/ 目錄下,配置文件的目錄結構如下

[root@cdh1 conf]# tree -L 1
 .
 ├── kylin_hive_conf.xml               # 該文件包含了 Hive 任務的配置項
 ├── kylin_job_conf_inmem.xml          # 該文件包含了 MapReduce 任務的配置項。當執行 In-mem Cubing 任務時,需要在改文件中爲 mapper 申請更多的內存
 ├── kylin_job_conf.xml                # 該文件包含了 MapReduce 任務的配置項。
 ├── kylin-kafka-consumer.xml          # 該文件包含了 Kafka 任務的配置項。
 ├── kylin.properties                  # 該文件是 Kylin 使用的全局配置文件。
 ├── kylin-server-log4j.properties     # 該文件包含了 Kylin 服務器的日誌配置項。
 ├── kylin-spark-log4j.properties
 ├── kylin-tools-log4j.properties      # 該文件包含了 Kylin 命令行的日誌配置項。
 └── setenv.sh # 該文件是用於設置環境變量的 shell 腳本,可以通過 KYLIN_JVM_SETTINGS 調整 Kylin JVM 棧的大小,且可以設置 KAFKA_HOME 等其他環境變量。

Kylin的配置文件主要是 kylin.properties,重要的配置如下,其它配置可以查看官方的配置文檔。

# 同一個Metadata表。默認HBase表爲kylin_metadata。主要用來保存元數據
kylin.metadata.url=kylin_metadata@hbase
# 指定 Kylin 服務所用的 HDFS 路徑,默認值爲 /kylin
kylin.env.hdfs-working-dir=/kylin
# 指定 Kylin 部署的用途,參數值可選 DEV。可選參數:DEV、QA、PROD
#  DEV will turn on some dev features, QA and PROD has no difference in terms of functions.
#  在 DEV 模式下一些開發者功能將被啓用
kylin.env=DEV
# 指定 Kylin 服務所用的 ZooKeeper 路徑,默認值爲 /kylin
kylin.env.zookeeper-base-path=/kylin
# 指定 Kylin 實例的運行模式,參數值可選 all, job, query,默認值爲 all
#   job 模式代表該服務僅用於任務調度,不用於查詢;
#   query 模式代表該服務僅用於查詢,不用於構建任務的調度;
#   all 模式代表該服務同時用於任務調度和 SQL 查詢。
#  all表示既可以運行job引擎,又可以運行query引擎。在一個Kylin引擎下只能運行一個Job引擎
kylin.server.mode=all
# 指定集羣名稱
kylin.server.cluster-name=my-kylin
# List of web servers in use, this enables one web server instance to sync up with other servers.
kylin.server.cluster-servers=cdh1:7070
# 指定 Kylin 的 REST 服務所使用的時區,默認值爲 GMT+8,(默認東八區,?)
kylin.web.timezone=GMT+8
# 是否支持跨域訪問,默認值爲 TRUE
kylin.web.cross-domain-enabled=true
# 是否啓用 Dashboard,默認值爲 FALSE
kylin.web.dashboard-enabled=true

#### JOB ###
# 作業失敗時最大嘗試的次數,默認爲0,不進行嘗試
kylin.job.retry=3
# 作業的最大並行度,默認爲10
kylin.job.max-concurrent-jobs=10

### 郵件通知設置
## If true, will send email notification on job complete
##kylin.job.notification-enabled=true
##kylin.job.notification-mail-enable-starttls=true
##kylin.job.notification-mail-host=smtp.office365.com
##kylin.job.notification-mail-port=587
##[email protected]
##kylin.job.notification-mail-password=mypassword
##[email protected]

#### ENGINE ###
# reduce階段默認輸入的大小,默認爲500MB
kylin.engine.mr.reduce-input-mb=500

#### SOURCE ###
# Kylin作業工程中產生的中間表存放在Hive的庫名,默認在 default
kylin.source.hive.database-for-flat-table=default
# Hive client類型, valid value [cli, beeline]
#  如果系統支持持beeline,可以修改爲beeline
kylin.source.hive.client=cli
# Parameters for beeline client, only necessary if hive client is beeline
# 當使用beeline時需要配置此參數
#kylin.source.hive.beeline-params=-n root --hiveconf hive.security.authorization.sqlstd.confwhitelist.append='mapreduce.job.*|dfs.*' -u jdbc:hive2://localhost:10000


#### STORAGE ###
# The storage for final cube file in hbase
kylin.storage.url=hbase
# htable表的壓縮編解碼方式 , valid value [none, snappy, lzo, gzip, lz4]
kylin.storage.hbase.compression-codec=none
# HBase的region切分大小,默認爲5GB
kylin.storage.hbase.region-cut-gb=5
# HBase表的底層存儲的HFile大小,越小的HFile,導致轉換HFile的MR就會有更多的reduces,並且處理的速度更快
# 如果設置爲0,則取消這個優化策略。默認爲2GB
kylin.storage.hbase.hfile-size-gb=2

2.7 啓動和停止Kylin

# 啓動
$KYLIN_HOME/bin/kylin.sh start

# 關閉
$KYLIN_HOME/bin/kylin.sh stop

# 查看Kylin後臺進程
ps -ef | grep kylin

啓動成功後控制檯會打印如下信息,此時我們可以看到Kylin的Web UI信息。

Retrieving hadoop conf dir...
KYLIN_HOME is set to /opt/apache-kylin-2.6.3-bin-hadoop3
Retrieving hive dependency...
Retrieving hbase dependency...
Retrieving hadoop conf dir...
Retrieving kafka dependency...
Retrieving Spark dependency...
Start to check whether we need to migrate acl tables
Retrieving hive dependency...
Retrieving hbase dependency...
Retrieving hadoop conf dir...
Retrieving kafka dependency...
Retrieving Spark dependency...
……

A new Kylin instance is started by root. To stop it, run 'kylin.sh stop'
Check the log at /opt/apache-kylin-2.6.3-bin-hadoop3/logs/kylin.log
Web UI is at http://node1:7070/kylin

2.8 報錯問題解決

初次安裝可能會出現一些問題,不要慌張,通過查看日誌信息可以找到對應的解決方法,這裏列出來常見的幾個錯誤的解決,有些錯誤也是筆者踩過的巨坑,希望大家不要走了彎路。

錯誤1:如果啓動時報無法通過指定的URL找到Kylin在HBase的元信息表:

Exception in thread "main" java.lang.IllegalArgumentException: Failed to find metadata store by url: kylin_metadata@hbase
	at org.apache.kylin.common.persistence.ResourceStore.createResourceStore(ResourceStore.java:99)
	at org.apache.kylin.common.persistence.ResourceStore.getStore(ResourceStore.java:111)
	at org.apache.kylin.rest.service.AclTableMigrationTool.checkIfNeedMigrate(AclTableMigrationTool.java:99)
	at org.apache.kylin.tool.AclTableMigrationCLI.main(AclTableMigrationCLI.java:43)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.apache.kylin.common.persistence.ResourceStore.createResourceStore(ResourceStore.java:92)
	... 3 more

這種問題是因爲HBase或者ZooKeeper或者HDFS上的元信息沒有徹底刪除或者權限不夠,導致信息初始化不完整,因此可以先保證Kylin配置文件中關於HDFS上的路徑有相應的權限,如果HBase有初始化的表,進入HBase shell 刪除對應的表,最後進入ZooKeeper的Cli將Kylin和HBase的ZNode節點信息刪除,再重啓Kylin進行元信息的初始化,必要時可能還需要重啓系統:

# 進入 zkCli.sh ,對znode進行操作
[root@cdh1 logs]# zkCli.sh

# 刪除如下信息
[zk: localhost:2181(CONNECTED) 1] rmr /kylin/kylin_metadata
[zk: localhost:2181(CONNECTED) 2] rmr /hbase/table/kylin_metadata

錯誤2:啓動時成功的,但至當我們訪問http://:7070/kylin時發現無法訪問,因此查看日誌cat $KYLIN_HOME/logs/kylin.out,發現如下錯誤。這個錯誤情況比較複雜,如果Web UI可能正常訪問,此問題可以不用管,因爲我們沒有設置https訪問。但是如果WebUI不能訪問,需要我們解決了。

Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
	at org.apache.catalina.connector.Connector.initInternal(Connector.java:995)
	at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
	... 18 more
Caused by: java.lang.IllegalArgumentException: /opt/apache-kylin-2.6.3-bin-hadoop3/tomcat/conf/.keystore (沒有那個文件或目錄)
	at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:115)
	at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:86)
	at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:244)
	at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1087)
	at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:265)
	at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:581)
	at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:68)
	at org.apache.catalina.connector.Connector.initInternal(Connector.java:993)
	... 19 more

從日誌中可以看到端口初始化失敗,緊接着是 /opt/apache-kylin-2.6.3-bin-hadoop3/tomcat/conf/ 沒有.keystore ,因此我們首先排查報錯的那個路徑是否有對應的寫權限,查看這個目錄的權限,賦予權限後重啓。

# 1 進入到 conf 目錄下
[root@node1 conf]# cd /opt/apache-kylin-2.6.3-bin-hadoop3/tomcat/conf/

# 1.1 查看信息,發現這個目錄下的文件下權限不夠,因此賦予權限
[root@node1 conf]# ll
總用量 252
drwxr-xr-x 3 root root     23 10月  6 03:16 Catalina
-rw-r--r-- 1 root root  13548 6月  27 19:25 catalina.policy
-rw-r--r-- 1 root root   7746 6月  27 19:25 catalina.properties
-rw-r--r-- 1 root root   7746 6月  27 19:25 catalina.properties.bak
-rw-r--r-- 1 root root   1534 6月  27 19:25 context.xml
-rw-r--r-- 1 root root   1338 6月  27 19:25 context.xml.bak
-rw-r--r-- 1 root root   1149 6月  27 19:25 jaspic-providers.xml
-rw-r--r-- 1 root root   2313 6月  27 19:25 jaspic-providers.xsd
-rw-r--r-- 1 root root   3622 6月  27 19:25 logging.properties
-rw-r--r-- 1 root root   7157 6月  27 19:25 server.xml
-rw-r--r-- 1 root root   7511 6月  27 19:25 server.xml.bak
-rw-r--r-- 1 root root   7157 6月  27 19:25 server.xml.init
-rw-r--r-- 1 root root   2164 6月  27 19:25 tomcat-users.xml
-rw-r--r-- 1 root root   2633 6月  27 19:25 tomcat-users.xsd
-rw-r--r-- 1 root root 169322 6月  27 19:25 web.xml

[root@cdh1 conf]# cd ..
# 1.2 conf先的文件權限賦爲 755
[root@cdh1 tomcat]# chmod 755 -R ./conf

重啓後再次訪問Web UI看是否可能正常訪問,如果還是無法正常訪問,可以修改Kylin自帶的Tomcat的配置文件,將https相關的配置註釋掉。

# 2 去掉Kylin自帶的Tomcat配置文件中的htts
vim $KYLIN_HOME/tomcat/conf/server.xml

# 2.1 搜做https並將其註釋掉
<!--<Connector port="7443" protocol="org.apache.coyote.http11.Http11Protocol"
                   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
                   keystoreFile="conf/.keystore" keystorePass="changeit"
                   clientAuth="false" sslProtocol="TLS" />-->

# 2.2 再次重啓

錯誤3:這個錯誤隱藏的比較深,也是比較常見的錯誤,因爲在啓動的時候,我們可以從啓動控制檯打印的日誌裏看到並沒有加載Hive的lib下的依賴,但是當我們執行關於Hive操作時(例如Job執行時、數據導入時等)就會在Web UI頁面提示因爲某個類導致了失敗,此時我們查看Kylin的日誌cat $KYLIN_HOME/logs/kylin.out,會發下如下的錯誤,網上也有一些解決方法(在系統環境變量添加export hive_dependency=$HIVE_HOME/conf:$HIVE_HOME/lib/*:$HCAT_HOME/share/hcatalog/hive-hcatalog-core-3.1.1.jar,然後修改Kylin啓動腳本,還有將Hive的lib下的jar全部拷貝到Kylin的lin下的),但是都會產生一些問題,我這裏發現這樣做後Kylin的元數據信息表無法初始化。

java.lang.NoClassDefFoundError: org/apache/hadoop/hive/conf/HiveConf
	at org.apache.kylin.source.hive.HiveClientFactory.getHiveClient(HiveClientFactory.java:27)
	at org.apache.kylin.source.hive.RedistributeFlatHiveTableStep.computeRowCount(RedistributeFlatHiveTableStep.java:40)
	at org.apache.kylin.source.hive.RedistributeFlatHiveTableStep.doWork(RedistributeFlatHiveTableStep.java:91)
	at org.apache.kylin.job.execution.AbstractExecutable.execute(AbstractExecutable.java:167)
	at org.apache.kylin.job.execution.DefaultChainedExecutable.doWork(DefaultChainedExecutable.java:71)
	at org.apache.kylin.job.execution.AbstractExecutable.execute(AbstractExecutable.java:167)
	at org.apache.kylin.job.impl.threadpool.DefaultScheduler$JobRunner.run(DefaultScheduler.java:114)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1309)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1137)
	... 10 more

然後我們還是仔細看下Kylin啓動時打印的環境變量信息,可以發現其實它是會將Kylin的lib文件夾下的依賴jar添加進來的,因此我們根據提示的錯誤信息,找到這個缺少的類的jar包,然後將這個jar包軟連接到Kylin的lib,重啓啓動Kylin問題就可以完美解決。這裏筆者也是經過多次排查,需要完整引入如下的五個Hive的依賴jar。

# 將hive-common-3.1.1.jar軟連接到Kylin的lib下。org/apache/hadoop/hive/conf/HiveConf所在的包
ln -s $HIVE_HOME/lib/hive-common-3.1.1.jar $KYLIN_HOME/lib/hive-common-3.1.1.jar
ln -s $HIVE_HOME/lib/hive-exec-3.1.1.jar $KYLIN_HOME/lib/hive-exec-3.1.1.jar
ln -s $HIVE_HOME/lib/hive-hcatalog-core-3.1.1.jar $KYLIN_HOME/lib/hive-hcatalog-core-3.1.1.jar
ln -s $HIVE_HOME/lib/hive-standalone-metastore-3.1.1.jar $KYLIN_HOME/lib/hive-standalone-metastore-3.1.1.jar
ln -s $HIVE_HOME/lib/libfb303-0.9.3.jar $KYLIN_HOME/lib/libfb303-0.9.3.jar

##########
# 一個創建軟連接的腳本
##!/bin/bash
#cd $HIVE_HOME/lib
#for a in *.jar;do
#ln -s $HIVE_HOME/lib/$a $KYLIN_HOME/lib/$a 
#done
##########

################
# 網上提供解決方法
#1 在系統環境配置文件中添加 hive_dependency
#vim /etc/profile
# 添加如下
#export hive_dependency=$HIVE_HOME/conf:$HIVE_HOME/lib/*:$HCAT_HOME/share/hcatalog/hive-hcatalog-core-3.1.1.jar
#2 生效
#source /etc/profile
# 在Kylin啓動腳本添加上這個參數,大概在地52行,添加如下代碼
#3vim $KYLIN_HOME/bin/kylin.sh

#43     #retrive $KYLIN_EXTRA_START_OPTS
#44     if [ -f "${dir}/setenv.sh" ]; then
#45         echo "WARNING: ${dir}/setenv.sh is deprecated and ignored, please remove it and use ${KYLIN_HOME}/conf/setenv.sh instead"
#46         source ${dir}/setenv.sh
#47     fi
#48 
#49     if [ -f "${KYLIN_HOME}/conf/setenv.sh" ]; then
#50         source ${KYLIN_HOME}/conf/setenv.sh
#51     fi
#52     export HBASE_CLASSPATH_PREFIX=$CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/tomcat-juli.jar:$CATALINA_HOME/lib/*:$hive_dependency:$HBASE_CLASSPATH_PREFIX
#53     export HBASE_CLASSPATH_PREFIX=${KYLIN_HOME}/conf:${KYLIN_HOME}/lib/*:${KYLIN_HOME}/ext/*:${HBASE_CLASSPATH_PREFIX}
#54     export HBASE_CLASSPATH=${HBASE_CLASSPATH}:${hive_dependency}:${kafka_dependency}:${spark_dependency}
#55 
#56     verbose "HBASE_CLASSPATH: ${HBASE_CLASSPATH}"
#57 }
################

#重啓Kylin
$KYLIN_HOME/bin/kylin.sh stop
$KYLIN_HOME/bin/kylin.sh start

2.9 啓動後的HDFS目錄結構

Kylin 會在 HDFS 上生成文件,根目錄是 /kylin/, 然後會使用 Kylin 集羣的元數據表名作爲第二層目錄名,默認爲 kylin_metadata (可以在conf/kylin.properties中定製)。

通常/kylin/kylin_metadata目錄下會有這麼幾種子目錄:cardinality, coprocessor, kylin-job_id, resources, jdbc-resources

  • cardinality: Kylin 加載 Hive 表時,會啓動一個 MR 任務來計算各個列的基數,輸出結果會暫存在此目錄。此目錄可以安全清除。
  • coprocessor:Kylin 用於存放 HBase coprocessor jar 的目錄,請勿刪除。
  • kylin-job_id: Cube 計算過程的數據存儲目錄,請勿刪除。 如需要清理,請遵循 storage cleanup guide
  • resources:Kylin 默認會將元數據存放在 HBase,但對於太大的文件(如字典或快照),會轉存到 HDFS 的該目錄下,請勿刪除。如需要清理,請遵循 cleanup resources from metadata
  • jdbc-resources:性質同上,只在使用 MySQL 做元數據存儲時候出現。

3 使用

Kylin 啓動後我們可以通過瀏覽器 http://:7070/kylin 進行訪問。其中 <hostname>爲具體的機器名、IP 地址或域名,默認端口爲 7070
kylin login
輸入初始用的戶名ADMIN和其對應的密碼爲KYLIN。我們就進入了Kylin的花花世界了,下面我們的需要沉迷在這裏一段時間。
Kylin Web UI - Home
接下來我們通過一個案例來看先Kylin具體的使用流程。在我們安裝的Kylin目錄下自帶了一份用於測試的樣例數據,這份數據包含了幾張表的數據,大小爲 1.49 MB,文件名的格式爲庫名.表名,其中事實表爲KYLIN_SALES,維表爲KYLIN_CAL_DTKYLIN_CATEGORY_GROUPINGS,另外兩張表我們暫時先不用管。

#查看樣例數據的數據量
[root@node1 conf]# wc -l $KYLIN_HOME/sample_cube/data/*
  10000 /opt/apache-kylin-2.6.3-bin-hadoop3/sample_cube/data/DEFAULT.KYLIN_ACCOUNT.csv
    731 /opt/apache-kylin-2.6.3-bin-hadoop3/sample_cube/data/DEFAULT.KYLIN_CAL_DT.csv
    144 /opt/apache-kylin-2.6.3-bin-hadoop3/sample_cube/data/DEFAULT.KYLIN_CATEGORY_GROUPINGS.csv
    244 /opt/apache-kylin-2.6.3-bin-hadoop3/sample_cube/data/DEFAULT.KYLIN_COUNTRY.csv
   9999 /opt/apache-kylin-2.6.3-bin-hadoop3/sample_cube/data/DEFAULT.KYLIN_SALES.csv
  21118 總用量

KYLIN_SALES 表時一個事實表,其保存了銷售訂單的明細信息,每一行對應着一筆交易訂單。CATEGORY_GROUPINGS 是一個維表,其保存了商品分類的詳細介紹。KYLIN_CAL_DT 也是一個維表,表中保存了時間的擴展信息。

3.1 準備數據

我們執行 ${KYLIN_HOME}/bin/sample.sh腳本,這個腳本主要做的事情有:①在Hive中創建前面提到的幾張表並將數據導入,其創建時執行的腳本爲$KYLIN_HOME/sample_cube/create_sample_tables.sql,這個腳本中主要是建表語句和加載數據;②上傳Sample Cube的metadata,樣例Cube的元數據位於$KYLIN_HOME/sample_cube/template下,每個目錄都代表元數據的一部分,而且目錄下面都是json格式的文件。當這腳本執行完畢後,會在控制檯提示Restart Kylin Server or click Web UI => System Tab => Reload Metadata to take effect,重啓服務或者在Web UI頁面重新加載元數據(意思就是重啓Kylin不是必須的操作),我們這裏選擇通過Web UI加載元數據,如下圖,按照提示點在Web UI,擊System,然後點擊頁面右邊的Actions下面的第一個選線Reload Metadata
在這裏插入圖片描述
在彈出的提示框中選擇Yes即可,後面提示我們加載元數據成功。
在這裏插入圖片描述
我們點擊頁頭的Model,可以看到我們剛纔導入的kylin_sales_cube。最左面的選項欄Models顯示的我們的模式設計,這裏定義了事實表和維度的關聯方式、維度、度量等內容。傍邊的Data Source的數據源,支持從Hive中加載數據表,以及使用Streaming Table。最右邊的Cubes 就是根據Models來設計的所有Cube列表,我們可以選擇一個Cube進行Drop、Delete、Build、Refresh等操作。
在這裏插入圖片描述

3.2 構建Cube

選在頁頭的 -- Choose Project --,選擇learn_Kylin,在Cubes頁面單擊Cube名稱爲kylin_sales_cube欄右側的Actions下拉框並選擇Build操作。
在這裏插入圖片描述
會有如下的彈出窗口。選擇Build Cube的時間範圍(這個Cube是增量更新的),我們可以看到開始時間已經給我們設置好了(2012-01-01 00:00:00),這是因爲在我們創建Cube過程中設置Refresh的分區開始時間已經設置好了,這個時間也是Hive表kylin_sales中字段part_dt最小的時間,我們選擇一年的數據,因此結束日期選擇2013-01-01 00:00:00(不包含這一天)。

0: jdbc:hive2://localhost:10000> SELECT MIN(part_dt) min_part_dt,MAX(part_dt) max_part_dt FROM kylin_sales;
+--------------+--------------+
| min_part_dt  | max_part_dt  |
+--------------+--------------+
| 2012-01-01   | 2014-01-01   |
+--------------+--------------+

在這裏插入圖片描述
接下來單擊接下來我們單擊Submit提交,提交後會在右下角提示Success。成功之後,我們可以從Monitor頁面的所有Job中找到新建的Job,如下圖所示。Job欄包含了Job Name、Cube、Process等內容,而且還包含了Actions相關操作。
在這裏插入圖片描述
單擊Job最右邊的箭頭符號,查看Job的詳細執行流程。Job詳細信息爲跟蹤一個Job提供了它的每一步記錄,也可以查看每一步的執行日誌 。我們可以將光標放在某個步驟狀態圖標上查看基本狀態和信息。
在這裏插入圖片描述
從上面我們可以看到Job還在執行,我們在這個時間可以看下Hive和Hadoop方面都有哪些變化。

Hive方面的變化
在Cube構建過程中(構建的過程時間會有點長),我們可以查看Hive表的變化,直接在默認的庫下執行即可(kylin.source.hive.database-for-flat-table=default),我們可以發現有一個表名很長的表,其實這個就是Intermediate Flat Table有人稱之爲平面表。

0: jdbc:hive2://localhost:10000> SHOW tables;
+----------------------------------------------------+
|                      tab_name                      |
+----------------------------------------------------+
| kylin_account                                      |
| kylin_cal_dt                                       |
| kylin_category_groupings                           |
| kylin_country                                      |
| kylin_intermediate_kylin_sales_cube_411503f7_131e_7d0f_7008_b170f894b330 |
| kylin_sales                                        |
+----------------------------------------------------+
7 rows selected (0.171 seconds)

查看日誌信息可以看到如下執行的SQL語句。從這個SQL中可以看到創建了一個名字很長的中間臨時表,其內容大概爲事實表和維度表的關聯輸後輸出維度和度量指標,以及根據我們增量構建Cube時指定的開始和結束時間來裁剪數據範圍。

Create and distribute table, cmd: 
hive -e "USE default;

DROP TABLE IF EXISTS kylin_intermediate_kylin_sales_cube_c2245d04_6204_d762_1458_8af95480fe3c;
CREATE EXTERNAL TABLE IF NOT EXISTS kylin_intermediate_kylin_sales_cube_c2245d04_6204_d762_1458_8af95480fe3c
(
`KYLIN_SALES_TRANS_ID` bigint
,`KYLIN_SALES_PART_DT` date
,`KYLIN_SALES_LEAF_CATEG_ID` bigint
,`KYLIN_SALES_LSTG_SITE_ID` int
,`KYLIN_CATEGORY_GROUPINGS_META_CATEG_NAME` string
,`KYLIN_CATEGORY_GROUPINGS_CATEG_LVL2_NAME` string
,`KYLIN_CATEGORY_GROUPINGS_CATEG_LVL3_NAME` string
,`KYLIN_SALES_LSTG_FORMAT_NAME` string
,`KYLIN_SALES_SELLER_ID` bigint
,`KYLIN_SALES_BUYER_ID` bigint
,`BUYER_ACCOUNT_ACCOUNT_BUYER_LEVEL` int
,`SELLER_ACCOUNT_ACCOUNT_SELLER_LEVEL` int
,`BUYER_ACCOUNT_ACCOUNT_COUNTRY` string
,`SELLER_ACCOUNT_ACCOUNT_COUNTRY` string
,`BUYER_COUNTRY_NAME` string
,`SELLER_COUNTRY_NAME` string
,`KYLIN_SALES_OPS_USER_ID` string
,`KYLIN_SALES_OPS_REGION` string
,`KYLIN_SALES_PRICE` decimal(19,4)
)
STORED AS SEQUENCEFILE
LOCATION 'hdfs://node1:8020/kylin/kylin_metadata/kylin-3cc3cb92-73a6-4742-2979-63651c60ddde/kylin_intermediate_kylin_sales_cube_c2245d04_6204_d762_1458_8af95480fe3c';
-- 'auto.purge'='true' 表示數據刪除後不會放到回收♻️箱,而是直接刪除
ALTER TABLE kylin_intermediate_kylin_sales_cube_c2245d04_6204_d762_1458_8af95480fe3c SET TBLPROPERTIES('auto.purge'='true');
INSERT OVERWRITE TABLE `kylin_intermediate_kylin_sales_cube_c2245d04_6204_d762_1458_8af95480fe3c` SELECT
`KYLIN_SALES`.`TRANS_ID` as `KYLIN_SALES_TRANS_ID`
,`KYLIN_SALES`.`PART_DT` as `KYLIN_SALES_PART_DT`
,`KYLIN_SALES`.`LEAF_CATEG_ID` as `KYLIN_SALES_LEAF_CATEG_ID`
,`KYLIN_SALES`.`LSTG_SITE_ID` as `KYLIN_SALES_LSTG_SITE_ID`
,`KYLIN_CATEGORY_GROUPINGS`.`META_CATEG_NAME` as `KYLIN_CATEGORY_GROUPINGS_META_CATEG_NAME`
,`KYLIN_CATEGORY_GROUPINGS`.`CATEG_LVL2_NAME` as `KYLIN_CATEGORY_GROUPINGS_CATEG_LVL2_NAME`
,`KYLIN_CATEGORY_GROUPINGS`.`CATEG_LVL3_NAME` as `KYLIN_CATEGORY_GROUPINGS_CATEG_LVL3_NAME`
,`KYLIN_SALES`.`LSTG_FORMAT_NAME` as `KYLIN_SALES_LSTG_FORMAT_NAME`
,`KYLIN_SALES`.`SELLER_ID` as `KYLIN_SALES_SELLER_ID`
,`KYLIN_SALES`.`BUYER_ID` as `KYLIN_SALES_BUYER_ID`
,`BUYER_ACCOUNT`.`ACCOUNT_BUYER_LEVEL` as `BUYER_ACCOUNT_ACCOUNT_BUYER_LEVEL`
,`SELLER_ACCOUNT`.`ACCOUNT_SELLER_LEVEL` as `SELLER_ACCOUNT_ACCOUNT_SELLER_LEVEL`
,`BUYER_ACCOUNT`.`ACCOUNT_COUNTRY` as `BUYER_ACCOUNT_ACCOUNT_COUNTRY`
,`SELLER_ACCOUNT`.`ACCOUNT_COUNTRY` as `SELLER_ACCOUNT_ACCOUNT_COUNTRY`
,`BUYER_COUNTRY`.`NAME` as `BUYER_COUNTRY_NAME`
,`SELLER_COUNTRY`.`NAME` as `SELLER_COUNTRY_NAME`
,`KYLIN_SALES`.`OPS_USER_ID` as `KYLIN_SALES_OPS_USER_ID`
,`KYLIN_SALES`.`OPS_REGION` as `KYLIN_SALES_OPS_REGION`
,`KYLIN_SALES`.`PRICE` as `KYLIN_SALES_PRICE`
 FROM `DEFAULT`.`KYLIN_SALES` as `KYLIN_SALES`
INNER JOIN `DEFAULT`.`KYLIN_CAL_DT` as `KYLIN_CAL_DT`
ON `KYLIN_SALES`.`PART_DT` = `KYLIN_CAL_DT`.`CAL_DT`
INNER JOIN `DEFAULT`.`KYLIN_CATEGORY_GROUPINGS` as `KYLIN_CATEGORY_GROUPINGS`
ON `KYLIN_SALES`.`LEAF_CATEG_ID` = `KYLIN_CATEGORY_GROUPINGS`.`LEAF_CATEG_ID` AND `KYLIN_SALES`.`LSTG_SITE_ID` = `KYLIN_CATEGORY_GROUPINGS`.`SITE_ID`
INNER JOIN `DEFAULT`.`KYLIN_ACCOUNT` as `BUYER_ACCOUNT`
ON `KYLIN_SALES`.`BUYER_ID` = `BUYER_ACCOUNT`.`ACCOUNT_ID`
INNER JOIN `DEFAULT`.`KYLIN_ACCOUNT` as `SELLER_ACCOUNT`
ON `KYLIN_SALES`.`SELLER_ID` = `SELLER_ACCOUNT`.`ACCOUNT_ID`
INNER JOIN `DEFAULT`.`KYLIN_COUNTRY` as `BUYER_COUNTRY`
ON `BUYER_ACCOUNT`.`ACCOUNT_COUNTRY` = `BUYER_COUNTRY`.`COUNTRY`
INNER JOIN `DEFAULT`.`KYLIN_COUNTRY` as `SELLER_COUNTRY`
ON `SELLER_ACCOUNT`.`ACCOUNT_COUNTRY` = `SELLER_COUNTRY`.`COUNTRY`
WHERE 1=1 AND (`KYLIN_SALES`.`PART_DT` >= '2012-01-01' AND `KYLIN_SALES`.`PART_DT` < '2013-01-01')
;

Hadoop方面的變化
默認情況下這個服務是沒有啓動的,因此我們查看Hadoop發生的一些變化信息需要先將Hadoop的jobhistory服務開啓,Hadoop的版本不同開啓這個服務的命令也不同,如果是CDH平臺的,選擇安裝jobhistory組件後默認開啓了這個服務,如果是原生Apache版本,可以執行如下命令開啓Hadoop 3.1.2 的 historyserver ,然後我們就可以看到提交的構建Cube作業的執行信息,同樣這個也可以對後續的問題進行快速定位。

# 啓動 jobhistory。訪問 http://node1:19888/jobhistory
#$HADOOP_HOME/bin/mapred historyserver >/dev/null 2>&1 &
$HADOOP_HOME/sbin/mr-jobhistory-daemon.sh start historyserver
WARNING: Use of this script to start the MR JobHistory daemon is deprecated.
WARNING: Attempting to execute replacement "mapred --daemon start" instead.

啓動之後訪問這個頁面,可以看到Kylin構建Cube中執行的MapReduce作業。
在這裏插入圖片描述
如果想放棄這個Job,單擊Job選項的Actions下拉框中的Discard按鈕。Job成功執行完畢後如下圖所示:
在這裏插入圖片描述

3.3 對構建好的Cube進行查詢

切換到 Kylin 的 Insight 頁面,這個頁面提供了交互式的SQL查詢。將下面的sql寫入到New Query中,然後點擊右下角的Submit提交SQL查詢,如下圖所示。

SELECT PART_DT,SUM(PRICE) AS total_selled, COUNT(DISTINCT SELLER_ID) AS sellers 
FROM KYLIN_SALES GROUP BY PART_DT ORDER BY PART_DT;

在這裏插入圖片描述
很快執行就成功了,在頁面下面可以看到0.33秒就返回了結果,結果如下圖所示。
在這裏插入圖片描述
爲了感受這個速度,和結果的準確性,我們同樣可以在Hive裏執行以下,查看下結果和執行的速度,兩個對比一下。

-- 1 查看錶默認庫下的表。可以看到前面表名很長的表已經不在了
+---------------------------+
|         tab_name          |
+---------------------------+
| kylin_account             |
| kylin_cal_dt              |
| kylin_category_groupings  |
| kylin_country             |
| kylin_sales               |
| person                    |
+---------------------------+
6 rows selected (3.409 seconds)

-- 2 執行同樣的 SQL 
--    這裏只展示結果表前面一部分的數據。從執行的結果可以看到,Hive執行的結果和Kylin執行的結果一模一樣。
--    但是從執行速度上看,Hive用了65秒鐘執行完畢,Kylin只用了0.33秒就查詢到了結果。
--    所有從這裏可以看到Kylin經過Cube構建,經過預計算後的查詢速度非常快。
0: jdbc:hive2://localhost:10000> SELECT PART_DT,SUM(PRICE) AS total_selled, COUNT(DISTINCT SELLER_ID) AS sellers 
. . . . . . . . . . . . . . . .> FROM KYLIN_SALES GROUP BY PART_DT ORDER BY PART_DT;
+-------------+---------------+----------+
|   part_dt   | total_selled  | sellers  |
+-------------+---------------+----------+
| 2012-01-01  | 466.9037      | 12       |
| 2012-01-02  | 970.2347      | 17       |
| 2012-01-03  | 917.4138      | 14       |
| 2012-01-04  | 553.0541      | 10       |
| 2012-01-05  | 732.9007      | 18       |
| 2012-01-06  | 296.3882      | 9        |
| 2012-01-07  | 1184.1870     | 23       |
| 2012-01-08  | 541.7355      | 14       |
|    ……       | ……            | ……       |
+-------------+---------------+----------+
731 rows selected (65.254 seconds)

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