Archive for 六月, 2012


上一个章节谈到了,以后银行赚你钱的方法,不需要再贷款给你收取利息。而是根据你的信用记录作出评估,比如说把全世界的企业按照不同规模,搞一个评级系统。或者是把每个人的信用评级都放到市场上,然后银行和对冲基金们,就可以根据这个来开赌了。
比如说,你A先生在政府部门工作,各方面财务记录都不错,所以你的信用评分是120分。但是大家考虑到政府要削减财政赤字,可能A先生的工作会受到影响,于是大家开赌A先生的信用评级,会下跌。
那么大家,就根据A先生的信用分走势,画星期K线、天K线和小时K线。根据政府内部的不同势力的博弈,一个新闻出来涨几点,另一个新闻出来跌几点,然后就把期货啊、期权啊、CDO啊,CDS啊,甚至是政府雇员个人信用指数啊、或者雇员职称级别不同斩出来的tranche啊,一股脑都拿来交易。
可能你A先生,一分钱都没有出去借,大家就已经在你的信用变动之中,赚了或者赔了几亿美元了。
要搞衍生品,就要考虑到定价模式。在期权横空出世的时候,来自于MIT(麻省理工学院)的三个数学天才Fisher Black、Myron Scholes和Robert C. Merton开发了期权的定价模式,并以此后来获得了诺贝尔经济学奖。
期权是一种标准的衍生品,就是你花钱买一个权利(或者说保险)可以让你决定在未来的某一天以一个固定的价格,可以去买一定数量的某种产品(比如农产品、石油等等),或者资产(比如房子、珠宝),或者金融代号(比如股票、债券、外汇)。
你可能以为你花的这个买权利的价格,一定是根据这种衍生品建基的实际产品的价格变动来制定,那么你就错了。
这个价格是由什么来决定的呢?
是由套利来决定的。套利,在英文中叫做arbitrage。意思是如果你有同样价值的产品,在购买资金流相似的情况下,其价格应该是相同的。因为很简单,如果你价格不同的话,就存在着套利的空间。就是说人家可以买进价格低的同数量产品,然后以高价格卖出去。
在中国以前搞价格双轨制的时候,你如果是个当官的,可以批条子,就可以把内部计划价格的产品,调动到市场价格那里高价出售。这中间的利润,是无风险的安全利润。
以前全球通讯没有现在这么发达的时候,也有人根据纽约、伦敦和香港的金价不同,搞套利交易。
因此你如果定价模式里面存在套利因素的话,那么就没有办法运作。于是必须开发出一种无套利模式,所谓no-arbitrage model。
在1970年代,这些麻省数学天才选择的模式,是当时非常标准的模式,称为geometric Brownian motion,所谓几何布朗运动。
几何布朗运动,就是下面这张图。
这个GBM理论,指的是小微粒子的随机运动。比如说灰尘和花粉啊,碰到了水分子或者空气分子之后的随机飘动。
这个理论被引进到金融工程领域之后,就要做一些相应的修改。因为用于股票和债券之类的金融产品,你肯定就不需要负数的。因为就象前文谈过,企业总值切件之后,大家的责任是有限的,所以最大的风险只能是有限投资归于0,而不是负数。
再加上其他的一些假定,比如说,微小粒子和空气分子还是有碰撞和摩擦的,在金融行业里,就是你买入和卖出发生的费用损失,暂时就假设为没有。
因此麻省理工的三剑客,就得出结论,你其实是可以给期权找出一个完美的对冲方式。就是说,无论你底下依托的金融产品价格如何变动,你都可以找到一个位置,如果进行合适的调整的话,总是和你的期权获得同样的收益。而且这个位置是自我支撑的,就是说一旦位置建立,根据必要的调整,你不需要再追加投入资金来保持平衡。
既然最后大家的收益是相同的,那么期权的价格,就必须等于这个完美对冲的费用。这个完美对冲,在英文里面也叫做replicating portfolio,复制投资组合。如果不是这样的话,你就给套利留下了空间。
这种思维的逻辑,认定了可以对期权进行准确的定价。而在这定价模式里面,居然没有考虑到投资人们对底层建基的金融产品价格会涨还是会跌的偏好,也没有考虑到投资人们对投资风险的态度和容忍程度。而这些都是其他的经济学科不能排除的。
在麻省三剑客的无套利建模的理论影响下,斯坦福大学的几位研究学者Michael Harrison、David Kreps和Stanley Pliska,运用了博弈论中的鞅理论(martingale theory)对其进行了证实。
首先,斯坦福三剑客证明,当而且仅当一个等价的鞅测度存在,市场才无套利机会。这个鞅测度,将新的、不同的鞅的概率分配给底层金融产品的不同价格路径,导致无风险利率下的贴现价,长远来看是不上不下的漂移,那么期权或者其他未定权益的价格,在同样的概率之下,其贴现价格,就是你预期的回报。
其次,当而且仅当一个市场是完整的,就是说金融产品的交易是涵盖所有可能的结果,可以让所有的未定权益都进行了麻省三剑客提出的完美对冲,那么鞅测度就是唯一的结果。
估计大部分同学,除了数学方面的高手之外,看完了这一段话,会觉得云里雾里。
因为这个模式相当抽象,为了让人们更好的理解,两位金融工程师(英文称为quant,也可翻译成定量分析师)Martin Baxter和Andrew Rennie在1996年出了一本教科书,用了一个赛马的赌博理论来介绍了这个理论。
假定你有两匹马,一匹是黑马,一匹是五花马,来比赛跑马。而开赌的庄家知道真正的赢的概率,黑马是25%,五花马是75%。因此庄家把赔率定为黑马是1赔3,五花马是3赔1。
就是说,如果你买一块钱黑马赢,如果黑马跑赢了,庄家赔你3块钱。而如果你买3块钱的五花马赢,然后五花马赢了,庄家赔你1块钱。
可是事实上,因为公众的喜好不同,结果你就发现,原来有1万块押注在黑马身上,但是2万块押注在五花马身上,这样的话,虽然庄家知道真正的赛马的概率,而且长远来讲,庄家上面的赔率一定会保证持平,但是由于公众赔率的不同,会导致在一场特定的跑马中,庄家会损失惨重。
这样的话,庄家就不会把赔率按照真正的概率去做,而是按照大家下注的比例。就是说黑马是1赔2, 五花马是2赔1。这样的话,不论赛马的结果如何,哪只马跑赢,庄家都会持平。
比如说,黑马胜了,1赔2,你就把买五花马赢的2万赔出去。如果五花马赢了,2赔1,你就把买黑马赢的1万给赔出去。
按照概率论学者的说法,根据第二种方法定价,庄家就改变了“测度”,将真正的概率(1/4对3/4)改成了持平概率(1/3对2/3)。后面的这种概率,就是鞅概率。
那么这种不是按照真正的概率,而是按照鞅概率的做法,在金融投资行业基本上变成了原教旨的信条。
虽然鞅概率和真实的概率有不同,但是在金融行业里面,大家也知道真实概率难以确定,而持平概率,就是鞅概率,是可以通过过去的数据给推算出来的。
赌马的庄家其实也不知道那匹马会爆冷,但是肯定就知道赌每只马赢的赌注各自有多少。其实就是说,这种概率既不是由过去的数据决定的,也不是由未来的概率决定的,而是根据现在各种押注的价格决定的。
这种无套利建模思维,本来是在小圈子存在,但是在几家大学的相关课程的设置,慢慢导致金融工程师们基本上都是这种理论训练出来。尤其是美国的金融机构的衍生品部门,即使在前几年大家都在狂赌的时候,仍然非常重视对冲组合。毕竟衍生品面临的价格波动,和利率变化的风险都不小,而且大家的分红模式和对冲模式紧紧挂钩,大家基本上是每天都要计算风险。
因为模式过于复杂,因此几百甚至几千台电脑联在一起,来计算模型,在晚上算出结果之后,第二天交易员们就可以根据结果来操盘。
而大家信赖的只是一句话:对冲成本决定价格。就是说,按照衍生品建基的底层金融产品的对冲投资组合来对冲衍生品,用那个对冲组合的成本来给衍生品定价。
当然如果要把衍生品卖出去给客人的话,你还是要在这个价格上加一块的,因为银行利润和交易员的花红,全在这一块了。
所以了解JP摩根的衍生品交易,提到correlation,就是你卖保险出去的时候,需要按照比例卖空一定量的指数。
不过谁也没有考虑过,如果对冲的模式不对的话,那又会出啥子乱子?

