Archive for the ‘未分类’ Category

One of the big topics in the BigData community is Map/Reduce. There are a lot of good blogs that explain what Map/Reduce does and how it works logically, so I won’t repeat it (look herehere and here for a few). Very few of them however explain the technical flow of things, which I at least need, to understand the performance implications. You can always throw more hardware at a map reduce job to improve the overall time. I don’t like that as a general solution and many Map/Reduce programs can be optimized quite easily, if you know what too look for. And optimizing a large map/reduce jobs can be instantly translated into ROI!

The Word Count Example

I went over some blogs and tutorials about performance of Map/Reduce. Here is one that I liked. While there are a lot of good tips out there, none, except the one mentioned, talk about the Map/Reduce program itself. Most dive right into the various hadoop options to improve distribution and utilization. While this is important, I think we should start the actual problem we try to solve, that means the Map/Reduce Job.

To make things simple I am using Amazons Elastic Map Reduce. In my setup I started a new Job Flow with multiple steps for every execution. The Job Flow consisted of one master node and two task nodes. All of them were using the Small Standard instance.

While AWS Elastic Map/Reduce has its drawbacks in terms of startup and file latency (Amazon S3 has a high volatility), it is a very easy and consistent way to execute Map/Reduce jobs without needing to setup your own hadoop cluster. And you only pay for what you need! I started out with the word count example that you see in every map reduce documentation, tutorial or Blog. The result of the job always produces files that look something like this:

the: 5967
all: 611
a: 21586

That idea is to count the occurrence of every word in a large number of text files. I processed around 30 files totaling somewhere around 200MB in size. I ran the original python version and then made a very small change to it. Without touching the configuration of hadoop I cut the execution time in half:

The Original Code:

#!/usr/bin/python
import sys
import re
def main(argv):
  line = sys.stdin.readline()
  pattern = re.compile("[a-zA-Z][a-zA-Z0-9]*")
  try:
    while line:
      for word in pattern.findall(line):
        print "LongValueSum:" + word.lower() + "\t" + "1"
      line = sys.stdin.readline()
  except "end of file":
    return None
if __name__ == "__main__":
  main(sys.argv)

The Optimized Code:

#!/usr/bin/python
import sys
import re
def main(argv):
  line = sys.stdin.readline()
  pattern = re.compile("[a-zA-Z][a-zA-Z0-9]*")
  map = dict()
  try:
    while line:
      for word in pattern.findall(line):
	map[word.lower()] = map.get(word.lower(), 0) + 1
      if ( len(map) > 10000 ):
        for item in map.iteritems():
	  print "LongValueSum:" + item[0] + "\t" + str(item[1])
	map.clear()
      line = sys.stdin.readline()
    for item in map.iteritems():
      print "LongValueSum:" + item[0] + "\t" + str(item[1])
  except "end of file":
    return None
if __name__ == "__main__":
  main(sys.argv)

Instead of “emitting” every word with value 1 to the OutputCollector, I did an internal reduce before emitting it. The result is that instead of emitted the word ‘a’ 1000 times with value 1, I emitted it 1 time with value 1000. The end result of the job is the same, but in half the time. To understand this we need to look at the execution flow of map reduce.

Execution Path and Distribution

Look at the following Flow Diagram taken from the “Hadoop Tutorial from Yahoo!” (Yahoo! Inc.) / CC BY 3.0

Map Reduce FlowMap Reduce Flow

Elastic Map Reduce first schedules a Map Task task per file (or parts of the file). It then feeds each line of the file into the map function. The map function will emit each key/value, in this case each word of the line, to the OutputCollector. Each emitted key/value will be written to an intermediate file for later reduce. The Shuffle Process will make sure that each key, in this case each word, will be sent to the same reduce task (meaning hadoop node) for aggregation. If we emit the same word multiple times it also needs to be written and sent multiple times, which results in more I/O (disk and network). The logical conclusion is that we should „pre-reduce“ this on a per task node basis and send the minimal amount of data. This is what the Combiner is for, which is really a Reducer that is run locally on the same node after the Mapping. So we should be fine, right? Not really.

Inside of Amazons Elastic Map Reduce

To get a better idea of where I spent the time, I deployed dynaTrace into Amazons Map Reduce environment. This can be done fully automated with a simple bootstrap action (I will publish the result as a Fastpack on our community at a later time).

The original python run lasted roughly 5 minutes each run (between 290 and 320 seconds), while the optimized ran around 3 minutes (160-170 seconds). I used dynaTrace to split those run times into their different components to get a feel for where we spend time. Some numbers have a rather high volatility which, as I found out, is due to Amazon S3 and to a smaller degree garbage collection. I executed it several times and the volatility did not have a big impact on the overall job execution time.

Map Reduce Job Business Transaction that details where we spend our timeMap Reduce Job Business Transaction that details where we spend our time

Click on the picture to analyze the details and you will see dramatic improvements on the mapping, combine and sort times. The Total Mapping time in this example is the overall execution time of all scheduled map tasks. The optimized code executed in less than 60% of the time. To a large degree this is due the map function itself (Map Only Time), which is actually quite surprising, after all we were not doing anything less really?

