復(fù)制-clickhouse

復(fù)制的注意點(diǎn)

目前只有合并樹(shù)系列的表 具有復(fù)制的功能。

復(fù)制的實(shí)現(xiàn)原理

clickhouse的復(fù)制 是基于 zookeeper來(lái)實(shí)現(xiàn)的。zookeeper 在clickhouse 復(fù)制的實(shí)現(xiàn)之中 扮演了 元數(shù)據(jù)存儲(chǔ)、日志框架、分布式協(xié)調(diào)服務(wù) 三重角色。
每個(gè)clickhouse 節(jié)點(diǎn)都會(huì)監(jiān)視 zookeeper /clickhouse/tables/分片號(hào)/數(shù)據(jù)庫(kù)名/表名/log 節(jié)點(diǎn)下的信息。當(dāng)向一個(gè)節(jié)點(diǎn)的可復(fù)制表寫(xiě)入數(shù)據(jù)時(shí),節(jié)點(diǎn)會(huì)向 /clickhouse/tables/分片號(hào)/數(shù)據(jù)庫(kù)名/表名/log 目錄下添加任務(wù)節(jié)點(diǎn)。另一個(gè)副本節(jié)點(diǎn)監(jiān)控到變化,執(zhí)行fetch操作(在zookeeper之中的數(shù)據(jù)變化,這里忽略),從對(duì)應(yīng)的節(jié)點(diǎn)拉取數(shù)據(jù)。

fetch

fetch 的定義

復(fù)制表的一個(gè)副本從另一個(gè)副本 通過(guò)http協(xié)議 克隆數(shù)據(jù),這個(gè)過(guò)程被稱(chēng)為fetch。

fetch 的實(shí)現(xiàn)

每個(gè)clickhouse 節(jié)點(diǎn) 專(zhuān)門(mén)維護(hù)一個(gè)線(xiàn)程池 用以執(zhí)行fetch操作。fetch的實(shí)質(zhì) 是通過(guò)http協(xié)議下載數(shù)據(jù)。

決定 fetch 線(xiàn)程池大小的參數(shù)

background_fetches_pool_size

clickhouse 節(jié)點(diǎn) 暴露的用于執(zhí)行fetch的端口是哪個(gè)

config.xml 文件之中的配置參數(shù)

 <interserver_http_port>9009</interserver_http_port>

通過(guò)http fetch的時(shí)候,接收方的超時(shí)時(shí)間

replicated_fetches_http_receive_timeout 參數(shù)決定,是合并樹(shù)表級(jí)別的配置參數(shù)。

通過(guò)http fetch的時(shí)候,發(fā)送方的超時(shí)時(shí)間

replicated_fetches_http_send_timeout

每個(gè)節(jié)點(diǎn)的fetch 并發(fā)度限制

replicated_max_parallel_fetches_for_host

限制 fetch 收 發(fā) 消耗的網(wǎng)絡(luò)帶寬大小

max_replicated_sends_network_bandwidth_for_server: 服務(wù)器級(jí)別的設(shè)置(限制所有表的總量)
max_replicated_fetches_network_bandwidth_for_server:服務(wù)器級(jí)別的設(shè)置(限制所有表的總量)
max_replicated_fetches_network_bandwidth : 表級(jí)別的設(shè)置
max_replicated_sends_network_bandwidth : 表級(jí)別的設(shè)置

fetch 操作會(huì)占據(jù)的資源

帶寬 cpu 內(nèi)存。 主要需要注意的是帶寬。

replica 在 zookeeper 的清理機(jī)制

  • max_replicated_logs_to_keep:當(dāng)一個(gè)副本節(jié)點(diǎn)掛掉的時(shí)候,zookeeper的log隊(duì)列最多保持多少個(gè)任務(wù)節(jié)點(diǎn)。
  • min_replicated_logs_to_keep:在log隊(duì)列之中最少保持多少個(gè)任務(wù)節(jié)點(diǎn)。即使任務(wù)節(jié)點(diǎn)已經(jīng)被執(zhí)行,但是還是需要保持配置數(shù)量的節(jié)點(diǎn)數(shù)。
  • cleanup_delay_period:合并樹(shù)級(jí)別的配置參數(shù),決定了后臺(tái)執(zhí)行復(fù)制表隊(duì)列的清理周期。
    如果發(fā)現(xiàn)隊(duì)列之中的節(jié)點(diǎn)數(shù)過(guò)多的話(huà),可以稍稍調(diào)小一下參數(shù),默認(rèn)的取值為30s。