写伦敦鲸鱼的主要目的,是希望我们可以发展出一批将来投身中国债券市场建设的人才,必须知道现在全球的资本市场的玩家们在干嘛。
最近10来年,金融市场发展最快的东东,就是金融衍生品。所谓衍生品,就是从一个东西里面衍生出来的产品。
比如说,你要是买股票,按照现在的定义,就不是在炒作衍生品。不过本来股票,也是从股票代表的企业衍生出来的。以前也可以算是衍生品,只不过慢慢大家接受了,就真把它当一回事了。
世界上基本上所有的东西,都可以靠组合和斩件来处理。
西方世界今天对全球的支配性地位,很大程度上,是靠地理大发现实现的。而地理大发现之所以发生,并不是因为人家西方人吃饱了饭,闲得蛋疼,要学徐霞客去走访名山大川,去拥抱大自然。
而是因为大家想靠探险去发现黄金发家致富。
要发财,就要有投资。以前的发财,是靠打着宗教旗号,用十字军东征,要夺回君士坦丁堡,要抢回来圣城耶路撒冷的马甲进行的。
领头的大哥们是各国的贵族,投资的是有钱的犹太人。不过东征的结果非常悲惨,死人无数,回来还要被犹太人追债,于是一怒之下,大家就杀了债主。
小时候,读莎士比亚的《威尼斯商人》,就可以看到,小伙子借了犹太人投资的钱,去探险/海盗/经商三合一,不过船给怒海沉了,被债主杀到,要靠法律狡辩来赖帐。
而当时的英国女王伊丽莎白也靠从贵族中间融资,成立了一支海盗船队,靠打劫南美洲回来的西班牙商船来赚钱。有时候命好的话,一次收入就相当于全年的税收了。
这只海盗船队,现在还在,叫做英国皇家海军,马甲换了,德性还是一样。
不过当时想得到这样的暴利,就得承受投资的风险。毕竟人家全部身家投资给你伊丽莎白,你的海盗如果海战中失利,被西班牙皇家海盗队给灭了,贵族们一样会睡街上。法国大革命的起因之一,就是法国贵族们的钱,融资给路易皇帝,投资到北美洲的新奥尔良房地产工程上去,赔大了,你皇帝哪能不付代价?
为了控制投资风险,于是有限责任公司应运而生。
这个就是一个组合再斩件的过程。就是把一个公司的资产,比如说海盗船队的硬件,和海盗们这些软件,通通组合在一起,然后给一个总价值出来。
在这个总价值之后,然后就斩件,把它分割成一股一股的股票,就让大家按照自己可以承受的风险能力,去投资认购。这样就把风险定量化,不需要以前那样,无限风险了。
但是大家投资认购你的股票了,那么怎么知道你的财政运行情况?
这个就是另一个发明,叫着复式平衡记帐法。就是你一边是收入,一边是支出,可以平衡地记录下来,这样大家就比较容易查帐了。
在这种情况下,从企业价值衍生出来的股票(当然根据不同的待遇,又组合成普通股和优先股),和后来出现的债券,都慢慢被大家所接受,而成为资产的一种了。
这个时候,金融衍生品,则主要是期货、期权以及各种指数了。
然后在近期,JP摩根的金融工程师们,开始思考如何解决一个银行最头疼的问题。
那就是银行的负债,主要是指储户的存款,通常是短期的,你一定要承诺兑现的义务(想象一下,你去银行取钱,人家不给你取),而银行的资产,主要是指你贷出去的款,通常是长期的,而且有可能收不回来。
这样的不平等的风险因素,就导致银行必须储备足够的资金,来预防贷款收不回来的风险。结果就是根据你贷款的风险评级,你需要储备不同数额的风险资金。
因此收益越大,风险越大的贷款,你储备的资金就越大。无论如何,一旦银行要储备足够的风险资金,就导致银行的总贷款额度降低了。如果你把坏帐率固定一下,那么显然如果你可以贷款出去的资金总额越大,你的收入就越高。所以如何把贷款的风险给转嫁出去,就可以解决银行的这个头痛问题。
于是贷款债券化,就应运而生了。
贷款债券化,一个最热闹的地方,就是房屋贷款债券化。
首先,你把所有的房屋贷款都组合起来,然后按照里面的风险评级,就把这个总和给斩成几个件。就像杀猪一样,你就搞出里脊肉、五花肉、猪颈骨、猪蹄子等等,然后由评级公司,给予不同的评级,那么就把评级之后的斩件,分解成一股一股债券。
这些评级,最安全的,当然也是收益最低的,就给养老基金给买去了。最不安全的,当然也是收益最高的,就给对冲基金给买去了。
这样的话,贷款的银行,就收取了一个贷款产生费用,就把自己的贷款当成债券给卖出去了。
那么银行也可以去投资/购买这些债券,这样的话,就没有任何银行贷款给人,而是所有的银行,都在“购买”债券,因此我就不需要按照银行运作的要求,必须储备资金来担保贷款风险了。
就是说,如果把美军的特种部队全部划归给中情局,那么美国就会有几万间谍在阿富汗活动,但是美军就一个都没有,完完全全从阿富汗撤军了。
不过接下来的问题,就是你买的这些债券是不是也有风险呢?尤其是这些债券下面的贷款,还不是你自己亲手做的,不是你好好审查了。
而且因为这些债券这个衍生品,所依赖的底层的贷款,因为审查贷款的银行只拿一个贷款产生费,你如何保证人家反正没有啥风险,就想尽办法,创造性的贷款出去,给不符合贷款条件的傻A?
后来大家都知道,这个就是所谓金融危机中的次贷危机。
不要紧,银行的金融工程师,发明了另外一个东西。你的债券有风险,那么就帮债券买保险嘛。
因为这个保险,是衍生于债券,而这个债券,是建立在贷款之上,而贷款的最重要指数,是在于信用评级,所以这个保险,也称为信用违约调期,所谓CDS,就是它了。
那么金融危机发生了,有两个小两口,其中女的失业了,月供有点紧张了。于是想和贷款的银行商量一下,可不可以暂时减缓一下,之后找到工作,加点钱给你,这样就是双赢。不然的话,我违约供应不了,我损失,你也肉痛,很不和谐嘛。
结果打完电话,人家贷款银行说,你这个贷款,早就成为债券卖出去了,跟我们无关。你爱干嘛干嘛。
那这部分债券在谁手里?不知道,可能在沙特投资人那里,也可能在德国投资人那里,也可能在新加坡投资人那里。
那他们不怕我这里一破产,他们的债券,就没有利息收了吗?
不怕,他们已经买了CDS了。
于是买了CDS的银行、对冲基金、保险公司等等,你买我的,我卖你的,结算来,结算去,最后就出现了一个问题,叫做“对家风险”,所谓counterparty risk。
啥意思?就是你本来应该从买来的CDS那里,从对家拿到钱。然后你就可以从卖出去的CDS那里,赔给对家钱。
现在你的对家倒毙了,没钱赔给你了。可是你还应该赔给别人,结果是你没问题,也被倒毙了的对家,给被倒毙了。
那为什么大家都无法知道实际的情况如何呢?因为金融衍生品不同于你股票市场一样,有一个中央交易所,在那里交易。因此这里可以知道所有选手的买卖情况。也容易根据风险要求这些玩家,准备可抵押的资产。
但是金融衍生品的交易,叫做OTC(Over the counter),就是桌底交易,任何两个对家可以签订合同,其他人一概不知。
这样的话,对家们冲来冲去,就冲到了一家,叫做AIG。
而AIG面临着破产。只要AIG一倒毙,它欠一大堆金融机构的CDS赔单,就没有办法兑现,结果就是美国、法国、英国等等几乎所有的大银行,都会因此而倒毙。
于是美国政府就拿国家的钱,就是小民们的钱,来赔了。
CDS的出现,可以算是金融资本主义的革命性变革。这个让传统投资者巴菲特非常不安,称其为金融原子弹。
因为现在几乎所有的西方国家经济,都是借贷经济。大家啥子都不用干,借钱过日子就行了。
借钱,靠的是信用。那么CDS,就是用来衡量并交易你的信用。
以前银行要赚钱,就需要借钱给你。但是现在不用了,银行可以交易你的信用赚钱。
以前是银行借你1百万,年利息5%,就赚你5万。
现在你借1百万,根据你的信用好坏,那么5%,就是你CDS的保险费比例。
现在所有的银行,都可以来下注对赌你的保险费比例变化。比如说,银行认为经济情况可能变坏,虽然你还有工作,但是整体风险会增大,你的坏账机会会增加,所有CDS的保费比例,会上升到6%。
于是银行买1万亿的CDX(CDS指数之一)多单,结果变成6%,就赚1千亿。
虽然你只借了1百万。
将来大家只是炒卖你的信用,哪怕你一分钱贷款都没有。

