Archive

Archive for the ‘调优’ Category

slabtop简单的用途

December 15th, 2011 5 comments

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

本文链接地址: slabtop简单的用途

我们知道内核的模块在分配资源的时候,为了提高效率和资源的利用率,都是透过slab来分配的。我们通过slab的信息,再配合源码能粗粗了解系统的运行情况,比如说什么资源有没有不正常的多,或者什么资源有没有泄漏。

linux系统透过/proc/slabinfo来向用户暴露slab的使用情况的,我们来看下:

$ head /proc/slabinfo 
slabinfo - version: 2.0
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <batchcount> <limit> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
msi_cache              2      2   3840    1    1 : tunables   24   12    8 : slabdata      2      2      0
ip_fib_alias          11    226     16  226    1 : tunables  120   60    8 : slabdata      1      1      0
ip_fib_hash           11    119     32  119    1 : tunables  120   60    8 : slabdata      1      1      0
dm_mirror            100    105   1052    7    2 : tunables   24   12    8 : slabdata     15     15      0
dm_mpath               0      0   1052    7    2 : tunables   24   12    8 : slabdata      0      0      0
dm_tio                 0      0     16  226    1 : tunables  120   60    8 : slabdata      0      0      0
dm_io                  0      0     20  185    1 : tunables  120   60    8 : slabdata      0      0      0
dm-bvec-(256)          0      0   3072    2    2 : tunables   24   12    8 : slabdata      0      0      0
...

其实还有更好的查看工具:slabtop很直观的可以看到slab使用情况和汇总,上图:

很清晰的为性能调优和trouble shoot提供一个参考面!

祝玩得开心!

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

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

Lockless Memory Allocator试用记

December 14th, 2011 5 comments

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

本文链接地址: Lockless Memory Allocator试用记

昨天@淘宝雕梁 同学推荐了无锁的内存分配器,上网站粗粗的了解了下,这家叫Lockless的公司主要有2个产品:
Lockless MPI 和 Lockless Memory Allocator, 我对内存分配器比较感兴趣,它对高性能服务器的影响还是非常大的,特别是mysql这样的服务器,看它的文档对性能的提升好像比较明显。

我们重点来了解下 Lockless Memory Allocator:

The Lockless Memory Allocator is downloadable under the GPL 3.0 License.

官网强调的特性:

Multithread Optimized
The Lockless memory allocator uses lock-free techniques to minimize latency and memory contention. This provides optimal scalability as the number of threads in your application increases. Per-thread data is used to reduce bus communication overhead. This results in thread-local allocations and frees not requiring any synchronization overhead in most cases.

官网做的和主流的几种分配器的性能比较:

详细的bechmark见这里,看上去让人挺印象深刻的。

代码在这里下载 http://locklessinc.com/downloads/, 支持32位和64位的Linux, 安装文档在这里

我们来尝鲜实验下:

$  wget http://locklessinc.com/downloads/lockless_allocator_src.tgz
$ tar xzf lockless_allocator_src.tgz 
$ cd lockless_allocator
$ gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.4.5 20110214 (Red Hat 4.4.5-6) (GCC) 

$ make
/bin/sh -ec 'gcc -MM  ll_alloc.c | sed -n "H;$ {g;s@.*:\(.*\)@ll_alloc.c := \$\(wildcard\1\)\nll_alloc.o ll_alloc.c.d: $\(ll_alloc.c\)@;p}" > ll_alloc.c.d'
cc ll_alloc.c -fomit-frame-pointer -Wcast-qual -Wmissing-format-attribute -Wlogical-op -Wstrict-aliasing -Wsign-compare -Wdeclaration-after-statement -Wnested-externs -Wdisabled-optimization -Winline -Wundef -Wimplicit -Wunused -Wfloat-equal -Winit-self -Wformat=2 -Wswitch -Wsequence-point -Wparentheses -Wimplicit -Wchar-subscripts -Wredundant-decls -Wstrict-prototypes -Wbad-function-cast -Wpointer-arith -Wwrite-strings -Wno-long-long -Wmissing-declarations -Wmissing-prototypes -Wextra -Wall -pedantic -ggdb3 -std=gnu99 -O3  -fPIC -pthread -c -o libllalloc.o 
strip -g libllalloc.o
ar rcs libllalloc.a libllalloc.o
ranlib libllalloc.a
cc ll_alloc.c -fomit-frame-pointer -Wcast-qual -Wmissing-format-attribute -Wlogical-op -Wstrict-aliasing -Wsign-compare -Wdeclaration-after-statement -Wnested-externs -Wdisabled-optimization -Winline -Wundef -Wimplicit -Wunused -Wfloat-equal -Winit-self -Wformat=2 -Wswitch -Wsequence-point -Wparentheses -Wimplicit -Wchar-subscripts -Wredundant-decls -Wstrict-prototypes -Wbad-function-cast -Wpointer-arith -Wwrite-strings -Wno-long-long -Wmissing-declarations -Wmissing-prototypes -Wextra -Wall -pedantic -ggdb3 -std=gnu99 -O3  -shared -fpic -Wl,-soname,libllalloc.so.1.3 -Wl,-z,interpose -o libllalloc.so.1.3 
strip libllalloc.so.1.3