復(fù)制表下的合并

1:execute_merges_on_single_replica_time_threshold 參數(shù)決定副本開(kāi)始合并的時(shí)間。假設(shè)有兩個(gè)副本,一個(gè)副本開(kāi)始合并,那么另一個(gè)副本是需要fetch 合并后的數(shù)據(jù)呢,還是自己也執(zhí)行合并。所以就取決于參數(shù) execute_merges_on_single_replica_time_threshold的值。取值為0,表示每個(gè)副本自己觸發(fā)合并。當(dāng)取值為某一個(gè)整數(shù)時(shí),副本A開(kāi)始執(zhí)行合并,副本B等待一段時(shí)間,如果副本A的合并執(zhí)行完成,那么副本B通過(guò)fetch獲取數(shù)據(jù),否則副本B自己本地開(kāi)始執(zhí)行合并。
2:當(dāng)log entry的創(chuàng)建時(shí)間 超過(guò) prefer_fetch_merged_part_time_threshold,
并且執(zhí)行合并的數(shù)據(jù)量的大小 超過(guò) prefer_fetch_merged_part_size_threshold,
那么執(zhí)行fetch 來(lái)加速合并。

可復(fù)制表的寫(xiě)入

復(fù)制的相關(guān)配置參數(shù)

復(fù)制表下的合并參數(shù)

  • execute_merges_on_single_replica_time_threshold:默認(rèn)的取值為0,表示各個(gè)節(jié)點(diǎn)在自己本地進(jìn)行合并。含義是,使某個(gè)副本首先開(kāi)始合并,如果在指定的時(shí)間內(nèi)完成合并,通過(guò)fetch來(lái)獲得合并后的數(shù)據(jù)。作用:用來(lái)緩解合并對(duì)cpu造成的壓力
  • prefer_fetch_merged_part_time_threshold:當(dāng)log entry的創(chuàng)建時(shí)間 超過(guò) prefer_fetch_merged_part_time_threshold,并且執(zhí)行合并的數(shù)據(jù)量的大小 超過(guò) prefer_fetch_merged_part_size_threshold,那么執(zhí)行fetch 來(lái)加速合并

復(fù)制表下的寫(xiě)入?yún)?shù)

  • insert_quorum
  • insert_quorum_timeout
  • insert_quorum_parallel

復(fù)制表下的查詢(xún)參數(shù)

  • max_replica_delay_for_distributed_queries:當(dāng)執(zhí)行查詢(xún)的時(shí)候,會(huì)選擇某個(gè)副本進(jìn)行數(shù)據(jù)查詢(xún),這是一個(gè)選擇的標(biāo)志,落后多久的副本仍然可以作為查詢(xún)的數(shù)據(jù)來(lái)源。
  • fallback_to_stale_replicas_for_distributed_queries:當(dāng)更新的副本不可用的時(shí)候,強(qiáng)制使用過(guò)時(shí)的副本進(jìn)行查詢(xún),保證查詢(xún)可行
  • select_sequential_consistency:一致性查詢(xún),只有insert_quorum_parallel被禁用的時(shí)候,才會(huì)生效。

復(fù)制表相關(guān)的系統(tǒng)表

system.replicas
system.replicated_fetches
system.replication_queue

復(fù)制的監(jiān)控

各節(jié)點(diǎn)配置的 fetch 任務(wù)隊(duì)列長(zhǎng)度

select 
   hostName() as hostName,
   value 
from clusterAllReplicas('default', 'system.settings')
where name = 'background_fetches_pool_size'
order by hostName;

