• Feeds

  • QCon Beijing qconbeijing全部演讲资料下载

    QCon Beijing 2009 qconbeijing slide download

    QCon全球企业开发大会(QCon Enterprise Software Development Conference)2009

    QCon 2009北京大会全部演讲资料下载 (包含pdf, ppt 等格式slide)

    永久链接:http://timyang.net/?p=136

    Update 2010/03/01: 目前Dropbox已经被封,请自行想办法解决。(点这里可申请Dropbox账号)
    Update 2010/05/11: 注意本文是2009年的演讲稿,QCon beijing 2010 的演讲稿官方尚未全部公布,部分下载见这里 http://www.cnblogs.com/coderzh/archive/2010/04/28/qcon-beijing-2010-ppt-slideshare.html

    http://dl.getdropbox.com/u/1080311/suncaoxipingqconbeijing-090423084840-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/augmentumshaorongqconbeijing-090423085848-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/vmwareliyanbingqconbeijing-090423084914-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/ebayrandyqconbeijing-090423080359-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/pmlvjianweiqconbeijing-090423081337-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/uelvweideqconbeijing-090423091515-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/alipaychengliqconbeijing-090423080430-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/sprinthenrikqconbeijing-090423081310-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/openwebdylanqconbeijing-090423091545-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/youkuqiudanqconbeijing-090423080809-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/azurewuyananqconbeijing-090423084537-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/outsoftingqconbeijing-090423081254-phpapp02.ppt 
    http://dl.getdropbox.com/u/1080311/qcon2009intro-090412122012-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/youdaodengyiqconbeijing-090423072448-phpapp02.ppt 
    http://dl.getdropbox.com/u/1080311/freewheeldianeqconbeijing-090423080513-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/reusearchpanjiayuqconbeijing-090423083708-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/collabortivecommercevisionwangqconbeijing-090423084739-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/tddmaitianzhiqconbeijing-090423083637-phpapp01.ppt 
    http://dl.getdropbox.com/u/1080311/QCon_Summary_Chinese.pdf 
    http://dl.getdropbox.com/u/1080311/flexmajianqconbeijing-090423090123-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/geowebmoxiezhangqconbeijing-090423090510-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/enterprisejavamaoxinshengqconbeijing-090423085404-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/doubanhongqiangningqconbeijing-090423080457-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/taobaoyuexuqiangqconbeijing-090423085411-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/aboutarchzhouaiminqconbeijing-090423080807-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/archqualitygaohuantangqconbeijing-090423080658-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/newinfoqchinaintro-090412122754-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/siemensliweiqconbeijing-090423080616-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/amazonjeffbarqconbeijing-090423083948-phpapp01.pdf 
    http://dl.getdropbox.com/u/1080311/ppwithagileyannhamonqconbeijing-090423081417-phpapp02.pdf 
    http://dl.getdropbox.com/u/1080311/jrubyluogudaoqconbeijing-090423085418-phpapp01.pdf 
    

    了解Linux的进程与线程

    上周碰到部署在真实服务器上某个应用CPU占用过高的问题,虽然经过tuning, 问题貌似已经解决,但我对tuning的方式只是基于大胆的假设并最终生效了。我更希望更多的求证一下程序背后CPU及OS kernel当时的运作机制。所以我读了一些Linux内核设计与实现及其他一些相关资料,对Linux process的机制与切换有了更多一些体会。本文尽可能条理一点,但由于牵涉点较多,同时自己可能觉得某些点有记录的价值,因此文字可能会零散。

    • 进程状态

    Linux进程的状态比较容易理解,值得注意的是 UNINTERRUPTIBLE 及 ZOMBIE

    TASK_RUNNING
    TASK_INTERRUPTIBLE
    TASK_UNINTERRUPTIBLE 此时进程不接收信号,这就是为什么有时候kill一个繁忙的进程没有响应。
    TASK_ZOMBIE 我们经常 kill -9 pid 之后运行ps会发现被kill的进程仍然存在,状态为 zombie。zombie的进程实际上已经结束,占用的资源也已经释放,仅由于kernel的相关进程描述符还未释放。
    TASK_STOPPED

    • Kernel space and user space

    Kernel space是供内核,设备驱动运行的内存区域。user space是供普通应用程序运行的区域。每一个进程都运行在自己的虚拟内存区域,不能访问其他进程的内存空间。普通进程不能访问kernel space, 只能通过系统调用来间接进行。当系统内存比较紧张时,非当前运行进程user space可能会被swap到磁盘。

    使用命令 pmap -x <pid> 可以查看进程的内存占用信息; lsof -a -p <pid> 可以查看一个进程打开的文件信息。ps -Lf <pid> 可以查看进程的线程数。

    另外procfs也是一个分析进程结构的好地方。procfs是一个虚拟的文件系统,它把系统中正在运行的进程都显现在/proc/<pid>目录下。

    • 进程创建

    进程创建通常调用fork实现。创建后子进程和父进程指向同一内存区域,仅当子进程有write发生时候,才会把改动的区域copy到子进程新的地址空间,这就是copy-on-write技术,它极大的提高了创建进程的速度。

    • Linux的线程实现

    Linux线程是通过进程来实现。Linux kernel为进程创建提供一个clone()系统调用,clone的参数包括如 CLONE_VM, CLONE_FILES, CLONE_SIGHAND 等。通过clone()的参数,新创建的进程,也称为LWP(Lightweight process)与父进程共享内存空间,文件句柄,信号处理等,从而达到创建线程相同的目的。

    Linux 2.6的线程库叫NPTL(Native POSIX Thread Library)。POSIX thread(pthread)是一个编程规范,通过此规范开发的多线程程序具有良好的跨平台特性。尽管是基于进程的实现,但新版的NPTL创建线程的效率非常高。一些测试显示,基于NPTL的内核创建10万个线程只需要2秒,而没有NPTL支持的内核则需要长达15分钟。

    在Linux 2.6之前,Linux kernel并没有真正的thread支持,一些thread library都是在clone()基础上的一些基于user space的封装,因此通常在信号处理、进程调度(每个进程需要一个额外的调度线程)及多线程之间同步共享资源等方面存在一定问题。为了解决这些问题,当年IBM曾经开发一套NGPT(Next Generation POSIX Threads), 效率比 LinuxThreads有明显改进,但由于NPTL的推出,NGPT也完成了相关的历史使命并停止了开发。

    NPTL的实现是在kernel增加了futex(fast userspace mutex)支持用于处理线程之间的sleep与wake。futex是一种高效的对共享资源互斥访问的算法。kernel在里面起仲裁作用,但通常都由进程自行完成。

    NPTL是一个1×1的线程模型,即一个线程对于一个操作系统的调度进程,优点是非常简单。而其他一些操作系统比如Solaris则是MxN的,M对应创建的线程数,N对应操作系统可以运行的实体。(N<M),优点是线程切换快,但实现稍复杂。

    • 信号

    进程接收信号有两种:同步和异步。同步信号比如SEGILL(非法访问), SIGSEGV(segmentation fault)等。发生此类信号之后,系统会立即转到内核陷阱处理程序,因此同步信号也称为陷阱。异步信号如kill, lwp_kill, sigsend等调用产生的都是,异步信号也称为中断。

    kill <pid> 调用的是 SIGTERM, 此信号可以被捕获和忽略。

    kill -9 <pid> 调用的是 SIGKILL, 杀掉进程,不能被捕获和忽略。

    SIGHUP是在终端被断开时候调用,如果信号没有被处理,进程会终止。这就是为什么突然断网刚通过远程终端启动的进程都终止的原因。防止的方法是在启动的命令前加上 nohup 命令来忽略 SIGHUP信号。如 nohup ./startup.sh &

    很多应用程序通常捕获SIGHUP用来实现一些自定义特性,比如通过控制台传递信号让正在运行的程序重新加载配置文件,避免重启带来的停止服务的副作用。可惜的是,在JAVA中没法直接使用这一功能,SUN JVM没有官方的signal支持,尽管它已经可以实现,详情可参看Singals and Java.

    另外有个有趣的现象是 zombie 状态的进程 kill/kill -9 都没有任何作用,这是由于进程本身已经不存在,所以没有相应的进程来处理signal, zombie状态的进程只是kernel中的进程描述符及相关数据结构没有释放,但进程实体已经不存在了。

    关于僵尸进程,也可参看下酷壳上的这篇Linux 的僵尸(zombie)进程,从程序的角度解释了相关原理。

    高性能网站经验-读杨建的Blog有感

    今天拜读了杨建的博客, 杨建开发的程序以高请求,高带宽为主,比如:

    开发的一系列系统中的两个 并发达到54.15w req/s , connections 340.25w  高峰一小时近20亿实际http请求处理量。

    所以整理了一些观点如下,喜欢吃快餐的请进。由于整理下面内容是跨十几篇文章的,就不一一给出链接了,需要看原文的简单Google一下即可找到。

    一 、如何衡量Web Server的性能指标

    总体来说同时在线connections和当时的每秒请求处理量是两个最重要的指标。

    实验环境数据: 杨建曾写了个HTTP服务框架,不使用磁盘I/O,简化了逻辑处理部分,只会输出 “hello world!”  程序部署在192.168.0.1上(2cup*4Core,硬件和系统都做过优化),在另外8台同等配置服务器上同时执行命令  ./apache/bin/ab -c 1000  -n 3000000   -k  “http://192.168.0.1/index.html” 几乎同时处理完毕,总合相加 40w req/s,他相信这是目前硬件水平上的极限值 。

    二、部署经验

    I. 对于cache处理的创新

    通过在url后面增加?maxage=xxx的做法,服务器通过这个参数来返回cache失效的maxage,比较灵活,优点:

    1. 可以控制HTTP header的的 max-age 值。
    2. 让用户为每个资源灵活定制精确的cache时间长度。
    3. 可以代表资源版本号。

    好奇,试验了一下杨建的系统
    $ curl -i http://sports.sinajs.cn/today.js?maxage=22

    HTTP/1.1 200 OK
    Server: Cloudia
    Last-Modified: Tue, 28 Apr 2009 14:10:02 GMT
    Cache-Control: max-age=22
    Content-Encoding: deflate
    Content-Length: 257
    Connection: Keep-Alive
    Content-Type: application/x-javascript

    大家可以看看返回的字段,其中有一点很有趣,返回直接不理http请求强制返回deflate(zip)格式, 比较霸道。

    II. IDC分布

    关于网络环境与IDC分布,正在迅速成长的公司可以了解下原文杨建介绍的经验,非常详尽。为什么说迅速成长的公司需要看,因为大的网络公司已经很清楚了,小的公司估计也用不上 :)

    III. DNS解析经验

    DNS解析有有个缺陷,每个单独域名里写在最前面的那个ip,它被轮询到的概率要比同组的服务器高10%,而且随着同组服务器的增多,这个差距会变大。所以最解析时候,每个IDC最好把硬件性能最好的服务器ip放在最前面。

    IV. 优化网卡, 调整内核参数

    这两段介绍也很有价值,主要是一些参数调优,做大型系统的推荐去看一下原文

    三、开发经验

    I. 关于epoll

    epoll最擅长的事情是监视大量闲散连接,批量返回可用描述符,这让单机支撑百万connections成为可能。
    边缘触发ET 和 水平触发LT 的选择:
    早期的文档说ET很高效,但是有些冒进。但事实上LT使用过程中,苦恼了将近一个月有余,一不留神CPU 利用率99%了,可能是我没处理好。后来zhongying同学帮忙把驱动模式改成了ET模式,ET既高效又稳定。
    简单地说,如果你有数据过来了,不去取LT会一直骚扰你,提醒你去取,而ET就告诉你一次,爱取不取,除非有新数据到来,否则不再提醒。

    自己用epoll写C的可以去深入了解下。

    II. 写数据

    顺便再说下写数据,一般一次可以write十几K数据到内核缓冲区。
    所以对于很多小的数据文件服务来说,是没有必要另外为每个connections分配发送缓冲区。
    只有当一次发送不完时候才分配一块内存,将数据暂存,待下次返回可写时发送。
    这样避免了一次内存copy,而且节约了内存。

    III. 如何节约CPU

    HTTP请求预处理 (预压缩,预取lastmodify,mimetype)
    预处理,原则就是,能预先知道的结果,我们绝不计算第二次。

    预压缩:我们在两三年前就开始使用预压缩技术,以节约CPU,伟大的微软公司在现在的IIS 7中也开始使用了。所谓的预压缩就是,从数据源头提供的就是预先压缩好的数据,IDC同步传输中是压缩状态,直到最后web server输出都是压缩状态,最终被用户浏览器端自动解压。

    IV. 怎样使用内存

    1. 避免内核空间和用户进程空间内存copy (sendfile, splice and tee)
    sendfile: 它的威力在于,它为大家提供了一种访问当前不断膨胀的Linux网络堆栈的机制。这种机制叫做“零拷贝(zero-copy)”,这种机制可以把“传输控制协议(TCP)”框架直接的从主机存储器中传送到网卡的缓存块(network card buffers)中去,避免了两次上下文切换。据同事测试说固态硬盘SSD对于小文件的随机读效率很高,对于更新不是很频繁的图片服务,读却很多,每个文件都不是很大的话,sendfile+SSD应该是绝配。

    2. 内存复用  (有必要为每个响应分配内存 ?)
    对于NBA JS服务来说,我们返回的都是压缩数据,99%都不超过15k,基本一次write就全部出去了,是没有必要为每个响应分配内存的,公用一个buffer就够了。如果真的遇到大数据,我先write一次,剩下的再暂存在内存里,等待下次发送。

    V. 减少磁盘I/O

    共享内存可以考虑用BDB实现,它取数据的速度每秒大概是100w条(2CPU*2Core Xeon(R) E5410 @ 2.33GHz环境测试,单条数据几十字节),如果你想取得更高的性能建议自己写。