2008年12月28日星期日

电信网通互联互通问题

由于电信和网通之间互联互通的问题,很多人选择双线路机房,所谓双线路机房就是拥有两条出口,一条电信一条网通。最近在一个双线路机房测试一台服务器,打算作为论坛的数据库服务器使用,服务器操作系统为Linux。计划配置为双IP,单域名,使得浏览者通过电信和网通两条线路都能正常访问服务器,而且各走各的,互不影响。在配置网络的时候遇到了问题,由于Linux默认只有一个网关,在网络上查询了很久,找到一个解决方案,因此整理了一下。感谢原文作者jac003ke



这个解决方案主要依赖一个技术: 策略路由.




策略性路由

  策略性是指对于IP包的路由是以网络管理员根据需要定下的一些策略为主要依据进行路由的。例如我们可以有这样的策略:“所有来直自网A的包,选择X路径;其他选择Y路径”,或者是“所有TOS为A的包选择路径F;其他选者路径K”。

  Cisco 的网络操作系统 (Cisco IOS) 从11.0开始就采用新的策略性路由机制。而Linux是在内核2.1开始采用策略性路由机制的。策略性路由机制与传统的路由算法相比主要是引入了多路由表以及规则的概念。








于是,我们需要定义一个策略, ip从哪个网卡进来,就从哪个网卡回去.







服务器操作系统RedHat linux as4,设置两张路由表



1. vi /etc/iproute2/rt_tables,增加网通和电信两个路由表
251 tel #电信路由表
252 cnc #网通路由表

2. 给网卡绑定两个地址用于电信和网通两个线路
ip addr add 192.168.0.2/24 dev eth0 #网通
ip addr add 10.0.0.2/24 dev eth1 #电信

3、分别设置电信和网通的路由表


l 增加设置策略路由函数


cat >> /etc/sysconfig/network-scripts/network-functions






policy_route() {
IP=/sbin/ip
IF1=eth1
IP1_NET=`$IP addr show $IF1 | grep 'inet ' | grep "global $IF1$" |awk '{print $2}'`
[ -n "$IP1_NET" ] || return 1;
IP1=`echo "$IP1_NET" | cut -d/ -f 1`
GW1=`grep GATEWAY /etc/sysconfig/network-scripts/ifcfg-$IF1 | cut -d= -f 2`

IF2=eth0
IP2_NET=`$IP addr show $IF2 | grep 'inet ' | grep "global $IF2$" | awk '{print $2}'`
[ -n "$IP2_NET" ] || return 1;
IP2=`echo "$IP2_NET" | cut -d/ -f 1`
GW2=`grep GATEWAY /etc/sysconfig/network-scripts/ifcfg-$IF2 | cut -d= -f 2`

NETWORK1=`ipcalc -n $IP1_NET|cut -d= -f2`
NETWORK2=`ipcalc -n $IP2_NET|cut -d= -f2`

echo "dev:$IF1 ip:$IP1_NET net:$NETWORK1 gateway:$GW1"
echo "dev:$IF2 ip:$IP2_NET net:$NETWORK2 gateway:$GW2"
echo

echo "setting route via table cnc"
$IP route replace $NETWORK1 dev $IF1 via $IP1 table cnc
$IP route replace default dev $IF1 via $GW1 table cnc
echo "setting route via table tel"
$IP route replace $NETWORK2 dev $IF2 via $IP2 table tel
$IP route replace default dev $IF2 via $GW2 table tel

echo "setting default gateway"
$IP route replace default via $GW1

echo "setting ip rule"
$IP rule del from $IP1
$IP rule add from $IP1 table cnc
$IP rule del from $IP2
$IP rule add from $IP2 table tel
}



以上script作用是,分别 获取两个网卡的ip, netmask, gateway. 然后定义一个电信的路由表,一个网通的路由表.最后一步非常重要, 配置从哪里进来就哪里回去的策略路由.



l 修改 /etc/sysconfig/network-scripts/ifup-post, 使其在网卡启动时自动执行策略路由函数


以下粗体字部分为新增


#add route policy


policy_route



# Notify programs that have requested notification


do_netreport



l 设置电信部分固定路由


由于本机设置缺省网关为网通网关, 部分需要主动向外的电信访问要设置固定路由.


cat >> /etc/sysconfig/network-scripts/route-eth0


61.143.210.0/24 dev eth0 via $GW2


202.96.128.0/24 dev eth0 via $GW2


60.190.167.0/24 dev eth0 via $GW2


61.143.224.0/24 dev eth0 via $GW2


125.90.204.0/24 dev eth0 via $GW2


59.32.232.0/24 dev eth0 via $GW2


218.71.140.0/24 dev eth0 via $GW2







l 最后确保新增/修改过 文件有可执行属性


