7月QCon广州站2022,关注Web 3.0、数据架构选型、数字化转型等热门话题,点击了解 了解详情
写点什么

华为云 AOM 基于 cassandra 的亿级数据监控实践系列

  • 2020 年 4 月 01 日
  • 本文字数:2948 字

    阅读完需:约 10 分钟

华为云AOM基于cassandra的亿级数据监控实践系列

2016 下半年加入 CloudBU 大家庭,开始搞华为云 AOM(应用运维管理)和 APM(应用性能管理),截止今天,AOM/APM 上线已成功上线稳定运行整整一年时间,当前在华为云上使用 AOM 的 VM 总数已达 m 台,每天处理的指标数据规模亿级,日志数据 TB 级。最近想把近一年内踩过的坑与大家共享下,希望能对开发者们有所帮助。


AOM 每天处理着亿级条数据,这么多数据是怎么存储的呢?


说到数据存储就会想到关系型数据库,比如 mysql,oracle,sybase。关系型数据库有自己的优势,数据强一致性,支持事务,通用,技术成熟。但是对于大批量数据的存储和查询就稍显吃力,毕竟 AOM 每秒的写入数据至少都是上万条,甚至是十几万条,随着系统规模增长,数据库的扩容也成为新的瓶颈。


AOM 的数据存储系统使用的是非关系型数据库-----cassandra,相比关系型数据库,cassandra 拥有高并发,大数据下读写能力强,支持分布式,易扩展等优点,当前也有最致命的缺点,不支持事务,不过对于事务我们可以通过 zk/etcd 等其他组件协助完成。


对于关系型数据库相比非关系型数据库为什么会有这么大的差异,这个就得从两者的架构上来讲了,下面小编以 mysql 和 cassandra 进行对比分析。


不管是 mysql 还是 cassandra,最终数据的存储都要落盘,我们先来看下磁盘的写入原理:



磁盘的基本组件可分为以下几部分:磁头,盘片,盘面,磁道,柱面,扇区等。


盘片被划分成一系列同心环,圆心是盘片中心,每个同心环叫做一个磁道,所有半径相同的磁道组成一个柱面。磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁盘的最小存储单元。当需要从磁盘读取数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点,磁头需要移动对准相应磁道,这个过程叫做寻道,所耗费时间叫做寻道时间,然后磁盘 旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做旋转时间。


即一次访盘请求(读/写)完成过程由三个动作组成:


1.寻道(时间):磁头移动定位到指定磁道


2.旋转延迟(时间):等待指定扇区从磁头下旋转经过


3.数据传输(时间):数据在磁盘与内存之间的实际传输


大家应该有过类似的经历,进行数据拷贝时,文件个数越少,单个文件越大,拷贝的速率越快,反之文件个数多,单个文件小,拷贝的速率越慢,这其中的原因就是因为在拷贝小文件时,系统的耗时基本都耗费在寻址上了。Cassandra 相比 mysql 有更高的写入能力,就是因为 cassandra 采用了更高效的写入机制,该机制大大缩短了磁盘的寻址时间(准确来讲应该是寻址次数)。


我们先来看下 Mysql(InnoDB)的索引原理, InnoDB 的索引采用 B+树,其数据结构如下所示:



所有的数据都存储在叶子节点,叶子节点之间都有指针,这是为了做范围遍历。B+树的优势在于快速索引,B+树的层高基本都在 2~3 层,也就意味着一次数据查找只需要 2~3 次 IO 操作。而且每次的单条数据都非常稳定,耗时和查找次数都差不多。B+树最大的性能问题是会产生大量的随机 IO,随着数据的插入,叶子节点会慢慢分裂,逻辑上连续的节点物理上确不连续,甚至相隔甚远,顺序遍历的时候,会产生大量的随机 IO 操作。这正如大家熟知的 ArrayList 和 LinkedList,ArrayList 在内存中是一块连续的内存,访问的时候顺序访问,LinkedList 是多个内存块通过指针串联起来的,访问的时候必须先通过指针获取下一个内存块的地址,然后再通过地址访问,因此 ArrayList 的访问远远高于 LinkedList。B+树的叶子节点就类似一个 LinkedList,随着叶子节点的分裂,在做顺序检索时,跨叶子节点的访问往往需要先找到下一个叶子节点的地址(磁盘寻址),然后才能访问到具体的叶子节点。


B+树的顺序检索会产生大量的随机 IO,B+树的写入同样会产生类似的问题,比如上图 B+树中的 9 和 86,它们所属的叶子节点在磁盘上相隔甚远,数据插入时就会产生两次随机写入。当大批量数据写入时,随机 IO 操作的次数也就更多。


如下是一张随机读写和顺序读写的性能比对图:



从上图可以直观的感受到随机读写与顺序读写的差异,这两者完全不在一个量级。用过 kafka 和 HDFS 的开发者就会发现 kafka 和 HDFS 的磁盘 IO 使用率非常高,有时甚至接近磁盘的最大写入速率,这个就是因为 kafka 和 HDFS 是基于文件的顺序写入(当然还有其他技术)。从以上分析来看,磁盘的随机读取/写入是影响 mysql 顺序检索和批量写入的最大因素,那我们有没有办法减少这种随机写入呢,此时 LSM-Tree(Log-Structured Merge-Tree)呼之欲出。


2006 年,google 发表了 BigTable 的论文。BigTable 的数据结构就采用了LSM,目前 LSM 被很多数据库作为存储结构,比如 HBase,Cassandra,LevelDB。LSM 抛弃了大多数数据库使用的传统文件组织方法,通过减少更新/写入操作带来的随机操作次数来提高数据的写入能力。


