ClickHouse 提供進階使用者問答

XNUMX 月份,Avito 工程師聚集在一起,與 ClickHouse 主要開發人員 Alexey Milovidov 和 Integros 的 Golang 開發人員 Kirill Shvakov 進行線上會議。 我們討論瞭如何使用資料庫管理系統以及遇到的困難。

根據這次會議,我們整理了一篇文章,其中包含專家對我們和觀眾關於備份、資料重新分片、外部字典、Golang 驅動程式和更新 ClickHouse 版本的問題的解答。 對於已經積極使用 Yandex DBMS 並對其現在和未來感興趣的開發人員來說,它可能很有用。 預設情況下,答案由 Alexey Milovidov 提供,除非另有說明。

小心,切口下面有很多文字。 我們希望帶有問題的內容能夠幫助您導航。

ClickHouse 提供進階使用者問答

Содержание

如果不想看文字,可以看聚會錄音 在我們的 YouTube 頻道上。 時間碼位於影片下的第一條評論。

ClickHouse 會不斷更新,但我們的資料不會。 怎麼辦?

ClickHouse不斷更新,我們經過優化最終處理的資料並沒有更新,而是在備份副本中。

假設我們遇到了一些問題並且資料遺失了。 我們決定恢復,結果發現備份伺服器上儲存的舊分割區與目前使用的 ClickHouse 版本有很大不同。 遇到這種情況該怎麼辦,有可能嗎?

從舊格式的備份中還原資料但無法連接到新版本的情況是不可能的。 我們確保 ClickHouse 中的資料格式始終保持向後相容。 如果某些很少使用的功能的行為發生了變化,這比功能的向後相容性重要得多。 新版本的 ClickHouse 應該始終能夠讀取儲存在磁碟上的資料。 這是法律。

目前從 ClickHouse 備份資料的最佳實踐是什麼?

考慮到我們已經優化了最終操作、一個巨大的 TB 資料庫以及最近三天更新的數據,然後沒有任何程式發生,如何進行備份?

我們可以製定自己的解決方案並在bash上寫下:以這樣或那樣的方式收集這些備份副本。 也許根本不需要拄著拐杖,而且腳踏車很早就發明了?

讓我們從最佳實踐開始。 在回答有關備份的問題時,我的同事總是建議提醒他們注意 Yandex.Cloud 服務,該服務已經解決了這個問題。 因此,如果可能的話,請使用它。

沒有完整的備份解決方案,百分之百內建於 ClickHouse 中。 有一些空白可以使用。 要獲得完整的解決方案,您要么必須手動進行一些修改,要么以腳本的形式建立包裝器。

我將從最簡單的解決方案開始,以最複雜的解決方案結束,具體取決於資料量和叢集的大小。 集群越大,解決方案變得越複雜。

如果資料表只有幾G,可以這樣備份:

  1. 保存表定義,即元資料 - 顯示創建表.
  2. 使用 ClickHouse 用戶端進行轉儲 - 選擇 * 從表 歸檔。 預設情況下,您將收到 TabSeparated 格式的檔案。 如果你想提高效率,可以採用 Native 格式。

如果資料量較大,則備份將花費更多時間和大量空間。 這稱為邏輯備份;它與 ClickHouse 資料格式無關。 如果是,那麼作為最後的手段,您可以進行備份並將其上傳到 MySQL 進行還原。

對於更進階的情況,ClickHouse 具有在本機檔案系統中建立分區快照的內建功能。 此功能可根據要求提供 更改表格凍結分區。 或簡單地 改變表格凍結 - 這是整個表的快照。

快照會針對一個分片上的一張表創建一致的快照,也就是說,透過這種方式不可能創建整個叢集的一致快照。 但對於大多數任務來說沒有這樣的需要,在每個分片上執行一個請求並獲得一致的快照就足夠了。 它以硬連結的形式創建,因此不佔用額外的空間。 接下來,將此快照複製到備份伺服器或用於備份的儲存。

恢復這樣的備份非常容易。 首先,使用現有表定義建立表。 接下來,將已儲存的分割區快照複製到這些表的 Directory-Detached 並執行查詢 附加分割區。 此解決方案非常適合最重要的數據量。

有時您需要更酷的東西 - 如果您的每台伺服器和數百台伺服器上有數十甚至數百 TB 的資料。 我從 Yandex.Metrica 的同事那裡得到了一個解決方案。 我不會向所有人推薦它——閱讀它並自己決定它是否合適。

首先,您需要建立多台具有大型磁碟架的伺服器。 接下來,在這些伺服器上,啟動多個 ClickHouse 伺服器並配置它們,以便它們充當相同分片的另一個副本。 然後使用這些伺服器上的檔案系統或某些工具來建立快照。 這裡有兩個選擇。 第一個選項是 LVM 快照,第二個選項是 Linux 上的 ZFS。

此後,您每天都需要創建快照,它會撒謊並佔用一些空間。 當然,如果資料發生變化,空間量會隨著時間的推移而增加。 這個快照可以隨時取出並恢復數據,這樣的解決方案很奇怪。 另外,我們還需要在配置中限制這些副本,以便它們不會嘗試成為領導者。

是否有可能在軸中組織受控的複製品滯後?

今年您計劃在 ClickHouse 中製作軸。 是否有可能在其中組織受控的副本滯後? 我們希望用它來保護自己免受變更和其他變化所帶來的負面情況的影響。

是否可以對變更者進行某種回滾? 例如,在現有的豎井中,假設直到這一刻您才應用更改,從這一刻起您停止應用更改?

如果一個命令到達我們的叢集並破壞了它,那麼我們就有一個有一個小時滯後的條件副本,我們可以說我們現在使用它,但我們不會在最後十分鐘內對其應用程式更改?

首先,關於副本的受控滯後。 有用戶提出這樣的要求,我們在 Github 上創建了一個問題,要求:“如果有人需要這個,喜歡它,就放個愛心吧。” 沒有人交付,問題就結束了。 但是,您已經可以透過設定 ClickHouse 來獲得這個機會。 確實,僅從 20.3 版本開始。

ClickHouse 在背景持續進行資料合併。 合併完成後,一組特定的資料將被替換為更大的資料。 同時,先前存在的資料片段將繼續保留在磁碟上一段時間。

首先,只要有選擇查詢使用它們,它們就會繼續存儲,以提供非阻塞操作。 選擇查詢可以輕鬆地從舊區塊中讀取。

其次,還有一個時間閾值──舊資料在磁碟上停留八分鐘。 這八分鐘可以定制,甚至可以變成一天。 這將消耗磁碟空間:根據資料流,事實證明,在最後一天,資料不僅會增加一倍,還可能增加五倍。 但如果出現嚴重問題,您可以停止 ClickHouse 伺服器並解決所有問題。

現在的問題是如何防止改變。 這裡值得深入研究,因為在舊版本的 ClickHouse 中,更改的工作方式是直接更改片段。 有一段資料有一些文件,我們這樣做,例如, 改變下降列。 然後從所有區塊中物理刪除該列。

但從 20.3 版本開始,alter 機制已經完全改變,現在資料總是不可變的。 它們根本不會改變 - 更改現在的工作方式與合併大致相同。 我們不是當場更換一件,而是創造一件新的。 在新區塊中,未更改的檔案將成為硬鏈接,如果我們刪除一列,它就會在新區塊中遺失。 舊的片段將在八分鐘後預設刪除,在這裡您可以調整上述設定。

這同樣適用於突變等改變。 當你這樣做時 更改刪除更改更新,它不會改變該片段,而是創建一個新片段。 然後刪除舊的。

如果表結構改變了怎麼辦?

