日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

得物基于StarRocks的OLAP需求實(shí)踐詳解_數(shù)據(jù)庫其它

作者:得物技術(shù) ? 更新時間: 2022-11-21 編程語言

1. 什么是 StarRocks

  • 新一代極速全場景MPP數(shù)據(jù)庫,可以用 StarRocks 來支持多種數(shù)據(jù)分析場景的極速分析;
  • 架構(gòu)簡潔,采用了全面向量化引擎,并配備全新設(shè)計(jì)的 CBO 優(yōu)化器,查詢速度(尤其是多表關(guān)聯(lián)查詢);
  • 很好地支持實(shí)時數(shù)據(jù)分析,并能實(shí)現(xiàn)對實(shí)時更新數(shù)據(jù)的高效查詢, 還支持現(xiàn)代化物化視圖,以進(jìn)一步加速查詢;
  • 用戶可以靈活構(gòu)建包括大寬表、星型模型、雪花模型在內(nèi)的各類模型;
  • 兼容 MySQL 協(xié)議,支持標(biāo)準(zhǔn) SQL 語法,易于對接使用,全系統(tǒng)無外部依賴,高可用,易于運(yùn)維管理。

2.?系統(tǒng)架構(gòu)

核心進(jìn)程:FE(Frontend)、BE(Backend)。

注:所有節(jié)點(diǎn)都是有狀態(tài)的。

FE(Frontend)負(fù)責(zé)管理元數(shù)據(jù),管理客戶端連接,進(jìn)行查詢規(guī)劃、查詢調(diào)度等工作。

?- ? Leader:Follower會通過類Paxos的BDBJE協(xié)議選主出一個Leader,所有事務(wù)的提交都是由Leader發(fā)起,并完成;

?- ? Follower:提高查詢并發(fā),同時參與投票,參與選主操作。

Follower

Observer:不參與選主操作,只會異步同步并且回放日志,主要用于擴(kuò)展集群的查詢并發(fā)能力。

BE(Backend)負(fù)責(zé)數(shù)據(jù)存儲以及SQL執(zhí)行等工作。

3.?存儲架構(gòu)

在StarRocks里,一張表的數(shù)據(jù)會被拆分成多個Tablet,而每個Tablet都會以多副本的形式存儲在BE節(jié)點(diǎn)中,如下圖:

Table數(shù)據(jù)劃分 + Tablet三副本的數(shù)據(jù)分布:

StarRocks支持Hash分布、Range-Hash的組合數(shù)據(jù)分布(推薦)。

為了等到更高的性能,強(qiáng)烈建議使用Range-Hash的組合數(shù)據(jù)分布,即先分區(qū)后分桶的方式。

  • Range分區(qū)可動態(tài)添加和刪減;
  • Hash分桶一旦確定,不能再進(jìn)行調(diào)整,只有未創(chuàng)建的分區(qū)才能設(shè)置新的分桶數(shù)。

分區(qū)和分桶的選擇是非常關(guān)鍵的。在建表時選擇好的分區(qū)分桶列,可以有效提高集群整體性能。

以下是針對特殊應(yīng)用場景下,對分區(qū)和分桶選擇的一些建議:

  • 數(shù)據(jù)傾斜:業(yè)務(wù)方如果確定數(shù)據(jù)有很大程度的傾斜,那么建議采用多列組合的方式進(jìn)行數(shù)據(jù)分桶,而不是只單獨(dú)采用傾斜度大的列做分桶。
  • 高并發(fā):分區(qū)和分桶應(yīng)該盡量覆蓋查詢語句所帶的條件,這樣可以有效減少掃描數(shù)據(jù),提高并發(fā)。
  • 高吞吐:盡量把數(shù)據(jù)打散,讓集群以更高的并發(fā)掃描數(shù)據(jù),完成相應(yīng)計(jì)算。

3.1 表的存儲

對表進(jìn)行存儲時,會對表進(jìn)行分區(qū)和分桶兩層處理,將表的數(shù)據(jù)分散到多臺機(jī)器進(jìn)行存儲和管理。

