乾貨 | 每天十億級資料更新,秒出查詢結果,ClickHouse在攜程酒店的應用

大資料頻道發表於2019-07-05

本文轉自 | 攜程技術中心  作者 | 蔡嶽毅

作者簡介

蔡嶽毅,攜程酒店大資料高階研發經理,負責酒店資料智慧平臺研發,大資料技術創新工作。喜歡探索研究大資料的開源技術框架。

一、背景


1)攜程酒店每天有上千表,累計十多億資料更新,如何保證資料更新過程中生產應用高可用;

2)每天有將近百萬次資料查詢請求,使用者可以從粗粒度國家省份城市彙總不斷下鑽到酒店,房型粒度的資料,我們往往無法對海量的明細資料做進一步層次的預聚合,大量的關鍵業務資料都是好幾億資料關聯許可權,關聯基礎資訊,根據使用者場景獲取不同維度的彙總資料;

3)為了讓使用者無論在app端還是pc端查詢資料提供秒出的效果,我們需要不斷的探索,研究找到最合適的技術框架。

對此,我們嘗試過關係型資料庫,但千萬級表關聯資料庫基本上不太可能做到秒出,考慮過Sharding,但資料量大,各種成本都很高。熱資料儲存到ElasticSearch,但無法跨索引關聯,導致不得不做寬表,因為許可權,酒店資訊會變,所以每次要刷全量資料,不適用於大表更新,維護成本也很高。Redis鍵值對儲存無法做到實時彙總,也測試過Presto,GreenPlum,kylin,真正讓我們停下來深入研究,不斷的擴充套件使用場景的是ClickHouse。

二、ClickHouse介紹


ClickHouse是一款用於大資料實時分析的列式資料庫管理系統,而非資料庫。通過向量化執行以及對cpu底層指令集(SIMD)的使用,它可以對海量資料進行並行處理,從而加快資料的處理速度。

主要優點有:

1)為了高效的使用CPU,資料不僅僅按列儲存,同時還按向量進行處理;

2)資料壓縮空間大,減少io;處理單查詢高吞吐量每臺伺服器每秒最多數十億行;

3)索引非B樹結構,不需要滿足最左原則;只要過濾條件在索引列中包含即可;即使在使用的資料不在索引中,由於各種並行處理機制ClickHouse全表掃描的速度也很快;

4)寫入速度非常快,50-200M/s,對於大量的資料更新非常適用;

ClickHouse並非萬能的,正因為ClickHouse處理速度快,所以也是需要為“快”付出代價。選擇ClickHouse需要有下面注意以下幾點:

1)不支援事務,不支援真正的刪除/更新;

2)不支援高併發,官方建議qps為100,可以通過修改配置檔案增加連線數,但是在伺服器足夠好的情況下;

3)sql滿足日常使用80%以上的語法,join寫法比較特殊;最新版已支援類似sql的join,但效能不好;

4)儘量做1000條以上批量的寫入,避免逐行insert或小批量的insert,update,delete操作,因為ClickHouse底層會不斷的做非同步的資料合併,會影響查詢效能,這個在做實時資料寫入的時候要儘量避開;

5)Clickhouse快是因為採用了並行處理機制,即使一個查詢,也會用伺服器一半的cpu去執行,所以ClickHouse不能支援高併發的使用場景,預設單查詢使用cpu核數為伺服器核數的一半,安裝時會自動識別伺服器核數,可以通過配置檔案修改該引數;

三、ClickHouse在酒店資料智慧平臺的實踐


3.1 資料更新

我們的主要資料來源是Hive到ClickHouse,現在主要採用如下兩種方式:

1)Hive到MySql,再匯入到ClickHouse

初期在DataX不支援hive到ClickHouse的資料匯入,我們是通過DataX將資料先匯入mysql,再通過ClickHouse原生api將資料從mysql匯入到ClickHouse。