如何恢復用舊方案製作的備份? 第二個問題是關於快照和檔案系統工具的情況。 在 Linux LVM 上使用 Btrfs 取代 ZFS 好嗎?

如果你這樣做 附加分割區 不同結構的分區,那麼ClickHouse會告訴你這是不可能的。 這就是解決方案。 第一個是使用舊結構建立 MergeTree 類型的臨時表,使用 Attach 將資料附加到其中,並進行更改查詢。 然後您可以複製或傳輸此資料並再次附加,或使用請求 更改表移動分區.

現在第二個問題是是否可以使用Btrfs。 首先,如果你有LVM,那麼LVM快照就夠了,檔案系統可以是ext4,也沒關係。 對於 Btrts,一切都取決於您的使用體驗。 這是一個成熟的檔案系統,但對於在特定場景下實際情況如何,仍然存在一些懷疑。 除非您在生產環境中使用 Btrfs,否則我不建議使用它。

目前資料重新分片的最佳實踐是什麼?

重新分片的問題是複雜且多方面的。 這裡有幾個可能的答案。 您可以從一方面說——ClickHouse 沒有內建的重新分片功能。 但恐怕這個答案不適合任何人。 因此,你可以從另一個角度說ClickHouse有很多重新分片資料的方法。

如果叢集空間不足或無法處理負載,您可以新增伺服器。 但這些伺服器預設是空的,上面沒有數據,沒有負載。 您需要重新排列數據,使其均勻分佈在新的、更大的集群中。

第一種方法是使用請求將部分分區複製到新伺服器 更改表格取得分割區。 例如,您按月進行分區,然後將 2017 年第一個月複製到新伺服器,然後將第三個月複製到其他新伺服器。 這樣做直到它變得或多或少均勻。

只能對錄製過程中不發生變化的分區進行傳輸。 對於新分區,必須停用記錄,因為它們的傳輸不是原子的。 否則,您最終會出現資料重複或空白。 不過,這個方法很實用,而且非常有效。 現成的壓縮分區透過網路傳輸,即資料沒有被壓縮或重新編碼。

這種方法有一個缺點,它取決於分片方案,您是否承諾該分片方案,您擁有什麼分片密鑰。 在您的指標範例中,分片鍵是路徑的雜湊值。 當您選擇分散式表時,它會立即轉到叢集中的所有分片並從那裡獲取資料。

這意味著什麼數據最終出現在哪個分片上實際上對您來說並不重要。 最重要的是,沿著一條路徑的資料最終會到達一個分片,但哪一個並不重要。 在這種情況下,傳輸現成的分區是完美的,因為透過選擇查詢,您還將收到完整的資料 - 無論是在重新分片之前還是之後,該方案並不重要。

但有些情況更為複雜。 如果在應用程式邏輯級別,您依賴特殊的分片方案,則該用戶端位於某某分片上,並且請求可以直接發送到那裡,而不是發送到分散式表。 或者您使用的是 ClickHouse 的最新版本並啟用了該設置 優化跳過未使用的碎片。 這種情況下,在select查詢時,會分析where部分的表達式,根據分片方案計算出需要使用哪些分片。 如果資料完全按照此分片方案進行分區,則此操作有效。 如果您手動重新排列它們,對應關係可能會發生變化。

所以這是第一個方法。 我正在等待你的答复,方法是否合適,或者我們繼續吧。

Vladimir Kolobaev,Avito 首席系統管理員:Alexey,當您需要分散負載(包括閱讀)時,您提到的方法效果不佳。 我們可以採用每月的分區,並且可以將上個月的資料轉移到另一個節點,但是當請求此資料時,我們只會載入它。 但我們希望加載整個集群,因為否則,在一段時間內整個讀取負載將由兩個分片處理。

阿列克謝‧米洛維多夫: 這裡的答案很奇怪——是的,這很糟糕,但它可能有用。 我將具體解釋如何進行。 值得查看資料背後的負載場景。 如果這是監控數據,那麼我們幾乎可以肯定地說絕大多數的請求都是針對新數據。

您安裝了新伺服器,遷移了舊分割區,也更改了記錄新資料的方式。 並且新的數據將分佈在整個集群中。 這樣,僅僅五分鐘後,最後五分鐘的請求將均勻加載群集;一天后,XNUMX小時的請求將均勻加載群集。 不幸的是,上個月的請求只會發送到部分叢集伺服器。

但通常您不會收到專門針對 2019 年 2019 月的請求。 最有可能的是,如果請求進入 2019 年,那麼它們將是整個 XNUMX 年的時間——很長一段時間,而不是某個小範圍。 而且這樣的請求也將能夠均勻地載入叢集。 但總的來說,您的評論是絕對正確的,這是一個臨時解決方案,不能完全均勻地傳播數據。

我還有幾點來回答這個問題。 其中之一是關於如何最初設計分片方案,以便重新分片會減少痛苦。 這並不總是可能的。

例如,您有監控數據。 監測數據不斷增加有三個原因。 首先是歷史數據的累積。 二是流量成長。 第三是監控對象數量的增加。 有新的微服務和指標需要保存。

其中,最大的成長可能與第三個原因有關——監控使用的增加。 在這種情況下,值得查看負載的性質,主要的選擇查詢是什麼。 基本選擇查詢很可能基於某些指標子集。

例如,某些服務在某些伺服器上的 CPU 使用情況。 事實證明,您可以透過某個鍵子集來獲取此資料。 對該資料的請求本身很可能非常簡單,並且在數十毫秒內完成。 用於監控服務和儀表板。 我希望我正確地理解這一點。

弗拉基米爾‧科洛巴耶夫: 事實上,我們經常求助於歷史數據,因為我們即時將當前情況與歷史情況進行比較。 快速存取大量資料對我們來說非常重要,ClickHouse 在這方面做得非常出色。

您說得完全正確,我們在最後一天經歷了大部分讀取請求,就像任何監控系統一樣。 但同時,歷史資料的負載也相當大。 它基本上來自一個警報系統,該系統每 XNUMX 秒運行一次,並對 ClickHouse 說:「給我過去六週的數據。 現在根據它們建立某種移動平均線,然後將當前值與歷史值進行比較。”

我想說的是,對於最近的請求,我們有另一個小表,其中僅存儲兩天的數據,主要請求飛入其中。 我們只將大型歷史查詢傳送到大型分片表。

阿列克謝‧米洛維多夫: 不幸的是,事實證明它不太適用於您的場景,但我會告訴您兩個不需要使用但在我朋友的服務中使用的糟糕且複雜的分片方案的描述。

有一個包含 Yandex.Metrica 事件的主集群。 事件是頁面瀏覽量、點擊量和轉換量。 大多數請求都會傳送到特定網站。 您開啟 Yandex.Metrica 服務,您有一個網站 - avito.ru,前往報告,並向您的網站發出請求。

但內部分析師也提出了其他要求——分析性的和全球性的。 為了以防萬一,我注意到內部分析師僅提出對 Yandex 服務的請求。 但儘管如此,即使是 Yandex 服務也佔據了所有數據的很大一部分。 這些請求不是針對特定計數器,而是針對更廣泛的過濾。

如何以一種方式組織數據,使所有事情都能在一個計數器上高效運行,並且全域查詢也能高效運行? 另一個困難是ClickHouse對Metrics叢集的請求數每秒數千個。 同時,一台 ClickHouse 伺服器無法處理非常重要的請求,例如每秒數千個。

叢集規模為六百多台伺服器。 如果您只是在該叢集上拉出一個分散式表並向那裡發送數千個請求,那麼它會變得比將它們發送到伺服器更糟糕。 另一方面,資料均勻分佈、我們向所有伺服器發出請求的選項會立即被駁回。