分區(qū)機(jī)制:高效過濾,提升查詢性能。

  • 分區(qū)類似分表,是對一個表按照分區(qū)鍵進(jìn)行分割,可以按照時間分區(qū),根據(jù)數(shù)據(jù)量按照天/月/年劃分等等。可以利用分區(qū)裁剪對少數(shù)訪問量,也可以根據(jù)數(shù)據(jù)的冷熱程度把數(shù)據(jù)分到不同介質(zhì)上。

分桶機(jī)制:充分發(fā)揮集群性能,避免熱點(diǎn)問題。

  • 使用分桶鍵Hash以后,把數(shù)據(jù)均勻的分布到所有的BE上,不要出現(xiàn)bucket數(shù)據(jù)傾斜的情況,分桶鍵的選擇原則就是高基數(shù)的列或者多個列組合成為一個高基數(shù)的列,盡量將數(shù)據(jù)充分打散。
  • 注:Bucket數(shù)量的需要適中,如果希望充分發(fā)揮性能可以設(shè)置為:BE數(shù)量 * CPU core/2,最好tablet控制在1GB左右,tablet太少并行度可能不夠,太多可能遠(yuǎn)數(shù)據(jù)過多,底層scan并發(fā)太多性能下降。

Tablet:最小的數(shù)據(jù)邏輯單元,可以靈活設(shè)置并行計(jì)算資源。

  • 一張表被切分成了多個Tablet,StarRocks在執(zhí)行SQL語句時,可以對所有Tablet實(shí)現(xiàn)并發(fā)處理,從而充分的利用多機(jī)、多核提供的計(jì)算能力。
  • 表在創(chuàng)建的時候可以指定副本數(shù),多副本夠保證數(shù)據(jù)存儲的高可靠,以及服務(wù)的高可用。

Rowset:每一次的數(shù)據(jù)變更就會產(chǎn)生一個Rowset。

  • 就是以組列存方式組織的的一些文件,每次的commit都會產(chǎn)生一個新的版本,每個版本包含哪些Rowset。
  • 每次寫入都會增加一個版本(無論是單條、還是stream load幾個G的文件)。

Segment:如果一個Rowset數(shù)據(jù)量比較大,則拆分成多個Segment數(shù)據(jù)斷落盤。

4.?需求背景

案例一:

  • 業(yè)務(wù)背景

指標(biāo)工廠服務(wù)主要面向業(yè)務(wù)人員,通過對業(yè)務(wù)指標(biāo)的采集和處理,實(shí)時反映產(chǎn)品狀態(tài),為運(yùn)營提供數(shù)據(jù)支撐、檢測產(chǎn)品漏洞或服務(wù)異常、提供指標(biāo)異常告警功能等。

  • 業(yè)務(wù)場景分析

業(yè)務(wù)指標(biāo)埋點(diǎn)方式多樣,并不局限于某種方式,只要符合埋點(diǎn)標(biāo)識明確、業(yè)務(wù)參數(shù)豐富、數(shù)據(jù)滿足可解析的基本要求皆可作為數(shù)據(jù)源,大致可以分為:SDK、MySQL BinLog、業(yè)務(wù)日志、阿里云ODPS數(shù)據(jù)分析。

存在的挑戰(zhàn),各種業(yè)務(wù)場景眾口難調(diào),歸納數(shù)據(jù)特征如下:

  • 需要全量日志明細(xì);
  • 需要數(shù)據(jù)可以始終是最新的,即滿足實(shí)時更新場景;
  • 需要對數(shù)據(jù)做層級聚合的,即可能是月、周、日、小時等;
  • 需要可以承載更大的寫入量;
  • 每個業(yè)務(wù)數(shù)據(jù)都要靈活的配置數(shù)據(jù)的保存時間;
  • 數(shù)據(jù)源來源多,報(bào)表定制化比較高,有多個數(shù)據(jù)源合并成一個大寬表的場景、也有多表連接的的需求;
  • 各種監(jiān)控圖、報(bào)表展示、業(yè)務(wù)實(shí)時查詢等,即較高的并非查詢。

引入StarRocks