The next thing we see is that the combine time has dropped dramatically, we could say it nearly vanished! That makes sense after all we were making sure that we emitted less duplicates, thus less to combine. In fact it might make sense to stop combining at all as we will see later on. Another item that has dramatically improved is the sort. Again that makes a lot of sense, less data to sort. While the majority of the combine and sort happens in a separate thread, it still saves a lot of CPU and I/O time!

On the other hand neither shuffle nor reduce time itself have changed really. I identified the fluctuations the table does show, as being AWS S3 volatility issues via a hotspot analysis, so I ignored them. The fact that we see no significant improvements here makes sense. The resulting intermediate files of each map task do not look much different, whether we combine or use the optimized code.

So it really was the optimization of the map operation itself, that lead to overall improvement in job run time. While I might have achieved the same goal by doubling the number of map nodes, it would cost me more to do so.

What happens during mapping

To understand why that simple change has such a large impact we need to look at what happens to emitted keys in a Map Job.

flow of the data from the mapper to memory buffer, sort&combine and finally the mergeflow of the data from the mapper to memory buffer, sort&combine and finally the merge

What most Map/Reduce tutorials forget to mention is that the collect method called by the Mapper serializes the key/value directly to an in-memory buffer, as can be seen in the diagram above and the hotspot below.

When the Mapper emits a key via collect, it gets written to an in memory bufferWhen the Mapper emits a key via collect, it gets written to an in memory buffer

Once that buffer has reached a certain saturation, the Spill Thread kicks in and writes the data to an intermediate file (this is controlled by several io.sort.spill. options). Map/Reduce normally deals with a large amount of potentially never repeating data, so it has to spill to file eventually.

The Spill Thread sorts, combines and writes the data to file in parallel to the mappingThe Spill Thread sorts, combines and writes the data to file in parallel to the mapping

It is not enough to simple dump the data to file, the content has to be sorted and combined first. The sort is a preparation for the shuffle process and relative efficient (it sorts based on binary bytes, because the actual order is not important). The combine however needs to de-serialize the key and values again prior to writing.

The combine in the spill thread needs to deserialize the data againThe combine in the spill thread needs to deserialize the data again

So emitting a key multiple times has

  1. a direct negative impact on the map time and CPU usage, due to more serialization
  2. an indirect negative impact on CPU due to more spilling and additional deserialization in the combine step
  3. a direct impact on the map task, due to more intermediate files, which makes the final merge more expensive

Slower mapping obviously impacts the overall Job time directly. The more data we emit, the more CPU and I/O is consumed by the Spill Thread. If the SpillThread is too slow (e.g. expensive combine, slow disk), the in memory buffer might get fully saturated, in which case the map task has to wait (this can be improved by adjusting the io.sort.spill.percent hadoop option).

Showing that the Mapper can be slowed down by the Spill Thread if there are too many keys to sort or combineThe Mapper was paused by the Spill Thread, because there was too much data to sort and combine

Finally after the Map Task finishes the actual mapping, it writes, sorts and combines the remaining data to file. Finally it merges all intermediate files into a single output file (which it might combine again). More emitted key’s thus mean more intermediate files to merge as well.

The complete Map Task shows the mapping itself and the flush at the end, which sorts, combines, merges and combines againThe complete Map Task shows the mapping itself and the flush at the end, which sorts, combines, merges and combines again

While the final flush only “slows” us down for 1.5 seconds, this still amounts to roughly 8 percent of the Mapper task. So we see it really does make a lot of sense to optimize the output of the map operation, prior to the combine or reduce step. It will save CPU, Disk and Network I/O and this of course means less Nodes are needed for the same work!

The one million X factor

Until now I have tried to explain the I/O and CPU implications of emitting many keys, but there is also another factor that should be considered when writing Map/Reduce jobs. The map function is executed potentially millions of times. Every ms consumed here can potentially lead to minutes in job time. Indeed most of the gain of my “optimization” came from speeding up the mapping itself and not from more effective combine and disk writes. On average each map method call had a little less to do and that paid off.

What that struck me when looking at Map/Reduce first, was that most samples and tutorials use scripting languages like python, perl or something else. This is realized via the Hadoop Streaming framework. While I understand that this lowers the barrier to write Map/Reduce jobs, it should not be used for serious tasks! To illustrate this I ran a randomly selected java version of the Word Count sample. The result is another 50-60% improvement on top of the optimized python (it might be even better, in a larger task).

Several Java and Python Word Count Map Reduce Jobs, that show the vast differences in execution timesSeveral Java and Python Word Count Map Reduce Jobs, that show the vast differences in execution times

The table shows the various execution times for:

  • Optimized Java: ~1.5 minutes job execution time
    The same trick as in python, if anybody really wants to have the code, it let me know.
  • Optimized Java with no Combiner: roughly 10 seconds faster than the optimized one
    As pointed out the pre-reduce in the map method makes the combine nearly redundant. The improvement in overall job time is minimal however due to the smallness of the job.
  • Original Java: ~2.5 minutes
    We see that all the times (mapping, combining, sorting, spilling) are a lot higher, as we came to expect
  • Optimized Python: ~3 minutes
  • Non-optimized python: ~5 minutes