為此我們設計了一套完整的資料匯入流程,保證資料從hive到mysql再到ClickHouse能自動化,穩定的執行,並保證資料在同步過程中線上應用的高可用。

乾貨 | 每天十億級資料更新,秒出查詢結果,ClickHouse在攜程酒店的應用

2)Hive到ClickHouse

DataX現在支援hive到ClickHouse,我們部分資料是通過DataX直接匯入ClickHouse。但DataX暫時只支援匯入,因為要保證線上的高可用,所以僅僅匯入是不夠的,還需要繼續依賴我們上面的一套流程來做ReName,增量資料更新等操作。

針對資料高可用,我們對資料更新機制做了如下設計:

3.1.1全量資料匯入流程


乾貨 | 每天十億級資料更新,秒出查詢結果,ClickHouse在攜程酒店的應用

全量資料的匯入過程比較簡單,僅需要將資料先匯入到臨時表中,匯入完成之後,再通過對正式表和臨時表進行ReName操作,將對資料的讀取從老資料切換到新資料上來。

3.1.2增量資料的匯入過程

乾貨 | 每天十億級資料更新,秒出查詢結果,ClickHouse在攜程酒店的應用

增量資料的匯入過程,我們使用過兩個版本。

由於ClickHouse的delete操作過於沉重,所以最早是通過刪除指定分割槽,再把增量資料匯入正式表的方式來實現的。

這種方式存在如下問題:一是在增量資料匯入的過程中,資料的準確性是不可保證的,如果增量資料越多,資料不可用的時間就越長;二是ClickHouse刪除分割槽的動作,是在接收到刪除指令之後內非同步執行,執行完成時間是未知的。如果增量資料匯入後,刪除指令也還在非同步執行中,會導致增量資料也會被刪除。最新版的更新日誌說已修復這個問題。

針對以上情況,我們修改了增量資料的同步方案。在增量資料從Hive同步到ClickHouse的臨時表之後,將正式表中資料反寫到臨時表中,然後通過ReName方法切換正式表和臨時表。

通過以上流程,基本可以保證使用者對資料的匯入過程是無感知的。

3.2 資料匯入過程的監控與預警

由於資料量大,資料同步的語句經常性超時。為保證資料同步的每一個過程都是可監控的,我們沒有使用ClickHouse提供的JDBC來執行資料同步語句,所有的資料同步語句都是通過呼叫ClickHouse的RestfulAPI來實現的。

呼叫RestfulAPI的時候,可以指定本次查詢的QueryID。在資料同步語句超時的情況下,通過輪詢來獲得某QueryID的執行進度。這樣保證了整個查詢過程的有序執行。在輪詢的過程中,會對異常情況進行記錄,如果異常情況出現的頻次超過閾值,JOB會通過簡訊給相關人員發出預警簡訊

3.3 伺服器分佈與運維

現在主要根據場景分國內,海外/供應商,實時資料,風控資料4個叢集。每個叢集對應的兩到三臺伺服器,相互之間做主備,程式內部將查詢請求分散到不同的伺服器上做負載均衡。

假如某一臺伺服器出現故障,通過配置介面修改某個叢集的伺服器節點,該叢集的請求就不會落到有故障的伺服器上。如果在某個時間段某個特定的資料查詢量比較大,組建虛擬叢集,將所有的請求分散到其他資源富於的物理叢集上。

下半年計劃把每個叢集的兩臺機器分散到不同的機房,可以繼續起到現有的主備,負載均衡的作用還能起到dr的作用。同時為了保障線上應用的高可用,我們會實現自動健康檢測機制,針對突發異常的伺服器自動拉出我們的虛擬叢集。

乾貨 | 每天十億級資料更新,秒出查詢結果,ClickHouse在攜程酒店的應用

我們會監控每臺伺服器每天的查詢量,每個語句的執行時間,伺服器CPU,記憶體相關指標,以便於及時調整伺服器上查詢量比較高的請求到其他伺服器。

乾貨 | 每天十億級資料更新,秒出查詢結果,ClickHouse在攜程酒店的應用