幸運(yùn)的是StarRocks有比較豐富的數(shù)據(jù)模型,覆蓋了上面的所有業(yè)務(wù)場景的需求,即:明細(xì)模型、更新模型、聚合模型、主鍵模型,同時選擇更為靈活的星型模型代替大寬表的方式,即直接使用多表關(guān)聯(lián)來查詢。

  • 明細(xì)模型:
  • 埋點(diǎn)數(shù)據(jù)經(jīng)過結(jié)構(gòu)化處理后按明細(xì)全量存儲;
  • 該場景對DB在億級數(shù)據(jù)量下查詢性能有較高的要求;
  • 數(shù)據(jù)可以通過配置動態(tài)分區(qū)來配置過期策略;
  • 場景使用時從結(jié)構(gòu)化數(shù)據(jù)選擇個別字段維度在線聚合查詢。
  • 聚合模型:
  • 埋點(diǎn)數(shù)據(jù)數(shù)據(jù)量巨大,且對明細(xì)數(shù)據(jù)不要求溯源,直接做聚合計(jì)算,比如計(jì)算PV、UV場景;
  • 數(shù)據(jù)可以通過配置動態(tài)分區(qū)來配置過期策略。
  • 更新模型:
  • 埋點(diǎn)數(shù)據(jù)狀態(tài)會發(fā)生變動,且需要實(shí)時更新數(shù)據(jù),更新數(shù)據(jù)范圍不會跨度多個分區(qū)的,比如:訂單、優(yōu)惠券狀態(tài)等;
  • 數(shù)據(jù)可以通過配置動態(tài)分區(qū)來配置過期策略。

基于以上業(yè)務(wù)場景的分析,這三種模型可以完美解決數(shù)據(jù)的問題。

需要實(shí)時的數(shù)據(jù)寫入場景,我也沿用了業(yè)內(nèi)流行的解決方案,即數(shù)據(jù)采集到 Kafka 之后,使用Flink做實(shí)時寫入到StarRocks。StarRocks提供了非常好用的Flink-connector插件。

小tips:

1.?雖然StarRocks已經(jīng)很好的優(yōu)化了寫入性能,當(dāng)寫入壓力大,仍會出現(xiàn)寫入拒絕,建議可適當(dāng)增大單次導(dǎo)入數(shù)據(jù)量,降低頻率,但同時也會導(dǎo)致數(shù)據(jù)落庫延遲增加。所以需要做好一定的取舍,做到收益最大化。?

2.?Flink的sink端不建議配置過大,會引起并發(fā)事務(wù)過多的報(bào)錯,建議每個flink任務(wù)source可以配置多些,sink的連接數(shù)不能過大。

小結(jié)

集群規(guī)模:5FE(8c32GB)、5BE(32c128GB)

目前該方案已支持?jǐn)?shù)百個業(yè)務(wù)指標(biāo)的接入,涉及幾十個大盤的指標(biāo)展示和告警,數(shù)據(jù)存儲TB級,每日凈增長上百G,總體運(yùn)行穩(wěn)定。

案例二:

  • 業(yè)務(wù)背景

內(nèi)部系統(tǒng)業(yè)務(wù)看板,主要服務(wù)于全公司員工,提供項(xiàng)目及任務(wù)跟蹤等功能。

  • 業(yè)務(wù)場景分析

分析業(yè)務(wù)特點(diǎn):

  • 數(shù)據(jù)變更頻繁(更新),變更時間跨度長
  • 查詢時間跨度多
  • 報(bào)表需準(zhǔn)實(shí)時更新
  • 關(guān)聯(lián)維表查詢多,部門/業(yè)務(wù)線/資源域等
  • 冷熱數(shù)據(jù),最近數(shù)據(jù)查詢頻繁
  • 歷史架構(gòu)與痛點(diǎn)

當(dāng)初數(shù)據(jù)庫選型時,結(jié)合業(yè)務(wù)特點(diǎn),用戶需要動態(tài)、靈活的增刪記錄自己的任務(wù),因而選擇了JOSN 模型減少了應(yīng)用程序代碼和存儲層之間的阻抗,選擇MongoDB作為數(shù)據(jù)存儲。

伴隨著公司快速快發(fā),當(dāng)需要報(bào)表展示,特別是時間跨度比較大,涉及到多部門、多維度、細(xì)粒度等報(bào)表展示時,查詢時間在MongoDB需要執(zhí)行10s甚至更久。

  • 引入StarRocks