有一個選項是截然相反的。 想像一下,如果我們跨站點對資料進行分片,並且對一個站點的請求會傳送到一個分片。 現在,叢集每秒能夠處理一萬個請求,但在一個分片上,任何一個請求都會運行得太慢。 它將不再在吞吐量方面進行擴展。 特別是如果這是網站 avito.ru。 如果我說 Avito 是 RuNet 中訪問量最大的網站之一,我不會透露這個秘密。 在一個分片上處理它是瘋狂的。

因此,分片方案設計得更狡猾。 整個簇被分割成若干個簇,我們稱之為層。 每個集群包含十幾個到幾十個分片。 這樣的星團一共有三十九個。

這一切是如何擴展的? 簇的數量沒有改變──幾年前是三十九個,現在仍然如此。 但在每個模型中,隨著數據的積累,我們逐漸增加分片的數量。 整個分片方案是這樣的:這些叢集被劃分為網站,為了了解哪個網站位於哪個叢集上,使用了 MySQL 中單獨的元資料庫。 一個站點 - 在一個叢集上。 在其內部,根據訪客 ID 進行分片。

記錄時,我們將它們除以訪客 ID 的餘數。 但是當添加新分片時,分片方案會改變;我們繼續分裂,但除以另一個數字的餘數。 這意味著一個訪客已經位於多個伺服器上,您不能依賴這一點。 這樣做只是為了確保更好地壓縮資料。 當發出請求時,我們會轉到分散式表,該表查看叢集並存取數十台伺服器。 這是一個非常愚蠢的計劃。

但如果我不說我們放棄了這個計劃,我的故事就不完整。 在新方案中,我們更改了所有內容並使用 clickhouse-copier 複製了所有資料。

在新方案中,所有站點都分為兩類-大型站點和小型站點。 我不知道閾值是如何選擇的,但結果是大型網站記錄在一個叢集上,其中有 120 個分片,每個分片有 360 個副本,即 120 台伺服器。 分片方案使得任何請求都會立即發送到所有分片。 如果您現在在 Yandex.Metrica 中開啟 avito.ru 的任何報告頁面,請求將傳送至 120 台伺服器。 RuNet 中很少有大型網站。 而且請求每秒不是一千個,甚至不到一百個。 所有這些都被分散式表悄悄地消化掉,每個表都由 XNUMX 台伺服器處理。

第二個叢集適用於小型站點。 這是一種基於網站 ID 的分片方案,每個請求都只傳送到一個分片。

ClickHouse 有一個 clickhouse-copier 實用程式。 你能告訴我關於她的事嗎?

我馬上就會說,這個解決方案比較麻煩,而且效率較低。 優點是它完全按照您指定的模式塗抹數據。 但該實用程式的缺點是它根本不重新分片。 它將資料從一個集群模式複製到另一個集群模式。

這意味著要使其工作,您必須有兩個叢集。 它們可以位於相同的伺服器上,但是資料不會增量移動,而是會被複製。

例如,原來有四台伺服器,現在有八台。 您在所有伺服器上建立新的分散式表、新的本機表並啟動 clickhouse-copier,在其中指示它應該從那裡讀取的工作方案,接受新的分片方案並將資料傳輸到那裡。 在舊伺服器上,您將需要比現在多一倍半的空間,因為舊資料必須保留在它們上,並且一半相同的舊資料將到達它們之上。 如果你事先想到數據需要重新分片並且有空間,那麼這種方法就適合。

clickhouse-copier 內部是如何運作的? 它將所有工作分解為一組任務,用於處理一個分片上一個表的一個分區。 所有這些任務都可以並行執行,clickhouse-copier可以在多個實例的不同機器上運行,但它對一個分區所做的無非是插入選擇。 資料被讀取、解壓縮、重新分區,然後再次壓縮、寫入某處並重新排序。 這是一個更艱難的決定。

你有一個名為「重新分片」的試點計畫。 她怎麼了?

早在 2017 年,就有了一個名為「重新分片」的試點計畫。 ClickHouse 甚至還有一個選項。 據我了解,它沒有起飛。 你能告訴我為什麼會這樣嗎? 這似乎是非常相關的。

整個問題在於,如果需要就地重新分片數據,則需要非常複雜的同步才能以原子方式完成此操作。 當我們開始研究這種同步是如何運作的時,很明顯地存在著根本性的問題。 這些基本問題不僅是理論上的,而且立即開始以可以非常簡單地解釋的東西的形式在實踐中顯現出來——沒有任何作用。

在將資料移至慢速磁碟之前是否可以將所有資料合併在一起?

關於合併上下文中移動到慢速磁碟選項的 TTL 問題。 除了透過 cron 之外,還有其他方法可以將所有部分合併為一個,然後再將它們移到慢速磁碟嗎?

這個問題的答案是,有可能在轉移之前以某種方式自動將所有碎片粘合在一起——不。 我認為這沒有必要。 您不必將所有部分合併為一個,只需指望它們會自動傳輸到慢速磁碟即可。

我們對於轉移規則有兩個標準。 第一個是被填滿的樣子。 如果目前儲存層的可用空間少於一定百分比,我們會選擇一個區塊並將其移至速度較慢的儲存。 或者更確切地說,不是更慢,而是下一個 - 根據您的配置。

第二個標準是尺寸。 這是關於移動大件。 您可以根據快盤上的可用空間調整閾值,資料將自動傳輸。

如果無法事先檢查相容性,如何遷移到新版本的ClickHouse?

這個話題經常被討論 在 ClickHouse 電報聊天中 考慮到不同的版本,仍然如此。 從版本 19.11 升級到 19.16,例如從 19.16 升級到 20.3 的安全性如何。 在無法提前檢查沙箱相容性的情況下遷移到新版本的最佳方法是什麼?

這裡有幾個“黃金”規則。 第一的 - 閱讀變更日誌。 它很大,但有單獨的段落介紹向後不相容的更改。 不要將這些點視為危險信號。 這些通常是輕微的不相容性,涉及一些您很可能不會使用的邊緣功能。

其次,如果沙箱中無法檢查相容性,並且您想在生產中立即更新,建議您不需要這樣做。 首先建立一個沙箱並進行測試。 如果沒有測試環境,那麼您很可能沒有一家非常大的公司,這意味著您可以將一些資料複製到您的筆記型電腦並確保一切正常。 您甚至可以在電腦上本機建立多個副本。 或者您可以在附近的某個地方獲取新版本並上傳一些資料 - 也就是說,建立一個臨時測試環境。

另一個規則是版本發布後一周內不更新,因為在生產中發現錯誤並隨後快速修復。 讓我們弄清楚 ClickHouse 版本的編號,以免混淆。

有版本20.3.4。 數字20表示製造年份-2020年。從裡面的內容來看,這並不重要,所以我們就不去注意了。 下一步 - 20.3。 每次我們發布帶有一些新功能的版本時,我們都會增加第二個數字(在本例中為 3)。 如果我們想為 ClickHouse 添加一些功能,我們必須增加這個數字。 也就是說,在 20.4 版本中,ClickHouse 會運作得更好。 第三位數字是20.3.4。 這裡 4 是我們沒有添加新功能,但修復了一些錯誤的補丁版本數量。 4 表示我們做了四次。

不要以為這是一件可怕的事。 通常,使用者可以安裝最新版本,並且每年的正常運行時間不會出現任何問題。 但是想像一下,在我們中國同志添加的一些處理點陣圖的函數中,當傳遞錯誤的參數時,伺服器崩潰了。 我們有責任解決這個問題。 我們將發布新的補丁版本,ClickHouse將變得更加穩定。

