携程用ClickHouse轻松玩转每天十亿级数据更新
作者头像
  • 解云舒
  • 2019-12-08 09:47:09 1

作者简介

蔡岳毅是携程酒店大数据高级研发经理,专注于酒店数据智能平台的研发及大数据技术创新。他热衷于研究大数据领域的开源技术框架。

背景

携程酒店每天需要处理上千张表,累计十多亿条数据更新,如何保证这些数据更新过程中高可用性是一个挑战。每天有接近百万次的数据查询请求,用户需要从国家、省份、城市等粗粒度数据逐步下钻到酒店和房型的详细数据。由于海量数据难以预先聚合,许多关键业务数据需要频繁关联权限和基础信息,根据用户的不同场景需求,获取相应的汇总数据。为了确保用户无论在移动端还是PC端都能快速查询数据,团队一直在探索最适合的技术框架。

ClickHouse介绍

ClickHouse是一款用于大数据实时分析的列式数据库管理系统,而不是传统意义上的数据库。它通过向量化执行和对CPU底层指令集(SIMD)的应用,能够高效地并行处理海量数据,从而大幅提升数据处理速度。

主要优点

  • 高效的CPU利用:数据不仅按列存储,还按向量处理。
  • 大压缩率:显著减少I/O操作。
  • 高吞吐量:单台服务器每秒可处理数十亿行数据。
  • 非B树结构的索引:无需满足最左原则,只需过滤条件在索引列中包含即可。
  • 快速全表扫描:即使数据不在索引中,也能通过并行处理机制快速扫描。
  • 高速写入:每秒可达50-200MB,适合大量数据更新。

使用注意事项

  • 不支持事务:不支持真正的删除或更新操作。
  • 低并发:官方建议QPS为100,可以通过修改配置文件增加连接数,但在服务器性能较好的情况下效果有限。
  • 特殊SQL语法:支持日常使用的80%以上的SQL语法,但JOIN操作较为特殊。
  • 批量写入:尽量进行1000条以上的批量写入,避免逐行插入或小批量插入,因为ClickHouse底层会不断进行异步数据合并,影响查询效率。
  • 高CPU利用率:单查询使用服务器一半的CPU,因此不适用于高并发场景,默认单查询使用CPU核数为服务器核数的一半。

ClickHouse在酒店数据智能平台的应用

数据更新

我们的主要数据源是从Hive到ClickHouse,目前采用以下两种方式:

  1. Hive到MySQL再到ClickHouse

    • 初期由于DataX不支持Hive到ClickHouse的数据导入,我们先将数据导入MySQL,再通过ClickHouse的原生API将数据从MySQL导入到ClickHouse。
    • 设计了一套完整的数据导入流程,确保数据从Hive到MySQL再到ClickHouse自动化、稳定运行,并且保证数据同步过程中的高可用性。
  2. 直接从Hive到ClickHouse

    • DataX现在支持Hive到ClickHouse的直接导入,但为了保证高可用性,仍然需要依赖一套流程进行ReName、增量数据更新等操作。
数据更新机制
  • 全量数据导入流程

    • 将数据先导入到临时表,导入完成后通过ReName操作将数据读取切换到新数据。
  • 增量数据导入流程

    • 最初通过删除指定分区,再导入增量数据到正式表的方式实现。
    • 针对存在的问题,我们修改了增量数据同步方案:在增量数据从Hive同步到ClickHouse的临时表之后,将正式表中的数据反写到临时表,再通过ReName方法切换正式表和临时表。
    • 这样可以基本保证用户在数据导入过程中的无感知体验。

数据导入过程的监控与预警

由于数据量大,数据同步语句常常超时。为了确保每个数据同步过程都可监控,我们没有使用ClickHouse提供的JDBC执行数据同步语句,而是通过调用ClickHouse的Restful API完成所有操作。

在调用Restful API时,可以指定查询的QueryID。在数据同步语句超时时,通过轮询查询进度来保证查询过程的有序运行。异常情况会记录下来,如果异常频次超过阈值,系统会通过短信通知相关人员。

服务器分布与运维

目前根据场景分为国内、海外/供应商、实时数据、风控数据四个集群。每个集群对应两到三台服务器,相互之间主备关系,查询请求分散到不同服务器进行负载均衡。

如果某台服务器出现故障,通过配置界面修正集群服务器节点,可以避免查询请求落到有问题的服务器上。在特定数据查询量较大的时间段,可以组建虚拟集群,将所有请求分散到资源丰富的物理集群上。

我们监控每台服务器的查询量、每个语句的执行时间、服务器的CPU和内存指标,以便及时调整查询量较高的请求到其他服务器。

ClickHouse应用探索

在使用ClickHouse过程中,我们遇到了一些问题,总结如下:

  1. 关闭Linux虚拟内存:在一次内存耗尽的情况下,我们发现杀掉占用内存最多的查询并不能解决问题。经过检查发现虚拟内存占用了大量资源,导致查询速度缓慢。关闭虚拟内存并重启服务后,问题解决。

  2. 为每个账户添加joinusenulls配置:默认情况下,ClickHouse的LEFT JOIN返回的是字段默认值而不是NULL值。为适应标准SQL习惯,需要为每个账户添加此配置。

  3. JOIN操作时数据量小的表放在左边:ClickHouse在JOIN操作时总是拿右表的每条记录去左表查找,因此右表应尽可能小。

  4. 批量写入数据时注意分区数量:使用ClickHouse官方JDBC批量写入数据时,控制每个批次的数据中涉及的分区数量,最好先通过ORDER BY语句对数据进行排序。

  5. 减少JOIN操作的数据量:尽量减少JOIN操作时的左右表数据量,必要时提前对某张表进行聚合操作,以减少数据条数。

  6. 使用稳定的版本:ClickHouse版本迭代较快,建议使用较稳定的版本,避免遇到新版本中的bug。

  7. 避免使用分布式表:ClickHouse的分布式表在性价比上不如物理表,建表时分区字段值不宜过多,否则可能导致磁盘空间不足。

  8. 监控CPU使用率:服务器CPU在50%左右时可能出现查询波动,70%时可能会出现大范围查询超时。因此,对ClickHouse查询的CPU使用率需重点关注。

  9. 优化查询语句:ClickHouse在某些查询场景下表现出色,例如6000万数据关联1000万数据再关联2000万数据,SUM一个月间夜量只需190毫秒;2.4亿数据关联2000万数据group by一个月的数据大约390毫秒。但查询语句仍需不断优化。

总结

自去年7月试点以来,携程酒店数据智能平台已有80%以上的业务接入ClickHouse,能够处理每天十多亿的数据更新和近百万次的数据查询。移动端查询功能98.3%能在1秒内返回结果,PC端查询功能98.5%能在3秒内返回结果。从查询速度和成本来看,ClickHouse优于传统的关系型数据库和ElasticSearch、Redis等工具。

我们将继续深入研究ClickHouse,跟进最新版本,并持续探索更适合的技术框架。

    本文来源:图灵汇
责任编辑: : 解云舒
声明:本文系图灵汇原创稿件,版权属图灵汇所有,未经授权不得转载,已经协议授权的媒体下载使用时须注明"稿件来源:图灵汇",违者将依法追究责任。
    分享
携程ClickHouse每天轻松更新数据
    下一篇