Linux监控工具vmstat命令详解

一、前言

很显然从名字中我们就可以知道vmstat是一个查看虚拟内存(Virtual Memory)使用状况的工具,但是怎样通过vmstat来发现系统中的瓶颈呢?在回答这个问题前,还是让我们回顾一下Linux中关于虚拟内存相关内容。

二、虚拟内存原理

在系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到进程下一次调用,并将释放出的内存提供给有需要的进程使用。

在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。

分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)。

当系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。经管Page-Out不是经常发生,但是如果Page-out频繁不断的发生,直到当内核管理分页的时间超过运行程式的时间时,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态亦被称作thrashing(颠簸)。

三、vmstat详解

1.用法

vmstat [-a] [-n] [-S unit] [delay [ count]]
vmstat [-s] [-n] [-S unit]
vmstat [-m] [-n] [delay [ count]]
vmstat [-d] [-n] [delay [ count]]
vmstat [-p disk partition] [-n] [delay [ count]]
vmstat [-f]
vmstat [-V]

-a:显示活跃和非活跃内存

-f:显示从系统启动至今的fork数量 。

-m:显示slabinfo

-n:只在开始时显示一次各字段名称。

-s:显示内存相关统计信息及多种系统活动数量。

delay:刷新时间间隔。如果不指定,只显示一条结果。

count:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。

-d:显示磁盘相关统计信息。

-p:显示指定磁盘分区统计信息

-S:使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(byte)。默认单位为K(1024 bytes)

-V:显示vmstat版本信息。
2.使用说明

例子1:每3秒输出一条结果

procs ———–memory———- —swap– —–io—- –system– —–cpu——
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 5358240 151544 1367740 0 0 0 1 0 0 0 0 100 0 0
0 0 0 5358728 151544 1367740 0 0 0 0 1036 6840 0 0 100 0 0
0 0 0 5358596 151544 1367740 0 0 0 63 1039 6856 0 0 100 0 0
0 0 0 5358520 151544 1367740 0 0 0 28 1030 6806 0 0 100 0 0
0 0 0 5358424 151544 1367740 0 0 0 28 1038 6857 0 0 100 0 0
0 0 0 5356692 151544 1367788 0 0 0 141 1078 6885 0 0 100 0 0
0 0 0 5357532 151544 1367792 0 0 0 0 1037 6836 0 0 100 0 0
0 0 0 5357840 151544 1367792 0 0 0 179 1062 6864 0 0 100 0 0
0 0 0 5357692 151544 1367792 0 0 0 28 1039 6867 0 0 100 0 0

字段说明:

Procs(进程):

r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。(长期大于1)
b: 等待IO的进程数量

Memory(内存):

swpd: 使用虚拟内存大小

注意:如果swpd的值不为0,但是SI,SO的值长期为0,这种情况不会影响系统性能。
free: 空闲物理内存大小
buff: 用作缓冲的内存大小
cache: 用作缓存的内存大小

注意:如果cache的值大的时候,说明cache处的文件数多,如果频繁访问到的文件都能被cache处,那么磁盘的读IO bi会非常小。

Swap:

si: 每秒从交换区写到内存的大小,由磁盘调入内存
so: 每秒写入交换区的内存大小,由内存调入磁盘

注意:内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有些朋友看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

IO:(现在的Linux版本块的大小为1kb)

bi: 每秒读取的块数
bo: 每秒写入的块数

注意:随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。

系统:

in: 每秒中断数,包括时钟中断。
cs: 每秒上下文切换数。

注意:上面2个值越大,会看到由内核消耗的CPU时间会越大。

CPU(以百分比表示):

us: 用户进程执行时间百分比(user time)

注意: us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超50%的使用,那么我们就该考虑优化程序算法或者进行加速。

sy: 内核系统进程执行时间百分比(system time)

注意:sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性表现,我们应该检查原因。

wa: IO等待时间百分比

注意:wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)。

id: 空闲时间百分比

例子2:显示活跃和非活跃内存