如果您的 ClickHouse 在生產環境中運行,並且 ClickHouse 的新版本發布了附加功能 - 例如,20.4.1 是第一個版本,請不要急於在第一天將其投入生產。 為什麼需要它? 如果您還沒有使用 ClickHouse,那麼您可以安裝它,並且很可能一切都會好起來的。 但如果 ClickHouse 已經穩定運行,那麼請密切關注補丁和更新,看看我們正在修復哪些問題。

基里爾·什瓦科夫: 我想補充一些關於測試環境的內容。 每個人都非常害怕測試環境,並且出於某種原因,他們認為如果您有一個非常大的 ClickHouse 集群,那麼測試環境應該不少於或至少小十倍。 根本不是那樣的。

我可以用我自己的例子來告訴你。 我有一個項目,裡面有ClickHouse。 我們的測試環境是專門為他設計的 - 這是 Hetzner 的一個小型虛擬機,價格為 XNUMX 歐元,裡面幾乎部署了所有東西。 為此,我們在 Ansible 中實現了完全自動化,因此原則上,去哪裡都沒有區別 - 硬體伺服器或僅部署在虛擬機器中。

可以做什麼? 如果能在 ClickHouse 文件中提供一個範例來說明如何在自己家中部署一個小型叢集 - 在 Docker 中、在 LXC 中,也許建立一個 Ansible playbook,因為不同的人有不同的部署。 這會簡化很多。 當您在五分鐘內部署並部署一個叢集時,嘗試解決問題就會容易得多。 這要方便得多,因為轉入未經測試的生產版本是一條沒有出路的路。 有時有效,有時無效。 因此,希望成功是不好的。

Maxim Kotyakov,資深後端工程師 Avito: 我將從大公司面臨的一系列問題中添加一些關於測試環境的內容。 我們有一個成熟的 ClickHouse 驗收集群;就資料方案和設定而言,它是生產環境的精確副本。 此叢集部署在資源最少的相當破舊的容器中。 我們在那裡寫入一定比例的生產數據,幸運的是可以在 Kafka 中複製流。 那裡的一切都是同步的和可擴展的——無論是在容量還是流量方面,而且理論上,在所有其他條件相同的情況下,它在指標方面應該像生產一樣。 所有可能爆炸的東西首先被滾到這個架子上,並在那裡放置幾天,直到準備好。 但自然地,這個解決方案是昂貴的、困難的並且具有非零的支援成本。

阿列克謝‧米洛維多夫: 我要跟大家介紹一下我們Yandex.Metrica的朋友的測試環境是什麼樣的。 其中一個叢集有 600 多台伺服器,另一個叢集有 360 多台伺服器,還有第三個叢集和幾個叢集。 其中一個的測試環境只是兩個分片,每個分片有兩個副本。 為什麼是兩個碎片? 這樣你並不孤單。 而且應該也有複製品。 只要您能負擔的最低金額即可。

此測試環境可讓您檢查查詢是否正常運作以及是否有任何重大問題。 但是,當一切正常,但負載出現一些小的變化時,通常會出現完全不同性質的問題。

讓我舉一個例子。 我們決定安裝新版本的 ClickHouse。 它已發佈在測試環境中,自動化測試已在 Yandex.Metrica 本身中完成,該測試比較舊版本和新版本的數據,運行整個管道。 當然,還有我們 CI 的綠色測試。 否則我們甚至不會提出這個版本。

一切都好。 我們正開始投入生產。 我收到一條訊息,表明圖表上的負載增加了數倍。 我們正在回滾版本。 我查看圖表並發現:負載實際上在推出期間增加了幾次,而在推出時又減少了。 然後我們開始回滾版本。 並且負載以相同的方式增加並以相同的方式下降。 所以結論是這樣的:負載由於佈局而增加,這並不奇怪。

然後很難說服同事安裝新版本。 我說:“沒關係,滾出去吧。” 祈禱吧,一切都會好起來的。 現在圖表上的負載增加了,但一切都很好。 堅持住。” 一般來說,我們這樣做了,就是這樣 - 該版本已發布用於生產。 但幾乎​​每種佈局都會出現類似的問題。

Kill query 應該殺死查詢,但事實並非如此。 為什麼?

一位用戶(某種分析師)來找我並創建了一個請求來放置我的 ClickHouse 叢集。 某個節點或整個集群,取決於請求發送到哪個副本或分片。 我看到這台伺服器上的所有CPU資源都在一個架子上,一切都是紅色的。 同時,ClickHouse本身也會回應請求。 我寫道:“請告訴我,進程列表,是什麼請求引發了這種瘋狂。”

我找到這個請求並向其寫入kill。 我發現什麼事也沒有發生。 我的伺服器在架子上,ClickHouse 然後給我一些命令,顯示伺服器處於活動狀態,一切都很好。 但是我所有的用戶請求都有降級,降級從ClickHouse中的記錄開始,並且我的kill查詢不起作用。 為什麼? 我認為終止查詢應該終止查詢,但事實並非如此。

現在將會有一個相當奇怪的答案。 重點是終止查詢不會終止查詢。

終止查詢會選取一個名為「我希望終止此查詢」的小方塊。 請求本身在處理每個區塊時都會查看此標誌。 如果已設置,請求將停止工作。 事實證明,沒有人殺死這個請求,他自己必須檢查一切並停止。 這應該適用於請求處於處理資料塊狀態的所有情況。 它將處理下一個資料塊,檢查標誌,然後停止。

當請求在某些操作上被阻止時,這不起作用。 確實,這很可能不是您的情況,因為根據您的說法,它使用了大量的伺服器資源。 這可能在外部排序和其他一些細節的情況下不起作用。 但一般來說這不應該發生,這是一個錯誤。 我唯一可以推薦的是更新 ClickHouse。

如何計算閱讀負載下的回應時間?

有一個表格存儲項目聚合 - 各種計數器。 行數約一億行。 如果您為 1K 個項目注入 1K RPS,是否可以指望可預測的回應時間?

從上下文來看,我們談論的是讀取負載,因為寫入沒有問題——甚至可以插入一千、十萬、有時幾百萬行。

閱讀要求有很大不同。 在選擇1中,ClickHouse每秒可以執行大約數萬個請求,因此即使是一個金鑰的請求也已經需要一些資源。 而且這樣的點查詢會比一些鍵值資料庫更加困難,因為每次讀取都需要透過索引讀取一塊資料。 我們的索引不是針對每筆記錄,而是針對每個範圍。 也就是說,您必須讀取整個範圍 - 預設為 8192 行。 您必須將壓縮資料塊從 64 KB 解壓縮到 1 MB。 通常,此類有針對性的查詢需要幾毫秒才能完成。 但這是最簡單的選擇。

讓我們嘗試一些簡單的算術。 如果將幾毫秒乘以一千,就會得到幾秒鐘。 好像不可能跟上每秒一千個請求,但實際上這是可能的,因為我們有幾個處理器核心。 因此,原則上,ClickHouse 有時可以容納 1000 RPS,但對於短期請求,特別有針對性的請求。

如果您需要透過簡單請求的數量來擴展 ClickHouse 集群,那麼我建議最簡單的方法 - 增加副本數量並將請求發送到隨機副本。 如果一個副本每秒處理 XNUMX 個請求(這是完全現實的),那麼三個副本將處理 XNUMX 個請求。

當然,有時您可以將 ClickHouse 配置為最大數量的點讀數。 為此需要什麼? 首先是降低索引的粒度。 在這種情況下,不應該減少到一個,而是基於每台伺服器索引中的條目數將是數百萬或幾千萬。 如果表有一億行,那麼粒度可以設定為64。

