如何通过火焰图快速定位Cassandra性能瓶颈

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Tair(兼容Redis),内存型 2GB
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 如何通过火焰图快速定位Cassandra性能瓶颈

运维大规模分布式系统的比较重要的一个挑战是可以有能力指出关键问题所在。在没有证据支持某种说法的情况下,当故障出现时,总是责怪组件(通常是数据库)的偶然性问题是很常见的一件事。我们已经讨论过监控工具、图形化输出、以及报警metric的重要性,并使用分布式tracing系统(比如zikin)去正确的辨别复杂系统的根源问题。

一旦你把问题缩小到一个单一的系统上面,你会怎么做?通常我们都会说这个会具体问题具体对待。有的问题是临时的,比如坏盘。有的问题却涉及到人为引入的变化,比如部署或者是错误的配置。这些都是有直接简单的解决办法:换盘或者是回滚部署。

但是如果出现的问题超出简单变化的范畴,那怎么办?到现在为止还没有提到的是规模增长造成的问题。规模可以成为另一个困难的问题,因为复现这个问题一般情况下是很微妙且复杂的。这些挑战有时是通过吞吐量(每秒请求数)、大小(兆字节)或延迟(5ms p99)来衡量的。例如,如果数据库服务器能够在内存不足的情况下为每个请求提供服务,那么它可能获得极好的吞吐量。随着数据集大小的增加,随机查找越来越可能进入磁盘,从而降低吞吐量。Time Window Compaction Strategy 是解决规模问题的一个很好的例子,除非有数字表明,否则还是很难理解的。除非遇到很大量的数据,否则你不会体会到compaction带来的痛苦,下规模情况下,很难遇到什么问题。

在失败期间,我们经常会把机器以及他们的程序执行过程当做一个黑盒子。几十亿条指令每秒都在执行,但是我们却没有办法看到内部的奥秘。很幸运的是,我们并没有完全忽略机器在做什么。多年来我们已经有了debugger以及profiler工具。 Oracle的JDK也为我们提供了Java Flight Recorder,我们可以使用它来分析本地或者生产中运行的流程。

mission_control

通过 flight recorder 进行profile是简单而直白的,但是想要翻译这个结果却需要一定的工作量。把上面的列表一一展开并查找需要的问题更消耗劳动力。 但是我们如果可以将信息可视化展出的话那么就更好了。 但是这却需要商业的license且仅能在Oracle的JDK上运行。

这就引入了我们上面列出的标题:一种可以展示可视化信息的方法,叫做火焰图。火焰图让我们可以快速的找出系统中的性能瓶颈。 由Brendan Gregg 发明。这也是一系列非常长的性能调整文章的第一部分,我们将在深入研究Cassandra的内部结构时再次提到它。

Swiss Java Knife

我们在本文中研究的方法将要用到Swiss Java Knife ,通常叫做SJK,用它来获取JVM的数据并生成火焰图。SJK是一个很不错的工具集,除了生成火焰图以外,我们可以使用它收集统计信息、监视线程以及执行各种其他诊断任务。它可以在MAC、Linux以及oracle JDK和Open JDK上工作。

我已经下载了jar,把它放在$home/bin中,并设置了一个shell函数来轻松调用它:

sjk(){
    java -jar ~/bin/sjk-plus-0.8.jar "@"
}

在我的电脑上,我使用cassandra-stress进行压测,我已经部署好了我的数据库,并开始使用下面的命令压测:

cassandra-stress read n=1000000

在分析的第一步中,我们需要使用SJK的stcap特性捕获正在运行的java应用程序的堆栈帧。为此,我们需要传入进程id和将数据转储到的文件。转储是以二进制格式编写的,我们稍后可以查询:

sjk stcap -p 92541 -i 10ms -o dump.std

然后我们可以分析数据。如果我们只有一个终端,我们可以打印出分析的柱状图。如果有明显的问题,这一点本身就非常有用。在这种情况下,我们可以看到很多时间都花在sun.misc.unsafe.park上,这意味着线程只是在等待,停在:

$ sjk ssa -f dump.std --histo
Trc     (%)  Frm  N  Term    (%)  Frame
372447  96%  372447       0   0%  java.lang.Thread.run(Thread.java:745)
309251  80%  309251  309251  80%  sun.misc.Unsafe.park(Native Method)
259376  67%  259376       0   0%  java.util.concurrent.locks.LockSupport.park(LockSupport.java:304)
254388  66%  254388       0   0%  org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:87)
 55709  14%  55709        0   0%  java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 52374  13%  52374        0   0%  org.apache.cassandra.concurrent.NamedThreadFactory$$Lambda$6/1758056825.run(Unknown Source)
 52374  13%  52374        0   0%  org.apache.cassandra.concurrent.NamedThreadFactory.lambda$threadLocalDeallocator$0(NamedThreadFactory.java:81)
 44892  11%  44892        0   0%  io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
 44887  11%  44887        0   0%  java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
 42398  11%  42398        0   0%  io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:409)
 42398  11%  42398        0   0%  io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
 42398  11%  42398        0   0%  io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:753)
 42398  11%  42398        0   0%  sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198)
 42398  11%  42398        0   0%  sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:117)
 42398  11%  42398    42398  11%  sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method)
 42398  11%  42398        0   0%  sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
 42398  11%  42398        0   0%  sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)