procs ———–memory———- —swap– —–io—- –system– —–cpu——
r b swpd free inact active si so bi bo in cs us sy id wa st
0 0 0 6973324 480504 8696732 0 0 0 1 0 0 0 0 100 0 0
0 1 0 6973120 480516 8696808 0 0 0 156 1061 6911 0 0 100 0 0
0 0 0 6972536 480568 8696988 0 0 0 5 1072 6965 0 0 100 0 0
1 0 0 6972896 480568 8697020 0 0 0 129 1038 6954 0 0 100 0 0
0 0 0 6973296 480568 8697020 0 0 0 0 1039 6904 0 0 100 0 0
0 0 0 6973604 480568 8697028 0 0 0 43 1035 6941 0 0 100 0 0
0 1 0 6973384 480568 8697012 0 0 0 37 1043 6950 0 0 100 0 0
0 0 0 6973608 480568 8697012 0 0 0 5 1030 6935 0 0 100 0 0
0 0 0 6973136 480572 8697004 0 0 0 48 1041 6933 0 0 100 0 0
0 0 0 6973640 480572 8697004 0 0 0 0 1033 6888 0 0 100 0 0

使用-a选项显示活跃和非活跃内存时,所显示的内容除增加inact和active外,其他显示内容与例子1相同。

字段说明:

Memory(内存):

inact: 非活跃内存大小(当使用-a选项时显示)
active: 活跃的内存大小(当使用-a选项时显示)

总结:

目前说来,对于服务器监控有用处的度量主要有:

r(运行队列)
pi(页导入)
us(用户CPU)
sy(系统CPU)
id(空闲)
注意:如果r经常大于4 ,且id经常少于40,表示cpu的负荷很重。如果bi,bo 长期不等于0,表示内存不足。

通过VMSTAT识别CPU瓶颈:
r(运行队列)展示了正在执行和等待CPU资源的任务个数。当这个值超过了CPU数目,就会出现CPU瓶颈了。

Linux下查看CPU核心数的命令:
cat /proc/cpuinfo|grep processor|wc -l

当r值超过了CPU个数,就会出现CPU瓶颈,解决办法大体几种:

1. 最简单的就是增加CPU个数和核数
2. 通过调整任务执行时间,如大任务放到系统不繁忙的情况下进行执行,进尔平衡系统任务
3. 调整已有任务的优先级

通过vmstat识别CPU满负荷:

首先需要声明一点的是,vmstat中CPU的度量是百分比的。当us+sy的值接近100的时候,表示CPU正在接近满负荷工作。但要注意的是,CPU 满负荷工作并不能说明什么,Linux总是试图要CPU尽可能的繁忙,使得任务的吞吐量最大化。唯一能够确定CPU瓶颈的还是r(运行队列)的值。

通过vmstat识别RAM瓶颈:

数据库服务器都只有有限的RAM,出现内存争用现象是Oracle的常见问题。

首先用free查看RAM的数量:
[oracle@oracle-db02 ~]$ free
total used free shared buffers cached
Mem: 2074924 2071112 3812 0 40616 1598656
-/+ buffers/cache: 431840 1643084
Swap: 3068404 195804 2872600

当内存的需求大于RAM的数量,服务器启动了虚拟内存机制,通过虚拟内存,可以将RAM段移到SWAP DISK的特殊磁盘段上,这样会 出现虚拟内存的页导出和页导入现象,页导出并不能说明RAM瓶颈,虚拟内存系统经常会对内存段进行页导出,但页导入操作就表明了服务器需要更多的内存了, 页导入需要从SWAP DISK上将内存段复制回RAM,导致服务器速度变慢。

解决的办法有几种:

1. 最简单的,加大RAM;
2. 改小SGA,使得对RAM需求减少;
3. 减少RAM的需求。(如:减少PGA)

PS:tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具。tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具。

tcpdump提供了源代码,公开了接口,因此具备很强的可扩展性,对于网络维护和入侵者都是非常有用的工具。tcpdump存在于基本的Linux系统中,由于它需要将网络界面设置为混杂模式,普通用户不能正常执行,但具备root权限的用户可以直接执行它来获取网络上的信息。因此系统中存在网络分析工具主要不是对本机安全的威胁,而是对网络上的其他计算机的安全存在威胁。

一、概述
顾名思义,tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。

# tcpdump -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
11:53:21.444591 IP (tos 0x10, ttl 64, id 19324, offset 0, flags [DF], proto 6, length: 92) asptest.localdomain.ssh > 192.168.228.244.1858: P 3962132600:3962132652(52) ack 2726525936 win 1266
asptest.localdomain.1077 > 192.168.228.153.domain: [bad udp cksum 166e!] 325+ PTR? 244.228.168.192.in-addr.arpa. (46)
11:53:21.446929 IP (tos 0x0, ttl 64, id 42911, offset 0, flags [DF], proto 17, length: 151) 192.168.228.153.domain > asptest.localdomain.1077: 325 NXDomain q: PTR? 244.228.168.192.in-addr.arpa. 0/1/0 ns: 168.192.in-addr.arpa. (123)
11:53:21.447408 IP (tos 0x10, ttl 64, id 19328, offset 0, flags [DF], proto 6, length: 172) asptest.localdomain.ssh > 192.168.228.244.1858: P 168:300(132) ack 1 win 1266
347 packets captured
1474 packets received by filter
745 packets dropped by kernel

不带参数的tcpdump会收集网络中所有的信息包头,数据量巨大,必须过滤。

二、选项介绍

-A 以ASCII格式打印出所有分组,并将链路层的头最小化。

-c 在收到指定的数量的分组后,tcpdump就会停止。