$ ls libllalloc.*
libllalloc.a  libllalloc.o  libllalloc.so.1.3

$ LD_PRELOAD=./libllalloc.so.1.3  erl
Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.5  (abort with ^G)
1> 

#另外一个终端确认libllalloc.so.1.3在使用
$ lsof  -c beam.smp
COMMAND   PID           USER   FD      TYPE DEVICE     SIZE    NODE NAME
beam.smp 8458          chuba  txt       REG    8,5  2344032 3775338 /usr/local/lib/erlang/erts-5.8.5/bin/beam.smp
...
beam.smp 8458          chuba  mem       REG    8,6    40384  195304 /home/chuba/lockless_allocator/libllalloc.so.1.3
...

这里面有个问题: 编译的时候需要的gcc版本比较高,gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)编译不过。
之前tcmalloc就没通过erl的使用,因为erlang内部的指针的后4位被用了,如果分配器不遵守16字节对齐,就会出问题。

看了代码实现的也很简单,代码质量也一般,不知道具体的性能如何,后续找个案例benchmark下!
未完待续!

祝玩得开心!

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

posix_fadvise清除缓存的误解和改进措施

December 11th, 2011 9 comments

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

本文链接地址: posix_fadvise清除缓存的误解和改进措施

在典型的IO密集型的数据库服务器如MYSQL中,会涉及到大量的文件读写,通常这些文件都是通过buffer io来使用的,以便充分利用到Linux操作系统的page cache。

Buffer IO的特点是读的时候,先检查页缓存里面是否有需要的数据,如果没有就从设备读取,返回给用户的同时,加到缓存一份;写的时候,直接写到缓存去,再由后台的进程定期涮到磁盘去。这样的机制看起来非常的好,在实践中也效果很好。

但是如果你的IO非常密集,就会出现问题。首先由于pagesize是4K,内存的利用效率比较低。其次缓存的淘汰算法很简单,由操作系统自主进行,用户不大好参与。当你的写很多,超过系统内存的某个上限的时候,后台的进程(swapd)要出来回收页面,而且一旦回收的速度小于写入的速度,就会出现不可预期的行为。

这里面最大的问题是:当你使用的内存包括缓存,没超过操作系统规定的上限的时候,操作系统选择不作为,让用户充分使用缓存,从它的角度来看这样效率最高。但是正是由于这种策略在实践中会导致问题。

比如说MYSQL服务器,我们可以把数据直接走direct IO,但是它的日志是走bufferio的。因为走directio需要对写入文件的偏移和大小都要扇区对全,这对日志系统来讲太麻烦了。由于MYSQL是基于事务的,会涉及到大量的日志动作,频繁的写入,然后fsync. 日志一旦写入磁盘,buffer page就没用了,但是一直会在内存呆着,直到达到内存上限,引起操作系统突然大量回收
页面,出现IO柱塞或者内存交换等负面问题。

那么我们知道了困境在哪里,我们可以主动避免这个现象的发生。有二种方法:
1. 日志也走direct io,需要规模的修改MYSQL代码,如percona就这么做了,提供相应的patch。
2. 日志还是走buffer io, 但是定期清除无用page cache.

第一张方法不是我们要讨论的,我们重点讨论第二种如何做:

我们在程序里知道文件的句柄,是不是就可以很轻松的用:

int posix_fadvise(int fd, off_t offset, off_t len, int advice);
POSIX_FADV_DONTNEED
The specified data will not be accessed in the near future.

来解决问题呢?
比如写类似 posix_fadvise(fd, 0, len_of_file, POSIX_FADV_DONTNEED);这样的代码来清掉文件所属的缓存。

前面介绍的vmtouch就有这样的功能,清某个文件的缓存。
vmtouch -ve logfile 就可以试验,但是你会发现内存根本就没下来,原因呢?

我们从代码来看posix_fadvise如何运作的:
参看 mm/fadvise.c:
Read more…

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

Flashcache新添加驱逐空闲脏页参数

December 10th, 2011 1 comment

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

本文链接地址: Flashcache新添加驱逐空闲脏页参数

我在之前的博文提过Flashcache的cache是以set为单位管理的,每个set默认2M。 当单个set里面的脏页数量超过dirty_thresh_pct的时候,就会启动背景工作队列来把超过设置的脏页回写到后备磁盘去。 这里有别的同学对flashcache设计文档的翻译.

参看dirty_thresh_pct的文档解释:

dev.flashcache..dirty_thresh_pct = 20
Flashcache will attempt to keep the dirty blocks in each set
under this %. A lower dirty threshold increases disk writes,
and reduces block overwrites, but increases the blocks
available for read caching.

