Archive for June, 2009
万恶的迅雷盗链
收到网站空间服务商的通知说这个月的流量已经达到3G+,超过上限2G了,而我两个博客加起来的访问量也才1000+,总不至于每次访问都能来个3M流量吧。然后查了下空间流量统计,发现之前在另外一个博客上传了一首Sentimental Kills,有人下载的时候用了迅雷,以至于这个月这个mp3一共被下了7000多次,直接把流量撑爆了,而那个博客是没有被任何搜索引擎收录的。
估计明天开始到月底,这个博客要暂时没法访问了。。。
SVN更新短信通知脚本
主要功能:开发人员执行svn commit后自动将开发人id、修订版本号和日志内容通过短信的方式通知所有人。
首先修改svn服务器对应项目目录hook/post-commit文件
#!/bin/bash
export LANG=en_US.utf8
REPOS="$1"
REV="$2"
cd /home/svn/repositories/sebank/hooks
./sms.py commit $REPOS $REV
注意别忘了这里的export LANG,我一开始测试的时候发现中文一直有乱码,后来才意识到shell的环境变量里缺这个。
hook/sms.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys, urllib, os
from subprocess import *
user = 'your mobile number'
pword = 'fetion password'
phone = [
'13764444444',
'13813333333',
]
repo = sys.argv[2]
rev = sys.argv[3]
cmdlog = 'svnlook log -r %s %s'%(rev, repo)
cmdauthor = 'svnlook author -r %s %s'%(rev, repo)
log = Popen(cmdlog, stdout=PIPE, shell=True).stdout.read().strip()
author = Popen(cmdauthor, stdout=PIPE, shell=True).stdout.read().strip()
msg = 'sebank #%s %s: %s' % (rev, author, log)
for number in phone:
url = 'http://sms.api.bz/fetion.php?username=%s&password=%s&sendto=%s&message=%s' % (user, pword, number, urllib.quote_plus(msg))
cmd = 'curl "%s"' % url
send = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
send.wait()
这里user是发送者的手机号,且该用户的飞信好友需包含其他用户,pword为飞信密码,phone为用户手机号码列表。
最后设置下这两个文件的权限,保证http/svn用户能执行即可。另外由于sms.py中飞信密码是明文保存的,注意控制它的读权限。
云计算
某门课程的Open Topic,我的话题是关于云计算的,读了一篇Above the Clouds: A Berkeley View of Cloud Computing
http://www.eecs.berkeley.edu/Pubs/TechRpts/2009/EECS-2009-28.html
这是UCB的RAD(Reliable Adaptive Distributed)实验室花了六个月时间brainstorm总结出来的paper,介绍了云计算的概念、现状及未来展望。以下内容主要来自于我上交的文档,做了一些修改,欢迎大家指正。
虽然现在对云计算这个概念的炒作大于实际研究,以至于很多人听到云计算这个名词就想到忽悠,但这里面还是很多东西需要好好考虑和设计的。云计 算和以前的cluster computing等概念虽有相同之处,区别也有不少,它涉及了经济学、虚拟化技术、安全等诸多领域的内容。
何谓云计算?
云计算包含两方面内容,一是通过Internet提供的作为服务的应用程序,这些服务以前也被称为SaaS(Software as a Service);二是提供这些服务的在数据中心的硬件和系统软件,这部分也就是我们通常所称呼为“云”的东西。
云计算平台的优势
云计算带来了三个新颖的观点:
1. 提供了看起来没有上限的可用计算资源,用户不需要提前考虑设备的需求量;
2. 免去了云计算用户的前期投入,使得公司可以从一个规模较小的硬件资源起家,并根据自己的需要增加资源;
3. 细粒度的计费手段,例如按每小时使用处理器数或者每天使用的存储空间计算,并在暂时不需要机器和存储空间时即时减免费用。
关于云计算资源拥有很好的弹性,以Amazon EC2为例,用户可以在几分钟内完成硬件资源的增加或者减少操作,而这在传统的应用程序部署中是很难做到的。文中提到了Facebook上的一个应用Animoto,这个应用的资源需求在三天内从50台服务器上升到了3500台服务器,这在传统的部署中很难估计并完成。另外还有一个问题,当资源需求下降时,传统方式部署的服务器资源就被闲置了,而通过云计算部署的资源甚至可以在晚上访问量下降时减少占用的硬件资源从而减少支出费用。
平台分类
现在的云计算平台提供了不同粒度的API。Amazon EC2是一个底层的极端,它提供了类似物理硬件的接口,用户可以几乎控制从内核开始的整个软件栈。通过虚拟技术提供的CPU、块设备、IP级别的连通技术使得开发人员几乎可以做任何事情。高度的灵活性带来的是可控性的损失,在自动伸缩性(automatic scalability)和容错转移(failover)方面,服务商就力不从心了。而Google AppEngine则提供了比较高层的API,主要面向传统的web应用,在牺牲灵活性之后能很好的实现自动伸缩和转移,并对用户完全透明。而微软的Azure则介于这两者之间,提供了CLR接口,用户可以通过.Net的一系列语言和类库实现自己的应用程序。
不同的平台有不同的适用范围,不可能有一方压倒性的胜过另一方,这个问题就像Ruby和C语言孰优孰劣一样。
当前问题及解决方案
1. 服务的有效性
即如何保证服务总是可以访问
文中提出的方法是不同的公司能提供独立的软件栈,以保证某一个服务无法使用后能及时切换到另一个。但这个实现似乎会有不少阻力,至少现在的云计算服务平台各自的API都还大相径庭,要在不同的平台间转移应用不怎么可行。
至于DDoS攻击,云计算的弹性可以很好的化解这个问题。文章算了一笔账,从黑市租借50万个攻击机器人攻击一个EC2的实例会使得受害者遭受额外的每小时460美刀的支出,但由于租借这些机器人需要1.5万美刀的资金,要使得受害者的损失大于攻击者的支出,这样的攻击需要持续32小时,对于攻击者来说很不可取。
2. 数据被锁定
数据被锁在服务提供商的数据平台中,客户无法很简单的把数据从一个站点转移到另一个。这也是Stallman反对云计算的一个重要原因,客户可能因为数据锁在云计算平台中而不得不接收服务提供商的价格提升等要求。
文中提到的一个解决方案就是统一平台的API,使得数据能在不同的服务提供商之间转移。我觉得这个方案也不现实,就像有了GAppEngine后,应该不会有另一家服务商提供类似的Python或者Java的API支持了吧?
不过也许可以有一个第三方的库把不同的服务商的API再做一层抽象,让应用程序来使用这些平台无关的API,就像是OpenCL/Streamware之于GPU。
3. 数据机密性
这个问题我想不算难点,可信计算已经是研究的热门之一了,而用户自己也可以将机密数据加密后再保存到云中。而虚拟机监控器层也能提供相应的保障,例如CHAOS和VMware的OverShadow可以保护在不可信的操作系统中应用程序运行的安全性,这样即使攻击者能利用操作系统层的漏洞,也无法对操作系统上面的受保护的应用程序进行攻击。
4. 数据传输瓶颈
用户的数据要传输到云里面,消耗的时间和带宽都很高,怎么办呢?
一个简单和实用的方案就是直接通过快递公司邮递硬盘,几TB的数据不到一天就能传到数据中心了。
另一个手段是尽可能地把数据保留在云中。我觉得广义的来说这也是一种locality的优化吧,但是这样就又要考虑到前面提到的数据锁定的问题了。
此外,降低网络传输的费用也是一个研究方向,据估计三分之二的网络带宽费用都是用在高端的路由器上,而另外的三分之一才是用在传输介质中。如何减少路由器的耗费是一个需要深入研究的问题,另外如何更有效的设计云里面的网络的拓扑结构也值得探讨。
5. 性能的不稳定
我觉得相对其他问题,这个问题应该算是很难解决的了。由于客户使用的虚拟机往往和其他虚拟机共享了云中的硬件资源,在共用I/O设备的时候表现性能会有较大的起伏。
提高性能稳定性的最直接的途径自然是提高体系结构和操作系统虚拟中断及I/O通道时的效率了。另外文中还考虑了使用闪存来降低I/O干扰的可能,不过我认为闪存随机写的性能很差,代替硬盘后的性能未必会好,尤其在多个虚拟机同时访问的情况下,稳定性就很难说了。
另外,在调度虚拟机的时候,还要采用Gang Schedule,即对于一些必须几个线程同时运行的程序,要保证这些虚拟机能被同时调度运行。
6. 文章还提到了另外5个障碍,包括存储设备的可伸缩性,如何快速伸缩、大规模分布式系统中的bug问题,这可以通过开发相应的可伸缩存储系统、算法以及分布式调试器解决。另外还有声誉共享(一个客户的恶意行为被其他网站记录,可能影响到同一台物理机上的另一个无辜的客户),软件协议等问题。这些应该都不是难点,而软件协议方面,微软也已经推出Windows Server和Windows SQL Server的到期支付(pay as you go)的协议。
Company-mode: Emacs自动补全
Company的全写是complete everything,它只是一个补全的前端,会自动调用semantic等后端插件。
新版的Company可以从它的官方主页(http://nschum.de/src/emacs/company-mode/)下载到,也可以从ELPA下载安装这个插件。
使用这个插件时只要在.emacs中加入
(add-to-list 'load-path "/path/to/company")
(autoload 'company-mode "company" nil t)
然后Emacs中使用M-x company-mode启动company模式即可。
具体的按键可以在company.el中看到
(defvar company-active-map
(let ((keymap (make-sparse-keymap)))
(define-key keymap "\e\e\e" 'company-abort)
(define-key keymap "\C-g" 'company-abort)
(define-key keymap (kbd "M-n") 'company-select-next)
(define-key keymap (kbd "M-p") 'company-select-previous)
(define-key keymap (kbd "") 'company-select-next)
(define-key keymap (kbd "") 'company-select-previous)
(define-key keymap [down-mouse-1] 'ignore)
(define-key keymap [down-mouse-3] 'ignore)
(define-key keymap [mouse-1] 'company-complete-mouse)
(define-key keymap [mouse-3] 'company-select-mouse)
(define-key keymap [up-mouse-1] 'ignore)
(define-key keymap [up-mouse-3] 'ignore)
(define-key keymap "\C-m" 'company-complete-selection)
(define-key keymap "\t" 'company-complete-common)
(define-key keymap (kbd "") 'company-show-doc-buffer)
(define-key keymap "\C-w" 'company-show-location)
(define-key keymap "\C-s" 'company-search-candidates)
(define-key keymap "\C-\M-s" 'company-filter-candidates)
(dotimes (i 10)
(define-key keymap (vector (+ (aref (kbd "M-0") 0) i))
`(lambda () (interactive) (company-complete-number ,i))))
keymap)
"Keymap that is enabled during an active completion.")
这里默认的补全按键是Tab,由于已经把它绑定到了yasnippet,我用了Shift-Tab替代(Ctrl-Tab似乎在terminal下没法用,不知道哪位能解决这个问题)
(define-key company-mode-map "\t" nil)
(define-key company-mode-map [(backtab)] 'company-complete-common)
如果按了Shift-Tab没有任何反应,请确认你的后端插件已经配置正确,可以参考这篇博文。
另外这里还有个视频,不喜欢看文字的话看一下这个就知道company怎么用了。http://nschum.de/src/emacs/company-mode/screencast/
两个和函数构造相关的趣味面试题
http://stackoverflow.com/questions/731832/interview-question-ffn-n
http://stackoverflow.com/questions/732485/interview-question-ffx-1-x
问题描述很简单,第一个问题是实现一个函数f,参数为一个带符号的32位整型,使得f(f(x)) = -x,即调用两次后返回的结果为原来的相反数;另一个问题也是实现一个函数g,参数为一个32位浮点,最后使得g(g(x)) = 1/x。如果不能满足所有的情况,就满足尽可能多的情形。
第二个问题比第一个问题简单一点,目前支持数最高的两个答案如下:
Read the rest of this entry »