Archive

Archive for the ‘Linux’ Category

巧用Systemtap注入延迟模拟IO设备抖动

October 28th, 2013 4 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 巧用Systemtap注入延迟模拟IO设备抖动

当我们的IO密集型的应用怀疑设备的IO抖动,比如说一段时间的wait时间过长导致性能或其他疑难问题的时候,这个现象处理起来就比较棘手,因为硬件的抖动有偶发性很难重现或者重现的代价比较高。

幸运的是systemtap可以拯救我们。从原理上讲,我们应用的IO都是通过文件系统来访问的,不管read/write/sync都是,而且我们的文件大部分都是以buffered方式打开的。在这个模式下,如果pagecache不命中的话,就需要访问设备。 知道了这个基本的原理以后,我们就可以用万能的systemtap往vfs的读写请求中受控的注入延迟,来达到这个目的。

要点有以下几个:
1. 受控的时间点。
2. 延迟时间可控。
3. 目标设备可控。

我写了个脚本注入IO延迟,模拟ssd/fio硬件的抖动来验证是否是IO抖动会给应用造成影响,三个步骤如下:
步骤1: 编译模块

$ cat inject_ka.stp
global inject, ka_cnt

probe procfs("cnt").read {
  $value = sprintf("%d\n", ka_cnt);
}
probe procfs("inject").write {
  inject= $value;
  printf("inject count %d, ka %s", ka_cnt, inject);
}

probe vfs.read.return,
      vfs.write.return {
  if ($return &&
      devname == @1 &&
      inject == "on\n")
  {
    ka_cnt++;
    udelay($2);
  }
}

probe begin{
  println("ik module begin:)");
}

$ stap -V
Systemtap translator/driver (version 2.1/0.152, commit release-2.0-385-gab733d5)
Copyright (C) 2005-2013 Red Hat, Inc. and others
This is free software; see the source for copying conditions.
enabled features: LIBSQLITE3 NSS BOOST_SHARED_PTR TR1_UNORDERED_MAP NLS

$ sudo stap -p4 -DMAXSKIPPED=9999 -m ik -g inject_ka.stp sda6 300
ik.ko

其中参数sda6是目标设备的名字,300是希望延迟的时间,单位us(超过300很容易报错,因为通常systemtap会对脚本执行的cpu进行检查,占用过多cpu的时候会触发保护机制,导致stap抱怨退出),通常对于ssd设备是足够的。

这个步骤会生成ik.ko,请验证生成模块的机器和目标的机器,操作系统的版本是一模一样的,而且请确保你的stap版本比较高,因为udelay函数在高版本的Stap才有。

步骤2:

将ik.ko拷贝到目标机器,执行

$ sudo staprun ik.ko
ik module begin:)

步骤3:
启动应用程序开始测试后一段时间,运行如下命令开始注入:

$ echo on|sudo tee /proc/systemtap/ik/inject  && sleep 10 && echo off|sudo tee /proc/systemtap/ik/inject

其中sleep N 是希望打开注入开关的时间。

小结:systemtap用好很无敌!

祝玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Linux, 工具介绍 Tags:

erlang和其他语言读文件性能大比拼

August 28th, 2013 26 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: erlang和其他语言读文件性能大比拼

百岁同学说:

今天公司技术比武,比赛题目是给一个1.1g的大文本,统计文本中词频最高的前十个词。花了两天用erlang写完了代码,但是放到公司16核的机器上这么一跑,结果不比不知道,一比吓一条。erlang写的代码执行时间花了55秒左右,同事们有的用java,有的用C,还有的用C++,用C最快一个老兄只花了2.6秒,用java的也只用了3.2秒。相比之下erlang的代码,真是一头大蜗牛,太慢了。

详细参见这篇文章:http://www.iteye.com/topic/1131748

读取文件并且分析这是很多脚本语言如perl, python,ruby经常会干的事情.这个同学的问题是很普遍的问题,不只一个人反映过慢的问题。
今天我们来重新来修正下这个看法, 我们用数据说话。

首先我们来准备下文件, 这个文件是完全的随机数,有1G大小:

$ dd if=/dev/urandom  of=test.dat count=1024 bs=1024K
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 188.474 s, 5.7 MB/s
$ time dd if=test.dat of=/dev/null 
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 1.16021 s, 925 MB/s

real    0m1.162s
user    0m0.219s
sys     0m0.941s
$ time dd if=test.dat of=/dev/null bs=1024k
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.264298 s, 4.1 GB/s

real    0m0.266s
user    0m0.000s
sys     0m0.267s

我们准备了1G大小左右的文件,由于用的是buffered io, 数据在准备好了后,全部缓存在pagecache里面,只要内存足够,这个测试的性能和IO设备无关。 我们试着用dd读取这个文件,如果块大小是4K的话,读取这个文件花了1.16秒,而如果块大小是1M的话,0.26秒,带宽达到4.1GB每秒,远超过真实设备的速度。

那么我们用erlang来读取下这个文件来比较下,我们有三种读法:
1. 一下子读取整个1G文件。
2. 一个线程一次读取1块,比如1M大小,直到读完。
3. 多个线程读取,每个读取一大段,每次读取1M块大小。
然后比较下性能。

首先普及下背景:
1. erlang的文件IO操作由efile driver来提高,这个driver内部有个线程池,大小由+A 参数控制,所以IO是多线程完成的。
2. erlang的文件分二种模式: 1. raw模式 2. io模式 在raw模式下,数据直接由driver提供给调用进程, io模式下数据先经过file_server做格式化,然后再给调用进程。
3. 数据可以以binary和list方式返回,list方式下文件内容的byte就是一个整数,在64位机器上占用8个字节内存。
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

erlang coredump问题

June 27th, 2013 2 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: erlang coredump问题

早上成立涛同学问道:

: :)我们最近发生了几次宕机。。节点无缘无故就没有了。也没有crash dump,也不知道任何线索。

我们知道erlang的VM在正常运作的时候,如果发现erlang程序的异常或者虚拟机资源不够如内存不够的时候,会产生erl_crash.dump文件,里面把crash的原因和上下文描述的非常清楚,定位问题起来就很容易。但是vm本身是c实现的,如果vm的实现有bug或者系统用到了自己写的nif,这个情况下就很容易把vm搞挂了。 vm都挂了,就不再可能还有机会产生erl_crash.dump.
所以这时候应该产生的是操作系统的core,碰巧如果系统的coredump没开,那么节点就会看起来无缘无故的消失了。

我摘取我们的个案给大家看下:我们在erlang系统里面用到了nif, 这个nif不是多线程安全的,所以在运作的时候产生问题了,搞垮了beam:
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索, Linux, 源码分析 Tags:

lz4: Extremely Fast Compression algorithm

March 15th, 2013 9 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: lz4: Extremely Fast Compression algorithm

最近在不少项目特别是存储相关的项目用到了lz4压缩算法,它有什么特点呢?

LZ4 is a very fast lossless compression algorithm, providing compression speed at 300 MB/s per core, scalable with multi-cores CPU. It also features an extremely fast decoder, with speeds up and beyond 1GB/s per core, typically reaching RAM speed limits on multi-core systems.

这个特性对于需要大吞吐量的压缩场合还是非常有用的,以很小的CPU代价换来更大的存储密度。

官方网站:https://code.google.com/p/lz4/, 摘抄下它的性能指标:

Name Ratio C.speed D.speed
LZ4 (r59) 2.084 330 915
LZO 2.05 1x_1 2.038 311 480
QuickLZ 1.5 -1 2.233 257 277
Snappy 1.0.5 2.024 227 729
LZF 2.076 197 465
FastLZ 2.030 190 420
zlib 1.2.5 -1 2.728 39 195
LZ4 HC (r66) 2.712 18 1020
zlib 1.2.5 -6 3.095 14 210

更多的测试可以看 这里 这里

它还有个高压缩率的版本:

LZ4 HC – High Compression Mode of LZ4

从源码lz4.c可以看到快的原因之一:
lz4

这个技术叫做 “The Blocking Technique”, 见图:
bt

考虑在项目中用起来。

祝玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Linux, 杂七杂八, 源码分析 Tags:

Linux下如何知道文件被那个进程写

March 12th, 2013 36 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Linux下如何知道文件被那个进程写

晚上朔海同学问:

一个文件正在被进程写 我想查看这个进程 文件一直在增大 找不到谁在写 使用lsof也没找到

这个问题挺有普遍性的,解决方法应该很多,这里我给大家提个比较直观的方法。

linux下每个文件都会在某个块设备上存放,当然也都有相应的inode, 那么透过vfs.write我们就可以知道谁在不停的写入特定的设备上的inode。
幸运的是systemtap的安装包里带了inodewatch.stp,位于/usr/local/share/doc/systemtap/examples/io目录下,就是用来这个用途的。
我们来看下代码:

$ cat inodewatch.stp 
#! /usr/bin/env stap

probe vfs.write, vfs.read
{
  # dev and ino are defined by vfs.write and vfs.read
  if (dev == MKDEV($1,$2) # major/minor device
      && ino == $3)
    printf ("%s(%d) %s 0x%x/%u\n",
      execname(), pid(), probefunc(), dev, ino)
}

这个脚本的使用方法如下: stap inodewatch.stp major minor ino

下面我们构造个场景: dd不停的写入一个文件,查出这个文件的ino, 以及它所在设备的major, minor, 运行stap脚本就可以得到答案。

Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Linux, 工具介绍 Tags: , ,

ulimit限制之nproc问题

March 2nd, 2013 4 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: ulimit限制之nproc问题

前两天微博上的@王关胜同学问了个问题:

#ulimit问题# 关于nproc设置:centos6,内核版本是2.6.32. 默认情况下,ulimit -u的值为1024,是/etc/security/limits.d/90-nproc.conf的值限制;注释掉这个限制后,值为95044;手工设置90-nproc.conf文件,值为新设置的值。想请 问这个95044是怎么来的?

这个问题挺有意思的,这里面有二个信息点:

1. 为什么limit配置文件是 /etc/security/limits.d/90-nproc.conf 而不是其他?
2. 为什么是nproc的值95044,而不是其他。

之前我也写了些ulimit的问题的解决,参见 这里

我们来简单的做下实验:

$ cat /etc/security/limits.d/90-nproc.conf          
*      soft    nproc   8933
$ ulimit -u
8933

$ cat /etc/security/limits.d/90-nproc.conf      #注释掉
#*      soft    nproc   8933
$ ulimit -u
385962

我们可以看出就是说当注释掉限制的话,不同的机器值是不同的。

我们先来回答第一个问题:为什么limit配置文件是 /etc/security/limits.d/90-nproc.conf 而不是其他
这个问题早些时候 杨德华 同学碰到了,也写了篇 博文 来解释redhat6下面如何破解nproc的限制,但是文章没提到这个问题。
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Linux, 源码分析 Tags: , ,

Understanding Linux CPU Load 资料汇总

March 1st, 2013 3 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Understanding Linux CPU Load 资料汇总

最近关注线上CPU load的人挺多,很多人觉得load太高系统就有问题,就想各种办法来折腾。其实在我看来load只是系统CPU运行队列的在运行进程数的近似值, 如下图:
load

对于Unix发展的初期,机器的性能比较差,CPU核数也少,参考意义比较大。现在的机器都是非常强悍的,CPU,内存,IO各个部件都可以并行运作,这个load相应的就应该和机器的变化相应的变大,我觉得很正常,无需担心,反而应该把注意力放到服务的QPS和RT才是王道。

在微博上讨论了一下午CPU Load,收到非常多的反馈,这里我顺手整理下方便大家:

1. Understanding Linux CPU Load – when should you be worried? 谢谢@nizen靖
参考: 这里 中文版

2. Understanding Linux Load Average 谢谢 @jametong
参考:part1 part2 part3

3. UNIX Load Average 谢谢 @jametong
参考:part1 part2 part3

4. Loadavg问题分析 谢谢 @淘木名、 @淘伯瑜、 @何_登成
参考 这里

小结:群众的力量无穷,很短的时间内挖出这么多有意义的材料。

祝玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Linux, 杂七杂八 Tags: