haproxy三种方法保持session一致(转)
作者:hartnett 发布于:2012-5-10 16:20 Thursday
|
1 用户IP 注意 9ai9 这个值替换成 你的php.ini 里session.name的值。 |
[招聘] 上海游戏公司高薪诚招Linux SA(6 - 15k)
作者:hartnett 发布于:2012-5-10 11:24 Thursday
职位描述:1.负责生产网络、服务器、数据库与支撑系统的建设、运维和监控,保证各业务系统正常运营;
2.负责IDC机房的基础设施运行及维护;
3.负责公司门户网站与webgame服务器的搭建、运维、监控;
4.负责对突发事件的快速响应和处理,排除故障;
5.负责对现有业务系统的架构与性能改善;
6.改进自动化运维系统,提高工程师工作效率。
职位要求:
1.计算机或相关理工科专业专科或以上学历,为人真诚正直;
2.精通Linux/Unix操作系统管理及优化;
3.熟悉LNMP、LAMP、BIND、squid、Postfix、memcached、rysnc常见应用的配置与优化;
4.熟悉Python、Bash Shell、Perl等至少一种脚本语言,要求有实际的,成熟的工具和产品开发经验;
5. 熟悉常见的开源负载均衡及高可用应用(LVS、nginx、haproxy、Keepalived、Heatbeat),有实际的实施经验者优先;
6.熟悉cacti/zabbix监控系统安装使用;
7.熟悉常用的自动化运维应用及实现方式(Cobbler,puppet,Func等);
8.有一定的数据库原理知识,熟悉mysql配置、主从搭建;
9.熟悉虚拟化应用,了解Openstack和Hadoop;
10.2年以上Linux/Unix系统运维经验,具有互联网Web应用运维、游戏运维经验者优先;
11.热爱运维技术,高度的责任心、良好的沟通技巧和团队合作精神,有上进心。
联系邮箱:netxfly[at]hotmail.com
以上条件不用全部符合,要求为人正直,有责任心,热爱运维,Linux系统管理基础好即可发简历过来试试。
公司介绍:
上海聚位网络科技发展有限公司专业从事网络游戏研发与运营,成立于2009年,目前涉足网络游戏运营及Webgame、MMORPG、Andriod、
Mac等多平台产品研发领域,同时有多款在研发项目。核心管理层均拥有一线知名游戏厂商的专业背景,经过两年的客户端网游和Webgame代理运营,在研
发——产品——市场环节上积累了丰富的数据,使公司具备了超过百万在线网游研发运营的经验、丰富的行业合作资源,同时拥有了其他中小企业或团队所没有的抗
风险能力和管理经验,通过自主平台为广大互联网用户提供多元化的互动娱乐内容和服务。
我们将以第三代网游商业模式改变游戏市场格局,以中国领先的次世代游戏视觉效果获得市场期待,以技术积累打造跨平台的引擎支持能力,针对未来5年内的互联网新型平台进行技术设计,输出商业化标准,引领中国网络游戏开发新规则。
公司具备先进完善的研发环境:强大的分析机制、严谨的项目管理系统、一流的培训和成果分享体系。我们的团队拥有游戏行业丰富的专业经验、具备高度
责任心,以制造精品文化、鼓励创新、把握市场为方针,注重技术积累,鼓励员工不断学习和超越。公司人员配比上技术人力投入占全部人力85%以上,全力确保
研发和运营技术支持能力居中国网游行业一流水平。目前公司正飞速发展,拥有各岗位、各能力层级的人才进一步提升自我、实现自我的广阔的发展空间优势。诚邀
广大业内精英共同加盟,期与致力于游戏文化产业的优秀人才共同打造精品,圆员工之梦想,携手腾飞。
我们的价值观是:责任心、学习、团结、效果第一、公平。
地址:
上海市宝山区沪太路2388号
邮编:
200436
公司网址:
http://www.play67.com
标签: 招Linux运维
使用Fabric自动化你的任务
作者:hartnett 发布于:2012-5-3 13:36 Thursday
source:http://www.cnblogs.com/holbrook/archive/2012/03/05/2380398.html
docs:http://docs.fabfile.org/en/1.4.1/index.html
fabric是什么?
Fabric是一个Python库,可以通过SSH在多个host上批量执行任务。你可以编写任务脚本,然后通过Fabric在本地就可以使用SSH在大量远程服务器上自动运行。这些功能非常适合应用的自动化部署,或者执行系统管理任务。
让我们首先看一个例子。我们知道在*NIX下面,uname命令是查看系统的发行版。可以写这样一个Fabric脚本:
from fabric.api import rundef host_type(): run('uname -s')
将上面的脚本保存为fabfile.py,就可以通过fab命令在多个主机上执行host_type脚本了:
$ fab -H localhost,linuxbox host_type
[localhost] run: uname -s
[localhost] out: Darwin
[linuxbox] run: uname -s
[linuxbox] out: Linux
执行过程中可能需要你输入系统密码。
安装
如果你看到这里了,说明你开始对Fabric感兴趣了。但是上述操作在你那里无法执行,因为你还没有安装Fabric。安装Fabric很简单,可以用pip或者easy_install,也可以下载原代码安装。
任务函数
很好,安装Fabric并没有难住你。可能你已经成功的执行了前面的任务,现在让我们更深入一些。
Fabric中的任务就是一个python函数,姑且让我们称之为“任务函数”。既然是python函数,那么对函数的一些用法也适用于任务函数。比如传递参数、互相调用、返回值等等。首先看一个传递参数的例子:
def hello(name="world"): print("Hello %s!" % name)
在执行任务的时候,可以通过fab的命令行参数为任务函数传递参数:
$ fab hello:name=Holbrook
Hello Holbrook!
组合任务的例子如下:
from fabric.api import rundef host_type(): run('uname -s')def hello(name="world"): print("Hello %s!" % name)def composite(name="world"): hello(name) host_type()
Fabric提供的命令
前面我们见过了fabric.api模块中的run函数,其功能是在远端主机上执行命令。fabric.api中还提供了local函数,用于执行本地(Fabric所在的主机)命令。如下:
from fabric.api import localdef lslocal(): local('ls')
类似远端命令和本地命令,Fabric也区分远端目录和本地目录。Fabric提供的对远端和本地目录的操作分别是cd和lcd。如果你用过命令行的ftp,这很容易理解。让我们看一个例子:
def filepath(): remote_dir = '/opt/xxx' with cd(remote_dir): run("touch README")
上面代码的功能是进入远端的/opt/xxx目录,并创建一个README文件。
Fabric还提供了很多的命令,比如文件操作等,可以参考Fabric的operations模块。
管理服务器连接
前面的例子中,都需要在fab命令行参数中指定server。当要管理大量服务器时很麻烦。Fabric提供了环境变量的字典env,其中就包含了hosts字典项,可以定义需要连接的server。如下:
from fabric.api import env, run env.hosts = ['host1', 'host2']def mytask(): run('ls /var/www')
也可以为每个任务单独指定要执行该任务的host列表:
from fabric.api import env, rundef set_hosts(): env.hosts = ['host1', 'host2']def mytask(): run('ls /var/www')
这样执行 fab set_hosts mytask时,就可以为set_hosts中指定的两个host执行mytask任务了。如果你懒得写函数,在fab命令行中指定也是一样的:
fab mytask:hosts="host1;host2"
为了更方便的执行批量任务,Fabric中还定义了Role,有兴趣可以阅读其官方文档。
管理SSH密码、用户、端口
尽管更推荐使用SSH公钥认证,但是Fabric还是提供了管理密码的机制。Fabric提供了两层密码。
如果你的server有相同的密码,可以在env.password中设置默认的密码;如果server密码不同,还可以在env.passwords中设置(host,password)对,为每个server设置单独的ssh密码。
上面的host字符串采用这种格式:username@hostname:port。所以,在指定ssh密码的同时,也就指定了ssh用户。同密码一样,你也可以在env.user中指定一个默认的用户。如果都没有指定,执行fab命令时会提示你输入密码。
小结
使用Fabric,你可以管理一系列host的SSH连接(包括主机名,用户,密码),定义一系列的任务函数,然后灵活的指定在哪些host上执行哪些任务。这非常使用于需要管理大量host的场景,比如运维,私有云管理,应用自动化部署等。本文只是一篇入门文档,远没有体现出Fabric的强大。实际上,Fabric还包括大量的功能,比如Role的定义,远程交互及异常处理,并发执行,文件操作等,并且不仅仅局限于命令行方式,可以在你的应用中调用Fabric。
希望本文能够引起你对Fabric的兴趣,并在你的实际应用中解决问题。
linux运维常用命令一句话(持续更新中)
作者:hartnett 发布于:2012-3-31 11:30 Saturday
整理收集一些Linux运维管理、系统管理的常用命令,太多了记不住,只能记录下来方便日后查看。也可以和大家分享。如果你有好的一句话命令也贴出来吧。本文持续更新中。
1、linux启动过程
开启电源 --> BIOS开机自检 --> 引导程序lilo或grub --> 内核的引导(kernel boot)--> 执行init(rc.sysinit、rc)--> mingetty(建立终端) --> Shell
2、网卡绑定多IP
# ifconfig eth0:1 192.168.1.99 netmask 255.255.255.0
3、设置DNS、网关
# echo "nameserver 202.16.53.68" >> /etc/resolv.conf # route add default gw 192.168.1.1
4、弹出、收回光驱
# eject # eject -t
5、用date查询昨天的日期
# date --date=yesterday
6、查询file1里面空行的所在行号
# grep ^$ file
7、查询file1以abc结尾的行
# grep abc$ file1
8、打印出file1文件第1到第三行
# sed -n '1,3p' file1 # head -3 file1
9、清空文件
# true > 1.txt # echo "" > 1.txt # > 1.txt # cat /dev/null > 1.txt
10、删除所有空目录
# find /data -type d -empty -exec rm -rf {} ; 11、linux下批量删除空文件(大小等于0的文件)的方法
# find /data -type f -size 0c -exec rm -rf {} ;
# find /data -type f -size 0c|xargs rm –f 12、删除五天前的文件
# find /data -mtime +5 -type f -exec rm -rf {} ; 13、删除两个文件重复的部份,打印其它
# cat 1.txt 3.txt |sort |uniq
14、攻取远程服务器主机名
# echo `ssh $IP cat /etc/sysconfig/network|awk -F = '/HOSTNAME/ {print $2}'` 15、实时监控网卡流量(安装iftop)
# /usr/local/iftop/sbin/iftop -i eth1 -n
16、查看系统版本
# lsb_release -a
17、强制踢出登陆用户
# pkill -KILL -t pts/1
18、tar增理备份、还原
# tar -g king -zcvf kerry_full.tar.gz kerry # tar -g king -zcvf kerry_diff_1.tar.gz kerry # tar -g king -zcvf kerry_diff_2.tar.gz kerry # tar -zxvf kerry_full.tar.gz # tar -zxvf kerry_diff_1.tar.gz # tar -zxvf kerry_diff_2.tar.gz
19、将本地80端口的请求转发到8080端口,当前主机外网IP为202.96.85.46
-A PREROUTING -d 202.96.85.46 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.9.10:8080
20、在11月份内,每天的早上6点到12点中,每隔2小时执行一次/usr/bin/httpd.sh
# crontab -e 0 6-12/2 * 11 * /usr/bin/httpd.sh
21、查看占用端口8080的进程
# netstat -tnlp | grep 8080 lsof -i:8080
22、在Shell环境下,如何查看远程Linux系统运行了多少时间?
# ssh user@被监控主机ip "uptime"
23、查看CPU使用情况的命令
每5秒刷新一次,最右侧有CPU的占用率的数据 # vmstat 5 top 然后按Shift+P,按照进程处理器占用率排序 # top
24、查看内存使用情况的命令
用free命令查看内存使用情况 # free -m top 然后按Shift+M, 按照进程内存占用率排序 # top
25、查看磁盘i/o
用iostat查看磁盘/dev/sdc3的磁盘i/o情况,每两秒刷新一次 # iostat -d -x /dev/sdc3 2
26、修复文件系统
# fsck –yt ext3 / -t 指定文件系统 -y 对发现的问题自动回答yes
27、read 命令5秒后自动退出
# read -t 5
28、grep -E -P 是什么意思
-E, --extended-regexp 采用扩展正规表达式。 -P,--perl-regexp 采用perl正规表达式
29、vi编辑器(涉及到修改,添加,查找)
插入(insert)模式
i 光标前插入 I 光标行首插入 a 光标后插入 A 光标行尾插入 o 光标所在行下插入一行,行首插入 O 光标所在行上插入一行,行首插入 G 移至最后一行行首 nG 移至第n行行首 n+ 下移n行,行首 n- 上移n行,行首 :/str/ 从当前往右移动到有str的地方 :?str? 从当前往左移动到有str的地方 :s/str1/str2/ 将找到的第一个str1替换为str2 :s/str2/str2/g 将当前行找到的所有str1替换为str2 :n1,n2s/str1/str2/g 将从n1行至n2行找到的所有的str1替换为str2 :1,.s/str1/str2/g 将从第1行至当前行的所有str1替换为str2 :.,$s/str1/str2/g 将从当前行至最后一行的所有str1替换为str2
30、linux服务器之间相互复制文件
copy 本地文件1.sh到远程192.168.9.10服务器的/data/目录下 # scp /etc/1.sh king@192.168.9.10:/data/ copy远程192.168.9.10服务器/data/2.sh文件到本地/data/目录 # scp king@192.168.9.10:/data/2.sh /data/
31、使用sed命令把test.txt文件的第23行的TEST换成TSET.
# sed -i '23s/TEST/TSET/' test.txt # sed -i '23 s/TEST/TSET/' test.txt
32、使history命令能显示时间
# export HISTTIMEFORMAT="%F %T "
33、如何查看目标主机192.168.0.1开放那些端口
# nmap -PS 192.168.0.1
34、如何查看网络连接
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 35、如何查看当前系统使用了那些库文件
# ldconfig -v
36、如何查看网卡的驱动版本
# ethtool -i eth0
37、使用tcpdump来监视主机192.168.0.1的tcp的80端口
# tcpdump tcp port 80 host 192.168.0.1
38、 如何看其它用户的邮件列表
# mial -u king
39、对大文件进行切割
按每个文件1000行来分割 # split -l 1000 httperr8007.log httperr 按照每个文件5m来分割 # split -b 5m httperr8007.log httperr
40、合并文件
取出两个文件的并集(重复的行只保留一份) # cat file1 file2 | sort | uniq 取出两个文件的交集(只留下同时存在于两个文件中的文件) # cat file1 file2 | sort | uniq -d 删除交集,留下其他的行 # cat file1 file2 | sort | uniq –u
41、打印文本模式下运行的服务
# chkconfig --list|awk '$5~/on/{print $1,$5}' 42、删除0字节文件
# find -type f -size 0 -exec rm -rf {} ; 43、查看进程,按内存从大到小排列
# ps -e -o "%C : %p : %z : %a"|sort -k5 -nr
44、查看http的并发请求数及其TCP连接状态
# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 45、获取IP地址
# ifconfig eth0|sed -n '2p'|awk '{print $2}'|cut -c 6-30
perl实现获取IP地址:
# ifconfig -a | perl -ne 'if ( m/^s*inet (?:addr:)?([d.]+).*?cast/ ) { print qq($1n); exit 0; }' 46、获取内存大小
# free -m |grep "Mem" | awk '{print $2}' 47、查看CPU核心数
# cat /proc/cpuinfo |grep -c processor
48、查看磁盘使用情况
# df -h
49、查看有多少个活动的PHP-cgi进程
# netstat -anp | grep php-cgi | grep ^tcp | wc -l
50、查看硬件制造商
# dmidecode -s system-product-name
童之磊:坚持成就梦想
作者:hartnett 发布于:2012-3-30 14:53 Friday
“一家公司存在的基础就是创造商业价值,任何伟大的事情,从企业的角度来讲,就要形成一套有效的商业模式,那才能叫好的公司。”——中文在线董事长兼总裁童之磊。
1999年,是我在清华的第6个年头。那一年,有个特别重要的事情,就是第一届中国大学生创业计划大赛。我的团队获得了第一名,我是队长,觉得特别兴奋。
易得方舟当时很明星,融资660万元,成为那个年代知本和资本结合的样本。比尔•盖茨和雅虎杨致远的创富神话,都使得我们这些年轻的学子们相信:好风凭借力,送我上青云。
易得方舟发展很快,5个人变成了80个人,它变成了国内最大的大学生门户网站,点击量一路上扬。但这不是我想要的,我要做数字出版。
理由很简单,我想做一件伟大的事情,而数字出版是用数字传承文明。中国有四大发明,火药、指南针、造纸术、印刷术,至少有两项发明在数字出版时代都不再需要,就是既不需要造纸,也不需要印刷。
2000年5月份的时候,中文在线成立,我出任总裁,25岁,被称为中国最年轻的总裁。公司成立那天,名家荟萃,余秋雨、余华都来了,白岩松是主持人。
没有清晰的盈利模式,早期的中文在线依赖于风险投资。大部分投资人都对我说:“革命性的想法,非常好,一定投。”我在磨刀霍霍时,互联网的冬天来了,投资人不再投资互联网。
质疑,铺天盖地的质疑。有人跟我说,网络出版真正的市场成熟还早,也有人跟我说,这个事情根本就不可能,你怎么可能改变大家的阅读习惯呢?
很快就到了绝境,公司的账上没钱了,我把自己的钱垫进去,垫完找朋友借。马上朋友也不借了,觉得是无底洞。
公司只剩下3名员工,为了活下来,我找了份月薪几万块钱的工作,靠这份薪水支撑公司正常运转。我当时给自己开的工资是1200,同事的工资比我高一些,就这样,活了一年。
被收购,不甘心
我没有放弃。有一次,我问一个朋友,有一天,你想看的所有的内容都可以通过数字化的方式给你,你觉得好不?他说那当然很好了。我就觉得很兴奋,更坚定了自己的信心。
2001年7月,有一个朋友告诉我,香港有一家公司准备在国内发展互联网教育,想要找一家公司合作。我去跟香港泰德集团的董事长陈平聊了聊,那时他在做“景山教育网”,是针对中小学的网校,而中文在线那个阶段在做中小学数字图书馆,两家公司有交集。
告别时,陈平问我:“我这缺总裁,你来不来?”我笑笑说,我有公司。他接着说:“我把你的公司收购了吧。”当时我认为他在开玩笑,哪有人为了找一个管理人员,还附带买一个公司。
一周后,陈平再次来到北京,下飞机就给我电话,又谈到收购公司的事情。又谈了两三次,我觉得对方很有诚意,就答应了。事情定下来大概在2001年年底。
数字出版在当时的互联网大势下,以中文在线的实力,理想和现实之间遥不可及,但在泰德的平台上,或许会有些改变。在处理了一些公司事务之后,2001年10月完成了收购计划,之后,我出任泰德集团执行总裁兼首席运营官。
在很多人眼里,我在泰德的日子过得很舒服,担任集团高层,负责总体管理,年薪数十万元,其实我心里并不快乐。泰德是家有着自己目标的公司,与数字出版无关,我在泰德呆了3年,看着泰德一天比一天好,但中文在线还在原地踏步,说真的,挺纠结的。
做企业逆水行舟,不进则退。你停在那里,别人在前进,就等于你在退步。
那时候北大方正也在做数字出版,还有一个叫博库的,当时融到了上千万美金。
在中国任何一个行当最初都有成千上百的人做,但慢慢就会行业洗牌。那3年,洗牌洗掉了一些,但有些发展还不错,我的梦想停在原地,像打点滴,不让你死,但是想活好也难。
从另外一个角度来看,我很感谢泰德,不管怎么说,中文在线在互联网泡沫满目疮痍的时候,没有死去。但从我内心来说,我很怕自己错过数字出版的浪潮,这样一个可以改变人类生活的事情。
我找陈平沟通了很多次,要求发展中文在线,陈平问我:“你觉得中文在线能不能上市?如果你觉得中文在线能够上市,那你可以去选择创业。如果说不能,你要的所有的东西在泰德其实都已经有了(泰德旗下有上市公司)。”
我告诉陈平,中文在线一定会成功,一定会上市,一定会成为一家伟大的公司。2004年初,我将自己在泰德的股份折现,又找朋友借了一大笔钱,以管理者回购的形式将中文在线从泰德手中赎了回来。
我带着中文在线重回清华科技园,那种感觉跟回家一样。
有效的商业模式才是好公司
二次创业开始了。这一次,我的经营思路清晰了起来。
我深知能落地的商业模式对一个公司来说,非常重要。任何伟大的事情,从企业的角度来讲,就要形成一套有效的商业模式,那才能叫好的公司。中文在线确定了两个清晰而健康的商业模式——中小学数字图书馆和移动阅读。
在 我看来,全国有3000所公共图书馆和1000所大学图书馆,而中小学有40万所,这是一个巨大的市场。几年下来,中文在线已是国内最大的中小学数字图书 馆提供商。“移动阅读”在日本叫“手机小说”,即利用WAP技术将小说内容发送到手机上,这是一个已经取得成功的商业模式。中文在线与中国移动合作共同开 拓了中国手机阅读市场,目前每月访问用户数超过6000万。
生存的问题解决了,数字出版的理想并没有止步于此,我想打通上下游。我们的上游就是出版社和作者,中文在线把他们授权的作品制作成电子图书,然后通过手机、互联网、手持终端、数字图书馆等媒体把版权提供给不同的用户,称为全媒体出版模式。
到目前为止,中文在线已经成为了全国最大的数字出版服务提供商之一,与全国四百多家出版机构,两千多名知名作家,10万余名驻站网络作者进行合作。
我入行12年了。以前有记者问过我,你最大的竞争对手是谁?说真的,我没有竞争对手,早些年对手都不见了,也有可能这个行业太早了,早得让人看不到希望。
2000年,我去拜访一个出版社的社长,向他介绍自己做网络出版的雄心。社长听完后对我说:“小童呀,你这个是白日做梦。你知道纸书有多少年的历史吗?它存在已经几千年了。你觉得这样的阅读习惯是你这样一个二十几岁的年轻人所能改变的吗?”
十多年过去了,我再次见到这位社长时,他激动地对我说:“童总呀,咱们可得好好地合作,一起搞数字出版。什么是电子书、什么是网络出版,第一堂课我就是听你讲的。”
周亚辉:跌倒后的生存艺术
作者:hartnett 发布于:2012-3-30 14:42 Friday 分类:生活杂谈
“我觉得大学生创业,其实就是拿着一把木头枪上战场,觉得自己很英雄,实际上是个木头枪,一枪就被人打死了,自己还打不死别人。”——昆仑万维董事长兼CEO周亚辉。
一
1999年,我是清华研究生一年级的学生,学校有个可以休学创业的政策,我是第12个人。政策延续了不到3年,那年 有不超过20人暂停学业出来创业。当时被媒体追捧的易得方舟、视美乐,是清华学生创业的代表企业。我很清晰地记得,我拿到了50万元的创业资本,清华科技 园投的。
我的项目是原创动漫网站,叫火神网,有点像现在的社交网络,每个人都有自己的展示空间,能交流沟通。那时候两眼一抹黑,纯粹是碰,没有一点前瞻性。我坚持了4年,为了活下来,做了很多事情,比如动画广告的外包,做过大量的多媒体光盘,还有一些小网站。
任何一个事情刚开始的时候,大都繁花似锦、烈火烹油之势,接下来就是冷暖自知。最初,在清华科技园租了一个办公室,账面只剩下10万块钱时,办公室就被退掉了。我就在五道口附近租了两个2000块钱的两居。刚刚工作的第一个暑假,几乎天天中午都吃蛋炒饭,3块钱,很便宜。
第一次创业失败了,说实话,很惭愧,一直都没有做起来。清华出来创业的那些人,都是很牛的人,到今天没有一个做上市。为什么会失败?懂得太少,判断力不够。做多媒体光盘,利润多薄?风险多大?很苦很苦的时候,我就会问自己,一个清华的学生做这些值得吗?
我出生在云南丽江,我所受的家庭教育、社会教育都比较单纯,对社会的理解也比较简单,没经过太复杂的东西。求学经历中,过分强调了一些专业技能教育。中国人不学财务,而美国人初高中都要学财务课程,因为财务伴随人的一生,人一辈子都要跟钱打交道。
如果让我重新选择人生,我肯定不会创业。没毕业就创业,或者毕业就创业,特别累,特别苦。你经常会生活在绝望之中,你看不到哪天会成功,哪天能够找到希望。(巨大的成功背后必然伴随着巨大的痛苦)
13年过去了,我觉得大学时代去创业,还是蛮幼稚的,机会在哪里?报纸上说的,那些统统都是假的。媒体铺天盖地开始报道时,已经不是机会了,蛋糕已经切好,钱已经装进口袋,所以当事人才公开了,媒体也开始跟进了。
二
想起第一次失败,我觉得自己不懂技术,所以我想去了解技术。听人说,千橡互动里面技术高手比较多,我就去了,做了一段时间总监,想明白了很多问题。
陈一舟给了我很大的启发,他对我说,互联网上第二拨创业者肯定比第一拨更难成功,上一拨创业时,哪里都是空地,你占一片就可以。现在,已经有几个大城市了,我们只能做游击队,一边找几片相对肥沃的草地,逐渐变成小村庄,再变成城市;一边寻找其他草地。
陈一舟在找创业的空地方面,堪称典范。他是一位连环创业者,更是一位并购高手,在早年把Chinaren卖给张朝阳后,他一直在找空地,他赌的是社区,所以买了校内,就是去年登陆纳斯达克的人人网。
网页游戏就是我的空地。游戏本质是一种创意,后来者永远都有机会,只要你创意够出色。为了把自己的想法变成现实,我把房子卖了,跟亲戚借了一些钱,还有自己的一些钱,大概一千多万吧。
接下来就是如何活着了,早期想在互联网领域分一杯羹,我跟所有的老板一样,面临着腾讯天花板的问题。通俗点说,就是腾讯如果进入你所在的行业,你打算如何应对?这个问题也是风险投资者问创业者的一个经典问题。
对于腾讯这样一个有着庞大用户和极强粘性的平台型企业,我从来没当成竞争对手。幸运的是我创业的时候,腾讯的格局变大了,他不会在小生意上跟小公司竞争,他把小生意让给小公司做。因此在国内,昆仑万维只是活着。
在国外,硅谷大部分公司创立的时候,都以伟大为目标,网页游戏这样的创意行当貌似有点边缘。
中国有一个长期的比较优势,就是人力成本。美国互联网的人力成本很高,有些生意他们做不了,年收入1000万美金、公司50人规模,这家公司不赚钱;而在国内,养活一百多人,还能挣钱。
我去考察日本市场的时候,发现创业环境根本不如国内那样汹涌蓬勃。日本最大的SNS公司,创业初期也只融到了50万美金,重要的是在日本那种环境中,能拿到50万美金就很牛了。我得出了一个结论,在日本,昆仑万维有机会,韩国大抵也是如此。
三
这次出发,我很清楚我在哪里。我给的定位是:在国内我们永远打不过腾讯,但在海外呢, Google不会做游戏,Facebook也不会做,有可能在各个国家做网页游戏第一名。只用了4年时间,我们已经做到了韩国网页游戏的第二名,日本已经做到了第一名。
在韩国,昆仑万维跟NHA、NC soft、Nexon这些巨头打;在欧洲,跟Ubisoft、Gameforge、Bigpoint打;在美国需要跟EA竞争。虽然说我出发比较晚,但游戏行业归根到底,是一个拼创意的行当,出发早晚不是问题。
我的专注得到了回报。刚刚过去的一年,公司收入超过1亿美元,海外市场的贡献率在60%以上。去年,昆仑万维获得了华为领投的2亿元人民币第二轮融资,我爽快地接受了他们的钱。
道理很简单,华为是昆仑万维的精神榜样,我希望能够把它作为我们的理想。华为在国际化方面,小到出差补助,都很规范。他们有很多好的经验,可以借鉴。
我的目标是成为一个互联网的平台公司,只有51%的把握。小时候看圣斗士星矢,他为了打败对手,把自己的五感全毁了,只剩下第六感,才打败了对手。我很笨,能力又不特别强,所有的精力和时间都花在工作上,花在未来的挑战上,才有可能做得成。
经过这么多事,我明白了一些特别深刻的道理,有些东西看起来很美,但最多只是个美丽的诱惑而已。你真去做就会发现,做不到一年合伙人就得散伙,很多创业机会只是看起来很美而已,实际上并不美。
linux下源码包制作成rpm包教程
作者:hartnett 发布于:2012-2-22 18:02 Wednesday 分类:默认分类
http://www.mysqlops.com/2012/02/22/linux-rpmbuild-rpm.html
[导读]
在puppet cookbook系列文档中,sky就不至一次的提到过使用puppet 来管理软件包,而大多数
同学都会问,那我下载的.tar.gz的压缩包怎么办呢?那如何使用puppet来管理呢?关于源码包的
安装,之前有篇文章已经介绍了从源码包构建包,sky还是会建议大家把源码包制作成rpm包,
放进yum仓库,再使用puppet来管理,这样会方便许多,做运维的,你懂的.
[正文]
1.要使用rpmbuild 这个命令,那么要安装rpm-build, centos下可以使用yum -y intall rpm-build 来完成安装.
2.rpmbuild 包和 /usr/src/redhat目录 ,这些 rpm build 的程序是要靠 spec 文件的控制.它是配置指定安装到另外的机器上的,
用来指示转换的源码补丁编译成二进制文件的包.默认编译操作是在下面的目录中,它是编译源码的相关动作操作的位置.
如果不指定其它的地方,那么 rpm building 的地方是主要在 /usr/src/redhat 的目录,目录的架构如下,这就是为 rpm-build 提供的目录结构.
1
2
3
4
5
6
7
8
9
10
11
12
|
/usr/src/redhat/|-- BUILD|-- RPMS| |-- i386| `-- ...|-- SOURCES| |-- foo-1.2.tar.gz| |-- foo-1.2-add_feature.patch| `-- foo-1.2-change_default.patch|-- SPECS| `-- foo.spec`-- SRPMS |
%define name foo # 名字
%define version 16 #version
Name: %{name} #name 就是使用的上面的宏指令
Version: %{version} #version 也是使用的上面的宏指令
Release: 1
License: GPL
Group: Applications/Productivity # 软件是哪个组的,更多信息查看 /usr/share/doc/rpm-version/GROUPS
URL: http://www.mysqlops.com
Source: ftp://www.mysqlops.com/pub/xxx.tar.gz
Patch0: foo-1.2-change_default.patch
Patch1: foo-1.2-add_feature.patch
PreReq: unzip # 安装前需要什么
Requires: pam # 安装后需要什么
BuildPreReq: gcc >= 2.96 #打包前需要什么
BuildRoot: %{_tmppath}/%{name}-root # 准备源码文件的 chroot 的目录
Summary: A fictional open source package for the offering. #摘要
%description #描述注意,spec 文件很多信息都是取自宏指令,如果没有明确指定,就会继承 /usr/lib/rpm/macros 和其它相关宏指令的文件.
Spec 文件之 %prep
%prep 这部分其它是由一些参数来组成一个 shell 脚本来从 SOURCES 中解压源码和应用补丁到 BUILD 目录中来准备下面的编译.
和 %prep 相关的宏指令
%setup
%patch
例:
%prep
%setup -q #提取源码到 BUILD 目录; -q 指不显示输出(quietly)
%patch0 -p1 # 应用 patch0
%patch1 -p1 -b .orig # 应用 Patch1 但是存下源文件成 .oring 的后缀
unzip foo_data.zip # 接下来解压 zip 文件
Spec 文件之 %build
%build 是编译和准备软件,运行象一个 shell 脚本,它运行在上下文目录指定的源码目录.在编译过程中,调用脚本 .config 在本地的目录(%configure 中配置的).
和 %build 相关的宏
%configure # 可以通过运行 rpm -eval %configure 来看它的设置
例:
%build
%configure –enable-shared
CFLAGS=-O2 make
Spec 文件之 %install
%install 是用来做 rpm 安装所有需要的文件.这些打包的文件会复制到前面的讲的 BuildRoot 中的目录树中.通常这个目录是使用的 /var/tmp 中.
$RPM_BUILD_ROOT 参数来设置 BuildRoot.主要不能使用真实目录来设置的主要原因是,在编译的过程中有可能会有文件替换到你系统中的文件引起系统
和软件问题.对其它的文件路径象在 %{_mandir}, %{_bindir} , %{_sysconfdir} 等等,都是使用预先定义的宏来指定的.
默认都是跑在这个 RPM_BUILD_ROOT 目录下的.
例:
1
2
3
4
|
%installrm -rf $RPM_BUILD_ROOT # 默认的$RPM_BUILD_ROOT 是 /var/tmp/%{name}-rootmake DESTDIR=$RPM_BUILD_ROOT install # 指定安装文件的路径install -m644 foo.8 ${RPM_BUILD_ROOT}/%{_mandir}/man8/foo.8 |
Spec 文件之 %clean
%clean 是用来清理 build 后的临时文件,主要是怕这些旧的文件影响以后编译.主要是要删除 $RPM_BUILD_ROOT 和运行 make clean .
例:
%clean rm -rf $RPM_BUILD_ROOT make clean
Spec 文件之 Scriptlets
这些选项可以让你动态的使用 shell 脚本来控制安装和删除,
%pre,%post 是用脚本运行在包安装后,注意没法交互
%preun,%postun 用脚本运行在包删除时
rpm -q –scripts packagename # 可以看到脚本的信息
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
%pregroupadd -g 201 foouseradd -g foo -s /bin/false -d /var/foo -M foo%post/sbin/ldconfigchkconfig --add food%preunif [ = 0 ]then service food stop > /dev/null 2>&1 chkconfig --del foodfi%postunif [ = 0 ]then userdel foo groupdel fooelse /sbin/ldconfig service food condrestart > /dev/null 2>&1fi |
注意,在这个当中的数字,如果是 1 是指是第一次安装,如果是 2 是指也许是升级.如果是 0 在 %postun , 是指被完全的删除.
Spec 文件之 %files
%files 任何打包的文件,都需要在这个包的详细的文件列表中,如果是目录,包的所有者的全部目录都在中间,%dir 来指定空目录,可以用
%files -f /tmp/dyanmic_filelist 来指定一个文件列表.默认 %config 会替换掉配置,给原来的配置修改名字为 .rpmorig,
如果不想修改的话,就用%config(noreplace) 就会给新的配置文件名字命名为 .rpmnew.
%defattr(mode,user,group)
%attr(mode,user,group) filename
%config 配置文件
%doc 文档
例:
1
2
3
4
5
6
7
8
9
|
%files%defattr(-,root,root)%config /etc/foo.conf # 指定了才能在更新和删除时有用/usr/sbin/food/usr/bin/foo%doc README # 目录是在 /usr/share/doc/%{name}-%{version}%doc /usr/share/man/man8/food.8/usr/share/foo/%dir /var/lock/foo/ # 空的目录 |
Spec 文件之 %changelog;
%changelog 是记录包的修改,比如加入一个新的补丁,修改配置,日志使用 data +”%a %b %d %Y”,
需要显示包的日志改变的信息可以使用 rpm-q –changelog.例:
%changelog
• Mon Aug 5 2002 Elvis Presley
[总结]
知道了怎么把rpm包相信大家就会知道,然后做yum 源了,做好了yum源,只需要客户端配置好使用安装源,这样是不是很方便,
如果自定义yum 源不会的,sky 改天写下吧,大概做法:centos下比较简单,安装下createrepo软件,然后再做个http服务,
就可以了.本篇文章大部分网上大多数都有的,大家可以实际测试下,如不清楚再问下吧.
nginx的access log中记录post请求的参数[zz]
作者:hartnett 发布于:2012-2-10 15:48 Friday
来源:http://www.51testing.com/?uid-116228-action-viewspace-itemid-236701
常见的nginx配置中access log一般都只有GET请求的参数,而POST请求的参数却不行。http://wiki.nginx.org/NginxHttpCoreModule#.24request_body
$request_body
This variable(0.7.58+) contains the body of the request.
The significance of this variable appears in locations with directives proxy_pass or fastcgi_pass.
正如上文件所示,只需要使用$request_body即可打出post的数据,在现存的server段加上下面的设置即可:
log_format access '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent $request_body "
$http_referer" "$http_user_agent" $http_x_forwarded_for';
access_log logs/test.access.log access;Twitter首席工程师:如何“打败”CAP定理
作者:hartnett 发布于:2012-2-8 17:05 Wednesday
英文原文:How to beat the CAP theoremCAP 定理是数据系统设计的基本理论,目前几乎所有的数据系统的设计都遵循了这个定理。但 CAP 定理给目前的数据系统带来了许多复杂的、不可控的问题,使得数据系统的设计越来越复杂。Twitter 首席工程师、Storm 的作者 Nathan Marz 在本文中通过避开 CAP 定理带来的诸多复杂问题,展示了一个不同于以往的数据系统设计方案,给我们的数据系统设计带来了全新的思路。
CAP 定理指出,一个数据库不可能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition-Tolerance)。
一致性(Consistency)是指执行了一次成功的写操作之后,未来的读操作一定可以读到这个写入的值。可用性 (Availability)是指系统总是可读可写的。Yammer 的 Coda Hale 和 Cloudera 的 Henry Robinson 都阐述过,分区容错性是不能牺牲的,因此只能在一致性和可用性上做取舍,如何处理这种取舍正是目前 NoSQL 数据库的核心焦点。
选择一致性而不是可用性的系统将面临一些尴尬的问题,当系统不可用时怎么办?你可以对写操作进行缓冲处理,但如果存储缓冲数据的机器出现故障, 客户端将丢失写入的值。同样地,缓冲写也可以被认为是一种非一致性的操作,因为客户端认为成功的写入实际上并没有写入到实际的数据库中。当然,系统可以在 机器不可用时向客户端返回错误,但可以想象,一个经常告诉客户端“请重试”的产品是多么令人讨厌。
另一个方案是选择可用性放弃一致性。这种情况下最好的一致性保障是“最终一致性”(Eventually Consistency)。当使用最终一致性的系统时,客户端有时会读到与刚刚写入数据不同的数据。有时候,同一时间同一个 key 的多个请求有可能返回不同的结果。数据更新并不能及时在所有的复制节点上生效,所以不同的复制节点上可能读取到的是不同的值。当你检测到数据不一致性时, 你需要进行修复(Repair)操作,这就需要使用矢量时钟(vector clock)记录数据的版本历史并合并不同的数据更新(这称为读取修复,read repair)。
我相信在应用层维护最终一致性对开发人员负担太重,开发人员极易弄错读取修复的代码,而一旦开发人员犯错,有问题的读取修复将对数据库系统造成不可逆的损坏。
所以牺牲可用性时问题会很多,牺牲一致性时构建和维护系统的复杂度又很高,但这里又只有两个选择,不管怎样做都会不完美。CAP 定理是改不了的,那么还有什么其他可能的选择吗?
实际上,还有一个办法:你并不能避开 CAP 定理,但可以把复杂的问题独立出来,免得你丧失对整个系统的掌控能力。CAP 定理带来的复杂性,其实是我们如何构建数据系统这一根本问题的体现。其中有两点特别重要:数据库中可变状态和更新状态的增量算法。复杂性正是这两点和 CAP 定理之间的相互作用导致的。
本文将通过一个数据库系统的设计,来说明如何解决 CAP 定理通常会造成的复杂性问题。但我要做的不仅仅如此,CAP 定理是一个针对机器发生错误时系统容错性的一个定理,而这里有比机器容错性更加重要的容错性——人为操作容错性。在软件开发中一个确定的事实是,开发人员 都并非完人,产品中难免有一些 Bug,我们的系统必须对有 Bug 的程序写入的错误数据有足够的适应能力,我要展示的系统将是这样一个可以容忍人为错误的系统。
本文将挑战你对数据系统如何构建这一问题的假设,通过颠覆传统数据系统构建方法,我会让大家看到一个前所未见的优雅、扩展性强、健壮的数据系统。
什么是数据系统?
在开始介绍系统设计之前,让我们先来看看我们要解决的问题:数据系统的目的在于什么? 什么是数据? 在我们考虑 CAP 定理之前,我们必须给出一个可以适用于所有数据应用程序的定义来回答上述问题。
数据应用程序种类很多,包括存入和提取数据对象、连接、聚合、流处理、机器学习等。似乎并不存在一个对数据系统的明确定义,数据处理的多样性使得我们很难用一个定义来描述。
事实却并非如此,下面这个简单的定义:
Query = Function (All Data)
概括了数据库和数据系统的所有领域。每一个领域——有 50 年历史的 RDBMS、索引、OLAP、OLTP、MapReduce、EFL、分布式文件系统、流处理器、NoSQL 等——都可以被概括进这个方程。
所谓数据系统就是要回答数据集问题的系统,这些问题我们称之为“查询”。上面的方程表明,查询就是数据上的一个函数。
上述方程对于实际使用来说太过于笼统,几乎对复杂的数据系统设计不起什么作用。但如果所有的数据系统都遵循这个方程又会怎样呢?这个方程是探索我们数据系统的第一步,而它最终将引导我们找到“打败”CAP 定理的方法。
这个方程里面有两个关键概念:数据、查询。这两个完全不同的概念经常被混为一谈,所以下面来看看这两个概念究竟是什么意思。
数据
我们先从“数据”开始。所谓数据就是一个不可分割的单位,它肯定存在,就跟数学里面的公理一样。
关于“数据”有两个关键的性质。首先,数据是跟时间相关的,一个真实的数据一定是在某个时间点存在于那儿。比如,假如 Sally 在她的社交网络个人资料中写她住在芝加哥,你拿到的这个数据肯定是她某个时间在芝加哥填写的。假如某天 Sally 把她资料里面居住地点更新为亚特兰大,那么她肯定在这个时候是住在亚特兰大的,但她住在亚特兰大的事实无法改变她曾经住在芝加哥这个事实——这两个数据都 是真实的。
其次,数据无法改变。由于数据跟某个时间点相关,所以数据的真实性是无法改变的。没有人可以回到那个时间去改变数据的真实性,这说明了对数据操 作只有两种:读取已存在的数据和添加更多的新数据。那么 CRUD 就变成了 CR【译者注:CRUD 是指 Create Read Update Delete,即数据的创建、读取、更新和删除】。
我去掉了“更新”操作,因为更新对于不可改变的数据没有任何作用。例如,更新 Sally 的位置信息本质上就是在她住的地方数据中新加一条最近的位置信息而已。
我同样去掉了“删除”操作,因为绝大部分删除操作可以更好地表述为新加一条数据。比如 Bob 在 Twitter 上不再关注 Mary 了,这并不能改变他曾经关注过 Mary 这个事实。所以与其删除 Bob 关注 Mary 这个数据,还不如新加一条 Bob 在某个时间点不再关注 Mary 这个数据。
这里只有很少数的情况需要永久“删除”数据,例如规则要求你每隔一段时间清掉数据,这个情况在我将要展示的系统中有很好的解决方案,所以为了简洁,我们暂不考虑这些情况。
查询
查询是一个针对数据集的推导,就像是一个数学里面的定理。例如,你可以通过计算“Sally 现在的位置在哪里”这个查询来得到 Sally 最新的位置数据。查询是整个数据集合上的函数,可以做一切事情:聚合、连接不同类型的数据等。因此,你可以查询系统中女性用户的数量,可以查询最近几小时 热门的 Twitter 内容。
前面我已经定义查询是整个数据集上的函数,当然,不是所有的查询都需要整个数据集,它们只需要数据集的一个子集。但我的定义是涵盖了所有的查询类型,如果想要“打败”CAP 定理,我们需要能够处理所有的查询。
打败 CAP 定理
计算查询最简单的办法就是按照查询语义在整个数据集上运行一个函数。如果这可以满足你对延迟的要求,那么就没有其他需要构建的了。
可想而知,我们不能指望在整个数据集上的查询能够很快完成,特别是那些服务大型网站、需要每秒处理几百万次请求的系统。但假如这种查询可以很快 完成,让我们来看看像这样的系统和 CAP 定理的 PK 结果:你将会看到,这个系统不仅打败了 CAP 定理,而且还消灭了它。
CAP 定理仍然适用,所以你需要在可用性和一致性上做出选择,这里的漂亮之处在于,一旦你权衡之后做出了选择,你就做完了所有的事情。通常的那些因为 CAP 定理带来的问题,都可以通过不可改变的数据和从原始数据中计算查询来规避。
如果你选择一致性而不是可用性,那么跟以前并没有多大的区别,因为你放弃了可用性,所以一些时候你将无法读取或者写入数据。当然这只是针对对强一致性有要求的系统。
如果你选择可用性而不是一致性,在这种情况下,系统可以达到最终一致性而且规避了所有最终一致性带来的复杂问题。由于系统总是可用的,所以你总 可以写入新数据或者进行查询。在出错情况下,查询可能返回的不是最近写入的数据,但根据最终一致性,这个数据最终会一致,而查询函数最终会把这个数据计算 进去。
这里的关键在于数据是不可变的。不可变数据意味着这里没有更新操作,所以不可能出现数据复制不同这种不一致的情况,也意味着不需要版本化的数 据、矢量时钟或者读取修复。在一个查询场景中,一个数据只有存在或者不存在两种情况。这里只有数据和在数据之上的函数。这里没有需要你为确保最终一致性额 外做的事情,最终一致性也不会因此使你的系统变得复杂。
之前的复杂度主要来自增量更新操作和 CAP 定理之间的矛盾,在最终一致性系统中可变的值需要通过读取修复来保证最终一致性。通过使用不可变数据,去掉增量更新,使用不可变数据,每次从原始数据计算查询,你可以规避那些复杂的问题。CAP 定理就被打败了。
当然,现在讲的只不过是想法而已,而且每次从原始数据计算查询基本上不可能。但我们从中可以学到一些在实际解决方案中的关键点。
- 数据系统因为不可变数据和不断增长的数据集变得简单了。
- 基本的写入操作就是写入一条新的不可变数据。
- 数据系统通过重新从原始数据计算查询规避了 CAP 定理带来的复杂度。
- 数据系统利用增量算法使得查询的返回延迟降低到一个可以接受的程度。
让我们开始探索这个数据系统应该如何设计。请注意从这里开始我们所描述都是针对系统优化、数据库、索引、EFL、批量计算、流处理——这些技术 都是对查询函数的优化,让查询返回时间降低到一个可以接受的程度。这很简单,但也是数据系统所面对的现实。数据库通常是数据管理的核心,但它们是更大蓝图 中的一部分。
批量计算
“如何让任意一个函数可以在任意一个数据集上快速执行完成”这个问题太过于复杂,所以我们先放宽了一下这个问题依赖条件。首先假设,可以允许数 据滞后几小时。放宽这个条件之后,我们可以得到一个简单、优雅、通用的数据系统构建解决方案。之后,我们会通过扩展这个解决方案使得它可以不用放宽条件来 解决问题。
由于查询是所有数据的一个函数,让查询变快的最简单的方法就是预先计算好这些查询。只要这里有新的数据,你就重新计算这些查询。这是可能的,因为我们放宽了条件使得我们的数据可以滞后几个小时。图 1 展示了这个工作流程。
图 1 预计算工作流程
为了实现这个,你的系统需要:
- 能很容易存储大的、不断增长的数据集;
- 能在数据集上可扩展地计算查询函数。
这样的系统是存在的,即 Hadoop。它是一个成熟的、经历了无数团队实战检验过的系统,同时拥有一个巨大的工具生态系统。它虽不完美,但是这里用来做批量处理的最好的一个工具。
许多人也许会告诉你,Hadoop 只适用于那些“非结构化”的数据,这是完全错误的看法。Hadoop 处理“结构化”的数据也很不错,通过使用像 Thrift 或者 Protocol Buffers 这样的工具,你可以使用丰富的数据结构存储你的数据。
Hadoop 由分布式文件系统 HDFS 和批处理框架 MapReduce 两部分构成。HDFS 可以通过文件存储大量数据,MapReduce 可以在这样数据上进行可扩展计算。这个系统完全符合我们的要求。
我们将数据以文件形式存储到 HDFS 中去。文件可以包括一个数据记录序列。新增数据时,我们只需要在包括所有数据的文件夹中新增一个包含这条新记录的文件即可。像这样在 HDFS 存储数据满足了“能够很容易存储大的、不断增长的数据集”这个要求。
预计算数据集上的查询也很直观,MapReduce 是一个足够复杂的框架,使得几乎所有的函数都可以按照多个 MapReduce 任务这种方式实现。像 Cascalog、Cascading 和 Pig 这样的工具使实现这些函数变得十分简单。
最后,为了可以快速访问这些预计算查询结果,你需要对查询结果进行索引,这里有许多数据库可以完成这个工作。ElephantDB 和 Voldemort read-only 可以通过从 Hadoop 中导出 key/value 数据来加快查询速度。这些数据库支持批量写和随机读,同时不支持随机写。随机写使得数据库变得复杂,所以通过不支持随机写,这些数据库设计得特别简洁,也 就几千行代码而已。简洁使得这些数据库鲁棒性变得非常好。
下面来看批量处理系统整体上是如何配合工作的。假设写一个网站分析程序来跟踪页面访问量,你需要能够查询到任意时间段的页面访问量,数据是以小时方式提供的。如图 2 所示。
图 2 批处理工程流程示例(timestamp 代表时间戳,count 代表个数)
实现这个很简单,每一个数据记录包括一个单一页面的访问量。这些数据通过文件形式存储到 HDFS 中,一个函数通过实现 MapReduce 计算任务,来计算一个 URL 下页面每小时的访问量。这个函数产生的是 key/value 对,其中[URL, hour]是 key,value 是页面的访问量。这些 key/value 对被导出到 ElephantDB 中去,使得应用程序可以快速得到任意[URL, hour]对对应的值。如果应用程序想要知道某个时间范围内某个页面的访问量,它可以查询 ElephantDB 中那段时间内的数据,然后把这些数据相加就可以得到这个访问量数据了。
在数据滞后几小时这个缺陷下,批量处理可以计算任意数据集上的任意函数。系统中的“任意性”是指这个系统可以处理任何问题。更重要的是,它很简单,容易理解和完全可扩展,你需要考虑的只是数据和查询函数,Hadoop 会帮你处理并行的事情。
批处理系统、CAP 定理和容忍人为错误
截至目前,我们的系统都很不错,这个批处理系统是不是可以达到容忍人为错误的目标呢?
让我们从 CAP 定理开始。这个批处理系统总是最终一致的:写入的数据总可以在几小时后被查询到。这个系统是一个很容易掌控的最终一致性系统,使得你可以只用关注你的数据和针对数据的查询函数。这里没有涉及读取修复、并发和其他一些需要考虑的复杂问题。
接下来看看这个系统对人为错误的容忍性。在这个系统中人们可能会犯两个错误:部署了一个有 Bug 的查询函数或者写入了错误的数据。
如果部署了一个有 Bug 的查询函数,需要做的所有事情就是修正那个 Bug,重新部署这个查询函数,然后在主数据集上重新计算它。这之所以能起作用是因为查询只是一个函数而已。
另外,错误的数据有明确的办法可以恢复:删除错误数据,然后重新计算查询。由于数据是不可变的,而且数据集只是往后添加新数据,写入错误的数据不会覆盖或者删除正确的数据,这与传统数据库更新一个数据就丢掉旧的数据形成了鲜明的对比。
注意到 MVCC 和 HBase 类似的行版本管理并不能达到上面人为错误容忍级别。MVCC 和 HBase 行版本管理不能永久保存数据,一旦数据库合并了这些版本,旧的数据就会丢失。只有不可变数据系统能够保证你在写入错误数据时可以找到一个恢复数据的方法。
实时层
上面的批量处理系统几乎完全解决了在任意数据集上运行任意函数的实时性需求。任何超过几个小时的数据已经被计算进入了批处理视图中,所以剩下来要做的就是处理最近几个小时的数据。我们知道在最近几小时数据上进行查询比在整个数据集上查询要容易,这是关键点。
为了处理最近几个小时的数据,需要一个实时系统和批处理系统同时运行。这个实时系统在最近几个小时数据上预计算查询函数。要计算一个查询函数,需要查询批处理视图和实时视图,并把它们合并起来以得到最终的数据。
图 3 计算一个查询
在实时层,可以使用 Riak 或者 Cassandra 这种读写数据库,而且实时层依赖那些数据库中对状态更新的增量算法。
让 Hadoop 模拟实时计算的工具是 Storm。我写 Storm 的目的是让 Hadoop 可以健壮、可扩展地处理大量的实时数据。Storm 在数据流上运行无限的计算,并且对这些数据处理提供了强有力的保障。
让我们回到刚才那个根据某个 URL 查询某个页面在某个时间段内页面访问量的例子,通过这个例子我将展示实时层是如何工作的。
批处理系统还是跟之前一样:一个基于 Hadoop 和 ElephantDB 的批处理工作流,在几个小时之前的数据上预计算查询函数。剩下就是让实时系统去处理最近几小时数据了。
我们将最近几小时的数据状态存入 Cassandra 中,用 Storm 去处理页面访问量数据流并并行更新到数据库中,针对每一个页面访问量,在[URL, hour]所代表的 key 下,有一个计数器,这个计数器在 Cassandra 中实现。这就是所有的事情,Storm 让事情变得非常简单。
图 4 批处理/实时架构示例
批处理层+实时层、CAP 定理和人为错误容忍性
貌似又回到一开始提出的问题上去了,访问实时数据需要使用 NoSQL 数据库和增量算法。这就说明回到了版本化数据、矢量时钟和读取修复这些复杂问题中来。但这是有本质区别的。由于实时层只处理最近几小时的数据,所有实时层 的计算都会被最终批处理层重新计算。所以如果犯了什么错误或者实时层出了问题,最终都会被批处理层更正过来,所有复杂的问题都是暂时的。
这并不意味着不需要关心实时层的读取修复和最终一致性,你仍然需要实时层尽可能的一致。但当犯了一个错误时,不会永久性地破坏数据。这便移除了许多你所需要面对的复杂问题。
在批处理层仅需要考虑数据和数据上的查询函数,批处理层因此很好掌控。在实时层,需要使用增量算法和复杂的 NoSQL 数据库。把所有的复杂问题独立到实时层中,对系统的鲁棒性、可靠性做出了重大贡献。
同样的,实时层并没有影响系统的人为错误容忍性,这个数据不可变和只追加的批处理系统,仍然是整个系统的核心,所以所有的都可以像上面说的一样被纠正过来。
我有一个类似的系统:Hadoop 和 ElephantDB 组成批处理系统,Storm 和 Cassandra 组成实时系统。由于缺乏监控,某天当我起床的时候发现 Cassandra 运行满负荷了,使得所有的数据请求都超时。这使得 Storm 计算失败,一些数据又重新回到了等待队列中,这个数据就一次次重复请求。
如果我没有批处理层,那么我就需要扩展和恢复 Cassandra,这个很不容易。更糟的是,因为请求不断的重复,无法得到正确的数据。
幸运的是,所有的复杂问题都被隔离到实时层中去了,我清空了所有的后台请求队列,把它们打到了批处理层上,同时重启了 Cassandra 集群,过了几个小时之后所有数据都恢复正常了。没有错误数据,请求中也没有不准确的地方。
垃圾回收
上面描述的所有东西都是建立在一个不可变的、不断增长的数据集上的。如果数据集已经很大,使得不可能用水平扩展储存所有时间的所有数据,该如何处理呢?这是不是就推翻了我说的一切呢?是不是需要回到可变数据的系统上呢?
不。我们可以很容易地用“垃圾回收”对基本模型进行扩展来解决上面的问题。垃圾回收是一个在主数据集上的简单函数,返回的是一个过滤版本的主数 据集。垃圾回收掉了旧数据,可以选择任意的垃圾回收策略。可以在易变的系统中只保留数据最新的一个值或者保留每个数据的历史。比如,如果要处理位置数据, 可以保留每人每年的一个地点。可变性是一个不是很灵活的垃圾回收形式(它跟 CAP 定理交互得也很糟糕)。
垃圾回收可以被实现成批处理的一个任务,隔段时间运行一下。由于它是作为离线批处理任务执行的,所以不影响我们与 CAP 定理的交互。
总结
让可扩展的数据系统复杂的原因不是 CAP 系统,而是数据增量算法和数据的可变状态。最近由于分布式数据库的兴起导致了复杂度越来越不可控。前面讲过,我将挑战对传统数据系统构建方法的假设。我把 CRUD 变成了 CR,把持久化层分成了批处理和实时两个层,并且得到对人为错误容忍的能力。我花费了多年来之不易的经验打破我对传统数据库的假设,并得到了这些结论。
批处理/实时架构有许多有趣的能力我并没有提到,下面我总结了一些。
算法的灵活性。随着数据量的增长,一些算法会越来越难计算。比如计算标识符的数量,当标识符集合越来越大时,将会越来越难计算。批处理/实时分 离系统给了你在批处理系统上使用精确算法和在实时系统上使用近似算法的灵活性。批处理系统计算结果会最终覆盖实时系统的计算结果,所以最终近似值会被修 正,而你的系统拥有了“最终精确性”。
数据结构迁移变得很容易。数据结构迁移的难题将一去不复返。由于批量计算是系统的核心,很容易在整个系统上运行一个函数,所以很容易更改你数据的结构或者视图。
简单的 Ad-Hoc 网络。由于批处理系统的任意性,使得你可以在数据上进行任意查询。由于所有的数据在一个点上都可以获取,所以 Ad-Hoc 网络变得简单而且方便。
自我检查。由于数据是不可变的,数据集就可以自我检查。数据集记录了它的数据历史,对于人为错误容忍性和数据分析很有用。
我并没有说我已经“解决”了数据量过大的问题,但我已经为解决大数据问题制订了一个框架。批处理/实时架构可以应用到任何一个数据系统中去,“授人以鱼,不如授人以渔”,我已经告诉你了如何去构建这样的系统。
为了提高系统整体能力来解决大数据的问题,我们还有许多工作需要做。
- 扩展数据模型,支持批量写和随机读。不是每一个应用程序都支持 key/value 的数据库,这也是我们团队对扩展 ElephantDB,使得可以支持搜索、文档数据库、区间查询感兴趣的原因。
- 更好的批处理原语。Hadoop 并不是批处理的最终形态,好多批处理计算 Hadoop 效率不高。Spark 是一个有意思的扩展 MapReduce 的项目。
- 提升后的读写 NoSQL 数据库。这里不同类型数据的数据库还有很大的提升空间,随着这些数据库的成熟,它们将收获很多。
- 高层级的抽象。未来工作中最有意思的就是对批处理模块和实时处理模块的高层次抽象,在批处理和实时架构下你没有理由不拥有一个简单的、描述性的、鲁棒性好的语言。
许多人需要一个可扩展的关系型数据库,本文就是想让你知道完全不需要那个。大数据量和 NoSQL 运动使数据管理比 RDBMS 更加复杂。那仅仅是因为我对大数据的处理采用了跟 RDBMS 同样的方法:把数据和视图混为一谈,并且依赖增量算法。大数据量需要采用完全不同的方式构建数据系统。通过存储持续增长的不可变数据,并且系统核心采用预 计算,大数据系统就可以变得比关系型数据库更易掌控,并且可扩展性很强。
(感谢 Nathan Marz 先生的授权,原文名为 How to beat the CAP theorem。同时感谢方建对本文翻译做出的贡献。)
设置Linux端口转发,并实现"双向通路"
作者:hartnett 发布于:2012-2-7 19:24 Tuesday
假设有两台服务器,A和B。我需要把访问A服务器的8081端口的数据转发到B服务器的8081端口,并接收B服务器的响应数据。
命令如下:
#echo 1 > /proc/sys/net/ipv4/ip_forward
#iptables -t nat -I PREROUTING -p tcp --dport 8081 -j DNAT --to xx.xx.xx.xx
#iptables -t nat -I POSTROUTING -p tcp --dport 8081 -j MASQUERADE
#service iptables save
#service iptables restart
===========================================================
第一条命令表示允许数据包转发;
第二条命令表示转发TCP 8081到xx.xx.xx.xx;
第三条命令表示使转发数据包实现“双向通路”,给数据包设置一个正确的返回通道。
第四条命令表示将规则保存到/etc/sysconfig/iptables文件
第五条命令表示重启iptables使刚才添加的规则生效
很多人按照网上的方法作端口映射,始终没有成功的原因是没有执行第四、第五条命令。
注:如果执行上述命令,依然不能转发,可能由于iptables服务没有停止,命令无法写入iptables文件,应先执行service iptables stop,再执行上述命令,最后service iptables start再启动服务
标签: linux转发