您可以減少壓縮塊的大小。 有這方面的設置 最小壓縮塊大小, 最大壓縮塊大小。 可以減少它們,重新填充數據,然後有針對性的查詢會更快。 但 ClickHouse 仍然不是一個鍵值資料庫。 大量小請求是負載反模式。

基里爾·什瓦科夫: 如果那裡有普通帳戶,我會提供建議。 當 ClickHouse 儲存某種計數器時,這是相當標準的情況。 我有一個用戶,他來自某某國家,還有一些第三領域,我需要增加一些東西。 以 MySQL 為例,創建一個唯一鍵 - 在 MySQL 中它是重複鍵,而在 PostgreSQL 中它是衝突 - 並且添加一個加號。 這會工作得更好。

當您沒有太多資料時,使用 ClickHouse 沒有太大意義。 有一些常規資料庫,它們在這方面做得很好。

我可以在 ClickHouse 中進行哪些調整以使快取中有更多資料?

讓我們想像一種情況- 伺服器有256 GB RAM,在日常使用中,ClickHouse 大約需要60-80 GB,高峰時最多130 GB。可以啟用和調整哪些內容,以便在緩存中存儲更多數據,並相應土地,磁碟的造訪次數減少了嗎?

通常,作業系統的頁面快取可以很好地完成此任務。 如果您只是打開頂部,查看快取或空閒 - 它還說明快取了多少 - 然後您會注意到所有可用記憶體都用於快取。 並且在讀取這些資料時,不會從磁碟中讀取,而是從RAM中讀取。 同時,我可以說快取得到了有效的利用,因為快取的是壓縮資料。

但是,如果您想進一步加快一些簡單查詢的速度,可以在 ClickHouse 內的解壓縮資料中啟用快取。 它被稱為 未壓縮的緩存。 在 config.xml 設定檔中,將未壓縮快取大小設為您需要的值 - 我建議不要超過可用 RAM 的一半,因為其餘部分將進入頁面快取。

此外,還有兩個請求等級設定。 第一個設定 - 使用未壓縮的快取 - 包括其使用。 建議對所有請求啟用它,除了重型請求,重型請求可以讀取所有資料並刷新快取。 第二個設定類似於使用快取的最大行數。 它會自動限制大型查詢,以便它們繞過快取。

如何配置 RAM 中儲存的 storage_configuration?

在新的 ClickHouse 文件中,我閱讀了相關部分 帶數據存儲。 描述包含快速 SSD 的範例。

我想知道如何使用卷熱內存配置相同的東西。 還有一個問題。 select 如何處理此資料組織,它會讀取整個資料集還是僅讀取磁碟上的資料集,以及該資料是否壓縮在記憶體中? prewhere 部分如何與這樣的資料組織一起工作?

此設定會影響資料塊的存儲,並且它們的格式不會以任何方式改變。
讓我們仔細看看。

您可以配置 RAM 中的資料儲存。 為磁碟配置的只是其路徑。 您建立一個掛載到檔案系統中某個路徑的 tmpfs 分割區。 你指定這個路徑作為最熱分區的資料儲存路徑,資料開始到達並寫入那裡,一切正常。

但我不建議這樣做,因為可靠性低,儘管如果您在不同的資料中心至少有三個副本,那麼這是可能的。 如果發生任何情況,資料將被恢復。 讓我們想像一下伺服器突然關閉並重新開啟。 分區又掛載了,但是什麼都沒有。 當 ClickHouse 伺服器啟動時,它發現它沒有這些片段,儘管根據 ZooKeeper 元數據,它們應該在那裡。 他查看哪些副本有它們,要求它們並下載它們。 這樣資料就會恢復。

從這個意義上說,將資料儲存在RAM 中與將資料儲存在磁碟上並沒有本質上的區別,因為當資料寫入磁碟時,它也會首先出現在頁快取中,然後再進行實體寫入。 這取決於檔案系統安裝選項。 但為了以防萬一,我會說 ClickHouse 在插入時不會進行 fsync。

在這種情況下,RAM 中的資料以與磁碟上完全相同的格式儲存。 select查詢同樣的方式選擇需要讀取的分片,選擇分片中所需的資料範圍,並讀取。 無論資料是在 RAM 中還是在磁碟上, prewhere 的工作原理都完全相同。

低基數最多多少個唯一值才有效?

Low Cardinality 的設計巧妙。 它編譯資料字典,但它們是本地的。 首先,每件作品都有不同的字典,其次,即使在一件作品中,每個範圍的字典也可能不同。 當唯一值的數量達到閾值(我認為是一百萬)時,字典就會被簡單地擱置並創建一個新字典。

答案通常是:對於每個局部範圍(例如,每天),最多有一百萬個唯一值,低基數是有效的。 之後將有一個簡單的後備,其中將使用許多不同的字典,而不僅僅是一個。 它的運作方式與常規字串列大致相同,可能效率稍低,但不會嚴重降低效能。

對具有 XNUMX 億行的表進行全文搜尋的最佳實踐是什麼?

有不同的答案。 首先要說的是ClickHouse不是全文搜尋引擎。 為此有特殊的系統,例如, Elasticsearch и 人頭獅身。 然而,我越來越多地看到人們說他們正在從 Elasticsearch 轉向 ClickHouse。

為什麼會出現這種情況? 他們透過以下事實來解釋這一點:從建立索引開始,Elasticsearch 就不再能夠應對某些磁碟區的負載。 索引變得太麻煩了,如果只是將資料傳輸到 ClickHouse,結果發現它們的儲存效率在體積上提高了數倍。 同時,搜尋查詢通常不需要在整個資料量中尋找某些短語,同時考慮形態,而是完全不同的短語。 例如,在過去幾個小時的日誌中尋找一些位元組序列。

在本例中,您在 ClickHouse 中建立一個索引,其第一個欄位將是日期和時間。 最大數據截止將基於日期範圍。 在選定的日期範圍內,通常已經可以進行全文搜索,甚至使用類似的暴力方法。 ClickHouse 中的 like 運算子是您能找到的最高效的 like 運算子。 如果你發現更好的東西,請告訴我。

但仍然是完整掃描。 完全掃描不僅在 CPU 上很慢,在磁碟上也很慢。 如果突然間您每天有 XNUMX TB 的數據,並且您在白天搜尋一個單詞,那麼您將不得不掃描 XNUMX TB 數據。 它可能位於普通硬碟上,最終它們將以這樣的方式加載,您將無法透過 SSH 存取該伺服器。

既然如此,我準備再提供一個小技巧。 它是實驗性的——它可能有效,也可能無效。 ClickHouse 具有三元組布隆過濾器形式的全文索引。 我們在 Arenadata 的同事已經嘗試過這些索引,而且它們通常完全按照預期工作。

為了正確使用它們,您應該充分了解它們的工作原理:什麼是三元布隆過濾器以及如何選擇其大小。 我可以說它們將有助於查詢一些罕見的短語、資料中很少找到的子字串。 在這種情況下,將透過索引選擇子範圍,並且將讀取較少的資料。

最近,ClickHouse 增加了更進階的全文搜尋功能。 首先,這是一次性搜尋一堆子字串,包括區分大小寫、不區分大小寫、支援 UTF-8 或僅支援 ASCII 的選項。 選擇您需要的最有效的一種。

也出現了一次搜尋多個正規表示式的情況。 您不需要將 X 寫成一個子字串或將 X 寫成另一個子字串。 你馬上寫,一切都會盡可能有效率地完成。

