ClickHouse中的循環複製集羣拓撲

關係型數據庫,但千萬級表關聯數據庫基本上不太可能做到秒出;考慮過Sharding,但數據量大,

各種成本都很高;熱數據存儲到ElasticSearch,但無法跨索引關聯,導致不得不做寬表,

因爲權限,酒店信息會變,所以每次要刷全量數據,不適用於大表更新,

維護成本也很高;Redis鍵值對存儲無法做到實時彙總;

1. 現有一個需求需要快速訪問 2個字段 至少佔 128KB 的 一條記錄 ,  累計十多億數據更新,如何保證數據更新過程中生產應用高可用

2. 每天有將近百萬次數據查詢請求

3. 讓用戶無論在app端還是pc端查詢數據提供秒出的效果

不斷擴展使用場景的,是ClickHouse

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

主要優點有:

  • 爲了高效的使用CPU,數據不僅僅按列存儲,同時還按向量進行處理;
  • 數據壓縮空間大,減少IO;處理單查詢高吞吐量每臺服務器每秒最多數十億行;
  • 索引非B樹結構,不需要滿足最左原則;只要過濾條件在索引列中包含即可;即使在使用的數據不在索引中,由於各種並行處理機制ClickHouse全表掃描的速度也很快;
  • 寫入速度非常快,50-200M/s,對於大量的數據更新非常適用。

 

在某些情況下,需要使用複製配置分佈式羣集,但沒有足夠的服務器將每個複製副本放置在單獨的節點上。最好在同一個節點上以特殊方式配置多個副本,這樣即使在節點出現故障時也可以繼續執行查詢。這種複製配置可以在不同的分佈式系統中找到,通常稱爲“循環”或“環”複製。在本文中,我們將討論如何在ClickHouse中設置循環複製。如果您對本主題不熟悉,我們建議您從一篇介紹性文章“ClickHouse數據分發”開始。

概念
假設有3個服務器和1個表。目標是將數據分發到3個碎片中並複製兩次。這需要在每個節點上有兩個不同的碎片。

 

 

 

 

羣集配置
讓我們從定義3個碎片和2個副本的簡單集羣配置開始。由於我們只有3個節點可以使用,我們將以“圓形”的方式設置副本主機,這意味着我們將使用第一個和第二個節點作爲第一個碎片,使用第二個和第三個節點作爲第二個碎片,使用第三個和第一個節點作爲第三個碎片。就像這樣:

  1. 1st shard, 1st replica, hostname: cluster_node_1
  2. 1st shard, 2nd replica, hostname: cluster_node_2
  3. 2nd shard, 1st replica, hostname: cluster_node_2
  4. 2nd shard, 2nd replica, hostname: cluster_node_3
  5. 3rd shard, 1st replica, hostname: cluster_node_3
  6. 3rd shard, 2nd replica, hostname: cluster_node_1

配置文件如下:

<shard>
    <replica>
        <host>cluster_node_1</host>
    </replica>
    <replica>
        <host>cluster_node_2</host>
    </replica>
</shard>
<shard>
    <replica>
        <host>cluster_node_2</host>
    </replica>
    <replica>
        <host>cluster_node_3</host>
    </replica>
</shard>
<shard>
    <replica>
        <host>cluster_node_3</host>
    </replica>
    <replica>
        <host>cluster_node_1</host>
    </replica>
</shard>

現在您可以看到,我們有以下存儲架構:

  1. cluster_node_1 stores 1st shard, 1st replica and 3rd shard, 2nd replica
  2. cluster_node_2 stores 1st shard, 2nd replica and 2nd shard, 1st replica
  3. cluster_node_3 stores 2nd shard, 2nd replica and 3rd shard, 1st replica

這顯然不起作用,因爲碎片具有相同的表名,當它們位於同一服務器上時,ClickHouse無法區分一個碎片/副本。這裏的訣竅是把每個碎片放到一個單獨的數據庫中!ClickHouse允許爲每個shard定義“default_database”,然後在查詢時使用它,以便將特定表的查詢路由到正確的數據庫。

關於在ClickHouse中使用“Circle”拓撲的另一個重要注意事項是,您應該將每個特定shard的內部複製選項設置爲TRUE。定義如下:

<shard>
    <internal_replication>true</internal_replication>
    <replica>
        <default_database>testcluster_shard_1</default_database>
        <host>cluster_node_1</host>
    </replica>
    <replica>
        <default_database>testcluster_shard_1</default_database>
        <host>cluster_node_2</host>
    </replica>
</shard>

現在讓我們嘗試定義與此配置相對應的shard表。


數據庫架構
如上所述,爲了在同一節點上彼此分離碎片,需要特定於碎片的數據庫。

  1. 第1個節點架構
    • testcluster_shard_1
    • testcluster_shard_3
  2. 第2個節點架構
    • testcluster_shard_2
    • testcluster_shard_1
  3. 第3個節點架構
    • testcluster_shard_3
    • testcluster_shard_2

複製表架構
現在讓我們爲碎片設置複製表。ReplicatedMergeTree表定義需要兩個重要參數:

Zookeeper中的表碎片路徑
副本標記
Zookeeper路徑對於每個碎片都應該是唯一的,副本標記在每個特定碎片中都應該是唯一的:

第1個節點:
CREATE TABLE testcluster_shard_1.tc_shard 
… 
Engine=ReplicatedMergeTree(‘/clickhouse/tables/tc_shard_1/events’, ‘replica_1’, …)

CREATE TABLE testcluster_shard_3.tc_shard 
… 
Engine=ReplicatedMergeTree(‘/clickhouse/tables/tc_shard_3/events’, ‘replica_2’, …)

第2個節點

CREATE TABLE testcluster_shard_2.tc_shard 
… 
Engine=ReplicatedMergeTree(‘/clickhouse/tables/tc_shard_2/events’, ‘replica_1’, …)

CREATE TABLE testcluster_shard_1.tc_shard 
… 
Engine=ReplicatedMergeTree(‘/clickhouse/tables/tc_shard_1/events’, ‘replica_2’, …)

第3個節點

CREATE TABLE testcluster_shard_3.tc_shard 
… 
Engine=ReplicatedMergeTree(‘/clickhouse/tables/tc_shard_3/events’, ‘replica_1’, …)

CREATE TABLE testcluster_shard_2.tc_shard 
… 
Engine=ReplicatedMergeTree(‘/clickhouse/tables/tc_shard_2/events’, ‘replica_2’, …)

分佈式表架構
剩下的就是分佈式表。爲了讓ClickHouse爲本地shard表選擇合適的默認數據庫,需要使用空數據庫創建分佈式表。這就觸發了默認值的使用。

CREATE TABLE tc_distributed
… 
ENGINE = Distributed( ‘testcluster’, ‘’, tc_shard, rand() )

當查詢到分佈式表時,ClickHouse會自動爲每個本地tc_shard表添加相應的默認數據庫。

 

 

將“load_balancing”設置設置爲“按順序”是有意義的,否則,ClickHouse可能會偶爾選擇第二個副本執行查詢,從而導致從同一羣集節點查詢的兩個碎片不是最佳的。

如果其中一個節點關閉,則仍有足夠的數據運行查詢:

 

 

結論
如上所示,可以在ClickHouse中設置循環或環形複製拓撲,但這並不簡單,需要不明顯的配置和額外的數據庫來分離碎片和副本。除了複雜的配置之外,由於每個羣集節點的雙重插入負載,這種設置與單獨的副本節點相比性能更差。雖然對副本重複使用相同的節點似乎很有吸引力,但在考慮循環複製部署時,需要考慮性能和配置問題。





 

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