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

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: 如何通过火焰图快速定位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

目录
相关文章
|
2月前
|
JavaScript
性能工具之 FlameGraph 火焰图
其实很多类似 perf 的工具都能生成火焰图,像 systemtap/dtrace 之类的 并且这个思路,现在在 js 优化、代码优化等各方面都有具体的应用了 至于怎么理解? 简单点说,就是看谁又平又宽
58 7
性能工具之 FlameGraph 火焰图
|
5月前
|
Ubuntu
代码性能展现 火焰图
代码性能展现 火焰图
36 0
|
8月前
|
缓存 监控 算法
利用可视化分析算法解析电脑屏幕监控软件性能瓶颈
想要通过可视化分析算法优化电脑屏幕监控软件性能嘛,有点复杂但还是挺关键的。提高软件的效率、减少资源占用,并提供更好的用户体验。以下是一些步骤,可以通过可视化分析算法帮助您优化电脑屏幕监控软件的性能——
141 3
|
9月前
|
存储 缓存 监控
转:哈希算法在屏幕监控软件中的性能分析与优化
在屏幕监控软件里,哈希算法经常被用来快速比较和侦测屏幕内容的变化,这样就能立即抓取屏幕截图或者视频帧的变动。就在这种情境下,哈希算法的性能优化变得特别重要,因为它直接影响到监控软件的实时反应和效率。下面分享一些关于如何在屏幕监控软件中对哈希算法进行性能分析和优化的建议——
41 1
|
10月前
|
Web App开发 Java Linux
【性能优化】使用Perfetto定位应用启动性能的瓶颈
本篇文章将会结合我个人对Perfetto的实际使用经历,讲解车载应用的启动时间是如何测量得到的,测量出启动时间后,我们又该如何找出其中的性能瓶颈。
886 1
【性能优化】使用Perfetto定位应用启动性能的瓶颈
|
10月前
|
Ubuntu
perf + 火焰图分析软件性能
perf + 火焰图分析软件性能
97 0
|
前端开发 数据可视化 关系型数据库
巧用 “ 火焰图 ” 快速分析链路性能
巧用 “ 火焰图 ” 快速分析链路性能
253 0
巧用 “ 火焰图 ” 快速分析链路性能
|
SQL 数据可视化 程序员
clickhouse与火焰图
clickhouse与火焰图
534 0
clickhouse与火焰图
|
缓存 监控 网络协议
|
Android开发 开发者
Android系统是如何计算应用启动耗时的?能否更精准定位性能瓶颈呢?
Android系统是如何计算应用启动耗时的?能否更精准定位性能瓶颈呢?
Android系统是如何计算应用启动耗时的?能否更精准定位性能瓶颈呢?

相关实验场景

更多