-C 在将一个原始分组写入文件之前,检查文件当前的大小是否超过了参数file_size 中指定的大小。如果超过了指定大小,则关闭当前文件,然后在打开一个新的文件。参数 file_size 的单位是兆字节(是1,000,000字节,而不是1,048,576字节)。

-d 将匹配信息包的代码以人们能够理解的汇编格式给出。

-dd 将匹配信息包的代码以c语言程序段的格式给出。

-ddd 将匹配信息包的代码以十进制的形式给出。

-D 打印出系统中所有可以用tcpdump截包的网络接口。

-e 在输出行打印出数据链路层的头部信息。

-E 用spi@ipaddr algo:secret解密那些以addr作为地址,并且包含了安全参数索引值spi的IPsec ESP分组。

-f 将外部的Internet地址以数字的形式打印出来。

-F 从指定的文件中读取表达式,忽略命令行中给出的表达式。

-i 指定监听的网络接口。

-l 使标准输出变为缓冲行形式,可以把数据导出到文件。

-L 列出网络接口的已知数据链路。

-m 从文件module中导入SMI MIB模块定义。该参数可以被使用多次,以导入多个MIB模块。

-M 如果tcp报文中存在TCP-MD5选项,则需要用secret作为共享的验证码用于验证TCP-MD5选选项摘要(详情可参考RFC 2385)。

-b 在数据-链路层上选择协议,包括ip、arp、rarp、ipx都是这一层的。

-n 不把网络地址转换成名字。

-nn 不进行端口名称的转换。

-N 不输出主机名中的域名部分。例如,‘nic.ddn.mil‘只输出’nic‘。

-t 在输出的每一行不打印时间戳。

-O 不运行分组分组匹配(packet-matching)代码优化程序。

-P 不将网络接口设置成混杂模式。

-q 快速输出。只输出较少的协议信息。

-r 从指定的文件中读取包(这些包一般通过-w选项产生)。

-S 将tcp的序列号以绝对值形式输出,而不是相对值。

-s 从每个分组中读取最开始的snaplen个字节,而不是默认的68个字节。

-T 将监听到的包直接解释为指定的类型的报文,常见的类型有rpc远程过程调用)和snmp(简单网络管理协议;)。

-t 不在每一行中输出时间戳。

-tt 在每一行中输出非格式化的时间戳。

-ttt 输出本行和前面一行之间的时间差。

-tttt 在每一行中输出由date处理的默认格式的时间戳。

-u 输出未解码的NFS句柄。

-v 输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息。

-vv 输出详细的报文信息。

-w 直接将分组写入文件中,而不是不分析并打印出来。

三、tcpdump的表达式介绍

表达式是一个正则表达式,tcpdump利用它作为过滤报文的条件,如果一个报文满足表 达式的条件,则这个报文将会被捕获。如果没有给出任何条件,则网络上所有的信息包 将会被截获。

在表达式中一般如下几种类型的关键字:

第一种是关于类型的关键字,主要包括host,net,port,例如 host 210.27.48.2, 指明 210.27.48.2是一台主机,net 202.0.0.0指明202.0.0.0是一个网络地址,port 23 指明端口号是23。如果没有指定类型,缺省的类型是host。

第二种是确定传输方向的关键字,主要包括src,dst,dst or src,dst and src, 这些关键字指明了传输的方向。举例说明,src 210.27.48.2 ,指明ip包中源地址是 210.27.48.2 , dst net 202.0.0.0 指明目的网络地址是202.0.0.0。如果没有指明 方向关键字,则缺省是src or dst关键字。

第三种是协议的关键字,主要包括fddi,ip,arp,rarp,tcp,udp等类型。Fddi指明是在FDDI (分布式光纤数据接口网络)上的特定的网络协议,实际上它是”ether”的别名,fddi和ether 具有类似的源地址和目的地址,所以可以将fddi协议包当作ether的包进行处理和分析。 其他的几个关键字就是指明了监听的包的协议内容。如果没有指定任何协议,则tcpdump 将会 监听所有协议的信息包。

除了这三种类型的关键字之外,其他重要的关键字如下:gateway, broadcast,less, greater, 还有三种逻辑运算,取非运算是 ‘not ‘ ‘! ‘, 与运算是’and’,’&&’;或运算是’or’ ,’||’; 这些关键字可以组合起来构成强大的组合条件来满足人们的需要。

四、输出结果介绍

下面我们介绍几种典型的tcpdump命令的输出信息

(1) 数据链路层头信息
使用命令:
#tcpdump –e host ICE
ICE 是一台装有linux的主机。它的MAC地址是0:90:27:58:AF:1A H219是一台装有Solaris的SUN工作站。它的MAC地址是8:0:20:79:5B:46; 上一条命令的输出结果如下所示:

21:50:12.847509 eth0 ICE. telne t 0:0(0) ack 22535 win 8760 (DF)

21:50:12是显示的时间, 847509是ID号,eth0 表示从网络接口设备发送分组, 8:0:20:79:5b:46是主机H219的MAC地址, 它表明是从源地址H219发来的分组. 0:90:27:58:af:1a是主机ICE的MAC地址, 表示该分组的目的地址是ICE。 ip 是表明该分组是IP分组,60 是分组的长度, h219.33357 > ICE. telnet 表明该分组是从主机H219的33357端口发往主机ICE的 TELNET(23)端口。 ack 22535 表明对序列号是222535的包进行响应。 win 8760表明发 送窗口的大小是8760。