第三,現在有正規表示式的近似搜尋和子字串的近似搜尋。 如果有人拼錯了某個單詞,則會搜尋最大匹配項。

組織大量使用者造訪 ClickHouse 的最佳方式是什麼?

告訴我們如何最好地組織大量消費者和分析師的訪問。 如何形成佇列、確定最大並發查詢的優先權以及使用什麼工具?

如果叢集夠大,那麼一個好的解決方案就是再增加兩台伺服器,這將成為分析師的切入點。 即不允許分析人員存取叢集中的特定分片,而只是建立兩台沒有資料的空伺服器,並在其上配置存取權限。 在這種情況下,分散式請求的使用者設定將傳輸到遠端伺服器。 也就是說,您在這兩台伺服器上配置所有內容,而這些設定會對整個叢集產生影響。

原則上,這些伺服器沒有數據,但其上的 RAM 量對於執行請求非常重要。 如果啟用外部聚合或外部排序,該磁碟也可以用於臨時資料。

查看與所有可能限制相關的設定非常重要。 如果我現在以分析師的身份進入 Yandex.Metrica 叢集並提出請求 從點擊中選擇計數,那麼我將立即得到一個異常,即我無法執行該請求。 我允許掃描的最大行數是 XNUMX 億行,集群上的一張表中總共有 XNUMX 兆行。 這是第一個限制。

假設我刪除了行限制並再次執行查詢。 然後我會看到以下異常 - 設定已啟用 按日期強制索引。 如果未指定日期範圍,我無法完成查詢。 您不必依賴分析師手動指定它。 典型的情況是日期範圍寫為事件日期在週之間。 然後他們只是在錯誤的位置指定了一個括號,而不是 and 結果是 or - or URL 匹配。 如果沒有限制,它就會抓取URL列,浪費大量資源。

另外,ClickHouse還有兩個優先權設定。 不幸的是,它們非常原始。 一種簡單地稱為 優先。 如果priority ≠ 0,並且正在執行某個優先權的請求,但是正在執行優先權值小於(即優先權較高)的請求,則優先權值大於(即優先權較低)的請求正在執行,只是暫停,在此期間根本不會工作。

這是一個非常粗略的設置,不適合叢集負載恆定的情況。 但是,如果您有重要的短的突發請求,且叢集大部分處於空閒狀態,則此設定很合適。

下一個優先權設定稱為 作業系統執行緒優先權。 它只是為 Linux 調度程序的所有請求執行線程設定好值。 它工作馬馬虎虎,但仍然有效。 如果您設定最小的nice值(它是最大的值,因此優先權最低),並為高優先權的請求設定-19,那麼CPU消耗的低優先權請求大約是高優先權請求的四倍。

您還需要配置最大請求執行時間 - 例如五分鐘。 查詢執行的最低速度是最酷的事情。 這個設定已經存在很久了,不僅需要斷言ClickHouse不會變慢,而且需要強制它。

想像一下,您設定:如果某個查詢每秒處理的行數少於一百萬行,您就不能這樣做。 這玷污了我們的好名聲、我們良好的資料庫。 我們就禁止這個吧。 實際上有兩種設定。 一種叫做 最小執行速度 - 以每秒行數為單位,第二個稱為檢查最小執行速度之前的逾時 - 預設為十五秒。 也就是說,十五秒是可能的,然後,如果很慢,則拋出異常併中止請求。

您還需要設定配額。 ClickHouse有一個內建的配額功能,可以統計資源消耗。 但不幸的是,不是 CPU、磁碟等硬體資源,而是邏輯資源──處理的請求數、讀取的行數和位元組數。 例如,您可以設定五分鐘內最多一百個請求和每小時一千個請求。

為什麼它如此重要? 因為某些分析查詢將直接從 ClickHouse 用戶端手動執行。 一切都會好起來的。 但如果你公司裡有高階分析師,他們會寫一個腳本,腳本可能會有錯誤。 而這個錯誤會導致請求無限循環執行。 這就是我們需要保護自己免受的影響。

是否可以將一個查詢的結果提供給十個客戶端?

我們有幾個用戶喜歡在同一時間點提出非常大的請求。 請求很大,原則上執行得很快,但由於同時有很多這樣的請求,所以變得非常痛苦。 是否可以執行連續十次到達的相同請求一次,並將結果提供給十個客戶端?

問題是我們沒有快取結果或緩存中間資料。 作業系統有一個頁面緩存,它會阻止你再次從磁碟讀取數據,但不幸的是,數據仍然會被解壓縮、反序列化和重新處理。

我想以某種方式避免這種情況,要么通過緩存中間數據,要么通過在某種隊列中排列類似的查詢並添加結果緩存。 目前,我們正在開發一個拉取請求,該請求添加了請求緩存,但僅適用於 in 和 join 部分中的子查詢 - 也就是說,該解決方案是不完整的。

然而,我們也面臨這樣的情況。 一個特別典型的例子是分頁查詢。 有一份報告,有好幾頁,要求限制10。然後同樣的事情,但限制10,10。 然後是下一頁。 問題是,為什麼我們每次都要計算這一切? 但現在沒有解決辦法,也沒有辦法避免。

有一個替代解決方案,作為 ClickHouse 旁邊的 sidecar 放置 - ClickHouse代理.

基里爾·什瓦科夫: ClickHouse Proxy 有一個內建的速率限制器和一個內建的結果快取。 那裡做了很多設置,因為正在解決類似的問題。 代理程式允許您透過對請求進行排隊來限制請求並配置請求快取的生存時間。 如果請求確實相同,Proxy 會發送多次,但只會發送到 ClickHouse 一次。

Nginx 在免費版本中也有緩存,這也可以工作。 Nginx 甚至有一個設置,如果請求同時到達,它會減慢其他請求,直到一個請求完成。 但在 ClickHouse Proxy 中,設定要好得多。 它是專門為ClickHouse做的,專門針對這些請求,所以更適合。 嗯,安裝很容易。

非同步操作和物化視圖怎麼樣?

存在一個問題,即重播引擎的操作是異步的 - 首先寫入數據,然後數據崩潰。 如果具有某些聚合的物化平板電腦位於該標誌下,則將向其寫入副本。 而如果沒有複雜的邏輯,那麼數據就會重複。 你能為這個做什麼?

有一個明顯的解決方案 - 在非同步折疊操作期間在特定類別的 matview 上實現觸發器。 是否有任何靈丹妙藥或計劃來實現類似的功能?

值得了解重複資料刪除的工作原理。 我現在要告訴你的內容與這個問題無關,但萬一值得記住。

當插入到複製表時,會對整個插入的區塊進行重複資料刪除。 如果您以相同的順序重新插入包含相同數量的相同行的同一塊,則會對資料進行重複資料刪除。 插入時會收到“Ok”回應,但實際上會寫入一包數據,並且不會重複。

為了確定性,這是必要的。 如果在插入過程中收到“Ok”,則表示您的資料已插入。 如果您收到來自 ClickHouse 的錯誤,則表示它們未插入,您需要重複插入。 但如果在插入過程中連接斷開,那麼你就不知道資料是否插入了。 唯一的選擇是再次重複插入。 如果資料確實已插入並且您重新插入它,則會進行區塊重複資料刪除。 這是避免重複所必需的。

它如何適用於物化視圖也很重要。 如果資料在插入主表時進行了重複資料刪除,那麼它也不會進入物化視圖。

現在關於這個問題。 您的情況更加複雜,因為您正在記錄各個行的重複項。 也就是說,複製的不是整個包,而是特定的行,並且它們在背景中折疊。 事實上,資料將在主表中折疊,但未折疊的資料將轉到物化視圖,並且在合併期間物化視圖不會發生任何變化。 因為物化視圖無非就是一個插入觸發器。 在其他操作期間,不會發生任何其他情況。

我在這裡無法讓你快樂。 您只需要針對這種情況尋找特定的解決方案。 例如,是否可以在物化視圖中重播它,並且重複資料刪除方法可能會以相同的方式運作。 但不幸的是,情況並非總是如此。 如果是聚合的話,就不行了。

基里爾·什瓦科夫: 那時我們還建造了拐杖。 存在一個問題,即有廣告印象,並且有一些我們可以即時顯示的數據 - 這些只是印象。 它們很少被重複,但如果發生這種情況,我們無論如何都會在以後折疊它們。 有些東西是無法複製的——點擊和整個故事。 但我也想立即向他們展示。

物化視圖是如何製作的? 有些視圖是直接寫入的——它被寫入原始數據,並寫入視圖。 在那裡,在某些時候數據不是很正確,它是重複的,等等。 而該表還有第二部分,它們看起來與物化視圖完全相同,也就是說,它們在結構上絕對相同。 我們偶爾會重新計算數據,計算沒有重複的數據,然後寫入這些表。

我們通過了 API - 這在 ClickHouse 中手動不起作用。 API 看起來:當我有最後一次添加到表中的日期時,可以保證已經計算出正確的數據,並且它向一個表和另一個表發出請求。 請求從一個請求中選擇最多一定的時間,從另一個請求中取得尚未計算的時間。 它可以工作,但不能單獨通過 ClickHouse。

如果您有某種 API(供分析師、使用者使用),那麼原則上這是一個選擇。 你總是在數,總是在數。 這可以每天進行一次或在其他時間進行。 您可以為自己選擇一個不需要且不重要的範圍。

ClickHouse有很多日誌。 如何才能對伺服器發生的一切一目了然?

ClickHouse 擁有非常大量的不同日誌,而且這個數量還在增加。 在新版本中,其中一些甚至預設啟用;在舊版本中,更新時必須啟用它們。 然而,這樣的人越來越多。 最終,我想看看我的伺服器現在發生了什麼,也許是在某種摘要儀表板上。

您的 ClickHouse 團隊或您朋友的團隊中是否有人支援現成儀表板的某些功能,這些功能會將這些日誌顯示為現成產品? 最終,僅查看 ClickHouse 中的日誌就很棒了。 但如果它已經以儀表板的形式準備好了,那就太酷了。 我會從中得到樂趣。

有儀表板,儘管它們不是標準化的。 在我們公司,大約有60個團隊使用ClickHouse,最奇怪的是他們中的許多人都有自己製作的儀表板,並且略有不同。 有些團隊使用內部 Yandex.Cloud 安裝。 有一些現成的報告,但不是所有必要的報告。 其他人有他們自己的。

我來自 Metrica 的同事在 Grafana 中有他們自己的儀表板,我也有自己的儀表板用於他們的叢集。 我正在研究諸如襯線緩存的緩存命中之類的事情。 更困難的是我們使用不同的工具。 我使用一個名為 Graphite-web 的非常古老的工具創建了儀表板。 他完全醜陋了。 我仍然這樣使用它,儘管 Grafana 可能會更方便、更美觀。

儀表板中的基本內容是相同的。 這些是叢集的系統指標:CPU、記憶體、磁碟、網路。 其他 - 同時請求數、同時合併數、每秒請求數、MergeTree 表格分割區的最大區塊數、複製延遲、複製佇列大小、每秒插入的行數、每秒插入的區塊數。 這不是從日誌中獲得的,而是從指標中獲得的。

弗拉基米爾‧科洛巴耶夫: 阿列克謝,我想糾正一下。 有格拉法納。 Grafana有一個資料來源,就是ClickHouse。 也就是說,我可以從 Grafana 直接向 ClickHouse 發出請求。 ClickHouse有一個包含日誌的表,對每個人來說都是一樣的。 因此,我想訪問 Grafana 中的這個日誌表並查看我的伺服器發出的請求。 如果有一個這樣的儀表板就太好了。

我自己騎腳踏車去的。 但我有一個問題──如果都是標準化的,而且Grafana大家都用,為什麼Yandex沒有這樣的官方儀表板呢?

基里爾·什瓦科夫: 事實上,進入 ClickHouse 的資料來源現在支援 Altinity。 我只想給一個向量,說明在哪裡挖掘以及推誰。 你可以問他們,因為 Yandex 仍然在製作 ClickHouse,而不是圍繞它的故事。 Altinity是目前推廣ClickHouse的主要公司。 他們不會拋棄他,而是會支持他。 因為原則上,要將儀表板上傳到 Grafana 網站,您只需要註冊並上傳即可 - 沒有特殊問題。

阿列克謝‧米洛維多夫: 在過去的一年裡,ClickHouse 增加了許多查詢分析功能。 每個請求都有關於資源使用情況的指標。 就在最近,我們增加了一個更低等級的查詢分析器來查看查詢每毫秒花在哪裡。 但要使用此功能,我必須打開控制台用戶端並輸入請求,但我總是忘記這一點。 我把它保存在某個地方,但一直忘記具體在哪裡。

我希望有一個工具可以說,這是您的大量查詢,按查詢類分組。 我按了一個,他們會告訴我這就是它重的原因。 現在還沒有這樣的解決方案。 而且真的很奇怪,當人們問我:“告訴我,Grafana 有現成的儀表板嗎?”,我說:“去 Grafana 網站,有一個‘Dashboards’社區,還有一個儀表板來自Dimka 的儀表板來自Kostyan。 我不知道那是什麼,我自己沒用過。”

如何影響合併以使伺服器不會崩潰 OOM?

我有一張表,表中只有一個分區,它是ReplacingMergeTree。 我已經向其中寫入資料四年了。 我需要對其進行更改並刪除一些數據。

我這麼做了,在處理這個請求的過程中,叢集中所有伺服器上的記憶體都被消耗掉了,叢集中所有伺服器都進入了OOM狀態。 然後他們都一起站起來,開始合併這個相同的操作,這個資料塊,然後又陷入了OOM。 然後他們又站起來,又跌倒了。 而這件事並沒有停止。

後來發現這其實是他們修復的一個錯誤。 這非常酷,非常感謝。 但仍有殘留物。 現在,當我考慮在表中進行某種合併時,我有一個問題 - 為什麼我不能以某種方式影響這些合併? 例如,按所需的 RAM 量來限制它們,或原則上按處理此特定表的量來限制它們。

我有一個名為“Metrics”的表,請在兩個線程中為我處理它。 無需並行創建十個或五個合併,只需分兩次進行即可。 我認為我的記憶體足夠處理兩個,但可能不足以處理十個。 為什麼恐懼依然存在? 因為表正在增長,有一天我將面臨一種情況,原則上不再是由於錯誤,而是因為數據會發生如此大的變化,以至於我根本沒有足夠的記憶體伺服器。 然後合併時伺服器會崩潰OOM。 而且,我可以取消變異,但梅爾吉已經不在了。

要知道,合併時,伺服器不會陷入 OOM,因為合併時,RAM 量僅用於一小部分資料。 所以無論數據量有多大,一切都會好起來的。

弗拉基米爾‧科洛巴耶夫: 美好的。 此刻,在錯誤修復後,我為自己下載了一個新版本,在另一個較小的表上,有很多分區,我執行了類似的操作。 在合併過程中,伺服器上大約 100 GB 的 RAM 被燒毀。 我有 150 個被佔用,100 個被吃掉,還剩下 50 GB 的窗口,所以我沒有陷入 OOM。