調(diào)研了StarRocks、ClickHouse兩款都是非常優(yōu)秀的分析型數(shù)據(jù)庫,在選型時,分析了業(yè)務(wù)應(yīng)用場景,主要集中在單表聚合查詢、多表關(guān)聯(lián)查詢、實(shí)時更新讀寫查詢。維度表更新頻繁,即存儲在MySQL中,StarRocks比較好的支持外表關(guān)聯(lián)查詢,很大程度上降低了開發(fā)難度,最終決定選用StarRocks作為存儲引擎。

改造階段,將原先MongoDB中的一個集合拆分成3張表。使用明細(xì)模型,記錄每天的對應(yīng)人員的任務(wù)信息,按天分區(qū),由之前的每人每天一條記錄改為,以事件為單位,每人每天可以多條記錄。
實(shí)現(xiàn)頻繁更新的維表,則選擇使用外部表,減少維度數(shù)據(jù)同步到StarRocks的復(fù)雜度。

小結(jié)

改造前,MongoDB查詢,寫法復(fù)雜,多次查詢。

db.time_note_new.aggregate(
    [
       {'$unwind': '$depart'},
       {'$match': {
           'depart': {'$in': ['部門id']},
           'workday': {'$gte': 1609430400, '$lt': 1646064000},
           'content.id': {'$in': ['事項(xiàng)id']}, 
           'vacate_state': {'$in': [0, 1]}}
       }, 
       {'$group': { 
           '_id': '$depart', 
           'write_hour': {'$sum': '$write_hour'}, 
           'code_count': {'$sum': '$code_count'}, 
           'all_hour': {'$sum': '$all_hour'}, 
           'count_day_user': {'$sum': {'$cond': [{'$eq': ['$vacate_state', 0]}, 1, 0]}}, 
           'vacate_hour': {'$sum': {'$cond': [{'$eq': ['$vacate_state', 0]}, '$all_hour', 0]}}, 
           'vacate_write_hour': {'$sum': {'$cond': [{'$eq': ['$vacate_state', 0]}, '$write_hour', 0]}}}
           -- ... more field
       }, 
       {'$project': {
           '_id': 1, 
           'write_hour': {'$cond': [{'$eq': ['$count_day_user', 0]}, 0, {'$divide': ['$vacate_write_hour', '$count_day_user']}]}, 
           'count_day_user': 1, 
           'vacate_hour': 1, 
           'vacate_write_hour': 1, 
           'code_count': {'$cond': [{'$eq': ['$count_day_user', 0]}, 0, {'$divide': ['$code_count', '$count_day_user']}]}, 
           'all_hour': {'$cond': [{'$eq': ['$count_day_user', 0]}, 0, {'$divide': ['$vacate_hour', '$count_day_user']}]}}
           -- ... more field
       }
    ]
)

改造后,直接兼容SQL,單次聚合。

WITH cont_time as (
    SELECT b.depart_id, a.user_id, a.workday, a.content_id, a.vacate_state
        min(a.content_second)/3600 AS content_hour,
        min(a.write_second)/3600 AS write_hour,
        min(a.all_second)/3600 AS all_hour
    FROM time_note_report AS a
    JOIN user_department AS b ON a.user_id = b.user_id
    -- 更多維表關(guān)聯(lián)
    WHERE b.depart_id IN (?)  AND a.content_id IN (?) 
      AND a.workday >= '2021-01-01' AND a.workday < '2022-03-31' 
      AND a.vacate_state IN (0, 1)
    GROUP BY b.depart_id, a.user_id, a.workday, a.content_id,a.vacate_state
)
SELECT M.*, N.*
FROM ( 
    SELECT t.depart_id,
         SUM(IF(t.content_id = 14, t.content_hour, 0))   AS content_hour_14,
         SUM(IF(t.content_id = 46, t.content_hour, 0))   AS content_hour_46,
         -- ...more
    FROM cont_time t
    GROUP BY t.depart_id
) M
JOIN ( 
    SELECT depart_id                                  AS join_depart_id,
      SUM(write_hour)                                 AS write_hour,
      SUM(all_hour)                                   AS all_hour
      -- 更多指標(biāo)
    FROM cont_time
    GROUP BY depart_id
) N ON M.depart_id = N.join_depart_id
ORDER BY depart_id ASC