各節(jié)點(diǎn)正在執(zhí)行的fetch任務(wù)數(shù)

select 
  hostName,
  count(*) as num 
from (
select 
   hostName() as hostName,
   database,
   table
from
  clusterAllReplicas('集群名', 'system.replicated_fetches')
) group by 
hostName

各節(jié)點(diǎn)正在執(zhí)行的fetch任務(wù)的信息,根據(jù)耗時(shí)時(shí)間進(jìn)行排序

select 
   hostName() as hostName,
   result_part_name,
   source_replica_path,
   source_replica_hostname,
   source_replica_port,
   database,
   table,
   elapsed,
   progress,
   total_size_bytes_compressed, --fetch所要讀取的所有的數(shù)據(jù)量 
   bytes_read_compressed, -- 已經(jīng)讀取的數(shù)據(jù)量
   thread_id,
   to_detached
from 
  clusterAllReplicas('default', 'system.replicated_fetches')
order by elapsed desc 

節(jié)點(diǎn)后臺(tái)等待執(zhí)行的fetch 任務(wù)數(shù)

select 
   hostName() as hostName,
   count(*) as num 
from 
   clusterAllReplicas('default', 'system.replication_queue') 
where 
   type = 'GET_PART'
 and is_currently_executing = 0 
order by hostName 

節(jié)點(diǎn)后臺(tái)等待執(zhí)行的fetch 任務(wù)詳細(xì)信息,根據(jù)等待時(shí)間倒序排序

select 
   hostName() as hostName,
   toUnixTimestamp(now()) - toUnixTimestamp(create_time) as task_wait_time,
   source_replica, --來(lái)源副本名
   replica_name,  -- 目標(biāo)副本名
   position,      --任務(wù)位置 
   node_name,     --任務(wù)節(jié)點(diǎn)名
   database,      -- 數(shù)據(jù)庫(kù)名
   table,         -- 表名
   new_part_name, -- 生成的副本的名字
   create_time,   --任務(wù)創(chuàng)建時(shí)間
   num_postponed, -- 推遲次數(shù)
   postpone_reason, -- 推遲原因
   last_postpone_time --上次推遲時(shí)間
from 
   clusterAllReplicas('default', 'system.replication_queue') 
where 
   type = 'GET_PART'
 and is_currently_executing = 0 
order by task_wait_time desc 

重試次數(shù)大于 指定限制的 fetch 任務(wù)數(shù)

select 
  hostName,
  count(*) as num
from (
select 
  hostName() as hostName,
  replica_name
from 
   clusterAllReplicas('集群名', 'system.replication_queue') 
where 
   num_tries > 設(shè)置的重試次數(shù)
   and  type = 'GET_PART'
)
where hostName in (${hostName})
group by
   hostName 

重試次數(shù)大于 指定限制的 fetch 任務(wù)的詳情

select 
   *
from (
select 
   hostName() as hostName,
   num_tries,
   last_exception,
   last_attempt_time,
   source_replica,
   replica_name,
   database,
   table,
   new_part_name,
   node_name,
   position,
   create_time
from 
  clusterAllReplicas('集群名', 'system.replication_queue') 
where 
   num_tries > 重試次數(shù)
   and  type = 'GET_PART'
)
where 
order by num_tries,create_time desc 
limit 30

后臺(tái)part fetch 失敗的次數(shù)

select * from system,events where event = 'ReplicatedPartFailedFetches'

查看fetch 的繁忙程度

通過(guò)查看任務(wù)還未執(zhí)行的延時(shí)時(shí)間,如果出現(xiàn)有的任務(wù)很久之前已經(jīng)提交了,但是很久未被執(zhí)行,可以來(lái)反應(yīng)

select 
  hostName() as hostName,
  toUnixTimestamp(now()) - toUnixTimestamp(create_time) as task_delay,
   * 
from 
  clusterAllReplicas('集群名', ' system.replication_queue ')
where is_currently_executing = 0
   and type = 'GET_PART'
order by 
   task_delay desc  limit 10 
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容