找了一下開源時序數據庫,相對門檻較低的有openTSDB,還可以看源碼,InfluxDB開源了單機版,集群版是閉源的。
openTSDB 是基於Hbase的,Hbase又要安裝java
一:安裝JDK1.8 參考教程 https://www.cnblogs.com/justuntil/p/11665540.html
1. 安裝前的清理工作。如果以前安裝過,給請理干凈。
rpm -qa | grep jdk
rpm -qa | grep gcj
yum -y remove java-xxx-xxx
2. 在線下載JDK
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.rpm
添加執行權限:
命令:chmod +x jdk-8u131-linux-x64.rpm
執行rpm進行安裝
命令:rpm -ivh jdk-8u131-linux-x64.rpm
查看JDK是否安裝成功
命令:java -version
查看JDK的安裝路徑,(一般默認的路徑:/usr/java/jdk1.8.0_131)
3. 配置JDK環境變量
vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_131
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
生效:source /etc/profile
二:安裝HBase 參考https://www.cnblogs.com/h--d/p/11580398.html
HBase是一個分布式的、面向列的開源數據庫,該技術來源於 Fay Chang 所撰寫的Google論文“Bigtable:一個結構化數據的分布式存儲系統”。就像Bigtable利用了Google文件系統(File System)所提供的分布式數據存儲一樣,HBase在Hadoop之上提供了類似於Bigtable的能力。HBase是Apache的Hadoop項目的子項目。HBase不同於一般的關系數據庫,它是一個適合於非結構化數據存儲的數據庫。另一個不同的是HBase基於列的而不是基於行的模式。
官網地址:http://hbase.apache.org/
文檔地址:http://hbase.apache.org/book.html#quickstart
1.下載HBase,可以去官網下載
wget https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/2.2.4/hbase-2.2.4-bin.tar.gz
tar -xzvf hbase-2.2.4-bin.tar.gz
cd hbase-2.2.4
2. 由於HBase依賴JAVA_HOME環境變量,所以要導入Java環境變量,編輯conf/hbase-env.sh文件,並取消注釋以#export JAVA_HOME =開頭的行,然后將其設置為Java安裝路徑。
cd conf
vi hbase-env.sh
export JAVA_HOME=/usr/java/jdk1.8.0_131
3. 編輯conf/hbase-site.xml,這是主要的HBase配置文件。這時,您需要在本地文件系統上指定HBase和ZooKeeper寫入數據的目錄並確認一些風險。默認情況下,在/tmp下創建一個新目錄。許多服務器配置為在重新引導時刪除/ tmp的內容,因此您應該將數據存儲在其他位置。
vi hbase-site.xml
<!-- hbase存放數據目錄 --> <property> <name>hbase.rootdir</name> <value>file:///var/www/HBase/hbase-2.2.4/hbase</value> </property> <!-- ZooKeeper數據文件路徑 --> <property> <name>hbase.zookeeper.property.dataDir</name> <value>/var/www/HBase/hbase-2.2.4/zookeeper</value> </property> <property> <name>hbase.unsafe.stream.capability.enforce</name> <value>false</value> <description> Controls whether HBase will check for stream capabilities (hflush/hsync). Disable this if you intend to run on LocalFileSystem, denoted by a rootdir with the 'file://' scheme, but be mindful of the NOTE below. WARNING: Setting this to false blinds you to potential data loss and inconsistent system state in the event of process and/or node failures. If HBase is complaining of an inability to use hsync or hflush it's most likely not a false positive. </description> </property>
4. 啟動HBase
cd bin
啟動
start-hbase.sh
關閉
stop-hbase.sh
使用jps命令查看master是否啟動成功
為了方便也可以將hbase也加入了環境變量中,方便使用,在/etc/profile文件中,增加一下內容
vi /etc/profile
export HBASE_HOME=/var/www/HBase/hbase-2.2.4
export PATH=$HBASE_HOME/bin:$PATH
source /etc/profile
5. 瀏覽器訪問 127.0.0.1:16010/master-status,(默認端口:16010)
三:HBase的使用
1. 在bin目錄下,連接到HBase,輸入hbase shell
2. 顯示HBase Shell幫助文本。鍵入help並按Enter鍵,以顯示HBase Shell的一些基本用法信息以及一些示例命令。注意,表名,行,列都必須用引號引起來。
3. 創建一個表,使用create命令創建一個新表。您必須指定表名稱和ColumnFamily名稱。 命令:create 'test', 'cf'
4. 列出有關表的信息,使用list命令確認您的表存在 命令:list 'test'
5. 使用describe命令查看詳細信息,包括配置默認值 命令:describe 'test'
6. 將數據放入表中。要將數據放入表中,請使用put命令。命令:put 'test', 'row1', 'cf:a', 'value1'
7. 一次掃描表中的所有數據,從HBase獲取數據的一種方法是掃描。使用scan命令掃描表中的數據。您可以限制掃描范圍,但是現在,所有數據都已獲取。scan 'test'
8. 獲取單行數據。要一次獲取一行數據 命令:get 'test', 'row1'
9. 禁用表格。如果要刪除表或更改其設置,以及在某些其他情況下,則需要先使用disable
命令禁用該表。您可以使用enable
命令重新啟用它。禁用命令:disable 'test' 啟用命令:enable 'test'
10. 要刪除(刪除)表,使用drop命令 命令:drop 'test'
11. 退出HBase Shell。要退出HBase Shell並從群集斷開連接,請使用以下quit命令。HBase仍在后台運行。命令:quit 或者exit()
四:HBase的使用 https://www.cnblogs.com/yybrhr/p/11156792.html
首先創建四個表
# 這張表數據會很大,考慮到讀寫效率,我們注意到這張表就一個列族
create 'tsdb',{NAME => 't', VERSIONS => 1, BLOOMFILTER => 'ROW'}
# opentsdb中建立metric name、tagK、tagV字面量與uid一一對應的表
# opentsdb不會存儲實際的字符串字面值
# 比如system.cpu.util的metric,會將system.cpu.util轉化為id(默認自增,后面介紹部分源碼的時候會有講到)后,存入HBase
# 這張表有id、name兩個列族,可通過id找到name,也可以通過name找到id
create 'tsdb-uid',{NAME => 'id', BLOOMFILTER => 'ROW'},{NAME => 'name', BLOOMFILTER => 'ROW'}
# 下面兩張表暫時可不必太關心,先創建出來就好
create 'tsdb-tree',{NAME => 't', VERSIONS => 1, BLOOMFILTER => 'ROW'}
create 'tsdb-meta',{NAME => 'name', BLOOMFILTER => 'ROW'}
# 備份表:tsdb,本地存放路徑/opt/soft/hbase/hbase_bak/hbase_bak_1562252298
hbase org.apache.hadoop.hbase.mapreduce.Export -Dhbase.export.scanner.batch=2000 -D mapred.output.compress=true tsdb file:///opt/soft/hbase/hbase_bak/hbase_bak_1562252298
五:OpenTSDB介紹 參考:https://www.jianshu.com/p/14a6f2dbff50
安裝包下載地址:https://github.com/OpenTSDB/opentsdb/releases
再安利一下。