Flashcache之所以这样做的目的是当它在处理用户IO请求需要cache块的时候,保证马上可以拿的出来。因为读写的时候,如果需要的cache块不能满足的话,flashcache选择简单的绕过cache机制,直接走uncache io, 同时启动页面回收,一下子收回超过设置部分的页面,对性能有很大的损失。
特别是顺序写的时候,写一圈,再回绕在写的场合,性能特别差,就是这个原因。

那么如何保持一定量的可用cache块就很重要。通常cache数据都有冷热点,而且和时间很大关系。flashcache对冷热的判断是透过LRU类似的算法来判断的,这个是基于使用频度的维度。但是缺乏时间维度的判断。

新版本的flashcache引入了fallow_delay参数来解决这个问题,如果一个脏页超过fallow_delay秒,默认15分钟,都没有重新被访问到,那么数据就会被回写。 回写后,作为候选页面可以被新的cache重新利用。
Read more…

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

Erlang open_port极度影响性能的因素

November 22nd, 2011 4 comments

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

本文链接地址: Erlang open_port极度影响性能的因素

Erlang的port相当于系统的IO,打开了Erlang世界通往外界的通道,可以很方便的执行外部程序。 但是open_port的性能对整个系统来讲非常的重要,我就带领大家看看open_port影响性能的因素。

首先看下open_port的文档:

{spawn, Command}

Starts an external program. Command is the name of the external program which will be run. Command runs outside the Erlang work space unless an Erlang driver with the name Command is found. If found, that driver will be started. A driver runs in the Erlang workspace, which means that it is linked with the Erlang runtime system.

When starting external programs on Solaris, the system call vfork is used in preference to fork for performance reasons, although it has a history of being less robust. If there are problems with using vfork, setting the environment variable ERL_NO_VFORK to any value will cause fork to be used instead.

For external programs, the PATH is searched (or an equivalent method is used to find programs, depending on operating system). This is done by invoking the shell och certain platforms. The first space separated token of the command will be considered as the name of the executable (or driver). This (among other things) makes this option unsuitable for running programs having spaces in file or directory names. Use {spawn_executable, Command} instead if spaces in executable file names is desired.

open_port一个外部程序的时候流程大概是这样的:beam.smp先vfork, 子进程调用child_setup程序,做进一步的清理操作。 清理完成后才真正exec我们的外部程序。

再来看下open_port实现的代码:
Read more…

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

Erlang R15的内存delayed dealloc特性对消息密集型程序的影响

November 21st, 2011 1 comment

在新的NUMA体系结构下,每个CPU都有自己的本地内存,如果要访问其他CPU的内存,那算remote了,要走CPU之间的QPI通道,通常这样速度会有40%的下降。
那么对于多线程的程序来讲,这个硬件的变化对软件也有很大的影响。在多线程程序里面,通常一个线程会为一个对象分配内存,然后把这个对象传递到不同的线程去使用,最后由其他线程释放内存。而这二个线程可能在不同的CPU上运行,这个场景很普遍,比如说Erlang的消息机制。如果谁创建谁释放对象,提高内存倒腾的效率,那么对于消息密集型程序会有很多帮助。

R15的最大的运行期优化见: 这里
这个特性也就是之前声称的delayed dealloc特性
对照下OTP团队之前的规划:

目前规划里面的1,2,3,4在R15里面都已经实现了。

Optimize memory allocation

A number of memory allocation optimizations have been implemented. Most
optimizations reduce contention caused by synchronization between
threads during allocation and deallocation of memory. Most notably:
* Synchronization of memory management in scheduler specific allocator
instances has been rewritten to use lock-free synchronization.
* Synchronization of memory management in scheduler specific
pre-allocators has been rewritten to use lock-free synchronization.
* The ‘mseg_alloc’ memory segment allocator now use scheduler specific
instances instead of one instance. Apart from reducing contention
this also ensures that memory allocators always create memory
segments on the local NUMA node on a NUMA system.

我们来尝鲜演示下,首先设计个消息密集型的程序:
Read more…

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

Categories: Erlang探索, 调优 Tags: ,

IO模式调查利器blkiomon介绍

November 9th, 2011 Comments off

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

本文链接地址: IO模式调查利器blkiomon介绍

blkiomon 是blktrace工具包带的一个方便用户了解IO情况的工具, 由于blktrace太专业,需要了解的IO协议栈的东西太多,blkiomon给大多数的用户提供了一种易于使用的方式.
blktrace的使用参考这里: http://blog.yufeng.info/archives/tag/blktrace
他可以告诉你IO的大小,完成花费时间,吞吐量, 还可以统计出这次关键参数的分布.
具体见man blkiomon

blkiomon is a block device I/O monitor. It periodically generates per-device request size and request latency statistics from blktrace data. It
provides histograms as well as data that can be used to calculate min, max, average and variance. For this purpose, it consumes D and C traces
read from stdin.

我们来演示下:
Read more…

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

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