ClickHouse部署系列1: ZooKeeper集群部署

ZooKeeper集群部署

  • ClickHouse分布式集群方案
    • 建立标准的ZK的目录使用规范
    • 副本的设置的建议
    • 机器选择的建议
    • ClickHouse的分布式高可用的架构方案
  • 在k8s集群上部署ZooKeeper
    • ZooKeeper简介
    • ZooKeeper部署安装
    • 创建manifest文件
    • 部署install

ClickHouse分布式集群方案

这两天在调研clickhouse集群部署方案,为实现高可用且性能较优,现可实行方案如下:

基于ClickHouse的集群的常见方案,结合业界的架构方案,优质的选择是基于ReplicatedMergeTree + Distributed的集群架构方案,也是分布式高可用的集群架构方案,但是在使用该集群架构的过程中,需要注意:

写表的方式:写本地表,读分布式表

由于分布式表的逻辑简单,仅仅是转发请求,所以在转发安全性上,会有风险,并且rand的方式,可能会造成不均衡,业界建议,通过DNS轮训,写本地表,这样最保险和均衡

统一的建表,表管理入口

CK的分布式,完全依赖配置文件,即每个节点,都共享同样的配置文件,建表要区分集群,又要区分副本,建议写一个脚本来统一建表,或者开发一个可视化的页面,操作管理CK表

建议结合查询的负载均衡做,分布式查询的节点可以在每一个节点都建分布式表,查询的选择性更多

建立标准的ZK的目录使用规范

ReplicatedMergeTree + Distributed的分布式的方案,副本的复制依赖zk,需要统一的规划Zookeeper的使用规范

一台或者多台查询机?建立分布式表,平衡好查询节点机器资源和数据量之间的关系

ClickHouse查询使用并行处理机制,对CPU和内存的要求比较高,不建议单台机器部署多个节点,同时建议建Zookeeper的节点和CK的节点分开部署,防止高负载下的相互影响

介于ClickHouse对并发的支持有限,建议查询做LB

CK默认的查询并发是100,当并发达到一定的程度,会存在一个排队的现象,介于多shard,多副本的情况,做查询的负载均衡能很好的提高查询的并发有限的问题

副本的设置的建议

同一份数据,日常至少有2份即可,如果其中一份挂掉,新建一个表,把另一份及时同步过来就好

重要的数据建议3个节点做复制,设置至少保证2个节点收到数据才算成功,增强数据的一致性

机器选择的建议

ClickHouse的节点故障,出现问题,在节点恢复的过程中:故障恢复的过程中的确存在带宽的问题

ClickHouse目前不支持多数据盘,选择合适的RAID方式,建议使用RAID5,配置热备盘,对数据的可靠性,数据恢复,运维难度都有比较好的保障

关闭Linux虚拟内存。在ClickHouse服务器内存耗尽的情况下,Kill掉占用内存最多的Query之后发现,这台ClickHouse服务器并没有如预期的那样恢复正常,所有的查询依然运行的十分缓慢。

通过查看服务器的各项指标,发现虚拟内存占用量异常。因为存在大量的物理内存和虚拟内存的数据交换,导致查询速度十分缓慢。关闭虚拟内存,并重启服务后,应用恢复正常。

由于CK查询性能在单节点查询的时候基本能跑满CPU,所以建议CPU的核数高一点,建议选择48核,内存选择192G

集群规模的建议
ClickHouse官方建议不搞特别大的集群,建议一个业务就跑一个集群,具体多少分片,自己衡量

请务必使用hostname,并在所有/etc/hosts下加入对应的host规则,否则可能一定导致zookeeper无法同步复制表信息!!!!

规划好和ClickHouse的数据交换服务及相关设置

实时写入ClicHouse的时候需要注意的问题

尽量做1000条以上批量的写入,避免逐行insert或小批量的insert,update,delete操作,因为ClickHouse底层会不断的做异步的数据合并,会影响查询性能,这个在做实时数据写入的时候要尽量避开;

ClickHouse的分布式高可用的架构方案

Load Balance + Distributed table + ReplicatedMergeTree + zookeeper

在k8s集群上部署ZooKeeper

假设已经部署好了k8s集群。

ZooKeeper简介

Apache ZooKeeper是一个分布式的开源协调服务,用于分布式应用程序。ZooKeeper允许你读取、写入和观察数据的更新。数据以文件系统的形式组织,并复制到整个集群(一组ZooKeeper服务器)的所有ZooKeeper服务器。所有对数据的操作都是原子的和顺序一致的。ZooKeeper通过使用Zab共识协议在整个集群的所有服务器上复制状态机来确保这一点。