LSM Tree 的核心思路其实非常简单,就是假定内存足够大,因此不需要每次有数据更新就必须将数据写入到磁盘中,而可以先将最新的数据驻留在磁盘中,等到积累到一定数目之后,再使用归并排序的方式将内存内的数据合并追加到磁盘队尾(因为所有待排序的树都是有序的,可以通过合并排序的方式快速合并到一起)。


LSM 的核心思路可以分为两部分:


①数据先写入内存


②将内存中的数据排序后追加到磁盘队尾



LSM 由两个或两个以上的存储结构组成。最简单的 LSM 由两部分组成,一部分常驻内存,称为 C0;另一部分存储在硬盘上,称为 C1。


数据写入时,先记录到本地的操作日志文件(HLog 或 CommitLog),为将来做数据恢复使用。然后将数据写入到 C0 中,由于 C0 使用的是内存,因此插入性能远远高于磁盘写入。当 C0 的节点数目超过一定阈值时,会将 C0 中的数据进行一次排序,然后追加到 C1 树中。


多部件的 LSM 就是包含多个存储结构:



随着数据规模增加,C0 中的数据超过阈值后就会往磁盘中写入一个新的 file,这样磁盘中的树(file)会越来越多。当较小的 Ci-1 个数超过一定阈值的时候,会进行 Ci-1 和 Ci 的合并。合并是为了减少整个 C 树的个数,加快搜索速度。


数据查询的时候,会按照树的生成时间按照从新到旧的顺序逐个遍历每个 C 树,即 C0,C1,C2….Ck。为什么要按照时间顺序从最近往之前遍历呢,这就是 LSM 的另一个巧妙点(更新/删除)。


LSM 的更新和删除操作都是往 C0 上新增一条记录,通过新记录+标记的方式完成,因此在遍历的时候必须按照时间顺序进行遍历,这样就可以保证数据更新和删除的正确性,同时保证了数据的顺序写入。当前 LSM 在进行 C 树合并时,会对删除和更新记录进行合并。


我们来看下 HBase 的整个架构图:



HBase 是基于 HDFS 之上采用 LSM 结构做的数据存储。HBase 的主要部件可以分为如下几类:


storeFile:小文件,不可编辑。即写入到磁盘中的C树。Hlog:LSM中用于记录写入记录的操作日志,为了将来做数据恢复使用,毕竟C0中的数据是在内存中存储,当HBase宕机后,内存中的数据就会丢失,此时需要从Hlog中恢复。Memstore:即C0树。
复制代码


至此,LSM 和 B+树的对比也就讲完了,下一篇文章会继续讲解 AOM 是如何使用 Casandra 的一些特性。


本文转载自 华为云产品与解决方案 公众号。


原文链接:https://mp.weixin.qq.com/s/_LqMT4jAant-gk2eVVXaGg


2020 年 4 月 01 日 21:18682

评论

发布
暂无评论
发现更多内容

android下赚钱的几个方式

android 程序员 移动开发

Android中自定义下拉样式Spinner

android 程序员 移动开发

Android企业级实战-界面篇-2

android 程序员 移动开发

Android刘海屏、水滴屏全面屏适配方案

android 程序员 移动开发

Android厂商推送冲突了。。。

android 程序员 移动开发

android各种提示Dialog 弹出框

android 程序员 移动开发

Android命令Monkey压力测试,详解

android 程序员 移动开发

Android-高级-UI-进阶之路-(五)-看完该篇文章-Canvas-你应该会了

android 程序员 移动开发

android下拉刷新——swipeRefresh的使用

android 程序员 移动开发

Android使用ViewPager实现图片轮播系列之四:手动滑动 + 左右箭头 + 删除数据

android 程序员 移动开发

Android动画之补间动画

android 程序员 移动开发

Android中自定义ViewGroup

android 程序员 移动开发

Android事件分发机制三:事件分发工作流程

android 程序员 移动开发

Android-音视频学习系列-(八)基于-Nginx-搭建(rtmp、http)直播服务器

android 程序员 移动开发

Android中关于Context的三言两语,源码强势分析带你了解Context!

android 程序员 移动开发

Android体系化进阶学习图谱:我们究竟还要学习哪些Android知识?(某大厂内部资料

android 程序员 移动开发

android图片加载库Glide4使用教程(项目中如何快速将Glide3替换成Glide4)

android 程序员 移动开发

AndroidAPP启动速度优化;冷启动和热启动解析

android 程序员 移动开发

Android与单片机---开发板---智能硬件---智能设备---数据协议--开发总结

android 程序员 移动开发

android之Fragment(官网资料翻译)

android 程序员 移动开发

Android修炼系列(十二),自定义一个超顺滑的回弹RecyclerView

android 程序员 移动开发

Android刘海屏、水滴屏全面屏适配详解

android 程序员 移动开发

Android-音视频学习系列-(三)-Shell-脚本入门

android 程序员 移动开发

Android-音视频学习系列-(十)基于-FFmpeg-+-OpenSLES-实现音频万能播放器

android 程序员 移动开发

Android低版本上APP首次启动时间减少80%(一)

android 程序员 移动开发

基于 OpenYurt & EdgeX Foundry 的云边端一体化解决方案

阿里巴巴云原生

云原生 边缘计算 openyurt EdgeX Foundry

android各种提示Dialog 弹出框(1)

android 程序员 移动开发

Android-自定义图像资源的使用(2)

android 程序员 移动开发

Android仿QQ锁屏状态下消息提醒(震动+提示音)

android 程序员 移动开发

基于 Istio 的全链路灰度方案探索和实践

阿里巴巴云原生

阿里云 云原生 istio 灰度 全链路

Android内存泄漏问题

android 程序员 移动开发

华为云AOM基于cassandra的亿级数据监控实践系列_文化 & 方法_华为云产品与解决方案_InfoQ精选文章