如圖是OpenTSDB的架構,核心組成部分就是TSD和HBase。TSD是一組無狀態的節點,可以任意的擴展,除了依賴HBase外沒有其他的依賴。
TSD對外暴露HTTP和Telnet的接口,支持數據的寫入和查詢。TSD本身的部署和運維是很簡單的,得益於它無狀態的設計,
不過HBase的運維就沒那么簡單了,這也是擴展支持BigTable和Cassandra的原因之一吧。
1. 數據模型
OpenTSDB采用按指標建模的方式,一個數據點會包含以下組成部分:
1. metric:時序數據指標的名稱,例如sys.cpu.user,stock.quote等。(類似於table表名吧)
2. timestamp:秒級或毫秒級的Unix時間戳,代表該時間點的具體時間。
3. tags:一個或多個標簽,也就是描述主體的不同的維度。Tag由TagKey和TagValue組成,TagKey就是維度,TagValue就是該維度的值。
4. value:該指標的值,目前只支持數值類型的值。
OpenTSDB底層存儲的優化思想,簡單總結就是以下這幾個關鍵的優化思路:
1. 對數據的優化:為Metric、TagKey和TagValue分配UniqueID,建立原始值與UniqueID的索引,數據表存儲Metric、TagKey和TagValue對應的UniqueID而不是原始值。
2. 對KeyValue數的優化:如果對HBase底層存儲模型十分了解的話,就知道行中的每一列在存儲時對應一個KeyValue,減少行數和列數,能極大的節省存儲空間以及提升查詢效率。
3. 對查詢的優化:利用HBase的Server Side Filter來優化多維查詢,利用Pre-aggregation和Rollup來優化GroupBy和降精度查詢。
3. UIDTable
接下來看一下OpenTSDB在HBase上的幾個關鍵的表結構的設計,首先是tsdb-uid表,結構如下:
Metric、TagKey和TagValue都會被分配一個相同的固定長度的UniqueID,默認是三個字節。tsdb-uid表使用兩個ColumnFamily,
存儲了Metric、TagKey和TagValue與UniqueID的映射和反向映射,總共是6個Map的數據。
從圖中的例子可以解讀出:
1. TagKey為'host',對應的UniqueID為'001'
2. TagValue為'static',對應的UniqueId為'001'
3. Metric為'proc.loadavg.1m',對應的UniqueID為'052'
為每一個Metric、TagKey和TagValue都分配UniqueID的好處,一是大大降低了存儲空間和傳輸數據量,每個值都只需要3個字節就可以表示,這個壓縮率是很客觀的;二是采用固定長度的字節,可以很方便的從row key中解析出所需要的值,並且能夠大大減少Java堆內的內存占用(bytes相比String能節省很多的內存占用),降低GC的壓力。
不過采用固定字節的UID編碼后,對於UID的個數是有上限要求的,3個字節最多只允許有16777216個不同的值,不過在大部分場景下都是夠用的。當然這個長度是可以調整的,不過不支持動態更改。
4. DataTable
第二張關鍵的表是數據表,結構如下:
該表中,同一個小時內的數據會存儲在同一行,行中的每一列代表一個數據點。如果是秒級精度,那一行最多會有3600個點,如果是毫秒級精度,那一行最多會有3600000個點。
這張表設計的精妙之處在於row key和qualifier(列名)的設計,以及對整行數據的compaction策略。row key格式為:
其中metric、tagk和tagv都是用uid來表示,由於uid固定字節長度的特性,所以在解析row key的時候,可以很方便的通過字節偏移來提取對應的值。Qualifier的取值為數據點的時間戳在這個小時的時間偏差,例如如果你是秒級精度數據,第30秒的數據對應的時間偏差就是30,所以列名取值就是30。列名采用時間偏差值的好處,主要在於能大大節省存儲空間,秒級精度的數據只要占用2個字節,毫秒精度的數據只要占用4個字節,而若存儲完整時間戳則要6個字節。整行數據寫入后,OpenTSDB還會采取compaction的策略,將一行內的所有列合並成一列,這樣做的主要目的是減少KeyValue數目。
5. 查詢優化
HBase僅提供簡單的查詢操作,包括單行查詢和范圍查詢。單行查詢必須提供完整的RowKey,范圍查詢必須提供RowKey的范圍,掃描獲得該范圍下的所有數據。通常來說,單行查詢的速度是很快的,而范圍查詢則是取決於掃描范圍的大小,掃描個幾千幾萬行問題不大,但是若掃描個十萬上百萬行,那讀取的延遲就會高很多。
OpenTSDB提供豐富的查詢功能,支持任意TagKey上的過濾,支持GroupBy以及降精度。TagKey的過濾屬於查詢的一部分,GroupBy和降精度屬於對查詢后的結果的計算部分。在查詢條件中,主要的參數會包括:metric名稱、tag key過濾條件以及時間范圍。
我們具體看一下OpenTSDB對查詢的優化措施:
1. Server side filter
HBase提供了豐富和可擴展的filter,filter的工作原理是在server端掃描得到數據后,先經過filter的過濾后再將結果返回給客戶端。Server side filter的優化策略無法減少掃描的數據量,但是可以大大減少傳輸的數據量。OpenTSDB會將某些條件的tag key filter轉換為底層HBase的server side filter,不過該優化帶來的效果有限,因為影響查詢最關鍵的因素還是底層范圍掃描的效率而不是傳輸的效率。
2. 減少范圍查詢內掃描的數據量
要想真正提高查詢效率,還是得從根本上減少范圍掃描的數據量。注意這里不是減小查詢的范圍,而是減少該范圍內掃描的數據量。這里用到了HBase一個很關鍵的filter,即FuzzyRowFilter,FuzzyRowFilter能夠根據指定的條件,在執行范圍掃描時,動態的跳過一定數據量。但不是所有OpenTSDB提供的查詢條件都能夠應用該優化,需要符合一定的條件,具體要符合哪些條件就不在這里說明了,有興趣的可以去了解下FuzzyRowFilter的原理。
3. 范圍查詢優化成單行查詢
這個優化相比上一條,更加的極端。優化思路非常好理解,如果我能夠知道要查詢的所有數據對應的row key,那就不需要范圍掃描了,而是單行查詢就行了。這里也不是所有OpenTSDB提供的查詢條件都能夠應用該優化,同樣需要符合一定的條件。單行查詢要求給定確定的row key,而數據表中row key的組成部分包括metric名稱、timestamp以及tags,metric名稱和timestamp是能夠確定的,如果tags也能夠確定,那我們就能拼出完整的row key。所以很簡單,如果要能夠應用此優化,你必須提供所有tag key對應的tag value才行。
以上就是OpenTSDB對HBase查詢的一些優化措施,但是除了查詢,對查詢后的數據還需要進行GroupBy和降精度。GroupBy和降精度的計算開銷也是非常可觀的,取決於查詢后的結果的數量級。對GroupBy和降精度的計算的優化,幾乎所有的時序數據庫都采用了同樣的優化措施,那就是pre-aggregation和auto-rollup。思路就是預先進行計算,而不是查詢后計算。不過OpenTSDB在已發布的最新版本中,還未支持pre-aggregation和rollup。而在開發中的2.4版本中,也只提供了半吊子的方案,它只提供了一個新的接口支持將pre-aggregation和rollup的結果進行寫入,但是對數據的pre-aggregation和rollup的計算還需要用戶自己在外層實現.
6. 總結:
OpenTSDB的優勢在於數據的寫入和存儲能力,得益於底層依賴的HBase所提供的能力。劣勢在於數據查詢和分析的能力上的不足,雖然在查詢上已經做了很多的優化,但是不是所有的查詢場景都能適用。可以說,OpenTSDB在TagValue過濾查詢優化,是這次要對比的幾個時序數據庫中,優化的最差的。在GroupBy和Downsampling的查詢上,也未提供Pre-aggregation和Auto-rollup的支持。不過在功能豐富程度上,OpenTSDB的API是支持最豐富的,這也讓OpenTSDB的API成為了一個標桿。
systemctl status/start/stop/restart opentsdb
來查看控制
[Unit] Description=OpenTSDB Service [Service] Type=forking PrivateTmp=yes ExecStart=/usr/share/opentsdb/etc/init.d/opentsdb start ExecStop=/usr/share/opentsdb/etc/init.d/opentsdb stop Restart=on-abort
systemctl status opentsdb 發現還沒啟動,dead狀態,
注意一下,默認opentsdb配置文件目錄:/etc/opentsdb/opentsdb.conf,默認opentsdb日志目錄:/var/log/opentsdb
修改配置 /etc/opentsdb/opentsdb.conf
tsd.network.port = 4242 tsd.http.staticroot = /usr/share/opentsdb/static/ tsd.http.cachedir = /tmp/opentsdb tsd.core.auto_create_metrics = true tsd.core.plugin_path = /usr/share/opentsdb/plugins # zookeeper的地址,即hbase依賴的zookeeper的地址,192.168.0.1:2181,192.168.0.2:2181,192.168.0.3:2181 tsd.storage.hbase.zk_quorum = localhost:2181 tsd.storage.fix_duplicates = true tsd.http.request.enable_chunked = true tsd.http.request.max_chunk = 4096000 tsd.storage.max_tags = 16 # 這里看到了我們上面在hbase中創建的4張表 tsd.storage.hbase.data_table = tsdb tsd.storage.hbase.uid_table = tsdb-uid tsd.storage.hbase.tree_table = tsdb-tree tsd.storage.hbase.meta_table = tsdb-meta # 下面幾個配置項到部分源碼解析的時候會有介紹,暫時可以先忽略 # tsd.query.skip_unresolved_tagvs = true # hbase.rpc.timeout = 120000
啟動opentsdb,systemctl start opentsdb
,成功的話,就可以打開opentsdb的界面了http://localhost:4242/