在 ClickHouse 部署方案中,ZooKeeper 主要扮演了以下4个角色:

  1. 元数据存储:ZooKeeper 存储了 ClickHouse 集群的元数据,包括表结构、分片配置、副本配置等。当 ClickHouse 集群中的节点需要获取或更新这些信息时,它们会与 ZooKeeper 交互。
  2. 分布式锁:当 ClickHouse 集群中的多个节点需要对同一份数据进行写入操作时,ZooKeeper 提供了分布式锁服务,确保了数据的一致性和完整性。
  3. 副本同步:在 ClickHouse 的分布式表中,数据会被分片并在多个副本之间复制。ZooKeeper 负责协调这些副本之间的同步,确保所有副本都有最新的数据。
  4. 故障检测和恢复:ZooKeeper 可以监控 ClickHouse 集群中的节点状态,当某个节点发生故障时,ZooKeeper 可以协调其他节点进行故障恢复,例如重新分配该节点的分片和副本。

总的来说,ZooKeeper 在 ClickHouse 部署方案中起到了关键的协调和管理角色,确保了 ClickHouse 集群的稳定性和高可用性。

ZooKeeper部署安装

本文ZooKeeper是部署在k8s集群上的,部署方案参考:zookeeper_on_k8s

创建manifest文件

主要包含4块内容:Headless Service, Service, PodSisruptionBudget, StatefulSet

apiVersion: v1
kind: Service
metadata:
  name: zk-hs
  labels:
    app: zk
spec:
  ports:
  - port: 2888
    name: server
  - port: 3888
    name: leader-election
  clusterIP: None
  selector:
    app: zk
---
apiVersion: v1
kind: Service
metadata:
  name: zk-cs
  labels:
    app: zk
spec:
  ports:
  - port: 2181
    name: client
  selector:
    app: zk
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: zk-pdb
spec:
  selector:
    matchLabels:
      app: zk
  maxUnavailable: 1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: zk
spec:
  selector:
    matchLabels:
      app: zk
  serviceName: zk-hs
  replicas: 3
  updateStrategy:
    type: RollingUpdate
  podManagementPolicy: OrderedReady
  template:
    metadata:
      labels:
        app: zk
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                    - zk
              topologyKey: "kubernetes.io/hostname"
      containers:
      - name: kubernetes-zookeeper
        imagePullPolicy: Always
        image: "registry.k8s.io/kubernetes-zookeeper:1.0-3.4.10"
        resources:
          requests:
            memory: "10Gi"
            cpu: "1"
        ports:
        - containerPort: 2181
          name: client
        - containerPort: 2888
          name: server
        - containerPort: 3888
          name: leader-election
        command:
        - sh
        - -c
        - "start-zookeeper \
          --servers=3 \
          --data_dir=/var/lib/zookeeper/data \
          --data_log_dir=/var/lib/zookeeper/data/log \
          --conf_dir=/opt/zookeeper/conf \
          --client_port=2181 \
          --election_port=3888 \
          --server_port=2888 \
          --tick_time=2000 \
          --init_limit=10 \
          --sync_limit=5 \
          --heap=512M \
          --max_client_cnxns=60 \
          --snap_retain_count=3 \
          --purge_interval=12 \
          --max_session_timeout=40000 \
          --min_session_timeout=4000 \
          --log_level=INFO"
        readinessProbe:
          exec:
            command:
            - sh
            - -c
            - "zookeeper-ready 2181"
          initialDelaySeconds: 10
          timeoutSeconds: 5
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - "zookeeper-ready 2181"
          initialDelaySeconds: 10
          timeoutSeconds: 5
        volumeMounts:
        - name: datadir
          mountPath: /var/lib/zookeeper
      securityContext:
        runAsUser: 1000
        fsGroup: 1000
  volumeClaimTemplates:
  - metadata:
      name: datadir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: csi-rbd-sc
      resources:
        requests:
          storage: 100Gi


在install之前,我们可以看到ZooKeeper Data需要创建PVC进行存储,由于我们用的后端存储是ceph,所以这里我直接创建cephfs的PVC

apiVersion: v1
kind: PersistentVolume
metadata:
  name: zookeeper-data-pv
spec:
  capacity:
    storage: 1000Gi
  accessModes:
    - ReadWriteMany
  cephfs:
    monitors:
      - 192.168.0.13:6789
      - 192.168.0.14:6789
      - 192.168.0.15:6789
    user: admin
    path: /app/zookeeper/data
    secretRef:
      name: ceph-secret
      namespace: airflow
    readOnly: false
  persistentVolumeReclaimPolicy: Retain
---
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zookeeper-data-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1000Gi
  volumeName: zookeeper-data-pv



这里我们使用ceph rbd作为后端持久化存储,这样能保证数据持久化,不会因为服务重启或中断而丢失。

生成之后,我们会有一个文件: zookeeper.yaml

部署install

kubectl create ns zookeeper
kubectl apply -f zookeeper.yaml -n zookeeper

你可能感兴趣的:(clickhouse,clickhouse,zookeeper,分布式)