ElasticSearch是一个基于Lucene的分布式全文搜索引擎。携程使用ES来处理日志。目前服务器规模500+,日均日志访问量约200TB。图片来自Pexels随着日志量的不断增加,一些问题也逐渐暴露出来:一方面,ES服务器越来越多,投资成本越来越高。另一方面,用户满意度不高,日志写入延迟、查询慢,甚至查不出来等问题一直困扰着用户。从运维人员的角度来看,ES的运维成本比较高,运维压力越来越大。为什么选择ClickHouseClickHouse是一个高性能的列式分布式数据库管理系统。我们对ClickHouse进行了测试,发现有以下优势:①ClickHouse写入吞吐量大,单台服务器的日志写入量在50MB-200MB/s之间。写入记录数超过60w,是ES的5倍多。②ES中比较常见的writingRejected导致数据丢失,写入延迟等问题,在ClickHouse中不容易发生。③查询速度快。官方称数据在pagecache中,单台服务器的查询速度约为2-30GB/s;没有pagecache,查询速度取决于磁盘读取率和数据压缩率。经过测试,ClickHouse的查询速度比ES快5-30倍。ClickHouse成本低于ES服务器:一方面,ClickHouse的数据压缩比高于ES,同样数据占用的磁盘空间仅为ES的1/3到1/30,节省磁盘空间,有效减少磁盘IO。这是ClickHouse查询效率更高的原因之一。另一方面,ClickHouse比ES占用更少的内存和消耗更少的CPU资源。我们估计使用ClickHouse处理日志可以将服务器成本降低一半。④与ES相比,ClickHouse稳定性更高,运维成本更低。⑤ES中不同组负载不均衡,部分组负载高,会导致写入Rejected等问题,需要手动进行索引迁移;在ClickHouse中,通过集群和分片策略,可以采用轮询和写入的方式,让数据更均匀地分布到所有节点。⑥ES中的大查询可能会导致OOM问题;ClickHouse会通过预设的查询限制查询失败,不会影响整体的稳定性。⑦ES需要冷热数据分离。每天迁移200T数据。稍有不慎,就会在搬迁过程中出现问题。一旦迁移失败,可能很快就会爆出热点节点,导致大量的人工维护和恢复工作。⑧ClickHouse是按性质分区的。一般不需要考虑冷热分离。特殊场景的用户确实需要冷热分离,数据量会小很多。ClickHouse自带的冷热分离机制可以很好的解决。⑨ClickHouse使用SQL语法,比ESDSL更简单,学习成本更低。结合携程的日志分析场景,日志在进入ES之前已经格式化成JSON,同类型的日志有统一的schema,符合ClickHouseTableschema。查询日志时,一般会按照一定的维度统计数量、总量、平均值等,符合ClickHouse做列式存储的使用场景。偶尔会有少部分场景需要对字符串进行模糊查询。通过一些条件过滤掉大量数据后,再对少量数据进行模糊匹配,ClickHouse也可以很胜任。另外我们发现90%以上的日志都没有使用ES的全文索引特性,所以我们决定尝试使用ClickHouse来处理日志。使用ClickHouse处理日志ClickHouse高可用部署方案①容灾部署和集群规划我们采用多分片2副本的方式,服务器之间使用Zookeeper互为备份,做到一台分片一台服务器不宕机数据丢失。为了访问不同大小的日志,我们将集群划分为多个6和20规模的集群。②跨IDC部署借助ClickHouse分布式表的特性,我们实现了跨集群搜索。携程有多个IDC,日志分布在不同的IDC。为了避免跨IDC迁移日志,我们在每个IDC部署一套ClickHouse,然后配置ClickHouse的跨IDCCluster,创建分布式表,实现跨多个IDC的数据查找。如下图所示:③几个重要的参数说明如下:max_threads:32#用来控制一个用户的查询线程数。max_memory_usage:10000000000#单次查询最多可以使用9.31G内存。max_execution_time:30#单个查询的最大执行时间。skip_unavailable_shards:1#通过分布式表查询时,当某个shard无法访问时,其他shard的数据仍然可以查询。④我们踩过的坑我们之前把Cluster的配置放在config.d目录下。当ClickHouse意外重启时,我们发现部分分片无法访问分布式表,所以我们不再使用config.d配置,这样Cluster配置放在metrika.xml中。向ClickHouse消费数据我们使用gohangout向ClickHouse消费数据。数据写入的一些建议:采用轮询的方式写入ClickHouse集群中的所有服务器,保证数据基本均匀分布。大批量低频写入,减少分块数量,减少服务器合并,避免分块过多异常。通过两个阈值控制数据写入的量和频率,10w条以上的记录写入一次或30s写入一次。写本地表,不要写分布式表,因为分布式表收到数据后会把数据拆分成多个部分,转发给其他服务器,这样会增加服务器之间的网络流量和服务器合并的工作量。这导致写入速度变慢,并增加了Toomanyparts的可能性。建表时,要考虑分区设置。之前遇到过有人将partition设置为timestamp,导致插入数据时一直报Toomanyparts的异常。我们一般按人才划分。主键和索引的设置,数据的乱序等也会导致写入变慢。对于数据展示,我们调研了Supperset、Metabase、Grafana等几种工具,最终决定在Kibana3上开发并支持ClickHouse,实现图表展示。主要原因是很多系统没有Kibana3强大的数据过滤功能。此外,考虑到迁移到其他系统的高成本,用户短期内难以适应。目前,我们已经在K3上开发了对应的几种常用图表(terms,histogram,percentiles,ranges,table)的ClickHouse版本。用户体验与原版基本一致,查询效率得到优化和大幅提升。查询优化Kibana中的TablePanel用于展示日志的详细数据。一般是查询最近一个小时所有字段的数据,最后只显示前500条记录。这种场景对ClickHouse很不友好。为了解决这个问题,我们将表格Panel的查询分为两步:第一步查询单位时间间隔的数据量,根据最终显示的数据量计算合理的查询时间范围。第二次,根据修正后的时间范围,结合TablePanel配置的默认显示Column查询明细数据。经过这些优化后,查询时间可以缩短到原来的1/60,查询的列可以减少50%,最终查询数据量可以减少到原来的1/120。ClickHouse提供了多种近似计算方法,在提供相对较高的精度的同时,减少了计算量。使用MATERIALIZEDVIEW或MATERIALIZEDCOLUMN正常完成计算也能有效减少查询的数据量和计算量。Dashboard迁移由于Kibana3上的Dashboard较多,我们开发了一个Dashboard迁移工具,通过修改kibana-init-*索引中Dashboard的配置来进行Dashboard迁移。连接ClickHouse的效果目前我们集群的日志量在100T左右(压缩前约600T),ClickHouse服务器的主要监控指标如下:ClickHouse占用内存比ES少。ES为了提高查询效率,会在内存中存放大量的数据,例如:段索引数据、过滤器缓存、字段数据缓存、索引缓冲区等。ES内存的使用量与索引量成正比,数据、写入、查询等。删除(离线)索引、迁移索引或扩容是处理ES内存问题的常用方法。但是,删除(离线)索引使得无法满足用户想要更长时间保存数据的需求,服务器的扩容导致成本增加。ClickHouse的内存消耗主要包括内存引擎、数据索引、加载到内存中的待计算数据、搜索结果等。ClickHouse中日志的数据量和存储时间主要与磁盘有关。与ES相比,ClickHouse至少可以节省60%的磁盘空间。如上图所示,Netflow日志占ES磁盘空间的32%,CDN日志占ES的18%,Dblog日志占ES的22.5%。与查询速度提升相比,ClickHouse比ES快4.4倍到38倍。原查询在ES上找不到的问题基本解决了,查询慢的问题也有了很大的改善。由于Netflow中数据量大,无法查询到ES。经过ClickHouse优化,查询耗时29.5s。CDN的查询CK和ES快38倍,dbLog的查询CK比ES快4.4倍。关于查询速度的对比,因为在生产环境中,不能保证ES和ClickHouse的环境是一样的。ES使用40核256G服务器。一台服务器部署一个ES实例,单台??服务器的数据量约为3T。ClickHouse采用32核128G服务器,单台服务器数据量约18T,一台服务器部署一个ClickHouse实例。使用ClickHouse处理日志查询速度有了很大的提升,基本解决了数据存储时间短的问题,用户体验也得到了提升。我们估计使用当前ES日志集群50%的服务器资源,可以完成对现有ES日志的处理,提供比当前更好的用户体验。ClickHouse基础运维总的来说,ClickHouse的运维要比ES简单,主要包括以下几个方面的工作:①新增日志接入和性能优化。②过期日志的清理,我们每天通过定时任务删除过期日志的分区。③ClickHouse监控,采用ClickHouse-exporter+VictoriaMetrics+Grafana实现。④数据迁移,通过ClickHouse分布式表的特性,我们一般不会对历史数据进行迁移,只是将新数据连接到新的集群,然后通过分布式表进行跨集群查询。随着时间的推移,历史数据将被清理并下线。当旧集群数据全部下线后,新旧集群迁移完成。当确实需要迁移数据时,使用ClickHouse_copier或者复制数据。⑤常见问题处理:slowquery:通过killquery终止slowquery的执行,通过上述优化方案进行优化。Toomanypartexception:过多的partsexception是由于编写的parts过多,parts的merge速度跟不上生成的速度。零件过多的原因主要有几个方面:设置不当。ClickHouse小批量、高频度写。我写了ClickHouse的分布式表。ClickHouse设置的合并线程数太少。无法启动:之前遇到过ClickHouse无法启动的问题。主要包括两个方面:文件系统损坏,可以通过修复文件系统来解决。某表数据异常导致ClickHouse加载失败。可以删除异常数据再启动,或者将异常文件移动到detached目录,待ClickHouseup后附加文件恢复数据。小结将日志从ES迁移到ClickHouse,可以节省更多的服务器资源,降低整体运维成本,提高查询速度,尤其是在用户紧急排错的时候。用户体验得到了显着改善。我们将继续致力于将ES日志迁移到ClickHouse,优化日志查询性能,让ClickHouse在日志分析领域为用户提供更大的价值。但是ClickHouse毕竟不是ES。ES在很多业务场景中仍然是不可替代的。ClickHouse不仅可以处理日志。进一步深入研究ClickHouse,让ClickHouse在更多领域发挥更大价值,是我们一直努力的方向。作者:GavinZhu简介:携程软件技术专家,负责监控系统运维开发、ES系统运维和Clickhouse技术应用推广和运维工作。编辑:陶佳龙来源:转载自公众号携程科技(ID:ctriptech)
