Performance Tweaks and Tools For Linux
Performance Tweaks and Tools For Linux
Performance Tweaks and Tools For Linux
-P
Inhibits the conversion of port numbers to names for network files
-p pid
Attach to the process with the process ID pid and begin tracing.
-T
Show the time spent in system calls.
-o filename
Write the trace output to the file filename rather than to stderr.
read query
response
slow query
strace ruby to see some interesting things...
stracing ruby: SIGVTALRM
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
rt_sigreturn(0x1a) = 2207807 <0.000009>
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
rt_sigreturn(0x1a) = 0 <0.000009>
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
rt_sigreturn(0x1a) = 140734552062624 <0.000009>
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
rt_sigreturn(0x1a) = 140734552066688 <0.000009>
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
rt_sigreturn(0x1a) = 11333952 <0.000008>
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
rt_sigreturn(0x1a) = 0 <0.000009>
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
rt_sigreturn(0x1a) = 1 <0.000010>
--- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
-s <len>
Snarf len bytes of data from each packet.
-n
Don't convert addresses (host addresses, port numbers) to names.
-q
Quiet output. Print less protocol information.
-A
Print each packet (minus its link level header) in ASCII.
-w <file>
Write the raw packets to file rather than printing them out.
<expr>
libpcap expression, for example:
tcp src port 80
tcp dst port 3306
tcp dst port 80
19:52:20.216294 IP 24.203.197.27.40105 >
174.37.48.236.80: tcp 438
E...*[email protected].%&.....%0....POx..%s.oP.......
GET /poll_images/cld99erh0/logo.png HTTP/1.1
Accept: */*
Referer: http://apps.facebook.com/realpolls/?
_fb_q=1
tcp dst port 3306
19:51:06.501632 IP 10.8.85.66.50443 >
10.8.85.68.3306: tcp 98
E..."K@[email protected]
.UB
.UD.....z....L............
GZ.y3b..[......W....
SELECT * FROM `votes` WHERE (`poll_id` =
72621) LIMIT 1
tcpdump -w <file>
PERFTOOLS
google's performance tools
CPUPROFILE=/tmp/myprof ./myapp
pprof ./myapp /tmp/myprof
wget http://google-perftools.googlecode.com/files/google-
perftools-1.6.tar.gz download
tar zxvf google-perftools-1.6.tar.gz
cd google-perftools-1.6
./configure --prefix=/opt
make compile
sudo make install
# for linux
export LD_PRELOAD=/opt/lib/libprofiler.so setup
# for osx
export DYLD_INSERT_LIBRARIES=/opt/lib/libprofiler.dylib
pprof.rb /tmp/myrbprof
github.com/tmm1/perftools.rb
gem install perftools.rb
github.com/ice799/ltrace/tree/libdl
ltrace -F <conf> -b -g -x <sym>
-b
Ignore signals.
-g
Ignore libraries linked at compile time.
-F <conf>
Read prototypes from config file.
-x <sym>
Trace calls to the function sym.
-F ltrace.conf
int mysql_real_query(addr,string,ulong);
void garbage_collect(void);
int memcached_set(addr,string,ulong,string,ulong);
ltrace -x garbage_collect
19:08:06.436926 garbage_collect() = <void> <0.221679>
19:08:15.329311 garbage_collect() = <void> <0.187546>
19:08:17.662149 garbage_collect() = <void> <0.199200>
19:08:20.486655 garbage_collect() = <void> <0.205864>
19:08:25.102302 garbage_collect() = <void> <0.214295>
19:08:35.552337 garbage_collect() = <void> <0.189172>
ltrace -x mysql_real_query
mysql_real_query(0x1c9e0500, "SET NAMES 'UTF8'", 16) = 0 <0.000324>
mysql_real_query(0x1c9e0500, "SET SQL_AUTO_IS_NULL=0", 22) = 0 <0.000322>
mysql_real_query(0x19c7a500, "SELECT * FROM `users`", 21) = 0 <1.206506>
mysql_real_query(0x1c9e0500, "COMMIT", 6) = 0 <0.000181>
ltrace -x memcached_set
memcached_set(0x15d46b80, "Status:33", 21, "\004\b", 366) = 0 <0.01116>
memcached_set(0x15d46b80, "Status:96", 21, "\004\b", 333) = 0 <0.00224>
memcached_set(0x15d46b80, "Status:57", 21, "\004\b", 298) = 0 <0.01850>
memcached_set(0x15d46b80, "Status:10", 21, "\004\b", 302) = 0 <0.00530>
memcached_set(0x15d46b80, "Status:67", 21, "\004\b", 318) = 0 <0.00291>
memcached_set(0x15d46b80, "Status:02", 21, "\004\b", 299) = 0 <0.00658>
memcached_set(0x15d46b80, "Status:34", 21, "\004\b", 264) = 0 <0.00243>
GDB
the GNU debugger
gdb <executable>
gdb attach <pid>
Debugging Ruby Segfaults
test_segv.rb:4: [BUG] Segmentation fault
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9.7.0]
def test
#include "ruby.h" require 'segv'
4.times do
VALUE Dir.chdir '/tmp' do
segv() Hash.new{ segv }[0]
{ end
VALUE array[1]; end
array[1000000] = NULL; end
return Qnil;
} sleep 10
test()
void
Init_segv()
{
rb_define_method(rb_cObject, "segv", segv, 0);
}
1. Attach to running process
$ ps aux | grep ruby
joe 23611 0.0 0.1 25424 7540 S Dec01 0:00 ruby test_segv.rb
2. Use a coredump
Process.setrlimit Process::RLIMIT_CORE, 300*1024*1024
$ sudo mkdir /cores
$ sudo chmod 777 /cores
$ sudo sysctl kernel.core_pattern=/cores/%e.core.%s.%p.%t
def run
@listeners.each {|name,s|
s.run
}
ruby-bleak-house myapp.rb
bleak /tmp/bleak.<PID>.*.dump
github.com/fauna/bleak_house
• BleakHouse
• installs a patched version of ruby: ruby-bleak-
house
• unlike gdb.rb, see where objects were created
(file:line)
• create multiple dumps over time with `kill -USR2
<pid>` and compare to find leaks
191691 total objects
Final heap size 191691 filled, 220961 free
Displaying top 20 most common line/class pairs
89513 __null__:__null__:__node__
41438 __null__:__null__:String
2348 ruby/site_ruby/1.8/rubygems/specification.rb:557:Array
1508 ruby/gems/1.8/specifications/gettext-1.9.gemspec:14:String
1021 ruby/gems/1.8/specifications/heel-0.2.0.gemspec:14:String
951 ruby/site_ruby/1.8/rubygems/version.rb:111:String
935 ruby/site_ruby/1.8/rubygems/specification.rb:557:String
834 ruby/site_ruby/1.8/rubygems/version.rb:146:Array
IOPROFILE
summarizes strace and lsof
wget http://aspersa.googlecode.com/svn/trunk/ioprofile
strace -cp <pid>
$ ioprofile t/samples/ioprofile-001.txt
total pread read pwrite write filename
10.094264 10.094264 0.000000 0.000000 0.000000 /data/data/abd_2dia/aia_227_228.ibd
8.356632 8.356632 0.000000 0.000000 0.000000 /data/data/abd_2dia/aia_227_223.ibd
0.048850 0.046989 0.000000 0.001861 0.000000 /data/data/abd/aia_instances.ibd
0.035016 0.031001 0.000000 0.004015 0.000000 /data/data/abd/vo_difuus.ibd
0.013360 0.000000 0.001723 0.000000 0.011637 /var/log/mysql/mysql-relay.002113
0.008676 0.000000 0.000000 0.000000 0.008676 /data/data/master.info
0.002060 0.000000 0.000000 0.002060 0.000000 /data/data/ibdata1
0.001490 0.000000 0.000000 0.001490 0.000000 /data/data/ib_logfile1
0.000555 0.000000 0.000000 0.000000 0.000555 /var/log/mysql/mysql-relay-log.info
0.000141 0.000000 0.000000 0.000141 0.000000 /data/data/ib_logfile0
0.000100 0.000000 0.000000 0.000100 0.000000 /data/data/abd/9fvus.ibd
strace -ttTp <pid> -o <file>
-c CELL
specify what to put in the cells of the output. ‘times’, ‘count’,
or ‘sizes‘.
• echo "|/path/to/core_helper.rb %p %s %u
%g" > /proc/sys/kernel/core_pattern
• http://gist.github.com/587443
and lots more
/proc/meminfo
/proc/scsi/*
/proc/net/*
/proc/sys/net/ipv4/*
...
MONITOR RAID STATUS
• how do you know when a hard drive in
your RAID array fails?
• 3ware - /usr/bin/tw_cli
snooki:/# /usr/StorMan/arcconf getconfig 1 AL
Controllers found: 1
----------------------------------------------------------------------
Controller information
----------------------------------------------------------------------
Controller Status : Optimal
Channel description : SAS/SATA
Controller Model : Adaptec 3405
Controller Serial Number : 7C4911519E3
Physical Slot :2
Temperature : 42 C/ 107 F (Normal)
Installed memory : 128 MB
Copyback : Disabled
Background consistency check : Enabled
Automatic Failover : Enabled
Global task priority : High
Stayawake period : Disabled
Spinup limit internal drives :0
Spinup limit external drives :0
Defunct disk drive count :0
Logical devices/Failed/Degraded : 1/0/0
--------------------------------------------------------
Controller Version Information
--------------------------------------------------------
BIOS : 5.2-0 (17304)
Firmware : 5.2-0 (17304)
Driver : 1.1-5 (2461)
• write a script to parse that
• run it with cron
• the ugly ruby script i use for adaptec:
http://gist.github.com/643666
more well known tools:
iostat, vmstat, top, and free
LINUX TWEAKS
ADJUST TIMER FREQUENCY
CONFIG_HZ_100=y
CONFIG_HZ=100
• Set the timer interrupt frequency.
• Fewer timer interrupts means processes
run with fewer interruptions.
• Servers (without interactive software)
should have lower timer frequency.
CONNECTOR
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
• connector kernel module is useful for
process monitoring.
• build or use a system like god to watch
processes.
• when processes die the kernel notifies you
• you can restart/recover/etc.
TCP SEGMENTATION OFFLOADING
sudo ethtool -K eth1 tso on
• Allows kernel to offload large packet
segmentation to the network adapter.
• Frees the CPU to do more useful work.
• After running the command above, verify
with:
[joe@timetobleed]% dmesg | tail -1
@joedamato
timetobleed.com