如果實際消耗 100 GB RAM,目前什麼可以保護我免於陷入 OOM? 如果合併時的 RAM 突然耗盡怎麼辦?

阿列克謝‧米洛維多夫: 有這樣的問題:專門用於合併的RAM的消耗不受限制。 第二個問題是,如果已經分配了某種合併,那麼它必須被執行,因為它記錄在複製日誌中。 複製日誌是使副本進入一致狀態所需的操作。 如果您不進行手動操作來回滾此複製日誌,則必須以一種或另一種方式執行合併。

當然,為了「以防萬一」防止 OOM 而設定 RAM 限制並不是多餘的。 它不會幫助合併完成,它會再次開始,達到某個閾值,拋出異常,然後再次開始 - 這不會帶來任何好處。 但原則上,引入此限制是有用的。

ClickHouse 的 Golang 驅動程式將如何開發?

由 Kirill Shvakov 編寫的 Golang 驅動程式現已獲得 ClickHouse 團隊的正式支援。 他 在 ClickHouse 儲存庫中,他現在又大又真實了。

一個小筆記。 有一個美妙且受人喜愛的無限有序範式存儲庫 - 這就是 Vertica。 他們也有自己的官方 python 驅動程序,並得到 Vertica 開發人員的支持。 有幾次,儲存版本和驅動程式版本差異很大,驅動程式在某個時候停止工作。 還有第二點。 在我看來,對這個官方驅動程式的支援是由「nipple」系統執行的 - 你給他們寫一個問題,它就會永遠掛起。

我有兩個問題。 現在,Kirill 的 Golang 驅動程式幾乎是 Golang 與 ClickHouse 通訊的預設方式。 除非有人仍然透過http介面進行通信,因為他喜歡那樣。 該驅動程式的開發將如何進行? 它會與存儲庫本身的任何重大更改同步嗎? 考慮問題的程序是什麼?

基里爾·什瓦科夫: 首先是一切都是如何官僚化組織的。 這一點沒有討論過,所以我無話可說。

為了回答這個問題,我們需要了解一下驅動程式的歷史。 我在一家擁有大量數據的公司工作。 這是一個廣告旋轉器,有大量事件需要儲存在某個地方。 在某個時候 ClickHouse 出現了。 我們向其中填充了數據,一開始一切都很好,但後來 ClickHouse 崩潰了。 那一刻我們決定不需要它。

一年後,我們又回到了使用ClickHouse的想法,我們需要以某種方式在那裡寫入資料。 介紹資訊是這樣的:硬體很薄弱,資源很少。 但我們一直都是這樣運作的,因此我們轉向了原生協議。

由於我們使用 Go 工作,很明顯我們需要一個 Go 驅動程式。 我幾乎全職做這件事——這是我的工作任務。 我們把它帶到了某種程度,原則上沒有人認為除了我們之外的任何人都會使用它。 然後CloudFlare也遇到了完全相同的問題,有一段時間我們和他們合作得非常順利,因為他們有相同的任務。 此外,我們在 ClickHouse 中和驅動程式中都這樣做了。

在某些時候,我乾脆停止這樣做,因為我在 ClickHouse 和工作方面的活動發生了一些變化。 因此問題並未結束。 需要某些東西的人會定期向儲存庫提交內容。 然後我查看拉取請求,有時我甚至自己編輯一些東西,但這種情況很少發生。

我想回到司機那裡。 幾年前,當這一切開始時,ClickHouse 也是不同的,並且具有不同的功能。 現在我們已經了解如何重新製作驅動程式以使其正常工作。 如果發生這種情況,那麼由於累積的拐杖,版本 2 無論如何都將不相容。

我不知道如何組織這件事。 我自己的時間不多。 如果有人完成了驅動程序,我可以幫助他們並告訴他們該怎麼做。 但Yandex是否積極參與該專案的開發尚未被討論。

阿列克謝‧米洛維多夫: 事實上,這些司機還沒有官僚主義。 唯一的一點是它們是提交給官方組織的,也就是說這個驅動程式被認可為Go官方的預設解決方案。 還有一些其他驅動程序,但它們是分開的。

我們沒有對這些驅動程式進行任何內部開發。 問題是我們是否可以僱用一個個人,不是為了這個特定的司機,而是為了所有社區司機的發展,或者我們可以從外部找到一個人。

啟用lazy_load 設定後重新啟動後,外部字典不會載入。 怎麼辦?

我們啟用了lazy_load設置,並且在伺服器重新啟動後,字典不會自行載入。 僅在用戶訪問此字典後才會引發它。 當我第一次訪問它時,它給出了一個錯誤。 是否可以使用 ClickHouse 以某種方式自動載入字典,或者您是否需要始終自己控制它們的準備情況,以便用戶不會收到錯誤?

也許我們有舊版的 ClickHouse,所以字典沒有自動載入。 可能是這樣嗎?

首先,可以使用查詢強制載入字典 系統重新載入字典。 其次,關於錯誤 - 如果字典已經加載,那麼查詢將根據加載的資料進行工作。 如果字典尚未加載,則在請求時直接加載。

這對於厚重的字典來說不太方便。 例如,您需要從 MySQL 中提取一百萬行。 有人做了一個簡單的選擇,但這個選擇將等待相同的百萬行。 這裡有兩種解決方案。 首先是關閉lazy_load。 其次,當伺服器啟動時,在對其施加負載之前,請執行以下操作 系統重新載入字典 或只是使用字典進行查詢。 然後字典將被載入。 您需要在啟用lazy_load設定的情況下控製字典的可用性,因為ClickHouse不會自動載入它們。

最後一個問題的答案是要么版本舊,要么需要調試。

如果系統重新載入字典中至少有一個字典因錯誤而崩潰,那麼系統重新載入字典不會載入任何字典,該怎麼辦?

還有一個關於系統重載字典的問題。 我們有兩本字典 - 一本未加載,第二本已加載。 在這種情況下,系統重新載入字典不會載入任何字典,您必須使用系統重新載入字典按名稱逐點載入特定字典。 這也和ClickHouse版本有關嗎?

我想讓你幸福。 這種行為正在改變。 這意味著如果你更新ClickHouse,它也會改變。 如果您對自己目前的行為不滿意 系統重新載入字典,更新,希望它能變得更好。

有沒有辦法在 ClickHouse 配置中配置詳細信息,但在出現錯誤時不顯示它們?

下一個問題是與字典相關的錯誤,即細節。 我們已在 ClickHouse 配置中為字典指定了連接詳細信息,如果出現錯誤,我們會收到這些詳細資訊和密碼作為回應。

我們透過向 ODBC 驅動程式配置新增詳細資訊解決了此錯誤。 有沒有辦法在 ClickHouse 配置中配置詳細信息,但在出現錯誤時不顯示這些詳細信息?

這裡真正的解決方案是在 odbc.ini 中指定這些憑證,並在 ClickHouse 本身中僅指定 ODBC 資料來源名稱。 對於其他字典來源,這種情況不會發生 - 無論是 MySQL 字典還是其他字典,當您收到錯誤訊息時,您都不應該看到密碼。 對於 ODBC,我也會查看 - 如果存在,則只需將其刪除即可。

獎勵:來自聚會的 Zoom 背景

透過點擊圖片,聚會的獎勵背景將為最執著的讀者打開。 我們與 Avito 技術吉祥物一起撲滅大火,與系統管理員室或老式計算機俱樂部的同事進行協商,並在橋下的塗鴉背景下進行日常會議。

ClickHouse 提供進階使用者問答

來源: www.habr.com

添加評論