以查詢報(bào)表2021/01/01~2022/03/01之間數(shù)據(jù)對比:

  • StarRocks: 1次查詢聚合,可完全通過復(fù)雜SQL聚合函數(shù)計(jì)算,耗時 295ms
  • Mongodb: 需分2次查詢+計(jì)算,共耗時3s+9s=12s

5. 經(jīng)驗(yàn)分享

在使用StarRocks時遇到的一些報(bào)錯和解決方案(網(wǎng)上資料較少的報(bào)錯信息):

a.數(shù)據(jù)導(dǎo)入Stream Load報(bào)錯:“current running txns on db 13003 is 100, larger than limit 100”

原因:超過了每個數(shù)據(jù)庫中正在運(yùn)行的導(dǎo)入作業(yè)的最大個數(shù),默認(rèn)值為100。可以通過調(diào)整max_running_txn_num_per_db參數(shù)來增加每次導(dǎo)入作業(yè)的個數(shù),最好是通過調(diào)整作業(yè)提交批次。即攢批,減少并發(fā)。

b. FE報(bào)錯:“java.io.FileNotFoundException: /proc/net/snmp (Too many open files)”

原因:文件句柄不足,這里需要注意,如果是supervisor管理進(jìn)程,則需要將文件句柄的配置加到fe的啟動腳本中。

if [[ $(ulimit -n) -lt 60000 ]]; then
  ulimit -n 65535
fi

c. StarRocks 支持使用 Java 語言編寫用戶定義函數(shù) UDF,在執(zhí)行函數(shù)報(bào)錯:“rpc failed, host: x.x.x.x”,be.out日志中報(bào)錯:

start time: Tue Aug 9 19:05:14 CST 2022
Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/Object

原因:在使用supervisor管理進(jìn)程,需要注意增加JAVA_HOME環(huán)境變量,即使是BE節(jié)點(diǎn)也是需要調(diào)用Java的一些函數(shù),也可以直接將BE啟動腳本增加JAVA_HOME環(huán)境變量配置。\

d. 執(zhí)行Delete操作報(bào)錯如下:

SQL > delete from tableName partition (p20220809,p20220810) where `c_time` > '2022-08-09 15:20:00' and `c_time` < '2022-08-10 15:20:00';
ERROR 1064 (HY000): Where clause only supports compound predicate, binary predicate, is_null predicate and in predicate

原因:目前delete后的where條件不支持between and操作,目前只支持 =、>、>=、<、<=、!=、IN、NOT IN

e. 使用Routine Load消費(fèi)kakfa數(shù)據(jù)的時候產(chǎn)生了大量隨機(jī)group_id

建議:建routine load的時候指定一下group name。

f. StarRocks連接超時,查詢語句報(bào)錯:“ERROR 1064(HY000):there is no scanNode Backend”,當(dāng)重新啟動BE節(jié)點(diǎn)后,短暫的恢復(fù)。日志報(bào)錯如下:

kafka log-4-FAIL, event: [thrd:x.x.x.x:9092/bootstrap]: x.x.x.x:9092/1: ApiVersionRequest failed: Local: Timed out: probably due to broker version < 0.10 (see api.version.request configuration) (after 10009ms in state APIVERSION_QUERY)

原因:當(dāng)Routine Load連接kafka有問題時,會導(dǎo)致BrpcWorker線程耗盡,影響正常訪問連接StarRocks。臨時解決方案是找到問題任務(wù),暫停任務(wù),即可恢復(fù)。

6. 未來規(guī)劃

接下來我們會有更多業(yè)務(wù)接入 StarRocks,替換原有 OLAP 查詢引擎;運(yùn)用更多的業(yè)務(wù)場景,積累經(jīng)驗(yàn),提高集群穩(wěn)定性。未來希望 StarRocks 優(yōu)化提升主鍵模型內(nèi)存占用,支持更靈活的部分列更新方式,持續(xù)優(yōu)化提升 Bitmap 查詢性能,同時優(yōu)化多租戶資源隔離。今后我們也會繼續(xù)積極參與 StarRocks 的社區(qū)討論,反饋業(yè)務(wù)場景。

原文鏈接:https://juejin.cn/post/7148632950844850212

欄目分類
最近更新