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 条评论
登录 后参与评论

相关文章

来自专栏数据和云

数据库高可用和分区解决方案-MongoDB 篇

许春植(Luocs) (阿里巴巴高级数据库管理员,7年以上数据库运维管理经验,擅长MySQL、Oracle及MongoDB数据库,目前主要研究并建设Mongo...

6356
来自专栏程序员的知识天地

众多Python Web框架比较,哪个适合你,你就用哪个!

Python程序员有很多很好的选择来创建Web应用程序和API;Django,Weppy,Bottle和Flask引领潮流。

1402
来自专栏杨建荣的学习笔记

Oracle闪回原理-Logminer解读redo(r11笔记第17天)

说到闪回日志,我们都知道闪回日志中记录的都是逆操作,那么就有两个问题需要解释了。 闪回日志和回滚段保存的数据有什么差别? 如果做了truncate操作,闪回日志...

35412
来自专栏刘君君

Rest Notes-基于网络应用的架构风格

1322
来自专栏CaiRui

nginx的worker_processes优化

nginx的worker_processes参数 来源: http://bbs.linuxtone.org/thread-1062-1-1.html 分享一: ...

5357
来自专栏Rainbond开源「容器云平台」

好雨云帮更新志( 2017.04.03-2017.04.16)

1182
来自专栏Java技术

记一次解决业务系统生产环境宕机问题!

Zabbix告警生产环境应用shutdown,通过堡垒机登入生产环境,查看应用容器进程,并发现没有该业务应用的相应进程,第一感觉进程在某些条件下被系统杀死了,然...

711
来自专栏ThoughtWorks

DocBook 让文档版本化

image.png #ThoughtWorkers好声音# 第十六期(图片:网络) 你们都知道ThoughtWorks曾经是扛敏捷的大旗的,你们也都知道敏捷是...

3076
来自专栏木头编程 - moTzxx

laravel5.0+ 常见报错整理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

1452
来自专栏linux、Python学习

IBM技术专家教你“懒惰”Linux管理员的10个关键技巧

好的系统管理员区分在效率上。如果一位高效的系统管理员能在 10 分钟内完成一件他人需要 2 个小时才能完成的任务,那么他应该受到奖励(得到更多报酬),因为他为公...

690

扫码关注云+社区