Java is faster than Python every time and the optimized version of Java is twice as fast as the optimized python version. Remember that this is a small example and that the hadoop parameters are the same for all runs . In addition CPU was never a limiting factor. If you execute the same small code millions of times, even small differences matter. The difference between a single line mapped in java and python is maybe not even measurable. With 200 MB of text it adds up to more than a minute! The same would be true for small changes in any java Map/Reduce job. The difference between the original and the optimized java version is still more than 60% improvement!

Word Count is very simple compared to some of the map/reduce jobs are out there, but it illustrates quite nicely that performance of our own code still matters. The key take away is that we still need to analyze and optimize the map task and our own code. Only after that is satisfactory, do we need to play around with the various hadoop options to improve distribution and utilization.

Conclusion

Map Reduce is a very powerful and elegant way to distribute processing of large amounts of data across many hosts. It is also a bit of a brute and it pays of to analyze and optimize the performance of the map and reduce tasks before we start playing with hadoop options. While Map/Reduce can reduce the job time by throwing more hardware the problem, easy optimizations often reach a similar effect. In the cloud and AWS Elastic Map Reduce that means less cost!

zz from: http://blog.dynatrace.com/2012/01/25/about-the-performance-of-map-reduce-jobs/

今天很有趣,我需要把一张mysql600多万数据、读写频繁的表拆分,趁着导测试数据的时间,总结一下我的2011.

2011年,最大的收获是亲近了佛法,完成了北京佛教研究所与北京广化寺开办的佛教初级和中级研修班的学习,并在正信、正见的道路上迈下了坚实的一步。

性格方面有了一些改变,之前我是个自认为蛮聪明、暴躁、急性子的人。而现在,走在路上,会突然警醒自己正在埋着头、飞快的迈着步子,于是刻意的放缓脚步、抬起头看看远方,发现生活中、道路上的种种美好。

在与人相处中,之前认为非黑即白,不可相容。而其实,善和恶,在一个短时间内是很难看得清楚的,强行的把我对善恶的观点加诸他人,其实不是因为我有多美好,而是我有多专制。

对于事业成功的定义,也有所变化。以金钱来衡量成功,其实很虚无。今年的高薪到了明年,可能就变成中下水平,而工作的愉悦程度、自身能力是否 稳步提高、企业文化才是略微真实和可把握的。

2011年是创业的一年。还行,公司能够保持正的资金流和一个相对稳定的发展态势。

2011年,我的技术进步可能稍慢,这一点比较遗憾。涉猎的范围比较杂乱, 部署了多台服务器,从apache转移到lighttpd,又转移到nginx;用了用NoSQL的cabinet存储,提高了性能,但是也遇到一些问题;做了mysql的主从备份,但是备份机没有发挥大的用途。做的最多的,还是业务层面的开发,年初对设计模式比较感兴趣,年末发现有些是过度设计,于是重构;遇到过性能瓶颈,从服务器、数据库和代码的角度进行了一些调优,但是也暴露出我经验不足的劣势。

2011年,家里又添了一只猫,现在有3个小家伙:噜噜、团团和咪宝。噜噜、团团仍然向肥胖不懈努力,咪宝在和病魔抗争,希望2012他可以健健康康!搬到了顺义,继续喂养小区里的流浪猫。也跟随公司在帮助几个流浪动物基地。

2011年,我的生活还不错,从空虚和追求享受,到学会从奉献和佛法中获取安定和快乐。

2012年,希望在修行的道路上能有进展,希望生活平静幸福,也希望技术方面可以有所突破。

安装

http://sourceforge.net/projects/clustershell/files/clustershell/1.5.1/ 下载源码安装。指定安装目录:

python setup.py install

新建配置文件:

mkdir /etc/clustershell