chmod +x /etc/sysconfig/network-scripts/*




















以上步骤都完成之后就可以重启网络( /etc/init.d/network restart ) ,当然了,reboot也是可以的.呵呵




2008年12月18日星期四

[转]优酷网视频存储架构

仅供参考.我就不发表什么意见了,大家来讨论下..
运维的同学都要看看.


视频分享网站总会面对这样两个问题:视频资源能否吸引网民以及视频浏览是否顺畅?中国互联网协会互联网数据中心发布的《2008上半年视频网站数据》显示,2008年上半年,优酷网月度总访问时长突破1.1亿小时,通过与全行业的浏览时长比对,优酷网占据的时长份额已超过50%。Gomez中国网站用户体验排行榜显示,2008 年7月1日到2008年7月31日,优酷网的平均响应时间是2.78秒。

1.1亿小时与2.78秒,正是这两个长短对比鲜明的数据,充分体现出优酷网“快者为王”的经营理念。近日,记者独家采访了优酷网CTO姚键,试图从技术方面揭密优酷网的快字诀。

一切为了性能

“2007年,优酷网的用户访问量提升了25倍。”姚键说起这个增长仍显激动,“硬件设备同样有相应的增加。”据记者了解,目前优酷网有近千万个视频资源,以每段视频20MB来计算,大约占据200TB的存储空间。优酷网采用服务器直连式存储(DAS)架构,即一台服务器只连接一台存储阵列。姚键透露,优酷网目前有数千台服务器。

优酷网的服务器主要来自戴尔,还有一部分来自惠普。优酷网引进的戴尔服务器主要以 PowerEdge 1950与PowerEdge 860为主,存储阵列以戴尔MD1000为主。如上图所示,优酷网将PowerEdge 1950作为Web服务器和流媒体服务器,分别服务于页面系统与视频系统。另外,还有一些服务器作为转码服务器,将用户上传的视频进行解码和再编码,最后做成统一的FLV格式。在存储层面,优酷网主要利用戴尔MD1000+ PowerEdge 860的组合,两者以DAS的方式相连,作为一个存储单元。

在回答记者提出的为何没使用网络存储,如SAN等架构时,姚键表示:“用户访问量持续成倍增长,对系统的性能、成本和可扩展性都造成了很大压力。采用DAS存储可以更好地满足对性能的需要。如果采用SAN存储,不仅成本增加会十分明显,而且在系统变得日益庞大时,性能也会出现瓶颈。”

“为了提高用户的访问速度,我们想了很多办法。”姚键表示,“我们甚至都不用RAID。不采用RAID技术,可以节省很大的存储空间,同时减少成本,而且能够提供更好的I/O性能。”据悉,目前优酷网的存储系统利用率都在90%以上。不用 RAID是否会给视频数据的安全带来不良后果?姚键表示:“由于优酷网采用了自建的内容分发网络(CDN)技术,所有视频在不同的城市都有副本,所以不用担心数据的安全性。即使某地的一段视频发生了损坏,用户也可由实时的调度系统引导至其他CDN站点进行视频浏览。在优酷网的内容分发网络中,局部失效不影响整体访问,实际上比存储网络的安全性更高。”

更大范围内的分级存储

自建的调度系统是优酷网实现快速访问体验的核心。优酷网将所有的服务器和存储设备分布在全国20多个CDN站点中,方便当地用户就近访问,以获得更快的视频体验。

不像其他应用可提前计划,互联网访问具有很大的不可预知性,很难预测什么视频在哪段时间的访问会突然增加。因此,实时有效的调度系统就显得非常关键。在网民访问优酷网的视频时,调度系统会根据该视频原本发布所在的位置、用户IP地址等信息安排网民就近访问,并会参考该站点的设备是否出现损坏、该地区是否是访问热点等因素,以便使用户的浏览速度达到最快。正是有了高效的调度系统,优酷网才可以将 90%以上的带宽都提供给用户,而其他CDN系统提供给用户的带宽通常只有70%~80%。

“优酷网所有的视频在一周之内会被用户访问一遍。”姚键说,“因此,优酷网的数据区分在线、离线的意义不大,更不用像其他行业那样要把部分历史数据进行归档处理。”事实上,优酷网对视频信息也会区别对待,只是区分的标准在于访问热度。访问频率高的视频会根据访问用户地址在各CDN站点间重新分布,并且会存放在SAS硬盘上,而冷门视频则会存放在速率稍慢的SATA硬盘上。

用户连线

优酷网CTO姚键

技术是互联网的生命。由于设备急速增加,我们非常在意系统的成本、性能与可扩展性。我们没有使用最先进、最贵的系统,就像Google使用自己的文件系统一样,不在乎贵不贵,而在乎是否合理运用。每台服务器或存储系统配多少块硬盘,文件块的大小为多少,我们都会做详细测试,以实现更佳的性能配置。

2008年12月10日星期三

[转] MySQL 中 GROUP BY 基本实现原理

原文地址:http://www.jianzhaoyang.com/database/mysql_group_by_implement

又是一篇讲原理的文章,看了之后就知道该如何优化group by的sql语句了.

正文如下:
之前连着写了几篇关于 MySQL 中常用操作的一些基本实现原理,如,MySQL ORDER BY,MySQL Join,这次再写一篇 MySQL 中 GROUP BY 的基本实现原理。

由于 GROUP BY 实际上也同样会进行排序操作,而且与 ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作。当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在GROUP BY 的实现过程中,与 ORDER BY 一样也可以利用到索引。

在 MySQL 中,GROUP BY 的实现同样有多种(三种)方式,其中有两种方式会利用现有的索引信息来完成 GROUP BY,另外一种为完全无法使用索引的场景下使用。下面我们分别针对这三种实现方式做一个分析。

1.使用松散(Loose)索引扫描实现 GROUP BY

何谓松散索引扫描实现 GROUP BY 呢?实际上就是当 MySQL 完全利用索引扫描来实现 GROUP BY 的时候,并不需要扫描所有满足条件的索引键即可完成操作得出结果。

下面我们通过一个示例来描述松散索引扫描实现 GROUP BY,在示例之前我们需要首先调整一下 group_message 表的索引,将 gmt_create 字段添加到 group_id 和 user_id 字段的索引中:


sky@localhost : example 08:49:45> create index idx_gid_uid_gc
-> on group_message(group_id,user_id,gmt_create);
Query OK, rows affected (0.03 sec)
Records: 96 Duplicates: 0 Warnings: 0

sky@localhost : example 09:07:30> drop index idx_group_message_gid_uid
-> on group_message;
Query OK, 96 rows affected (0.02 sec)
Records: 96 Duplicates: 0 Warnings: 0

然后再看如下 Query 的执行计划:


sky@localhost : example 09:26:15> EXPLAIN
-> SELECT user_id,max(gmt_create)
-> FROM group_message
-> WHERE group_id < 10
-> GROUP BY group_id,user_id\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: group_message
type: range
possible_keys: idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 8
ref: NULL
rows: 4
Extra: Using where; Using index for group-by
1 row in set (0.00 sec)

我们看到在执行计划的 Extra 信息中有信息显示“Using index for group-by”,实际上这就是告诉我们,MySQL Query Optimizer 通过使用松散索引扫描来实现了我们所需要的 GROUP BY 操作。

下面这张图片描绘了扫描过程的大概实现:



要利用到松散索引扫描实现 GROUP BY,需要至少满足以下几个条件:
◆GROUP BY 条件字段必须在同一个索引中最前面的连续位置;
◆在使用GROUP BY 的同时,只能使用 MAX 和 MIN 这两个聚合函数;
◆如果引用到了该索引中 GROUP BY 条件之外的字段条件的时候,必须以常量形式存在;

为什么松散索引扫描的效率会很高?
因为在没有WHERE子句,也就是必须经过全索引扫描的时候, 松散索引扫描需要读取的键值数量与分组的组数量一样多,也就是说比实际存在的键值数目要少很多。而在WHERE子句包含范围判断式或者等值表达式的时候, 松散索引扫描查找满足范围条件的每个组的第1个关键字,并且再次读取尽可能最少数量的关键字。

2.使用紧凑(Tight)索引扫描实现 GROUP BY
紧凑索引扫描实现 GROUP BY 和松散索引扫描的区别主要在于他需要在扫描索引的时候,读取所有满足条件的索引键,然后再根据读取恶的数据来完成 GROUP BY 操作得到相应结果。


sky@localhost : example 08:55:14> EXPLAIN
-> SELECT max(gmt_create)
-> FROM group_message
-> WHERE group_id = 2
-> GROUP BY user_id\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: group_message
type: ref
possible_keys: idx_group_message_gid_uid,idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 4
ref: const
rows: 4
Extra: Using where; Using index
1 row in set (0.01 sec)

这时候的执行计划的 Extra 信息中已经没有“Using index for group-by”了,但并不是说 MySQL 的 GROUP BY 操作并不是通过索引完成的,只不过是需要访问 WHERE 条件所限定的所有索引键信息之后才能得出结果。这就是通过紧凑索引扫描来实现 GROUP BY 的执行计划输出信息。

下面这张图片展示了大概的整个执行过程:



在 MySQL 中,MySQL Query Optimizer 首先会选择尝试通过松散索引扫描来实现 GROUP BY 操作,当发现某些情况无法满足松散索引扫描实现 GROUP BY 的要求之后,才会尝试通过紧凑索引扫描来实现。

当 GROUP BY 条件字段并不连续或者不是索引前缀部分的时候,MySQL Query Optimizer 无法使用松散索引扫描,设置无法直接通过索引完成 GROUP BY 操作,因为缺失的索引键信息无法得到。但是,如果 Query 语句中存在一个常量值来引用缺失的索引键,则可以使用紧凑索引扫描完成 GROUP BY 操作,因为常量填充了搜索关键字中的“差距”,可以形成完整的索引前缀。这些索引前缀可以用于索引查找。而如果需要排序GROUP BY结果,并且能够形成索引前缀的搜索关键字,MySQL还可以避免额外的排序操作,因为使用有顺序的索引的前缀进行搜索已经按顺序检索到了所有关键字。

3.使用临时表实现 GROUP BY
MySQL 在进行 GROUP BY 操作的时候要想利用所有,必须满足 GROUP BY 的字段必须同时存放于同一个索引中,且该索引是一个有序索引(如 Hash 索引就不能满足要求)。而且,并不只是如此,是否能够利用索引来实现 GROUP BY 还与使用的聚合函数也有关系。

前面两种 GROUP BY 的实现方式都是在有可以利用的索引的时候使用的,当 MySQL Query Optimizer 无法找到合适的索引可以利用的时候,就不得不先读取需要的数据,然后通过临时表来完成 GROUP BY 操作。


sky@localhost : example 09:02:40> EXPLAIN
-> SELECT max(gmt_create)
-> FROM group_message
-> WHERE group_id > 1 and group_id < 10
-> GROUP BY user_id\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: group_message
type: range
possible_keys: idx_group_message_gid_uid,idx_gid_uid_gc
key: idx_gid_uid_gc
key_len: 4
ref: NULL
rows: 32
Extra: Using where; Using index; Using temporary; Using filesort

这次的执行计划非常明显的告诉我们 MySQL 通过索引找到了我们需要的数据,然后创建了临时表,又进行了排序操作,才得到我们需要的 GROUP BY 结果。整个执行过程大概如下图所展示:

当 MySQL Query Optimizer 发现仅仅通过索引扫描并不能直接得到 GROUP BY 的结果之后,他就不得不选择通过使用临时表然后再排序的方式来实现 GROUP BY了。

在这样示例中即是这样的情况。 group_id 并不是一个常量条件,而是一个范围,而且 GROUP BY 字段为 user_id。所以 MySQL 无法根据索引的顺序来帮助 GROUP BY 的实现,只能先通过索引范围扫描得到需要的数据,然后将数据存入临时表,然后再进行排序和分组操作来完成 GROUP BY。

2008年12月9日星期二

[转]亿级数据的高并发通用搜索引擎架构设计

原文地址: http://blog.s135.com/post/385.htm

搜索team的同学看看有什么可以借鉴的地方?

[文章作者:张宴 本文版本:v1.0 最后修改:2008.12.09 转载请注明原文链接:http://blog.s135.com/post/385.htm]

  曾经在七月,写过一篇文章──《基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计》,前公司的分类信息搜索基于此架构,效果明显,甚至将很大一部分带Where条件的MySQL SQL查询,都改用了Sphinx+MySQL搜索。但是,这套架构仍存在局限:一是MySQL本身的并发能力有限,在200~300个并发连接下,查询和更新就比较慢了;二是由于MySQL表的主键与Sphinx索引的ID一一对应,从而无法跨多表建立整站查询,而且新增加类别还得修改配置文件,比较麻烦;三是因为和MySQL集成,无法发挥出Sphinx的优势。

  最近,我设计出了下列这套最新的搜索引擎架构,目前已经写出“搜索查询接口”和“索引更新接口”的beta版。经测试,在一台“奔腾四 3.6GHz 双核CPU、2GB内存”的普通PC机,7000万条索引记录的条件下,“搜索查询接口”平均查询速度为0.0XX秒(查询速度已经达到百度、谷歌、搜狗、中国雅虎等搜索引擎的水平,详见文章末尾的“附2”),并且能够支撑高达5000的并发连接;而“索引更新接口”进行数据分析、入队列、返回信息给用户的全过程,高达1500 Requests/Sec。

  “队列控制器”这一部分是核心,它要控制队列读取,更新MySQL主表与增量表,更新搜索引擎数据存储层Tokyo Tyrant,准实时(1分钟内)完成更新Sphinx增量索引,定期合并Sphinx索引。我预计在这周写出beta版。

点击在新窗口中浏览此图片

  图示说明:
  1、搜索查询接口:
  ①、Web应用服务器通过HTTP POST/GET方式,将搜索关键字等条件,传递给搜索引擎服务器的search.php接口;
  ②③、search.php通过Sphinx的API(我根据最新的Sphinx 0.9.9-rc1 API,改写了一个C语言的PHP扩展sphinx.so),查询Sphinx索引服务,取得满足查询条件的搜索引擎唯一ID(15位搜索唯一ID:前5位类别ID+后10位原数据表主键ID)列表;
  ④⑤、search.php将这些ID号作为key,通过Memcache协议一次性从Tokyo Tyrant中mget取回ID号对应的文本数据。
  ⑥⑦、search.php将搜索结果集,按查询条件,进行摘要和关键字高亮显示处理,以JSON格式或XML格式返回给Web应用服务器。

  2、索引更新接口:
  ⑴、Web应用服务器通过HTTP POST/GET方式,将要增加、删除、更新的内容告知搜索服务器的update.php接口;
  ⑵、update.php将接收到的信息处理后,写入TT高速队列(我基于Tokyo Tyrant做的一个队列系统);
  注:这两步的速度可达到1500次请求/秒以上,可应对6000万PV的搜索索引更新调用。

  3、搜索索引与数据存储控制:
  ㈠、“队列控制器”守护进程从TT高速队列中循环读取信息(每次50条,直到末尾);
  ㈡、“队列控制器”将读取出的信息写入搜索引擎数据存储层Tokyo Tyrant;
  ㈢、“队列控制器”将读取出的信息异步写入MySQL主表(这张主表按500万条记录进行分区,仅作为数据永久性备份用);
  ㈣、“队列控制器”将读取出的信息写入MySQL增量表;
  ㈤、“队列控制器”在1分钟内,触发Sphinx更新增量索引,Sphinx的indexer会将MySQL增量表作为数据源,建立增量索引。Sphinx的增量索引和作为数据源的MySQL增量表成对应关系;
  ㈥、“队列控制器”每间隔3小时,短暂停止从TT高速队列中读取信息,并触发Sphinx将增量索引合并入主索引(这个过程非常快),同时清空MySQL增量表(保证了MySQL增量表的记录数始终只有几千条至几十万条,大大加快Sphinx增量索引更新速度),然后恢复从TT高速队列中取出数据,写入MySQL增量表。

  本架构使用的开源软件:
  1、Sphinx 0.9.9-rc1
  2、Tokyo Tyrant 1.1.9
  3、MySQL 5.1.30
  4、Nginx 0.7.22
  5、PHP 5.2.6

  本架构自主研发的程序:
  1、搜索查询接口(search.php)
  2、索引更新接口(update.php)
  3、队列控制器
  4、Sphinx 0.9.9-rc1 API的PHP扩展(sphinx.so)
  5、基于Tokyo Tyrant的高速队列系统


  附1:MySQL FullText、Lucene搜索、Sphinx搜索的第三方对比结果:
  1、查询速度:
  MySQL FullText最慢,Lucene、Sphinx查询速度不相上下,Sphinx稍占优势。
  点击在新窗口中浏览此图片

  2、建索引速度:
  Sphinx建索引速度是最快的,比Lucene快9倍以上。因此,Sphinx非常适合做准实时搜索引擎。

  3、详细对比数据见以下PDF文档:  

下载文件 (已下载 21 次)


2008年12月8日星期一

[转]这样的程序员创业有戏

原文地址 http://column.iresearch.cn/u/lei_jun/archives/2008/43765.shtml 雷军

 

文章提到5点对刚入门的程序员的要求.

1 只有真正喜欢才能写好程序

基本上每一个行业都一样,只有做喜欢的事情才能做好.

2 把程序当成艺术品,象写诗一样来写代码

这点我非常同意,代码不是光给自己看的. 写出大家都能看懂,都能从中学习到东西的代码才是好代码.

3 必须写够十万行代码,不要心存侥幸

基本功很重要!

4 时刻保持好奇心

世界变化太快了,跟不上就要落后

5 不要局限在技术本身,多花点精力关注用户

不单单关注用户,关注其他方面也很重要. steve jobs把他从书法学到的东西融汇到苹果公司来,取得了巨大的成功.

正文:


这是我为12月4日开始的“2008软件开发2.0技术大会”准备的讲稿。到了现场,我发现这个讲稿对现场近千人的技术高手不适合,只好临时讲了移动互联网的趋势。


 致刚入门的程序员五点建议


 每个IT企业,尤其是初创企业,非常苦恼:找不到好的程序员。现在大学、软件学院及各种培训机构,每年培养几十万的程序员,毕业的每个人都有同样困恼:找不到好的工作。问题出在哪里呢?其实,企业需要的是不是刚会写程序的人,需要来了就能干活的人,尤其能把活干好的人。而刚毕业的大学生多半刚学会如何写程序,的确很难企业需求。


企业到底需要什么样的程序员,一个刚入门的程序员如何成为企业需要的高手呢?还有很多程序员问我,“我需要具备什么样的能力就可以去创业?”我一直在琢磨类似的问题。我自己写过十年程序,也在金山管理过一千多人的研发队伍,最近也在做天使投资,仔细总结了如下五点建议与所有程序员分享。


 建议一、只有真正喜欢才能写好程序


 喜欢写程序,做程序员就是上天堂;


不喜欢写程序,做程序员就是下地狱。


程序员需要整天趴在电脑前,经常没日没夜的,非常辛苦,而且工作来不得半点虚假,少写一个标点符号都不行。喜欢的人,日子过得非常开心,每写一行代码,都会有新的成就,尤其当自己的作品被广泛应用的时候,那种自豪感油然而起。不喜欢的人,坐在电脑前极端无聊,被进度压得喘不过气来,天天为找bug改bug生气。


只有喜欢,只有热爱,才能把程序写好!


我建议不喜欢写程序的人早点转行,不要勉强自己,免得误人误己。


 建议二、把程序当艺术品,象写诗一样来写代码


 现在很少有公司做 codeview (对写好的程序做代码级检查),于是很多人在进度的压力下潦草应付,只要测试通过就算搞定。表面上看,开发速度很快,进度有保障;但实际上,这样的程序连开发者自己都很难读懂,一旦有bug,很难调试,将来维护升级都非常困难。这样的代码多半只能重写,浪费自然严重。


如果每个人写程序的时候当艺术品来写,写每行都认认真真、干干净净的,虽然速度略微慢了一点,但综合的开发成本会低很多。


如何写象诗一样美的代码呢?方法也很简单。


一、买几本经典的编程书,把书上所有例程全部重新写一遍,逐个比较和书上范例的差距,一步一步改善自己编程的风格和技巧。时间长了,自然就能写出象书上例程一样的代码,甚至可以比书上写得好。


二、基础扎实后,多看看Linux 等系统级的源代码,看看高手是如何写的,就有感觉了。


三、通读一下MSDN中所有的资料,这样,“读书破万卷,下笔如有神”。


还有,一定要牢记软件工程的铁律:可能出错的地方一定会出错。每个变量都做初始化,引用每个参数都会做有效性检查,在可能出错的每个地方都会做边界条件检查,这样开发出来的程序一定会稳固很多,就是出错也会很容易修改。野路子出来的高手,一般开发速度很快,但做完后bug很多,经常需要很长时间修改。而真正的高手,追求的境界是 bugfree code(零缺陷代码)。


 建议三、必须写够十万行代码,不要心存侥幸


 程序员象木工一样,熟能生巧。程序员必须写足够代码量的程序,才会有感觉,这是一个苦力活,没有任何捷径可走。


计算机是一门实践性的科学,没有动手能力做支撑,很难做出好的科研成果。我的一个学长是美国卡内基梅隆大学的博士,卡内基梅隆大学计算机系在全世界非常出名,他说每个博士生必须写十万行代码才能毕业,卡内基梅隆大学博士进任何一个大企业基本不用面试。而国内培养大部分的研究生、博士生,动手能力都偏弱。


没有写过足够代码量的,想成为高手是不可能的,只能纸上谈兵!


 建议四、时刻保持好奇心


 计算机技术更新换代非常快,每年都有各种各样的新技术出现。在我过去的职业生涯中,仅编程语言,我就用过 basic, masm, pascal, c++, vba, Delphi, java 等。需要时刻保持好奇心,不断学习各种新的东西,才能在未来的几十年职业生涯中不落伍。你要理解为什么 iPhone 出来很多高手用iPhone,现在一天到晚惦记着换部 gPhone 玩玩。


人的精力有效,高手往往工作压力也比较大,如何在有限的时间内掌握整个行业动态,的确是一个不简单的事情。我的经验是经常看业内的各种技术杂志,参加各种聚会,可以节约很多时间。最重要的是,交几个博学的技术高手,多和他们交流,一定获益匪浅!


 建议五、不要局限在技术本身,多花点精力关注用户


 做到前面几条,就已经是千金难求的高手了。但一个真正的高手需要知道用户需要什么,如何做出让用户满意的产品。


现在的软件研发越来越强烈团队协作,不少团队都配置了专门的需求分析的工程师、用户界面及用户体验的设计师,软件研发的分工越来越细。很多程序员以为只要把技术搞好,不用管用户需求和用户体验。实际上,需求方案及界面方案不可能写得非常细,具体的实施还是程序员自己来实现的。这个时候,好坏的差距很快就体现出来了。


我们写程序的最终目的是满足用户需求,不是简单完成需求规划方案中的功能。所以,程序员一定要认真揣摩用户心理,能明白用户的真实需求。


其次,怎么设计交互界面,让用户觉得好用,用起来舒服,这里面学问很大。我举一个小例子,每个程序窗口右上角都有三个按钮,如最小化、关闭等。乔布斯觉得不好看,不易用,他提出改用红绿蓝的交通灯。这样修改后,果然 Mac OS 漂亮和易用了很多。


目前互联网和手机上的应用开发,都非常强调小团队研发。这样研发模式速度会快很多,但对程序员的综合素质的要求也就更高了。


我强烈建议程序员不要仅仅局限在技术本事,还需要多点精力考虑和用户相关的问题,学会洞察用户的需求,并努力设计好用易用的产品。做着这点的程序高手,创业成算就很大了。


 这些就是我说的《创业十大标准》中提到的“技术过硬”要求。


这样的技术高手,如果捕捉到合适的产品方向,并且具备一定带团队的能力,创业成功机会很大!事实上,绝大部分创业的技术公司,创始人都是这样的人!比如迅雷的邹胜龙和程浩,UCWEB的何小鹏和梁捷等。


 程序员系列:


    《我十年的程序员生涯》


    《我写BITLOK那七年


    《阳光灿烂的日子》


    《致刚入门的程序员五点建议》


 直接登录 www.leijun.com 访问雷军博客



 

2008年12月6日星期六

一则svn使用故障处理

今天发现其中一台视频转换机器的svn updae出错

svn: Can't convert string from native encoding to 'UTF-8':
svn: ?\232?\182?\133?\231?\130?\171?\231?\154?\132Breaking ?\232?\161?\151?\232?\136?\158 ?\229?\176?\145?\229?\185?\180 POPPIN ?\229?\165?\179?\231?\148?\159 NEWSTYLE ?\232?\177?\134?\232?\177?\134.txt


 

开始时候以为是系统变量设置不对

echo $LANG
en_US.en


这个跟其他svn 正常的视频转换机器是一样的.

 

然后尝试svn checkout 一份到另外一个目录 A, 再执行update操作, 一切正常..

于是将目录A 中所有文件rync到原目录中..

原目录中再执行svn update, 还是依旧出错.

于是,在原目录中ls一下,发现有一个 中文名的txt,遂删除之.. svn update 恢复正常.

分析一下,svn的出错信息里面原来已经提示了这个文件了.由于是乱码,所以看不懂..

总结, 没有必要的话,不要在svn 仓库目录里面增加不在svn上的文件.特别是不要有中文文件名.

2008年11月24日星期一

不要轻信PHP_SELF

看了tingo发的文章,PHP中$_SERVER的详细参数与说明, 有感而发..

我们编程的时候要紧记,任何用户端的输入都是不可靠的.





if (isset($_REQUEST['submitted']) && $_REQUEST['submitted'] == '1') {
echo "Form submitted!";
}
?>







看似准确无误的代码,但是暗藏着危险。让我们将其保存为 foo.php ,然后放到 PHP 环境中使用


foo.php/%22%3E%3Cscript%3Ealert('xss')%3C/script%3E%3Cfoo访问,会发现弹出个 Javascript 的 alert -- 这很明显又是个 XSS 的注入漏洞。究其原因,发现是在

echo $_SERVER['PHP_SELF'];这条语句上直接输出了未过滤的值。追根数源,我们看下 PHP 手册的描述

'PHP_SELF' The filename of the currently executing script, relative to the document root. For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar would be /test.php/foo.bar. The __FILE__ constant contains the full path and filename of the current (i.e. included) file. If PHP is running as a command-line processor this variable contains the script name since PHP 4.3.0. Previously it was not available.原因很明确了,原来是 $_SERVER['PHP_SELF'] 虽然“看起来”是服务器提供的环境变量,但这的确和 $_POST 与 $_GET 一样,是可以被用户更改的。

其它类似的变量有很多,比如 $_COOKIE 等(如果用户想“把玩”他们的 cookie,那我们也是没有办法)。解决方案很简单,使用 strip_tagshtmlentities 等此类函数过滤或者转义。

echo htmlentities($_SERVER['PHP_SELF']); 

 

2008年11月18日星期二

[转]Innodb 索引结构了解 - Innodb Index Structure

 虽然不是每个人都是DBA,但是了解一下数据库具体的实现方式,对于大家数据库编程,设计数据库等等都是很有好处的.
Innodb 里面,primary key是非常重要的,其他index是依赖primary key实现的.即使建表的时候没有定义primary key,mysql也会自己建立/维护一个隐藏的primary key.



Innodb 索引结构了解 - Innodb Index Structure








Innodb 作为 MySQL 中使用最为广泛的 事务型存储引擎,不仅在事务实现数据版本控制方面和其他存储引擎有一定的区别,其数据结构也是以非常有特点的方式存储的。

每个Innodb表的数据其实可以说就是以一个树型(B-Tree)结构存储的,表的数据和主键(Primary Key)共同组成了一个索引结构,也就是我们常说的Innodb的Clustered Primary Key。在这个Clustered Primary Key中,Leaf Nodes其实就是实际的表记录,我们常规理解上的索引信息全部在Branch Nodes上面。

除了Clustered Primary Key之外的其他所有索引在Innodb中被称为Secondary Index。Secondary Index就和普通的B-Tree索引差不多了,只不过在Secondary Index的所有Leaf Nodes上面同时包含了所指向数据记录的主键信息,而不是直接指向数据记录的位置信息。

所以,在 Innodb 中,如果主键值占用存储空间较大的话,会直接影响整个存储 Innodb 表所需要的物理空间,同时也会直接影响到 Innodb 的查询性能。

下面是画的一张 Innodb 索引基本结构图,包括 Primary Key 和 Secondary Index 两种索引的比较。

innodb_index_structure

原文出自: Innodb 索引结构了解 - Innodb Index Structure


 

 


2008年11月12日星期三

一个不错的mysql配置工具

网上找到一个不错的shell sctipt, 它可以自动给出一些对于当前mysql server配置的建议值,譬如key_buffer应该增大之类的.

 

有兴趣的同学可以试一下,不过记住一句话,尽信书不如无书.

 

shell script 文件下载

[转]Linux中如何让进程在后台运行

相信熟悉系统管理的同学都知道命令后加& 可以将命令放在后台运行. 但是你还知道几种可以把命令放在后台运行的方法以及他们的异同呢? 

下文可以给大家一定的启发,有许多方法可以达到目的的时候,我们该如何去选择.

 

Author:NinGoo posted on NinGoo.net 

在Linux中,如果要让进程在后台运行,一般情况下,我们在命令后面加上&即可,实际上,这样是将命令放入到一个作业队列中了:
$ ./test.sh &
[1] 17208

$ jobs -l
[1]+ 17208 Running ./test.sh &

对于已经在前台执行的命令,也可以重新放到后台执行,首先按ctrl+z暂停已经运行的进程,然后使用bg命令将停止的作业放到后台运行:
$ ./test.sh
[1]+ Stopped ./test.sh

$ bg %1
[1]+ ./test.sh &

$ jobs -l
[1]+ 22794 Running ./test.sh &

但是如上方到后台执行的进程,其父进程还是当前终端shell的进程,而一旦父进程退出,则会发送hangup信号给所有子进程,子进程收到hangup以后也会退出。如果我们要在退出shell的时候继续运行进程,则需要使用nohup忽略hangup信号,或者setsid将将父进程设为init进程(进程号为1)
$ echo $$
21734

$ nohup ./test.sh &
[1] 29016

$ ps -ef | grep test
515 29710 21734 0 11:47 pts/12 00:00:00 /bin/sh ./test.sh
515 29713 21734 0 11:47 pts/12 00:00:00 grep test

$ setsid ./test.sh &
[1] 409

$ ps -ef | grep test
515 410 1 0 11:49 ? 00:00:00 /bin/sh ./test.sh
515 413 21734 0 11:49 pts/12 00:00:00 grep test

上面的试验演示了使用nohup/setsid加上&使进程在后台运行,同时不受当前shell退出的影响。那么对于已经在后台运行的进程,该怎么办呢?可以使用disown命令:
$ ./test.sh &
[1] 2539

$ jobs -l
[1]+ 2539 Running ./test.sh &

$ disown -h %1

$ ps -ef | grep test
515 410 1 0 11:49 ? 00:00:00 /bin/sh ./test.sh
515 2542 21734 0 11:52 pts/12 00:00:00 grep test

另外还有一种方法,即使将进程在一个subshell中执行,其实这和setsid异曲同工。方法很简单,将命令用括号() 括起来即可:
$ (./test.sh &)

$ ps -ef | grep test
515 410 1 0 11:49 ? 00:00:00 /bin/sh ./test.sh
515 12483 21734 0 11:59 pts/12 00:00:00 grep test

注:本文试验环境为Red Hat Enterprise Linux AS release 4 (Nahant Update 5),shell为/bin/bash,不同的OS和shell可能命令有些不一样。例如AIX的ksh,没有disown,但是可以使用nohup -p PID来获得disown同样的效果。

还有一种更加强大的方式是使用screen,首先创建一个断开模式的虚拟终端,然后用-r选项重新连接这个虚拟终端,在其中执行的任何命令,都能达到nohup的效果,这在有多个命令需要在后台连续执行的时候比较方便:
$ screen -dmS screen_test

$ screen -list
There is a screen on:
27963.screen_test (Detached)
1 Socket in /tmp/uscreens/S-jiangfeng.

$ screen -r screen_test


原文: http://www.ningoo.net/html/2008/how_to_run_processes_on_background_in_linux.html

2008年11月7日星期五

[转载]大型网站运维探讨和心得

看到一篇不错的心得体会;相信我们做技术的都会有或多或少的担忧自己的未来职业发展:

今天看到一篇心得体会,转过来和大家一起探讨一下:
特别是关于个人素质方面,我觉得讲得很不错, 所有技术部同学都应该认真看看,特别是运维组的同学.

一、什么是大型网站运维?
首先明确一下,全文所讲的”运维“是指:大型网站运维,与其它运维的区别还是蛮大的;然后我们再对大型网站与小型网站进行范围定义,此定义主要从运维复杂性角度考虑,如网站规范、知名度、服务器量级、pv量等考虑,其它因素不是重点;因此,我们先定义服务器规模大于1000台,pv每天至少上亿(至少国内排名前10),如sina、baidu、QQ,51.com等等;其它小型网站可能没有真正意义上的运维工程师,这与网站规范不够和成本因素有关,更多的是集合网络、系统、开发工作于一身的“复合性人才”,就如有些公司把一些合同采购都纳入了运维职责范围,还有如IDC网络规划也纳入运维职责。所以,非常重要一定需要明白:运维对其它关联工种必须非常了解熟悉:网络、系统、系统开发、存储,安全,DB等;我在这里所讲的运维工程师就是指专职运维工程师。
我们再来说说一般产品的“出生”流程:
1、首先公司管理层给出指导思想,PM定位市场需求(或copy成熟应用)进行调研、分析、最终给出详细设计。
2、架构师根据产品设计的需求,如pv大小预估、服务器规模、应用架构等因素完成网络规划,架构设计等(基本上对网络变动不大,除非大项目)
3、开发工程师将设计code实现出来、测试工程师对应用进行测试。
4、好,到运维工程师出马了,首先明确一点不是说前三步就与运维工作无关了,恰恰相反,前三步与运维关系很大:应用的前期架构设计、软/硬件资源评估申请采购、应用设计性能隐患及评估、IDC、服务性能\安全调优、服务器系统级优化(与特定应用有关)等都需运维全程参与,并主导整个应用上线项目;运维工程师负责产品服务器上架准备工作,服务器系统安装、网络、IP、通用工具集安装。运维工程师还需要对上线的应用系统架构是否合理、是否具备可扩展性、及安全隐患等因素负责,并负责最后将产品(程序)、网络、系统三者进行拼接并最优化的组合在一起,最终完成产品上线提供用户使用,并周而复使:需求->开发(升级)->测试->上线(性能、安全问题等之前预估外的问题随之慢慢就全出来了)在这里提一点:网站开发模式与传统软件开发完全不一样,网站一天开发上线1~5个升级版本是家常便饭,用户体验为王嘛,如果某个线上问题像M$ 需要1年解决,用户早跑光了;应用上线后,运维工作才刚开始,具体工作可能包括:升级版本上线工作、服务监控、应用状态统计、日常服务状态巡检、突发故障处理、服务日常变更调整、集群管理、服务性能评估优化、数据库管理优化、随着应用PV增减进行应用架构的伸缩、安全、运维开发工作:
a 、尽量将日常机械性手工工作通过工具实现(如服务监控、应用状态统计、服务上线等等),提高效率。
b、解决现实中服务存在的问题,如高可靠性、可扩展性问题等。
c、大规模集群管理工具的开发,如1万台机器如何在1分钟内完成密码修改、或运行指定任务?2000台服务器如何快速安装操作系统?各分布式IDC、存储集群中数PT级的数据如何快速的存储、共享、分析?等一系列挑战都需运维工程师的努力。
在此说明一下其它配合工种情况,在整个项目中,前端应用对于网络/系统工程师来说是黑匣子,同时开发工程师职责只是负责完成应用的功能性开发,并对应用本身性能、安全性等应用本身负责,它不负责或关心网络/系统架构方面事宜,当然软/硬件采购人员等事业部其它同事也不会关心这些问题,各司其职,但项目的核心是运维工程师~!所有其它部门的桥梁。
上面说了很多,我想大家应该对运维有一些概念了,在此打个比方吧,如果我们是一辆高速行驶在高速公路上的汽车,那运维工程师就是司机兼维修工,这个司机不简单,有时需要在高速行驶过程中换轮胎、并根据道路情况换档位、当汽车速度越来越快,汽车本身不能满足高速度时对汽车性能调优或零件升级、高速行进中解决汽车故障及性能问题、时刻关注前方安全问题,并先知先觉的采取规避手段。这就是运维工作~!
最后说一下运维工程师的职责:”确保线上稳定“,看似简单,但实属不容易,运维工程师必须在诸多不利因素中进行权衡:新产品模式对现有架构及技术的冲击、产品高频度的升级带来的线上BUG隐患、运维自动化管理承度不高导致的人为失误、IT行业追求的高效率导致流程执行上的缺失、用户增涨带来的性能及架构上的压力、IT行业宽松的技术管理文化、创新风险、互联网安全性问题等因素,都会是网站稳定的大敌,运维工程师必须把控好这最后一关,需具体高度的责任感、原则性及协调能力,如果能做到各因素的最佳平衡,那就是一名优秀的运维工程师了。
另外在此聊点题外话,我在这里看到有很多人要sina、QQ、baidu,51.com等聊自已的运维方面的经验,其实这对于它们有点免为其难:
a、各公司自已网络架构、规模、或多或少还算是公司的核心秘密,要保密,另外,对于大家所熟知的通用软件、架构,由于很多公司会根据自已实际业务需要,同时因为原版性能、安全性、已知bug、功能等原因,进行过二次开发(如apache,php,mysql),操作系统内核也会根据不同业务类型进行定制的,如某些应用属于运算型、某些是高IO型、或大存储大内存型。根据这些特点进行内核优化定制,如sina就在memcache上进行过二次开发,搞出了一个MemcacheDB,具体做得如何我们不谈,但开源了,是值得称赞的,国内公司对于开源基本上是索取,没有贡献;另外,服务器也不是大家所熟知的型号,根据业务特点,大部份都是找DELL/HP/ibm进行过定制;另外,在分布式储存方面都有自已解决方案,要不就是使用现成开源hadoop等解决方案,或自已开发。但90%都是借鉴google GFS的思想:分布式存储、计算、大表。
b、各公司业务方向不一样,会导致运维模式或方法都不一样,如51.com和baidu运维肯定区别很大,因为他们业务模式决定了其架构、服务器量级、IDC分布、网络结构、通用技术都会不一样,主打新闻门户的sina与主打sns的51.com运维模式差异就非常大,甚至职责都不大一样;但有一点,通用技术及大致架构上都大同小异,大家不要太神化,更多的公司只是玩垒积木的游戏罢了,没什么技术含量。
c、如上面所讲,目前大型网站运维还处于幼年时期理念和经验都比较零散,没有成熟的知识体系,可能具体什么是运维,大家都要先思索一番,或压根没想过,真正讨论也只是运维工作的冰山一角,局限于具体技术细节,或某某著名网站大的框架,真正运维体系化东西没有,这也许是目前网上运维相关资料比较少的原故吧。或者也是国内运维人员比较难招,比较牛的运维工程师比较少见的原因之一吧。

二、运维工作师需要什么样的技能及素质
做为一名运维工程师需要什么样的技能及素质呢,首先说说技能吧,如大家上面所看到,运维是一个集多IT工种技能与一身的岗位,对系统->网络->存储->协议->需求->开发->测试->安全等各环节都需要了解一些,但对于某些环节需熟悉甚至精通,如系统(基本操作系统的熟悉使用,*nix,windows..)、协议、系统开发(日常很重要的工作是自动运维化相关开发、大规模集群工具开发、管理)、通用应用(如lvs、ha、web server、db、中间件、存储等)、网络,IDC拓朴架构;
技能方面总结以下几点:
1、开发能力,这点非常重要,因为运维工具都需要自已开发,开发语言:c/c++(必备其中之一)、perl、python、php(其中之一)、shell(awk,sed,expect….等),需要有过实际开发经验,否则工作会非常痛苦。
2、通用应用方面需要了解:操作系统(目前国内主要是linux、bsd)、webserver相关(nginx,apahe,php,lighttpd,java。。。)、数据库(mysql,oralce)、其它杂七八拉的东东。。。系统优化,高可靠性。。。这些只是加分项,不需必备,可以边工作边慢慢学,这些东西都不难。当然在运维中,有些是有分工偏重点不一样。
3、系统、网络、安全,存储,CDN,DB等需要相当了解,知道其相关原理。
个人素质方面:
1、 沟通能力、团队协作:运维工作跨部门、跨工种工作很多,需善于沟通、并且团队协作能力要强;这应该是现代企业的基本素质要求了,不多说。
2、工作中需胆大心细:胆大才能创新、不走寻常路,特别对于运维这种新的工种,更需创新才能促进发展;心细,运维工程师是网站admin,最高线上权限者,一不小心就会遗憾终生或打入十八层地狱。
3、主动性、执行力、精力旺盛、抗压能力强:由于IT行业的特性,变化快;往往计划赶不上变化,运维工作就更突出了,比如国内各大公司服务器往往是全国各地,哪里便宜性价比高,就那往搬,进行大规模服务迁移(牵扯的服务器成百上千台),这是一个非常头痛的问题;往往时间非常紧迫,如限1周内完成,这种情况下,运维工程师的主动性及执行力就有很高的要求了:计划、方案、服务无缝迁移、机器搬迁上架、环境准备、安全评估、性能评估、基建、各关联部门扯皮,7X24小紧急事故响应等。
4、其它就是一些基本素质了:头脑要灵光、逻辑思维能力强、为人谦虚稳重、亲和力、乐于助人、有大局观。
5、最后一点,做网站运维需要有探索创新精神,通过创新型思维解决现实中的问题,因为这是一个处于幼年的职业(国外也一样,但比国内起步早点),没有成熟体系或方法论可以借鉴,只能靠大家自已摸索努力。

三、怎样才算是一个合格的运维工程师
1、保证服务达到要求的线上标准,如99.9%;保证线上稳定,这是运维工程师的基本责职所在。
2、不断的提升应用的可靠性与健壮性、性能优化、安全提升;这方面非常考验主动性、和创新思维。
3、网站各层面监控、统计的覆盖度,软件、硬件、运行状态,能监控的都需要监控统计,避免监控死角、并能实时了解应用的运转情况。
4、通过创新思维解决运维效率问题;目前各公司大部份运维主要工作还是依赖人工操作干预,需要尽可能的解放双手。
5、运维知识的积累与沉淀、文档的完备性,运维是一个经验性非常强的岗位,好的经验与陷阱都需积累下来,避免重复性范错。
6、计划性和执行力;工作有计划,计划后想法设法达到目标,不找借口。
7、自动化运维;能对日常机械化工作进行提炼、设计并开发成工具、系统,能让系统自动完成的尽量依靠系统;让大家更多的时间用于思考、创新思维、做自已喜欢的事情。
以上只是技术上的一些层面,当然个人意识也是很重要的。

四、运维职业的迷惘、现状与发展前景
运维岗位不像其它岗位,如研发工程师、测试工程师等,有非常明确的职责定位及职业规划,比较有职业认同感与成就感;而运维工作可能给人的感觉是哪方面都了解一些,但又都比上专职工程师更精通、感觉平时被关注度比较低(除非线上出现故障),慢慢的大家就会迷惘,对职业发展产生困惑,为什么会有这种现象呢? 除了职业本身特点外,主要还是因为对运维了解不深入、做得不深入导致;其实这个问题其它岗位也会出现,但我发现运维更典型,更容易出现这个问题;

针对这个问题我谈一下网站运维的现状及发展前景(也在思考中,可能不太深入全面,也请大家斧正补充)

运维现状:
1、处于刚起步的初级阶段,各大公司有此专职,但重视或重要承度不高,可替代性强;小公司更多是由其它岗位来兼顾做这一块工作,没有专职,也不可能做得深入
2、技术层次比较低;主要处于技术探索、积累阶段,没有型成体系化的理念、技术。
3、体力劳动偏大;这个问题主要与第二点有关系,很多事情还是依靠人力进行,没有完成好的提练,对于大规模集群没有成熟的自动化管理方法,在此说明一下,大规模集群与运维工作是息息相关的如果只是百十来台机器,那就没有运维太大的生存空间了。
4、优秀运维人才的极度缺乏;目前各大公司基本上都靠自已培养,这个现状导致行业内运维人才的流动性非常低,非常多好的技术都局限在各大公司内部,如google 50万台机器科学的管理,或者国内互联公司top 10 的一些运维经验,这些经验是非常有价值的东西并决定了一个公司的核心竞争力;这些问题进而导致业内先进运维技术的流通、贯通、与借签,并最终将限制了运维发展。
5、很多优秀的运维经验都掌握在大公司手中;这不在于公司的技术实力,而在于大公司的技术规模、海量PV、硬件规模足够大,如baidu可怕的流量、51.com海量数据~~~~这些因素决定了他们遇到的问题都是其它中/小公司还没有遇到的,或即将遇到。但大公司可能已有很好的解决方案或系统。
发展前景:
1、从行业角度来看,随着中国互联网的高速发展(目前中国网民已跃升为全球第一)、网站规模越来越来大、架构越来越复杂;对专职网站运维工程师、网站架构师的要求会越来越急迫,特别是对有经验的优秀运维人才需求量大,而且是越老越值钱;目前国内基本上都是选择毕业生培养(限于大公司),培养成本高,而且没有经验人才加入会导致公司技术更新缓慢、影响公司的技术发展;当然,毕业生也有好处:白纸一张,可塑性强,比较认同并容易融入企业文化。
2、从个人角度,运维工程师技术含量及要求会越来越高,同时也是对公司应用、架构最了解最熟悉的人、越来越得到重视。
3、网站运维将成为一个融合多学科(网络、系统、开发、安全、应用架构、存储等)的综合性技术岗位,给大家提供一个很好的个人能力与技术广度的发展空间。
4、运维工作的相关经验将会变得非常重要,而且也将成为个人的核心竞争力,具备很好的各层面问题的解决能力及方案提供、全局思考能力等。
5、特长发控和兴趣的培养;由于运维岗位所接触的知识面非常广阔,更容易培养或发挥出个人某些方面的特长或爱好,如内核、网络、开发、数据库等方面,可以做得非常深入精通、成为这方面的专家。
6、如果真要以后不想做运维了,转到其它岗位也比较容易,不会有太大的局限性。当然了,你得真正用心去做。
7、技术发展方向、网站/系统架构师。

五、运维关键技术点解剖
1、 大规模集群管理问题
首先我们先要明确集群的概念,集群不是泛指各功能服务器的总合,而是指为了达到某一目的或功能的服务器、硬盘资源的整合(机器数大于两台),对于应用来说它就是一个整体,目前常规集群可分为:高可用性集群(HA),负载均衡集群(如lvs),分布式储、计算存储集群(DFS,如google gfs ,yahoo hadoop),特定应用集群(某一特定功能服务器组合、如db、cache层等),目前互联网行业主要基于这四种类型;对于前两种类似,如果业务简单、应用上post操作比较少,可以简单的采用四层交换机解决(如f5),达到服务高可用/负责均衡的作用,对于资源紧张的公司也有一些开源解决办法如lvs+ha,非常灵活;对于后两种,那就考验公司技术实力及应用特点了,第三种DFS主要应用于海量数据应用上,如邮件、搜索等应用,特别是搜索要求就更高了,除了简单海量存储,还包括数据挖掘、用户行为分析;如google、yahoo就能保存分析近一年的用户记录数据,而baidu应该少于30天、soguo就更少了。。。这些对于搜索准备性、及用户体验是至关重要的。
接下来,我们再谈谈如何科学的管理集群,有以下关键几点:
I、监控
主要包括故障监控和性能、流量、负载等状态监控,这些监控关系到集群的健康运行,及潜在问题的及时发现与干预;
a、服务故障、状态监控:主要是对服务器自身、上层应用、关联服务数据交互监控;例如针对前端web server,我们就可以有很多种类型的监控,包括应用端口状态监控,便于及时发现服务器或应用本身是否crash、通过icmp包探测服务器健康状态,更上层可能还包括应用各频道业务的监控,常用方法是采用面业特征码进行判断,或对重点页面进行签名,以网站被黑篡改(报警、并自动恢复被篡改数据)等等,这些只是一部份,还有N多监控方式,依应用特点而定,还有一些问题需解决,如集群过大,如何高性能的进行监控也是一个现实问题。
b、其它就是集群状态类的监控或统计,为我们合理管理调优集群提供数据参考、包括服务瓶颈、性能问题、异常流量、攻击等问题。
II、故障管理
a、硬件故障问题;对于成百上千或上万机器的N多集群,服务器死机、硬件故障概率是非常大的,几乎每时每刻都有服务硬件问题,死机、硬盘损坏、电源、内存、交换机。针对这种情况,我们在设计网站架构时需要充分考虑到这些问题,并将其视为常态;更多的依靠应用的冗余机制来规避这种风险,但给系统工程师足够宽裕的处理时间。(如google不是号称同时死800台机器,服务不会受到任何影响吗);这就是考验运维工程师及网站架构师功能的地方了,好的设计能达到google所描述自恢复能力,如gfs,糟糕的设计那就是一台服务器的死机可能会造成大面积服务的连锁故障反映,直接对用户拒绝响应。
b、应用故障问题;可能是某一bug被触发、或某一性能阀值被超越、攻击等情况不一而定,但重要的一点,是要有对这些问题的预防性措施,不能想当然,它不会出问题,如真出问题了,如何应对? 这需要运维工程师平时做足功夫,包括应急响应速度、故障处理的科学性、备用方案的有效等。

III、自动化
自动化:简而言之,就是将我们日常手动进行的一些工作通过工具,系统自动来完成,解放我们的双手及枯燥的重复性劳动,例如:没有工具前,我们安装系统需要一台一台裸机安装,如2000台,可能需要10人/10天,搞烂N张光盘,人力成本更大。。。而现在通过自动化工具,只需几个简单命令就能搞定、还有如机器人类程序,自动完成以往每天人工干预的工作,使其自动完成、汇报结果,并具备一定的专家系统能力,能做一些简单的是/非判断、优化选择等。。。这些好处非常明显不再多说。。。应该说,自动化运维是运维工程师职业化的一个追求,利已利公,虽然这是一个异常艰巨的任务:不断变更的业务、不规范化的应用设计、开发模式、网络架构变更、IDC变更、规范变动等因素,都可能会对现有自动化系统产生影响,所以需要模块化、接口化、变因参数化等因此,自动化相关工作,是运维工程师的核心重点工作之一,也是价值的体现。
五、运维中关键技术点解剖(比较实际,现实中的案例,今天先想出这几条,如大家有其它感觉兴趣的,可以提出,一起交流~)

1 大量高并发网站的设计方案
2 高可靠、高可伸缩性网络架构设计
3 网站安全问题,如何避免被黑?
4 南北互联问题,动态CDN解决方案
5 海量数据存储架构

转自chinaunix

2008年11月6日星期四

[转]expect实现ssh交互

转载至:http://www.hiadmin.com/expect%e5%ae%9e%e7%8e%b0ssh%e8%87%aa%e5%8a%a8%e4%ba%a4%e4%ba%92/

expect实现ssh自动交互
9月 4th, 2008 Posted in shell < by John.Lv >
由于最近刚接手一批oracle数据库服务器,只能使用指定用户oracle进行相关操作。而且ssh没有做public key,并且也没有权限做ssh的public key,使用shell脚本居然问我一次又一次的要密码,怎么脚本自动化?没办法,只能使用expect来实现了。
一般使用ssh的public key的ssh脚本如下:

#!/bin/sh
servers=`cat /etc/hosts | grep -v ^# | grep ^192.168.1 | cut -f1`
username="oracle"
echo exec cmd all...
for server in $servers; do
echo "##########################################"
echo $server
ssh $username@$server $1
echo "##########################################"
done
wait
echo complete!

上面是shell脚本,这里就不多解释了,相信大家都能看明白。$1可以是运行命令也可以执行脚本,随便你,只要你喜欢!
如果不允许或者没有权限使用ssh的public key,那么只能使用expect进行ssh自动交互了

#!/usr/bin/expect
set username "oracle"
#ssh的用户名
set passwd "oracle11"
#ssh的密码
set servers [exec cat /etc/hosts | grep -v ^# | grep ^192.168.1 | cut -f1]
#读取hosts中要访问的主机
foreach server $servers {
#循环
spawn ssh $username@$server "[lindex $argv 0]";
#执行ssh,注意expect中输入的第一个变量用$argv 0表示。
expect "*password: ";
sleep .1;
send "$passwd\r";
#当出现提示输入密码时,自动输入密码
interact;
}

ok,这样指定的一般用户在ssh且不能使用key时就不用一次次输入密码了。

2008年11月5日星期三

msn假死的简单解决办法

原文: http://hi.baidu.com/%C7%E1%C7%E1%B5%E3%B5%E3/blog/item/1c793987719b922fc75cc33f.html

最近msn经常假死,导致系统无反应,要过几秒才恢复,非常讨厌.

于是google一把, 在hosts文件加上如下

127.0.0.1 crl.microsoft.com

 

世界清净了..