(2) ARP包的tcpdump输出信息

使用命令:
#tcpdump arp

得到的输出结果是:

22:32:42.802509 eth0 > arp who-has route tell ICE (0:90:27:58:af:1a)
22:32:42.802902 eth0 表明从主机发出该分组,arp表明是ARP请求包, who-has route tell ICE表明是主机ICE请求主机route的MAC地址。 0:90:27:58:af:1a是主机 ICE的MAC地址。

(3) TCP包的输出信息

用tcpdump捕获的TCP包的一般输出信息是:

src > dst: flags data-seqno ack window urgent options

src > dst:表明从源地址到目的地址, flags是TCP报文中的标志信息,S 是SYN标志, F (FIN), P (PUSH) , R (RST) “.” (没有标记); data-seqno是报文中的数据 的顺序号, ack是下次期望的顺序号, window是接收缓存的窗口大小, urgent表明 报文中是否有紧急指针。 Options是选项。

(4) UDP包的输出信息

用tcpdump捕获的UDP包的一般输出信息是:

route.port1 > ICE.port2: udp lenth

UDP十分简单,上面的输出行表明从主机route的port1端口发出的一个UDP报文 到主机ICE的port2端口,类型是UDP, 包的长度是lenth。

五、举例

(1) 想要截获所有210.27.48.1 的主机收到的和发出的所有的分组:
#tcpdump host 210.27.48.1

(2) 想要截获主机210.27.48.1 和主机210.27.48.2或210.27.48.3的通信,使用命令(注意:括号前的反斜杠是必须的):
#tcpdump host 210.27.48.1 and (210.27.48.2 or 210.27.48.3 )

(3) 如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2

(4) 如果想要获取主机192.168.228.246接收或发出的ssh包,并且不转换主机名使用如下命令:
#tcpdump -nn -n src host 192.168.228.246 and port 22 and tcp

(5) 获取主机192.168.228.246接收或发出的ssh包,并把mac地址也一同显示:
# tcpdump -e src host 192.168.228.246 and port 22 and tcp -n -nn

(6) 过滤的是源主机为192.168.0.1与目的网络为192.168.0.0的报头:
tcpdump src host 192.168.0.1 and dst net 192.168.0.0/24

(7) 过滤源主机物理地址为XXX的报头:
tcpdump ether src 00:50:04:BA:9B and dst……
(为什么ether src后面没有host或者net?物理地址当然不可能有网络喽)。

(8) 过滤源主机192.168.0.1和目的端口不是telnet的报头,并导入到tes.t.txt文件中:
Tcpdump src host 192.168.0.1 and dst port not telnet -l > test.txt

ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型。

例题:如何使用tcpdump监听来自eth0适配卡且通信协议为port 22,目标来源为192.168.1.100的数据包资料?

答:tcpdump -i eth0 -nn port 22 and src host 192.168.1.100

例题:如何使用tcpdump抓取访问eth0适配卡且访问端口为tcp 9080?

答:tcpdump -i eth0 dst 172.168.70.35 and tcp port 9080

例题:如何使用tcpdump抓取与主机192.168.43.23或着与主机192.168.43.24通信报文,并且显示在控制台上

tcpdump -X -s 1024 -i eth0 host (192.168.43.23 or 192.168.43.24) and host 172.16.70.35

Linux系统出现了性能问题,一般我们可以通过top、iostat、free、vmstat等命令来查看初步定位问题。其中iostat可以提供更丰富的IO性能状态数据。

1. 基本使用
$iostat -d -k 1 10
参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;1 10表示,数据显示每隔1秒刷新一次,共显示10次。

$iostat -d -k 1 10
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 39.29 21.14 1.44 441339807 29990031
sda1 0.00 0.00 0.00 1623 523
sda2 1.32 1.43 4.54 29834273 94827104
sda3 6.30 0.85 24.95 17816289 520725244
sda5 0.85 0.46 3.40 9543503 70970116
sda6 0.00 0.00 0.00 550 236
sda7 0.00 0.00 0.00 406 0
sda8 0.00 0.00 0.00 406 0
sda9 0.00 0.00 0.00 406 0
sda10 60.68 18.35 71.43 383002263 1490928140

Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 327.55 5159.18 102.04 5056 100
sda1 0.00 0.00 0.00 0 0

tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。

kB_read/s:每秒从设备(drive expressed)读取的数据量;kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;kB_read:读取的总数据量;kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes。

上面的例子中,我们可以看到磁盘sda以及它的各个分区的统计数据,当时统计的磁盘总TPS是39.29,下面是各个分区的TPS。(因为是瞬间值,所以总TPS并不严格等于各个分区TPS的总和)

2. -x 参数

使用-x参数我们可以获得更多统计信息。

iostat -d -x -k 1 10
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 1.56 28.31 7.80 31.49 42.51 2.92 21.26 1.46 1.16 0.03 0.79 2.62 10.28
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 2.00 20.00 381.00 7.00 12320.00 216.00 6160.00 108.00 32.31 1.75 4.50 2.17 84.20

rrqm/s:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge);wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。

rsec/s:每秒读取的扇区数;wsec/:每秒写入的扇区数。r/s:The number of read requests that were issued to the device per second;w/s:The number of write requests that were issued to the device per second;

await:每一个IO请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。

%util:在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。

3. -c 参数

iostat还可以用来获取cpu部分状态值:

iostat -c 1 10
avg-cpu: %user %nice %sys %iowait %idle
1.98 0.00 0.35 11.45 86.22
avg-cpu: %user %nice %sys %iowait %idle
1.62 0.00 0.25 34.46 63.67

4. 常见用法

$iostat -d -k 1 10 #查看TPS和吞吐量信息
iostat -d -x -k 1 10 #查看设备使用率(%util)、响应时间(await)
iostat -c 1 10 #查看cpu状态

5. 实例分析

$iostat -d -k 1 |grep sda10
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda10 60.72 18.95 71.53 395637647 1493241908
sda10 299.02 4266.67 129.41 4352 132
sda10 483.84 4589.90 4117.17 4544 4076
sda10 218.00 3360.00 100.00 3360 100
sda10 546.00 8784.00 124.00 8784 124
sda10 827.00 13232.00 136.00 13232 136

上面看到,磁盘每秒传输次数平均约400;每秒磁盘读取约5MB,写入约1MB。

iostat -d -x -k 1
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 1.56 28.31 7.84 31.50 43.65 3.16 21.82 1.58 1.19 0.03 0.80 2.61 10.29
sda 1.98 24.75 419.80 6.93 13465.35 253.47 6732.67 126.73 32.15 2.00 4.70 2.00 85.25
sda 3.06 41.84 444.90 54.08 14204.08 2048.98 7102.04 1024.49 32.57 2.10 4.21 1.85 92.24

可以看到磁盘的平均响应时间80。磁盘响应正常,但是已经很繁忙了。

延伸:

rrqm/s: 每秒进行 merge 的读操作数目.即 delta(rmerge)/s
wrqm/s: 每秒进行 merge 的写操作数目.即 delta(wmerge)/s
r/s: 每秒完成的读 I/O 设备次数.即 delta(rio)/s
w/s: 每秒完成的写 I/O 设备次数.即 delta(wio)/s
rsec/s: 每秒读扇区数.即 delta(rsect)/s
wsec/s: 每秒写扇区数.即 delta(wsect)/s
rkB/s: 每秒读K字节数.是 rsect/s 的一半,因为每扇区大小为512字节.(需要计算)
wkB/s: 每秒写K字节数.是 wsect/s 的一半.(需要计算)
avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区).delta(rsect+wsect)/delta(rio+wio)
avgqu-sz: 平均I/O队列长度.即 delta(aveq)/s/1000 (因为aveq的单位为毫秒).
await: 平均每次设备I/O操作的等待时间 (毫秒).即 delta(ruse+wuse)/delta(rio+wio)
svctm: 平均每次设备I/O操作的服务时间 (毫秒).即 delta(use)/delta(rio+wio)
%util: 一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的.即 delta(use)/s/1000 (因为use的单位为毫秒)

如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘
可能存在瓶颈.
idle小于70% IO压力就较大了,一般读取速度有较多的wait.
同时可以结合vmstat 查看查看b参数(等待资源的进程数)和wa参数(IO等待所占用的CPU时间的百分比,高过30%时IO压力高)
另外 await 的参数也要多和 svctm 来参考.差的过高就一定有 IO 的问题.
avgqu-sz 也是个做 IO 调优时需要注意的地方,这个就是直接每次操作的数据的大小,如果次数多,但数据拿的小的话,其实 IO 也会很小.如果数据拿的大,才IO 的数据会高.也可以通过 avgqu-sz × ( r/s or w/s ) = rsec/s or wsec/s.也就是讲,读定速度是这个来决定的.

另外还可以参考
svctm 一般要小于 await (因为同时等待的请求的等待时间被重复计算了),svctm 的大小一般和磁盘性能有关,CPU/内存的负荷也会对其有影响,请求过多也会间接导致 svctm 的增加.await 的大小一般取决于服务时间(svctm) 以及 I/O 队列的长度和 I/O 请求的发出模式.如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明 I/O 队列太长,应用得到的响应时间变慢,如果响应时间超过了用户可以容许的范围,这时可以考虑更换更快的磁盘,调整内核 elevator 算法,优化应用,或者升级 CPU.
队列长度(avgqu-sz)也可作为衡量系统 I/O 负荷的指标,但由于 avgqu-sz 是按照单位时间的平均值,所以不能反映瞬间的 I/O 洪水.

别人一个不错的例子.(I/O 系统 vs. 超市排队)

举一个例子,我们在超市排队 checkout 时,怎么决定该去哪个交款台呢? 首当是看排的队人数,5个人总比20人要快吧? 除了数人头,我们也常常看看前面人购买的东西多少,如果前面有个采购了一星期食品的大妈,那么可以考虑换个队排了.还有就是收银员的速度了,如果碰上了连 钱都点不清楚的新手,那就有的等了.另外,时机也很重要,可能 5 分钟前还人满为患的收款台,现在已是人去楼空,这时候交款可是很爽啊,当然,前提是那过去的 5 分钟里所做的事情比排队要有意义 (不过我还没发现什么事情比排队还无聊的).

I/O 系统也和超市排队有很多类似之处:

r/s+w/s 类似于交款人的总数
平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数
平均服务时间(svctm)类似于收银员的收款速度
平均等待时间(await)类似于平均每人的等待时间
平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少
I/O 操作率 (%util)类似于收款台前有人排队的时间比例.

我们可以根据这些数据分析出 I/O 请求的模式,以及 I/O 的速度和响应时间.