cp conf/* /etc/clustershell

新增配置文件groups:

[admin@v080049 apps]$ cat /etc/clustershell/groups
web: 192.168.80.49 192.168.80.105 192.168.80.106
db: 192.168.80.103 192.168.80.104
需要配置ssh的免密码登录。
使用

简单测试:clush -g web ‘ls’

部署代码:clush -g web “cd ~/prepare/happy_itry_v2/; echo ‘yes’ | ./taobao_push.sh “

双网卡,双IP配置,加静态路由

张映 发表于 2011-12-23

分类目录: 服务器相关

北网通,南电信的问题是很让人郁闷的一件,这也是河蟹社会的一种特色吧。为了解决这个问题,我考虑过三种方案:

1,双网卡,双IP;或者单网卡,双IP。

这种方案,成本低,但是维护挺麻烦,并且速度比后面二个要慢。

2,BGP双线机房。

BGP的费用要比第一种方案要高,但是全国真正是BGP机房的到底有多少,应当就那么几家。其他假的比较多。用这种方案就不用在搞双IP了,一个IP就OK。

3,CDN加速

CDN的价格是最高,买的是dell r410的服务器,拖管在机房,带宽160元/m/月,还是熟人才拿到这价格。我和chinacache的客户经理当面谈过,刚开始的价格是400元/m/月,后来我说是我朋友推荐的,直接降到200元/m/月,这价格降的真是离谱。我有一个linux运维的QQ群,在里面问chinacache的CDN多少钱一个月一M,有得说100多元/m/月,有的说900多元/m/月,卧槽,这差别太大。感觉不规范,所以没用,现在和朋友一起创业,能省就省,所以我选择了第一种方案。扯了这么多,进入正题。

一,服务器服务安排

服务器,我准备了三台dell r410的机器,

1,web服务器

2,mysql服务器

3,文件服务器

每台服务器有二个网卡,eth1走内网,eth0走外网,并且网通和电信都走eth0,这样的方式我个人觉得比一个网卡走网通,一个网卡走电信要快。在交换机上设置二个vlan一个走内网,一个走外网,交换机设置就不在这儿多说了。

二,网络配置

1,cd /etc/sysconfig/network-scripts

2,修改 ifcfg-eth1

  1. [root@localhost network-scripts]# cat ifcfg-eth1
  2. DEVICE=”eth1″
  3. NM_CONTROLLED=”yes”
  4. ONBOOT=”yes”
  5. TYPE=Ethernet
  6. BOOTPROTO=none
  7. IPADDR=192.168.1.2
  8. PREFIX=24
  9. DEFROUTE=yes
  10. IPV4_FAILURE_FATAL=yes
  11. IPV6INIT=no
  12. NAME=”System eth1″
  13. UUID=5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03
  14. HWADDR=78:2B:CB:57:28:E5

3,修改ifcfg-eth0

  1. [root@localhost network-scripts]# cat ifcfg-eth0
  2. DEVICE=”eth0″
  3. NM_CONTROLLED=”yes”
  4. ONBOOT=”yes”
  5. TYPE=Ethernet
  6. BOOTPROTO=none
  7. IPADDR=222.121.121.121
  8. PREFIX=24
  9. GATEWAY=222.121.121.1
  10. NETMASK=255.255.255.128
  11. DEFROUTE=yes
  12. IPV4_FAILURE_FATAL=yes
  13. IPV6INIT=no
  14. NAME=”System eth0″
  15. UUID=9c92fad9-6ecb-3e6c-eb4d-8a47c6f50c04
  16. HWADDR=78:2B:CB:57:28:E6

4,cp ifcfg-eth0 ifcfg-eth0:0

  1. [root@localhost network-scripts]# cat ifcfg-eth0:0
  2. DEVICE=”eth0:0″
  3. NM_CONTROLLED=”yes”
  4. ONBOOT=”yes”
  5. TYPE=Ethernet
  6. BOOTPROTO=none
  7. IPADDR=112.121.121.121
  8. PREFIX=24
  9. NETMASK=255.255.255.0
  10. DEFROUTE=yes
  11. IPV4_FAILURE_FATAL=yes
  12. IPV6INIT=no
  13. NAME=”System eth0″
  14. UUID=9c92fad9-6ecb-3e6c-eb4d-8a47c6f50c04
  15. HWADDR=78:2B:CB:57:28:E6

5,重起网络/etc/init.d/network restart

到这儿,双网卡,双IP基本上就配置好,但是网通和电信都是走的电信的网关,这样的话丢包会比较严重的。解决这个问题,有二个比较好的方法,一是加静态路由,一是加策略路由。我用的方法是加静态路由。

三,添加静态路由

route add -net 1.24.0.0 netmask 255.248.0.0 gw 60.12.105.145 dev eth0:0
route add -net 1.56.0.0 netmask 255.248.0.0 gw 60.12.105.145 dev eth0:0

上面是通过命令来加的,如果是双网卡的要加上dev的。因为静态路由有很多条,所以还是一起加比较好。

1,vim route.sh

2,把route add全部加到 route.sh里面

3,chmod +x route.sh

4,开机启动echo “sh /路径/route.sh” >> /etc/rc.local

下载网通路由,下载下来后,根据实际情况后修改

zz from:http://blog.51yip.com/server/1358.html

我们的念头总是很多,以刚才的我为例。刚写完一个功能,于是起来走走。第一个念头是,燃一炷香。这个念头刚起,又想给妈妈打电话,继而又想起家里煤气有问题要给燃气公司打电话。一瞬间里,这3个只是粗的念头,微细念头更不知有多少!

如果随顺了自己的习气,那可能我刚才做的不是去燃一炷香,而是先打了某个电话。那第一个念头可能就被忘记了。这样的次数一多,就会觉得烦躁,因为做事的顺序不是依次而行的,而是东一下、西一下,毫无章法。

而如果能够专注的做事,察觉每个念头的升起,觉知这个念头是否与佛法相契合,若契合那么便全神贯注地做完,然后等待下一个念头的升起。我相信,这种生活会是精进和愉悦的。

设置-通用-网络-蜂窝数据网络-彩信
apn: cmwap    mmsc: http://mmsc.monternet.com   mms代理服務器: 10.0.0.172    mms最大信息大小:50000
配置成功后,“信息”左下角的照相机图片可点。相册的转发中包含“信息”选项。

首先,需要确保中奖人数不可以超出产品总量,这个可以通过db操作完成:

用户抽奖前,预先计算抽奖结果:

  1. 检查是否有剩余量
  2. 算法,根据概率、中奖人数、抽奖人数,计算是否中奖
  3. 将结果存入数据库
    • 若之前已有抽奖结果,但未确认,则使用之前的抽奖结果
    • 若之前无抽奖结果,则使用该次抽奖结果
      • 若为中奖,则减少剩余量
        • 若失败,则修改抽奖结果,视为未中奖
      • 将抽奖结果存入cache table

用户抽奖时,需要点击确认按钮,才会完成整个抽奖流程,否则一定时间之后,定时任务会将剩余量恢复回去。

抽奖算法:

算法1:特点是,中奖概率随时间推移而增大。

  1. 预先设定一个百分比和结束时间,随机或者设置一个int or long类型的期望区间值expect(比如13)
  2. 抽奖时set prob = pow(curTime/endTime, 2) * prob ,根据时间动态计算一个正态分布的当前概率prob,并且获取到一个区间[0, (int)1/prob)
  3. 获取一个落在该区间的随机值
  4. 根据expect,计算落在该区间的期待值,若与随机值相等,则中奖

算法2:特点是,固定某个时间区间的第N个抽奖用户中奖(适用于,希望持续多久)

  1. 预先设定开始、结束时间,以及时间区间(x秒),N的值
  2. 抽奖时,根据当前时间、开始时间,计算当前时间区间的起始时间,并获取从该起始时间到当前,有多少人抽奖
  3. 若自己为第N个人,则中奖(依赖之前的db操作,可以保障没有多个人同时中奖)

算法3:特点是,实际中奖概率绝对不大于设定概率(适用于,希望多少人抽奖)

  1. 若当前中奖人数/抽奖人数>=中奖率,则该用户不中奖(抽奖人数已含当前用户)
  2. 否则,依中奖率随机出一个lcg_value,若小于中奖率,则中奖
  3. 若不中奖,则根据其他项目(比如积分等),随机出一个结果

当利用负载均衡时,一台负责均衡server后面会挂载多台web server,为了测试某一台服务器时,就可以利用ssh的端口转发功能。

比如,在一台web server上,执行ssh -CfNg -R 19211:127.0.0.1:80 ssh-server-ip,就可以把ssh-server-ip的19211端口映射到该web server的80端口。然后将测试机的hosts配置到ssh-server-ip,就可以测试了。

ps:测试ssh转发是否成功,可以使用tcpdump,在web server上执行:/usr/sbin/tcpdump host ssh-server-ip -vv,查看是否有流量。

这样配置完了之后,最简单的方式就是在ssh-server上进行测试,因为建立的连接,监听的是本地127.0.0.1端口:

tcp        0      0 127.0.0.1:19211             0.0.0.0:*                   LISTEN      -

而对外开放的80端口是:

tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      -

这时,也可利用ssh-server作为浏览器的代理服务器,在其他机器上进行测试。

  • 3台机器:ssh-server,web-server,开发机(浏览器)
  • 根据以上的步骤,在web-server和ssh-server间建立了端口转发
  • 将开发机的hosts配置到127.0.0.1,同时利用chrome的proxy switch之类的工具,使用ssh-server作为浏览器代理
  • 在开发机访问:http://hostname:19211/path/,ok

转载1:

zz from: https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/

当你在咖啡馆享受免费 WiFi 的时候,有没有想到可能有人正在窃取你的密码及隐私信息?当你发现实验室的防火墙阻止了你的网络应用端口,是不是有苦难言?来看看 SSH 的端口转发功能能给我们带来什么好处吧!

让我们先来了解一下端口转发的概念吧。我们知道,SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。但是,SSH 还同时提供了一个非常有用的功能,这就是端口转发。它能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程有时也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。例如,Telnet,SMTP,LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,如果您工作环境中的防火墙限制了一些网络端口的使用,但是允许 SSH 的连接,那么也是能够通过将 TCP 端口转发来使用 SSH 进行通讯。总的来说 SSH 端口转发能够提供两大功能:

  1. 加密 SSH Client 端至 SSH Server 端之间的通讯数据。
  2. 突破防火墙的限制完成一些之前无法建立的 TCP 连接。


SSH 端口转发

如上图所示,使用了端口转发之后,TCP 端口 A 与 B 之间现在并不直接通讯,而是转发到了 SSH 客户端及服务端来通讯,从而自动实现了数据加密并同时绕过了防火墙的限制。


我们先来看第一个例子,在实验室里有一台 LDAP 服务器(LdapServerHost),但是限制了只有本机上部署的应用才能直接连接此 LDAP 服务器。如果我们由于调试或者测试的需要想临时从远程机器(LdapClientHost)直接连接到这个 LDAP 服务器 , 有什么方法能够实现呢?

答案无疑是本地端口转发了,它的命令格式是:

ssh -L <local port>:<remote host>:<remote port> <SSH hostname>

在 LdapClientHost 上执行如下命令即可建立一个 SSH 的本地端口转发,例如:

$ ssh -L 7001:localhost:389 LdapServerHost


本地端口转发

这里需要注意的是本例中我们选择了 7001 端口作为本地的监听端口,在选择端口号时要注意非管理员帐号是无权绑定 1-1023 端口的,所以一般是选用一个 1024-65535 之间的并且尚未使用的端口号即可。

然后我们可以将远程机器(LdapClientHost)上的应用直接配置到本机的 7001 端口上(而不是 LDAP 服务器的 389 端口上)。之后的数据流将会是下面这个样子:

  • 我们在 LdapClientHost 上的应用将数据发送到本机的 7001 端口上,
  • 而本机的 SSH Client 会将 7001 端口收到的数据加密并转发到 LdapServertHost 的 SSH Server 上。
  • SSH Server 会解密收到的数据并将之转发到监听的 LDAP 389 端口上,
  • 最后再将从 LDAP 返回的数据原路返回以完成整个流程。

我们可以看到,这整个流程应用并没有直接连接 LDAP 服务器,而是连接到了本地的一个监听端口,但是 SSH 端口转发完成了剩下的所有事情,加密,转发,解密,通讯。

这里有几个地方需要注意:

  1. SSH 端口转发是通过 SSH 连接建立起来的,我们必须保持这个 SSH 连接以使端口转发保持生效。一旦关闭了此连接,相应的端口转发也会随之关闭。
  2. 我们只能在建立 SSH 连接的同时创建端口转发,而不能给一个已经存在的 SSH 连接增加端口转发。
  3. 你可能会疑惑上面命令中的 <remote host> 为什么用 localhost,它指向的是哪台机器呢?在本例中,它指向 LdapServertHost 。我们为什么用 localhost 而不是 IP 地址或者主机名呢?其实这个取决于我们之前是如何限制 LDAP 只有本机才能访问。如果只允许 lookback 接口访问的话,那么自然就只有 localhost 或者 IP 为 127.0.0.1 才能访问了,而不能用真实 IP 或者主机名。
  4. 命令中的 <remote host> 和 <SSH hostname> 必须是同一台机器么?其实是不一定的,它们可以是两台不同的机器。我们在后面的例子里会详细阐述这点。
  5. 好了,我们已经在 LdapClientHost 建立了端口转发,那么这个端口转发可以被其他机器使用么?比如能否新增加一台 LdapClientHost2 来直接连接 LdapClientHost 的 7001 端口?答案是不行的,在主流 SSH 实现中,本地端口转发绑定的是 lookback 接口,这意味着只有 localhost 或者 127.0.0.1 才能使用本机的端口转发 , 其他机器发起的连接只会得到“ connection refused. ”。好在 SSH 同时提供了 GatewayPorts 关键字,我们可以通过指定它与其他机器共享这个本地端口转发。
    ssh -g -L <local port>:<remote host>:<remote port> <SSH hostname>

我们来看第二个例子,这次假设由于网络或防火墙的原因我们不能用 SSH 直接从 LdapClientHost 连接到 LDAP 服务器(LdapServertHost),但是反向连接却是被允许的。那此时我们的选择自然就是远程端口转发了。

它的命令格式是:

ssh -R <local port>:<remote host>:<remote port> <SSH hostname>

例如在 LDAP 服务器(LdapServertHost)端执行如下命令:

$ ssh -R 7001:localhost:389 LdapClientHost


远程端口转发

和本地端口转发相比,这次的图里,SSH Server 和 SSH Client 的位置对调了一下,但是数据流依然是一样的。我们在 LdapClientHost 上的应用将数据发送到本机的 7001 端口上,而本机的 SSH Server 会将 7001 端口收到的数据加密并转发到 LdapServertHost 的 SSH Client 上。 SSH Client 会解密收到的数据并将之转发到监听的 LDAP 389 端口上,最后再将从 LDAP 返回的数据原路返回以完成整个流程。

看到这里,你是不是会有点糊涂了么?为什么叫本地转发,而有时又叫远程转发?这两者有什么区别?

不错,SSH Server,SSH Client,LdapServertHost,LdapClientHost,本地转发,远程转发,这么多的名词的确容易让人糊涂。让我们来分析一下其中的结构吧。首先,SSH 端口转发自然需要 SSH 连接,而 SSH 连接是有方向的,从 SSH Client 到 SSH Server 。而我们的应用也是有方向的,比如需要连接 LDAP Server 时,LDAP Server 自然就是 Server 端,我们应用连接的方向也是从应用的 Client 端连接到应用的 Server 端。如果这两个连接的方向一致,那我们就说它是本地转发。而如果两个方向不一致,我们就说它是远程转发。

我们可以回忆上面的两个例子来做个对照。

本地转发时:

LdapClientHost 同时是应用的客户端,也是 SSH Client,这两个连接都从它指向 LdapServertHost(既是 LDAP 服务端,也是 SSH Server)。

远程转发时:

LdapClientHost 是应用的客户端,但却是 SSH Server ;而 LdapServertHost 是 LDAP 的服务端,但却是 SSH Client 。这样两个连接的方向刚好相反。

另一个方便记忆的方法是,Server 端的端口都是预定义的固定端口(SSH Server 的端口 22,LDAP 的端口 389),而 Client 端的端口都是动态可供我们选择的端口(如上述例子中选用的 7001 端口)。如果 Server 端的两个端口都在同一台机器,Client 端的两个端口都在另一台机器上,那么这就是本地连接;如果这四个端口交叉分布在两个机器上,每台机器各有一个 Server 端端口,一个 Client 端端口,那就是远程连接。

弄清楚了两者的区别之后,再来看看两者的相同之处。如果你所在的环境下,既允许 LdapClientHost 发起 SSH 连接到 LdapServerHost,也允许 LdapServerHost 发起 SSH 连接到 LdapClientHost 。那么这时我们选择本地转发或远程转发都是可以的,能完成一样的功能。

接着让我们来看个进阶版的端口转发。我们之前涉及到的各种连接 / 转发都只涉及到了两台机器,还记得我们在本地转发中提到的一个问题么?本地转发命令中的 <remote host> 和 <SSH hostname> 可以是不同的机器么?

ssh -L <local port>:<remote host>:<remote port> <SSH hostname>

答案是可以的!让我们来看一个涉及到四台机器 (A,B,C,D) 的例子。


多主机转发应用

在 SSH Client(C) 执行下列命令来建立 SSH 连接以及端口转发:

$ ssh -g -L 7001:<B>:389 <D>

然后在我们的应用客户端(A)上配置连接机器(C )的 7001 端口即可。注意我们在命令中指定了“ -g ”参数以保证机器(A)能够使用机器(C)建立的本地端口转发。而另一个值得注意的地方是,在上述连接中,(A)<-> (C) 以及 (B)<->(D) 之间的连接并不是安全连接,它们之间没有经过 SSH 的加密及解密。如果他们之间的网络并不是值得信赖的网络连接,我们就需要谨慎使用这种连接方式了。


恩,动态转发,听上去很酷。当你看到这里时,有没有想过我们已经讨论过了本地转发,远程转发,但是前提都是要求有一个固定的应用服务端的端口号,例如前面例子中的 LDAP 服务端的 389 端口。那如果没有这个端口号怎么办?等等,什么样的应用会没有这个端口号呢?嗯,比如说用浏览器进行 Web 浏览,比如说 MSN 等等。

当我们在一个不安全的 WiFi 环境下上网,用 SSH 动态转发来保护我们的网页浏览及 MSN 信息无疑是十分必要的。让我们先来看一下动态转发的命令格式:

$ ssh -D <local port> <SSH Server>

例如:

$ ssh -D 7001 <SSH Server>


动态端口转发

似乎很简单,我们依然选择了 7001 作为本地的端口号,其实在这里 SSH 是创建了一个 SOCKS 代理服务。来看看帮助文档中对 -D 参数的描述:

-D port
 This works by allocating a socket to listen to port on the local
 side, and whenever a connection is made to this port, the con-
 nection is forwarded over the secure channel, and the applica-
 tion protocol is then used to determine where to connect to from
 the remote machine.  Currently the SOCKS4 and SOCKS5 protocols
 are supported, and ssh will act as a SOCKS server.  Only root
 can forward privileged ports.  Dynamic port forwardings can also
 be specified in the configuration file.

之后的使用就简单了,我们可以直接使用 localhost:7001 来作为正常的 SOCKS 代理来使用,直接在浏览器或 MSN 上设置即可。在 SSH Client 端无法访问的网站现在也都可以正常浏览。而这里需要值得注意的是,此时 SSH 所包护的范围只包括从浏览器端(SSH Client 端)到 SSH Server 端的连接,并不包含从 SSH Server 端 到目标网站的连接。如果后半截连接的安全不能得到充分的保证的话,这种方式仍不是合适的解决方案。

好了,让我们来看最后一个例子 – X 协议转发。

我们日常工作当中,可能会经常会远程登录到 Linux/Unix/Solaris/HP 等机器上去做一些开发或者维护,也经常需要以 GUI 方式运行一些程序,比如要求图形化界面来安装 DB2/WebSphere 等等。这时候通常有两种选择来实现:VNC 或者 X 窗口,让我们来看看后者。

使用 X 窗口通常需要分别安装:X Client 和 X Server 。在本例中我们的 X Client 就是所访问的远程 Linux/Unix/Solaris/HP,而我们的 X Server 则是发起访问的本地机器(例如你面前正在使用的笔记本或台式机)。把 X Client 端的 X 窗口显示在 X Server 端需要先行在 X Client 端指定 X Server 的位置,命令格式如下:

export DISPLAY=<X Server IP>:<display #>.<virtual #>

例如:

export DISPLAY=myDesktop:1.0

然后直接运行 X 应用即可,X 窗口就会自动在我们的本地端打开。

一切运行正常,但是,这时候 IT 部门突然在远程 Linux/Unix/Solaris/HP 前面加了一道防火墙。非常不幸的是,X 协议并不在允许通过的列表之内。怎么办?只能使用 VNC 了么?不,其实只要使用了 SSH 端口转发即可通过,同时也对 X 通讯数据做了加密,真是一举两得。(当然,使用此方法前最好先咨询相关 IT 部门是否符合相应的安全条例,以免造成违规操作。)

建立命令也很简单,直接从本地机器(X Server 端)发起一个如下的 SSH 连接即可:

$ ssh -X <SSH Server>


X 转发

建立连接之后就可以直接运行远程的 X 应用。注意建立 X 转发之后会自动设置 DISPLAY 环境变量,通常会被设置成localhost:10.0,我们无需也不应该在连接之后再进行修改此环境变量。

一个比较常见的场景是,我们的本地机器是 Windows 操作系统,这时可以选择开源的 XMing 来作为我们的 XServer,而 SSH Client 则可以任意选择了,例如 PuTTY,Cygwin 均可以配置 访问 SSH 的同时建立 X 转发。


至此,我们已经完成了本地端口转发,远程端口转发,动态端口转发以及 X 转发的介绍。回顾起来,总的思路是通过将 TCP 连接转发到 SSH 通道上以解决数据加密以及突破防火墙的种种限制。对一些已知端口号的应用,例如 Telnet/LDAP/SMTP,我们可以使用本地端口转发或者远程端口转发来达到目的。动态端口转发则可以实现 SOCKS 代理从而加密以及突破防火墙对 Web 浏览的限制。对于 X 应用,无疑是 X 转发最为适用了。虽然每一部分我们都只是简单的介绍了一下,但如果能灵活应用这些技巧,相信对我们的日常生活 / 工作也是会有所帮助的。

转载2:

zz from: http://www.cnblogs.com/hexapodsoft/archive/2007/04/24/724826.html

记得第一次做跳板还是高中时代,是台韩国的win2k,装的是Snake的socks代理.
当时还相当紧张,传了一堆工具上去删日志,已经是上世纪末的事了,呵呵.

言归正传,
选择ssh的4个理由:

1、使用方便,功能强大,加密强度高,运行稳定.

2、ssh几乎是*nix系统的标配,不需额外安装.现在的想找台没跑sshd的*nix主机也是件难事.

3、防火墙基本不会对ssh的连接下黑手

4、跨平台,linux BSD UNIX m$ 等不同平台上的ssh都能相互连接.

ssh实现转发,只要用到以下两条命令:

ssh -CfNg -L 6300:127.0.0.1:1080 anyside@192.168.1.119
ssh -CfNg -R 1080:127.0.0.1:6300 anyside@192.168.1.119

不论是做跳板,还是加密隧道,还是加密其他的网络连接也都是这两条命令。
视具体情况而定,有时只要用到其中一条,有时两条都要用到。

条命解释:
-CfNg (照抄即可)
C表示压缩数据传输
f表示后台用户验证,这个选项很有用,没有shell的不可登陆账号也能使用.
N表示不执行脚本或命令
g表示允许远程主机连接转发端口

-L 本地转发

ssh -CfNg -L 6300:127.0.0.1:1080 anyside@192.168.1.119
表示:
1、本机(运行这条命令的主机)和远程主机192.168.1.119建立加密隧道,anyside是远程主机192.168.1.119上的账号。
2、在本机上打开6300端口.用 netstat -an|grep 6300 可看到 127.0.0.1:6300 或 127.0.0.1.6300
3、把本机的6300端口映通过加密隧道射到192.168.1.119的1080端口.

简单说,本机的6300端口就是远程主机192.168.1.119的1080端口。

-R 远程转发

ssh -CfNg -R 1080:127.0.0.1:6300 anyside@192.168.1.119
1、本机(运行这条命令的主机)和远程主机192.168.1.119建立加密隧道,anyside是远程主机192.168.1.119上的账号。
2、在远程主机192.168.1.119上打开1080端口.
3、把本机的6300端口映通过加密隧道射到192.168.1.119的1080端口.

本机的6300端口可直接看作远程主机192.168.1.119的1080端口。

举个实用的例子:
有A、B、C 3台服务器,A,C有公网IP,B是某IDC的服务器无公网IP。
A希望同过B连接C的80端口,A<=>B<=>C

在B上执行如下命令即可:
host-B$ ssh -CfNg -L 6300:127.0.0.1:80 userc@C
host-B$ ssh -CfNg -R 80:127.0.0.1:6300 usera@A

服务器A和服务器C之间,利用跳板服务器B建立了加密隧道。

在A上连接127.0.0.1:80,就等同C上的80端口

需要注意的是:
服务器B上的6300端口的数据没有加密,可被监听,
例:
#tcpdump -s 0 -i lo port 6300

我们是一家创业公司,目前在淘宝、sina、qq、yoka、人人等网站上都运营着自行研发的APP应用,用户过百万,现在正处于业务拓展期,急需web前端开发工程师一名!
职位描述:
web前端开发工程师,负责网站的前端页面开发。
要求如下:
1.熟练使用JavaScript、CSS、HTML语言,若了解前端开发框架(如mootools、jQuery)或浏览器兼容性者加分
2.了解PHP语言,若使用过Linux操作系统者加分
3.聪明、踏实、勤奋
我们能为您提供的:
1.创业的激情,我们正处于高速发展期,加入我们,您会拥有广阔的qian景
2.丰富的学习机会,我们的业务涉及淘宝、sina等各大网站,您将会了解到目前火热的web APP开发技巧
3.web开发从前端到后端(甚至OPS知识),只要您愿意学,我们都会为您实战的机会

关于clusterShell 请查阅官网 http://sourceforge.net/apps/trac/clustershell

tar zxvf clustershell-1.5.1.tar.gz

cd clustershell-1.5.1

python setup.py install

mkdir /etc/clustershell

cp conf/* /etc/clustershell

如果遇到 ImportError: No module named setuptools

需要安装setuptools这个扩展

如果不能 yum install python-setuptools(我的机器没有注册就不能yum)

就下载安装下

1. 下载 http://peak.telecommunity.com/dist/ez_setup.py

2. 运行 $ python ez_setup.py


/usr/local/python/bin/nodeset -h

zz from: http://blog.csdn.net/vaal_water/article/details/6967805