Cassandra 在 CDN 监控数据中的应用

作者:陈润生

背景

本次是在腾讯云cdn监控最详细数据数据量在非压缩情况下每天10T左右的数据,进行存储并提供接口多样化查询的背景下,使用cassadnra进行实践,本文目的在于通过cassandra在cdn监控数据中的应用,分享一种无阻碍快速使用cassandra的思路,而非cassandra最佳实践。

业务场景

监控数据大部分使用场景都是使用域名+时间作为条件来查询数据,查询频率不高,并且cdn提供给用户高频率查询有一层数据汇总缓存,减少了查询频率。典型的写多读少的场景。

数据字段:

域名,时间,指标名,平台,ip,指标值

为什么选择cassandra

1、cassandra写入快,cassandra写数据时,首先会将请求写入Commit Log以确保数据不会丢失,然后再写入内存中的Memtable,超过内存容量后再将内存中的数据刷到磁盘的SSTable,并定期异步对SSTable做数据合并(Compaction)以减少数据读取时的查询时间。因为写入操作只涉及到顺序写入和内存操作,因此有非常高的写入性能。在测试中,cassandra数据写入速度,比hbase要快。

2、cassandra是列式存储及顺序写入,对于命中分区键的低频率顺序数据查询,效率还是比较理想,测试中查出10个时间点所有域名(10W域名)并格式化,耗时在5秒内。监控数据最小是一分钟数据,该读取速度能满足业务的需求。

3、cassandra搭建简单,因为cassandra的区中心化模式,只需安装节点,配置同步后,修改seed、启动程序即可。可用性高。

4、cassandra的一致性问题,可以通过多副本的方式来规避。比如开3副本,写2,读2。

cassandra 在监控数据中的一些姿势

1、不使用counter

counter类型在cassandra中似乎是一个累赘(个人观点)。在5分钟数据入库时,数据在汇总后,大概是20W-30W行每分钟,此时cassandra只要调大heap,即可以支持counter,并且对系统的负载不会特别高。当使用1分钟数据入库时,数据汇总后,数据量大概是50W行每分钟,字段使用counter后,节点频繁挂掉,并且出现大量写入超时及失败的情况。监控发现内存暴增,且集群负载极高,gc频率也特别高,集群不可用性极其高。counter的写入是会对数据进行一次查询后,再写入,所以可能会引起所有数据成为热点数据,引起集群负载异常。所以对于小量数据,使用counter是比较方便,但是数据量大了之后,建议放弃counter,且counter对于重入的数据,无法辨识,只能通过业务来消除,对业务逻辑造成一定的复杂度。

对于counter的替代,监控数据中,每一批入库数据,使用一个唯一可识别的键值,对每行数据做唯一性标示,即避免了重入的问题,也避免了counter带来的集群不稳定问题。

2、删除数据的姿势

cassandra删除数据的时候,并不会直接删除,而是有一个tombstone被写进来,标示该数据已经被删除,并且等到gc_grace_seconds后,才会被删除。

cassandra drop表的时候,会将该表的数据全部生成一个snapshot,且不会删除,必须人工删除或使用nodetool cleansnapshot来清理

最细粒度ip数据存储的时候,使用spark直接往cassandra写数据,数据分表比较困难(还没get到这姿势),在数据写了一段时间后,磁盘告警。当时很傻很天真地以为使用遍历分区表键的方式,来清理数据,然而事与愿违,查询分区键的时候,出现大量超时且读不出来的情况,数据清理上突然间陷入了困境。即没办法分表删除,也没办法遍历分区键删除。这份数据真想不到要怎么清理了。再想到nosql数据库都会有key过期的一些做法。随即查了一下,发现有ttl这个东西,经过一周测试,该方式是确实可行。但是查询超时的情况有所增长,但是在可接受范围,该超时情况暂时还没实际解决。

删除数据当前使用了两种方式:

a、设置表的ttl,并且调整gc_grace_seconds,一般建议1800-3600秒,可以配合节点退出监控的间隔来设置,主要是避免墓碑被删掉之后,节点启动数据又重现。使用该方式,在数据入库时,可以直接写数据,不用再筛选数据。

b、数据分表,定时drop 历史表,使用nodetool cleansnapshot,清理数据。使用该方式因为分表,在数据入库时,要对数据进行一次筛选。当使用nodetool cleansnapshot时,如果数据量太大,可能会引起util_max飙高,数据查询超时的情况。

3、分区键的选择

分区键的选择,这是一个数据建模的关键,对于查询速度,写入都有至关重要的影响。因为监控数据的业务场景都是必须通过域名来查询数据,所以域名做为分区键是再合适不过了,这样即可避免写入的热点问题,也实现了集群的负载均衡。但是又带来了一个问题,通过时间点或时间段查询数据,则无法查询。下一点则介绍了当前的解决方法。

4、其他索引的建立(非2级索引)

通过数据冗余的方式,来建立索引。当前每一个时间戳的分区键都存到了redis,即建立了一层索引。为什么索引数据不直接写入cassandra?因为如果cassandra表的分区键使用时间戳,会带来全天写入的热点问题,导致某一节点负载特别高。所以当天的热数据索引都存到redis,第二天凌晨会将前一天的冷数据索引通过同步程序,同步到cassandra。

5、数据写入的姿势

