一.背景
1.公司的后端架构基于k8s的微服务体系,每个服务都拥有独立的Mysql库。而我们还有MongoDB集群,redis集群的数据分布,这样对于我们在做数据聚合的时候异常麻烦,数据抽象也不够具体。公司的平均日活大概在500W左右,最近在研发推荐系统,需要大量的数据来跑行为分析,所以搭建完善的数据聚合平台迫在眉睫。
2.每天会有百万次的查询请求,数据的查询粒度由上往下,愈发细,关键业务的数据需要穿插多个rpc,关联好几M的数据,维度的不同,导致查询的压力也极速上升
初始的时候,我们尝试将MySQL做Sharding,但数据量较大,成本还是比较高的。然后又尝试将热点扔到ES中,但是如果信息变化了,每次不得不刷全量数据,所以不太适合做大表的更新。
直到我们碰到ClickHouse!
二.基本介绍
https://clickhouse.yandex/docs/en/ 参考官方文档
下面来说说我们在ClickHouse上的实践
三.基于Zookeeper的ClickHouse集群构建
环境CenterOs7,4台机器作为ClickHouse的集群,其中一台作为Query节点,另外3台为cluster,另外我们还需要3台机搭建Zookeeper集群
clickhouse1: 实例1, 端口: tcp 9000, http 8123, 同步端口9009, 类型: 分片1, 副本1
clickhouse2: 实例1, 端口: tcp 9000, http 8123, 同步端口9009, 类型: 分片1, 副本2
clickhouse2: 实例2, 端口: tcp 9001, http 8124, 同步端口9010, 类型: 分片2, 副本1
clickhouse3: 实例1, 端口: tcp 9000, http 8123, 同步端口9009, 类型: 分片2, 副本2
clickhouse3: 实例2, 端口: tcp 9001, http 8124, 同步端口9010, 类型: 分片3, 副本1
clickhouse1: 实例2, 端口: tcp 9001, http 8124, 同步端口9010, 类型: 分片3, 副本2
最终我们需要是以上的架构,下面我们来具体操作下
1.安装jdk1.8
jdk环境是zk必须,所以安装jdk
>mkdir /usr/local/java >tar -xf jdk-8u131-linux-x64.tar.gz -C /usr/local/java >vim /etc/profile #===========jdk1.8============== export JAVA_HOME=/usr/local/java export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH
2.安装zookeeper
集群有n个节点,每个节点的数据依靠zookeeper协调同步。
>mkdir ../zookeeper >tar -xf zookeeper-3.4.10.tar.gz >mv zookeeper-3.4.10/* /usr/local/zookeeper >mv /usr/local/zookeeper/conf/zoo_sample.cfg /usr/local/zookeeper/conf/zoo.cfg >vim /usr/local/zookeeper/conf/zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper/zkdata dataLogDir=/data/zookeeper/zklog clientPort=2181 autopurge.purgeInterval=0 globalOutstandingLimit=200 server.1=xxx.xxx.xxx.xxx:2888:3888 server.2=xxx.xxx.xxx.xxx:2888:3888 server.3=xxx.xxx.xxx.xxx:2888:3888 >vim /usr/local/zookeeper/conf/zookeeper-env.sh #!/bin/bash ZOO_LOG_DIR=/data/zookeeper/zklog #日志文件放置的路径 ZOO_LOG4J_PROP="INFO,ROLLINGFILE" #设置日志轮转 JVMFLAGS="-d64 -Xmx512m -Xms512m -Xmn128m -Xloggc:${ZOO_LOG_DIR}/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${ZOO_LOG_DIR}/oom.log" >mkdir /data/zookeeper/zkdata -p >mkdir /data/zookeeper/zklog 在3台机器上启动zk >/usr/local/zookeeper/bin/zkServer.sh start >/usr/local/zookeeper/bin/zkServer.sh status
3.安装ClickHouse集群
- 1st shard, 1st replica, hostname: clickhouse1
- 1st shard, 2nd replica, hostname: clickhouse2
- 2nd shard, 1st replica, hostname: clickhouse2
- 2nd shard, 2nd replica, hostname: clickhouse3
- 3rd shard, 1st replica, hostname: clickhouse3
- 3rd shard, 2nd replica, hostname: clickhouse1
安装clickHouse需要以下几个包
使用rpm -ivh +6个rpm包。会自动解决安装的前后顺序,基本没有依赖包需要,只缺少一个lib,使用yum安装即可。
安装之后clickhouse会自动加到systemd启动当中,
/etc/clickhouse-server clickhouse服务的配置文件目录,包括:config.xml和users.xml /etc/clickhouse-client clickhouse客户端的配置文件目录,里面只有一个config.xml并且默认为空 /var/lib/clickhouse clickhouse默认数据目录 /var/log/clickhouse-server clickhouse默认日志目录 /etc/init.d/clickhouse-server clickhouse启动shell脚本,用来方便启动服务的.我们这里主要使用脚本启动,因为我们在单机上运行2个服务。 /etc/security/limits.d/clickhouse.conf 最大文件打开数的配置,这个在config.xml也可以配置 /etc/cron.d/clickhouse-server clickhouse定时任务配置,默认没有任务,但是如果文件不存在启动会报错. /usr/bin clickhouse编译好的可执行文件目录,主要有下面几个: clickhouse clickhouse主程序可执行文件 clickhouse-compressor clickhouse-client 是一个软链指向clickhouse,主要是客户端连接操作使用 clickhouse-server 是一个软链接指向clickhouse,主要是服务操作使用
主要我们来看下 config.xml,metrika.xml 这两个文件
- config.xml
<yandex> <!-- 日志 --> <logger> <level>trace</level> <log>/data_rd5/clickhouse/log/server.log</log> <errorlog>/data_rd5/clickhouse/log/error.log</errorlog> <size>1000M</size> <count>10</count> </logger> <!--时区--> <timezone>Asia/Shanghai</timezone> <!-- 端口 --> <http_port>8123</http_port> <tcp_port>9000</tcp_port> <interserver_http_port>9009</interserver_http_port> <!-- 本机域名 --> <interserver_http_host></interserver_http_host> <!-- 监听IP --> <listen_host></listen_host> <!-- 最大连接数 --> <max_connections>64</max_connections> <!-- 没搞懂的参数 --> <keep_alive_timeout>3</keep_alive_timeout> <!-- 最大并发查询数 --> <max_concurrent_queries>100</max_concurrent_queries> <merge_tree> <parts_to_delay_insert>300</parts_to_delay_insert> <parts_to_throw_insert>600</parts_to_throw_insert> <max_delay_to_insert>2</max_delay_to_insert> <max_suspicious_broken_parts>5</max_suspicious_broken_parts> </merge_tree> <!-- 单位是B --> <uncompressed_cache_size>8589934592</uncompressed_cache_size> <mark_cache_size>10737418240</mark_cache_size> <!-- 存储路径 --> <path>/data_rd5/clickhouse/</path> <tmp_path>/data_rd5/clickhouse/tmp/</tmp_path> <!-- user配置 --> <users_config>users.xml</users_config> <default_profile>default</default_profile> <log_queries>1</log_queries> <default_database>default</default_database> <remote_servers incl="clickhouse_remote_servers" /> <zookeeper incl="zookeeper-servers" optional="true" /> <distributed_ddl> <path>/usr/local/zookeeper/bin</path> </distributed_ddl> <macros incl="macros" optional="true" /> <!-- 没搞懂的参数 --> <builtin_dictionaries_reload_interval>3600</builtin_dictionaries_reload_interval> <!-- 控制大表的删除 --> <max_table_size_to_drop>0</max_table_size_to_drop> <include_from>/etc/clickhouse-server/metrika.xml</include_from> </yandex>
- metrika.xml
<yandex> <!-- 集群配置 --> <clickhouse_remote_servers> <bip_ck_cluster> <!-- 数据分片1 --> <shard> <weight>1</weight> <internal_replication>true</internal_replication> <replica> <host></host> <port>9000</port> <user>default</user> <password>6lYaUiFi</password> </replica> <replica> <host></host> <port>9000</port> <user>default</user> <password>6lYaUiFi</password> </replica> </shard> <!-- 数据分片2 --> <shard> <weight>1</weight> <internal_replication>true</internal_replication> <replica> <host></host> <port>9001</port> <user>default</user> <password>6lYaUiFi</password> </replica> <replica> <host></host> <port>9000</port> <user>default</user> <password>6lYaUiFi</password> </replica> </shard> <!-- 数据分片3 --> <shard> <weight>1</weight> <internal_replication>true</internal_replication> <replica> <host></host> <port>9001</port> <user>default</user> <password>6lYaUiFi</password> </replica> <replica> <host></host> <port>9001</port> <user>default</user> <password>6lYaUiFi</password> </replica> </shard> </bip_ck_cluster> </clickhouse_remote_servers> <!-- 本节点副本名称(这里无用) --> <macros> <layer>01</layer> <shard>01</shard> <replica>ck01-01-01</replica> </macros> <!-- 监听网络(貌似重复) --> <networks> <ip>::/0</ip> </networks> <!-- ZK --> <zookeeper-servers> <node index="1"> <host></host> <port>2181</port> </node> <node index="2"> <host></host> <port>2181</port> </node> <node index="3"> <host></host> <port>2181</port> </node> </zookeeper-servers> <!-- 数据压缩算法 --> <compression incl="clickhouse_compression"> <case> <min_part_size>10000000000</min_part_size> <min_part_size_ratio>0.01</min_part_size_ratio> <method>zstd</method> </case> </compression> </yandex>
以上是两个主要文件的配置,以及每一个标签的注解,config为主配置文件,metrika为zk的监听文件
集群:6+1模式,6台数据节点和1台查询节点。
机器配置:32C+128G+88000G,查询节点不带硬盘。
有一个不得不说的东西,raid磁盘列阵,他利用虚拟化存储技术把多个硬盘组合起来,成为一个或多个硬盘阵列组,目的提升性能或数据冗余或是两者同时提升。
我们看到config.xml里的这个配置
<path>/data_rd5/clickhouse/</path> <tmp_path>/data_rd5/clickhouse/tmp/</tmp_path>
raid5优势以及缺点:
- 提供更好的性能。
- 支持冗余和容错。
- 支持热备份。
- 将用掉一个磁盘的容量存储奇偶校验信息。
- 单个磁盘发生故障后不会丢失数据。我们可以更换故障硬盘后从奇偶校验信息中重建数据。
- 适合于面向事务处理的环境,读操作会更快。
- 由于奇偶校验占用资源,写操作会慢一些。
- 重建需要很长的时间
具体raid组的配置玩法 ,有机会再说。
四.总结
万事开头难,今天理了下clickHouse的安装,这只是最简单的第一步,下一期,理一下具体的数据同步方式,以及ClickHouse在生产中碰到的一系列问题及解决方案