乾貨 | 每天十億級資料更新,秒出查詢結果,ClickHouse在攜程酒店的應用

四、ClickHouse使用探索


我們在使用ClickHouse的過程中遇到過各種各樣的問題,總結出來供大家參考。

1)關閉Linux虛擬記憶體。在一次ClickHouse伺服器記憶體耗盡的情況下,我們Kill掉佔用記憶體最多的Query之後發現,這臺ClickHouse伺服器並沒有如預期的那樣恢復正常,所有的查詢依然執行的十分緩慢。

通過檢視伺服器的各項指標,發現虛擬記憶體佔用量異常。因為存在大量的實體記憶體和虛擬記憶體的資料交換,導致查詢速度十分緩慢。關閉虛擬記憶體,並重啟服務後,應用恢復正常。

2)為每一個賬戶新增join_use_nulls配置。ClickHouse的SQL語法是非標準的,預設情況下,以Left Join為例,如果左表中的一條記錄在右表中不存在,右表的相應欄位會返回該欄位相應資料型別的預設值,而不是標準SQL中的Null值。對於習慣了標準SQL的我們來說,這種返回值經常會造成困擾。

3)JOIN操作時一定要把資料量小的表放在右邊,ClickHouse中無論是Left Join 、Right Join還是Inner Join永遠都是拿著右表中的每一條記錄到左表中查詢該記錄是否存在,所以右表必須是小表。

4)通過ClickHouse官方的JDBC向ClickHouse中批量寫入資料時,必須控制每個批次的資料中涉及到的分割槽的數量,在寫入之前最好通過Order By語句對需要匯入的資料進行排序。無序的資料或者資料中涉及的分割槽太多,會導致ClickHouse無法及時的對新匯入的資料進行合併,從而影響查詢效能。

5)儘量減少JOIN時的左右表的資料量,必要時可以提前對某張表進行聚合操作,減少資料條數。有些時候,先GROUP BY再JOIN比先JOIN再GROUP BY查詢時間更短。

6)ClickHouse版本迭代很快,建議用去年的穩定版,不能太激進,新版本我們在使用過程中遇到過一些bug,記憶體洩漏,語法不相容但也不報錯,配置檔案併發數修改後無法生效等問題。

7)避免使用分散式表,ClickHouse的分散式表效能上價效比不如物理表高,建表分割槽欄位值不宜過多,太多的分割槽資料匯入過程磁碟可能會被打滿。

8)伺服器CPU一般在50%左右會出現查詢波動,CPU達到70%會出現大範圍的查詢超時,所以ClickHouse最關鍵的指標CPU要非常關注。我們內部對所有ClickHouse查詢都有監控,當出現查詢波動的時候會有郵件預警。

9)查詢測試Case有:6000W資料關聯1000W資料再關聯2000W資料sum一個月間夜量返回結果:190ms;2.4億資料關聯2000W的資料group by一個月的資料大概390ms。但ClickHouse並非無所不能,查詢語句需要不斷的調優,可能與查詢條件有關,不同的查詢條件表是左join還是右join也是很有講究的。

五、總結


酒店資料智慧平臺從去年7月份試點,到現在80%以上的業務都已接入ClickHouse。滿足每天十多億的資料更新和近百萬次的資料查詢,支撐app效能98.3%在1秒內返回結果,pc端98.5%在3秒內返回結果。

從使用的角度,查詢效能不是資料庫能相比的,從成本上也是遠低於關係型資料庫成本的,單機支撐40億以上的資料查詢毫無壓力。與ElasticSearch,Redis相比ClickHouse可以滿足我們大部分使用場景。

我們會繼續更深入的研究ClickHouse,跟進最新的版本,同時也會繼續保持對外界更好的開源框架的研究,嘗試,尋找到更合適我們的技術框架。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31545816/viewspace-2649652/,如需轉載,請註明出處,否則將追究法律責任。

相關文章