数据写入,cassandra提供了thrift接口和native接口,thrift接口已经不建议实用,对于数据的写入方式,api提供了同步、异步和批量的写入方式。

cassandra的批量写入的方式,每一批次的数据量是有限制的,每次提交太多行数据则会写入失败。datastax上明确说了,它对提高写入效率并没有很大帮助,batch的主要功能是一种事务型的操作,但是在每次提交的数据中,如果是同一个分区的数据,或者同一个节点的数据,确实是能提高写入效率,因为它能避免了节点间的网络开销。datastax上文章表示,可以实用异步写入的方式来替代。但是在实际的写入中,发现batch的写入速度还是可以的,不比异步写入慢,而且不需要等待回调。所以我还是使用了batch

6、数据读取的姿势

数据读取,尽量将大批量的查询划分成合适的小批量查询,分多次请求拉取,否则,容易出现查询超时的情况,因为对于不在memtable的数据,cassandra会再到sstable搜索,这样查询会有一定延迟。如果数据量比较大,超时情况会变严重。

7、节点存活监控

因为cassandra的节点容易出现莫名其妙挂掉的情况,所以在每一个节点部署的时候,都加了一个进程存活的旁路监控脚本,实时监控,并拉起进程。

8、heap调整

调大heap,可以减少数据频繁从memtable flush到sstable,且数据可以cache更多到内存,增强查询效率,但是如果heap过大,gc的时候,容易产生节点过长时间的不可用,所以heap的设置,这个得根据具体的场景和jvm的gc来调整。暂时还没研究到具体的算法可以确定这个值。就目前的数据量,我是配置了32G的heap,暂时还没发现什么特别大的问题。

9、cassandra版本变动会有不向下兼容的情况

除了重新搭建,不会更新cassandra版本,这个大坑,当某个版本使用稳定了之后,则固化不升级。

暂时未解决的一些问题:

1、数据查询超时

对于部分数据量比较大的查询,会存在第一次查询超时的情况,必须发起第二次重试,才可正常查询,或者把大批量查询分多次查询来实现。

2、节点程序莫名关闭

该问题暂时无解,现在的处理方式是,监控进程是否存在,如果不存在则拉起程序并发告警。

3、遍历分区键的问题

distinct 分区键的时候,键比较多,几十到上百万,查询时只能查询到前面的部分键,查到后面基本都回超时,使用sdk分批查询时超时的情况也是必现,暂时无解。目前的替代方式,是对当天活动的分区键冗余存到redis,每天凌晨同步一次到cassandra的一个表中,这样来避免分区键实时入cassandra的热点的问题,且保留了遍历分区键的功能。

总结

cdn监控数据利用了cassandra的高可用,写入速度快,搭建简单等特点,存储了每天高达10T的数据。通过数据冗余建立索引、分区键的选择、调整heap,支持了多样化的查询。通过外部旁路监控程序监控进程等手段保证了集群的高可用。弃用counter类型,保证数据的唯一性和节点的高可用性。

cassandra文章相对比较少,版本间变动比较大,cassandra在cdn监控数据的应用中,只是将cassandra当做一个高可用,灵活扩展的keyvalue存储来使用,使用了其中最简单和最常用的功能。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ImportSource

扒扒HTTP缓存

摘要: 本文会从理论和实战两方面描述http缓存。理论层面会介绍:缓存命中、缓存丢失、Revalidations(重新验证)、命中率(Hit Rate)、字节...

3286
来自专栏CSDN技术头条

Schemaless架构(二):Uber基于MySQL的Trip数据库

ber的Schemaless数据库是从2014年10月开始启用的,这是一个基于MySQL的数据库,本文就来探究一下它的架构。本文是系列文章的第二部分;第一部分是...

2047
来自专栏北京马哥教育

Nginx+FPM结构模型剖析及优化

随着php脚本语言使用的普及,目前webserice服务大部分都在用nginx+(php-fpm)的结构,了解了其工作过程后才可以在各个方面想办法做调整优化和故...

4086
来自专栏Linux驱动

32.Linux-2440下的DMA驱动(详解)

DMA(Direct Memory Access) 即直接存储器访问, DMA 传输方式无需 CPU 直接控制传输,通过硬件为 RAM 、I/O 设备开辟一条直...

2269
来自专栏JAVA烂猪皮

大型分布式网站架构:缓存在分布式系统中的应用

缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题。提供高性能的数据快速访问。

992
来自专栏IT技术精选文摘

缓存在分布式系统中的应用

缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题。提供高性能的数据快速访问。 一、缓存概述 缓存是分布式系统中的重要组件,主要...

2469
来自专栏陈寨寨的专栏

elasticsearch5.3.0 bulk index 性能调优实践

本文整理了在搭建 elasticsearch 集群的时候需要注意的配置项,通过对这些配置项的调整,期望提高 elasticsearch 写入的性能。

1.2K0
来自专栏MessageQueue

消息过滤

在实际应用中,往往对一个Topic下的消息还会有不同的细分,消费方会根据细分的类型消费Topic中特定的一部分消息,这就涉及到了消息过滤。

1082
来自专栏Java Edge

Redis键过期策略

3698
来自专栏IT大咖说

MongoDB技术分享:WiredTiger存储引擎

内容来源:2018 年 10 月 27 日,MongoDB中文社区联席主席郭远威在“2018年MongoDB中文社区 广州大会”进行《WiredTiger存储引...

312

扫码关注云+社区