然后我们就有了我们的stcap的dump,通过下面的命令,可以生成我们的火焰图:

sjk ssa --flame -f dump.std > flame-sjk.svg

当你使用浏览器打开svg的文件的时候,你可以看到下面的图:

flame_sjk_screen

如果打开机器上的flame图,可以将鼠标移到不同的部分上,查看方法调用和所用时间的百分比。横坐标长度越宽,在stack里出现的频率就越高。浏览图表很容易理解我们的程序在哪里花费时间。

这并不是生成火焰图的唯一技术。Brendan Gregg 有一长串的链接和参考资料,我建议详细阅读在他的火焰图页。我打算编写一个实用程序,将SJK格式导出为brendan在他的博客上使用的格式,因为它看起来更好一些,鼠标悬停更好,支持向下钻取,还有搜索功能。它们还支持不同的flame图,如果您要在不同的构建中进行性能比较,这是很好的方式。

我希望你喜欢这篇关于用火焰图可视化Cassandra文章。我们已经与我们合作过的团队多次使用这个工具来调整Cassandra的配置并优化性能。在本系列的下一篇文章中,我们将研究如何调整垃圾收集参数以最大化吞吐量,同时将延迟保持在最低限度。

译者注:

1.生成火焰图的方式很多,文章中说的是一种方式,可以参考Brendan Gregg 一系列文章;

2.上述是针对Cassandra生成的火焰图,对于其他的java平台软件也适用,比如HBase、Spark等;

3.可以生成c++ 等其他平台的软件的火焰图,不仅仅限于java程序,使用的profile工具不仅仅是SJK,也可以是perf、systemtap;

4.火焰图不仅仅限于cpu(on-cpu、off-cpu),还可以绘制出内存、磁盘等的火焰图。

翻译自:https://thelastpickle.com/blog/2018/01/16/cassandra-flame-graphs.html

入群邀约
为了营造一个开放的 Cassandra 技术交流环境,社区建立了微信群公众号和钉钉群,为广大用户提供专业的技术分享及问答,定期开展专家技术直播,欢迎大家加入。另外阿里云提供免费Cassandra试用:https://www.aliyun.com/product/cds
8a55f5a99463a7276265074b1079d74f4ab3d164

目录
相关文章
|
3月前
|
数据采集 缓存 监控
优化 Grafana 性能:技巧与窍门
【8月更文第29天】Grafana 是一个非常受欢迎的开源数据可视化平台,它能够连接到各种数据源并提供高度定制化的仪表板。然而,随着数据量的增长和复杂查询的增多,Grafana 的性能可能会受到影响。本文将探讨如何优化 Grafana 的性能,以提高其响应速度和稳定性,并通过具体的代码示例来展示这些技巧。
419 1
|
5月前
|
监控 Java 测试技术
五步定位性能瓶颈
五步定位性能瓶颈
74 1
|
6月前
|
JavaScript
性能工具之 FlameGraph 火焰图
其实很多类似 perf 的工具都能生成火焰图,像 systemtap/dtrace 之类的 并且这个思路,现在在 js 优化、代码优化等各方面都有具体的应用了 至于怎么理解? 简单点说,就是看谁又平又宽
149 7
性能工具之 FlameGraph 火焰图
|
11月前
|
Ubuntu
代码性能展现 火焰图
代码性能展现 火焰图
70 0
|
缓存 监控 算法
利用可视化分析算法解析电脑屏幕监控软件性能瓶颈
想要通过可视化分析算法优化电脑屏幕监控软件性能嘛,有点复杂但还是挺关键的。提高软件的效率、减少资源占用,并提供更好的用户体验。以下是一些步骤,可以通过可视化分析算法帮助您优化电脑屏幕监控软件的性能——
168 3
|
监控 算法
转:如何使用模糊算法提高监控软件的性能
如何才能提高监控软件的性能呢?其实,咱们可以通过模糊算法从各个角度着手,让监控系统变得更聪明更高效。模糊逻辑就是那种对付那些有点儿模糊不太确定信息的法宝,它在解决一些莫名其妙的情况时可是大显身手。在监控软件的世界里,模糊逻辑也是个大明星,可以帮助我们做出更明智的决策和更敏捷的响应,然后整个系统就会变得特别厉害!
74 0
|
Ubuntu
perf + 火焰图分析软件性能
perf + 火焰图分析软件性能
175 0
|
SQL JSON 运维
如何使用下探分析定位多维指标异常根因
在系统运维过程中,关键指标的异常变化往往意味着服务异常、系统故障等等。因此我们往往会对一些关键指标进行自动巡检,例如异常检测和时序预测等等,及时感知指标的异常变化,了解系统的健康状况。对于复杂系统来说,感知到异常后直接在系统层面根因定位可能是十分困难的。因此我们需要一些手段缩小问题的排查范围或者直接定位问题,如使用 trace 根因分析等等。阿里云日志服务上线了下探分析功能,用于多维指标异常根因定位。我们将介绍该功能的使用场景和使用案例。
687 0
如何使用下探分析定位多维指标异常根因
|
前端开发 数据可视化 关系型数据库
巧用 “ 火焰图 ” 快速分析链路性能
巧用 “ 火焰图 ” 快速分析链路性能
336 0
巧用 “ 火焰图 ” 快速分析链路性能
|
缓存 监控 网络协议