UP | HOME

转载2013

Table of Contents

YouTube 架构学习体会

#+BEGIN_HTML
这几天一直在关注和学习一些大型网站的架构,希望有一天自己也能设计一个高并发、高容错的系统并能应用在实践上。今天在网上找架构相关的资料时,看到一个被和谐的视频网站YouTube的架构分析,看了以后觉得自己又向架构走近了一步,于是赶快拿出来与大家一起分享。

YouTube发展迅速,每天超过1亿的视频点击量,但只有很少人在维护站点和确保伸缩性。这点和PlentyOfFish类似,少数人维护庞大系统。是什么原因呢?放心绝对不是靠人品,也不是靠寂寞,下面就来看看YouTube的整体技术架构吧。

平台 

Apache
Python
Linux(SuSe)
MySQL
psyco,一个动态的Python到C的编译器
lighttpd代替Apache做视频查看

状态 

支持每天超过1亿的视频点击量
成立于2005年2月
于2006年3月达到每天3千万的视频点击量
于2006年7月达到每天1亿的视频点击量
2个系统管理员,2个伸缩性软件架构师
2个软件开发工程师,2个网络工程师,1个DBA

Web服务器 

1,NetScaler用于负载均衡和静态内容缓存
2,使用mod_fast_cgi运行Apache
3,使用一个Python应用服务器来处理请求的路由
4,应用服务器与多个数据库和其他信息源交互来获取数据和格式化html页面
5,一般可以通过添加更多的机器来在Web层提高伸缩性
6,Python的Web层代码通常不是性能瓶颈,大部分时间阻塞在RPC
7,Python允许快速而灵活的开发和部署
8,通常每个页面服务少于100毫秒的时间
9,使用psyco(一个类似于JIT编译器的动态的Python到C的编译器)来优化内部循环
10,对于像加密等密集型CPU活动,使用C扩展
11,对于一些开销昂贵的块使用预先生成并缓存的html
12,数据库里使用行级缓存
13,缓存完整的Python对象

14,有些数据被计算出来并发送给各个程序,所以这些值缓存在本地内存中。这是个使用不当的策略。

应用服务器里最快的缓存将预先计算的值发送给所有服务器也花不了多少时间。只需弄一个代理来监听更改,预计算,然后发送。

视频服务

1,花费包括带宽,硬件和能源消耗
2,每个视频由一个迷你集群来host,每个视频被超过一台机器持有
3,使用一个集群意味着:
-更多的硬盘来持有内容意味着更快的速度
-failover。如果一台机器出故障了,另外的机器可以继续服务
-在线备份
4,使用lighttpd作为Web服务器来提供视频服务:
-Apache开销太大
-使用epoll来等待多个fds
-从单进程配置转变为多进程配置来处理更多的连接
5,大部分流行的内容移到CDN:
-CDN在多个地方备份内容,这样内容离用户更近的机会就会更高
-CDN机器经常内存不足,因为内容太流行以致很少有内容进出内存的颠簸
6,不太流行的内容(每天1-20浏览次数)在许多colo站点使用YouTube服务器
-长尾效应。一个视频可以有多个播放,但是许多视频正在播放。随机硬盘块被访问
-在这种情况下缓存不会很好,所以花钱在更多的缓存上可能没太大意义。
-调节RAID控制并注意其他低级问题
-调节每台机器上的内存,不要太多也不要太少 

视频服务关键点

1,保持简单和廉价
2,保持简单网络路径,在内容和用户间不要有太多设备
3,使用常用硬件,昂贵的硬件很难找到帮助文档
4,使用简单而常见的工具,使用构建在Linux里或之上的大部分工具

5,很好的处理随机查找(SATA,tweaks)

缩略图服务

1,做到高效令人惊奇的难
2,每个视频大概4张缩略图,所以缩略图比视频多很多
3,缩略图仅仅host在几个机器上
4,持有一些小东西所遇到的问题:
-OS级别的大量的硬盘查找和inode和页面缓存问题
-单目录文件限制,特别是Ext3,后来移到多分层的结构。内核2.6的最近改进可能让 Ext3允许大目录,但在一个文件系统里存储大量文件不是个好主意
-每秒大量的请求,因为Web页面可能在页面上显示60个缩略图
-在这种高负载下Apache表现的非常糟糕
-在Apache前端使用squid,这种方式工作了一段时间,但是由于负载继续增加而以失败告终。它让每秒300个请求变为20个
-尝试使用lighttpd但是由于使用单线程它陷于困境。遇到多进程的问题,因为它们各自保持自己单独的缓存
-如此多的图片以致一台新机器只能接管24小时
-重启机器需要6-10小时来缓存
5,为了解决所有这些问题YouTube开始使用Google的BigTable,一个分布式数据存储:
-避免小文件问题,因为它将文件收集到一起
-快,错误容忍
-更低的延迟,因为它使用分布式多级缓存,该缓存与多个不同collocation站点工作
-更多信息参考Google Architecture,GoogleTalk Architecture和BigTable

数据库 

1,早期
-使用MySQL来存储元数据,如用户,tags和描述
-使用一整个10硬盘的RAID 10来存储数据
-依赖于信用卡所以YouTube租用硬件
-YouTube经过一个常见的革命:单服务器,然后单master和多read slaves,然后数据库分区,然后sharding方式
-痛苦与备份延迟。master数据库是多线程的并且运行在一个大机器上所以它可以处理许多工作,slaves是单线程的并且通常运行在小一些的服务器上并且备份是异步的,所以slaves会远远落后于master
-更新引起缓存失效,硬盘的慢I/O导致慢备份
-使用备份架构需要花费大量的money来获得增加的写性能
-YouTube的一个解决方案是通过把数据分成两个集群来将传输分出优先次序:一个视频查看池和一个一般的集群
2,后期
-数据库分区
-分成shards,不同的用户指定到不同的shards
-扩散读写
-更好的缓存位置意味着更少的IO
-导致硬件减少30%
-备份延迟降低到0

-现在可以任意提升数据库的伸缩性

数据中心策略

1,依赖于信用卡,所以最初只能使用受管主机提供商
2,受管主机提供商不能提供伸缩性,不能控制硬件或使用良好的网络协议
3,YouTube改为使用colocation arrangement。现在YouTube可以自定义所有东西并且协定自己的契约
4,使用5到6个数据中心加CDN
5,视频来自任意的数据中心,不是最近的匹配或其他什么。如果一个视频足够流行则移到CDN
6,依赖于视频带宽而不是真正的延迟。可以来自任何colo
7,图片延迟很严重,特别是当一个页面有60张图片时

8,使用BigTable将图片备份到不同的数据中心,代码查看谁是最近的

学到的东西

1,Stall for time。创造性和风险性的技巧让你在短期内解决问题而同时你会发现长期的解决方案
2,Proioritize。找出你的服务中核心的东西并对你的资源分出优先级别
3,Pick your battles。别怕将你的核心服务分出去。YouTube使用CDN来分布它们最流行的内容。创建自己的网络将花费太多时间和太多money
4,Keep it simple!简单允许你更快的重新架构来回应问题
5,Shard。Sharding帮助隔离存储,CPU,内存和IO,不仅仅是获得更多的写性能
6,Constant iteration on bottlenecks:
-软件:DB,缓存
-OS:硬盘I/O
-硬件:内存,RAID
7,You succeed as a team。拥有一个跨越条律的了解整个系统并知道系统内部是什么样的团队,如安装打印机,安装机器,安装网络等等的人。

文章出处:http://www.itivy.com/ivy/archive/2011/3/6/634350416046298451.html

2013.07.25 push
#+END_HTML

“三个故事” 告诉了你许多

#+BEGIN_HTML
(一)
甲不喜欢吃鸡蛋,每次发了鸡蛋都给乙吃。
刚开始乙很感谢,久而久之便习惯了。
习惯了,便理所当然了。
于是,直到有一天,甲将鸡蛋给了丙,乙就不爽了。
她忘记了这个鸡蛋本来就是甲的,甲想给谁都可以。为此,她们大吵一架,从此绝交。

(二)
有一年,很热的夏天,一队人出去漂流。
女孩的拖鞋在玩水的时候,把拖鞋掉下去了,沉底了。
到岸边的时候,全是晒的很烫的鹅卵石,他们要走很长的一段路。
于是,女孩儿就向别人寻求帮忙,可是谁都只有一双拖鞋。
女孩心里很不爽,因为她习惯了向别人求助,而只要撒娇就会得到满意地答复。
可是这次却没有。她忽然觉得这些人都不好,都见死不救。
后来,有一个男孩将自己的拖鞋给了她,然后自己赤脚在那晒得滚烫的鹅卵石上走了很久的路。
还自嘲说是铁板烧。
女孩表示感谢,男孩说,你要记住,没有谁是必须要帮你的。
帮你是出于交情,不帮你是应该。
女孩记住了男孩的话,自此以后学会了对施以援手的人铭记在心,并给以更大的回报。
很多时候,我们总是希望得到别人的好。
一开始,感激不尽。
可是久了,便是习惯了。
习惯了一个人对你的好,便认为是理所应当的。
有一天不对你好了,你便觉得怨怼。
其实,不是别人不好了,而是我们的要求变多了。
习惯了得到,便忘记了感恩。

(三)
傍晚,一只羊独自在山坡上玩。
突然从树木中窜出一只狼来,要吃羊,羊跳起来,拼命用角抵抗,并大声向朋友们求救。
牛在树丛中向这个地方望了一眼,发现是狼,跑走了;
马低头一看,发现是狼,一溜烟跑了;
驴停下脚步,发现是狼,悄悄溜下山坡;
猪经过这里,发现是狼,冲下山坡;
兔子一听,更是一箭一般离去。
山下的狗听见羊的呼喊,急忙奔上坡来,从草丛中闪出,一下咬住了狼的脖子,
狼疼得直叫唤,趁狗换气时,怆惶逃走了。
回到家,朋友都来了,
牛说:你怎么不告诉我?我的角可以剜出狼的肠子。
马说:你怎么不告诉我?我的蹄子能踢碎狼的脑袋。
驴说:你怎么不告诉我?我一声吼叫,吓破狼的胆。
猪说:你怎么不告诉我?我用嘴一拱,就让它摔下山去。
兔子说:你怎么不告诉我?我跑得快,可以传信呀。
在这闹嚷嚷的一群中,唯独没有狗。
真正的友谊,不是花言巧语,而是关键时候拉你的那只手。
那些整日围在你身边,让你有些许小欢喜的朋友,不一定是真正的朋友。
而那些看似远离,实际上时刻关注着你的人,在你快乐的时候,不去奉承你;
你在你需要的时候,默默为你付出、关心你的人,那才是真正的朋友。

三个故事的出处已无从考证,觉得说的挺有道理的有copy过来了。

2013.09.02 push
#+END_HTML

FreeBSD10的几个新特性

#+BEGIN_HTML
LDNS代替了BIND,感觉BIND的漏洞很头疼。
GCC被踢出基本系统,用CLANG代替了。
支持Raspberry Pi和arm6/arm7
AMD GPU显卡的支持
Virtio,玩虚拟机的福音
growfs终于可以扩大分区了
FUSE进入基本系统,可以直接使用NTFS,但愿把乱码一起解决了。
可以在磁盘中保存更大量的文件
https://wiki.freebsd.org/WhatsNew/FreeBSD10

2013.09.27 push
#+END_HTML

你!Fix Bug的五个阶段

#+BEGIN_HTML
下面的文章和《各种流行的编程方式》有异曲同工,请你不要理解错了。本文来源,翻译如下:

――――――――――――――――――

一个非常严重和困难的bug,能够成就一个饱经沧桑深受压力的有经验的专业程序员的职业生涯。经受这种考验的创伤程度,相当你受到了一次严重的身体伤害,离婚,或是家庭成为的离世。

研究人员在研究了计算机编程心理学后,得出了一个程序员们在解决一个困难的bug时的心路里程。这些不同的境界,很像为大众所知的Kübler-Ross Stages of Grief(这个模型描述了人对待哀伤与灾难过程中的5个独立阶段(否认,愤怒,耍赖,抑郁,接受)。绝症患者被认为会经历这些阶段),而且原因都很相似。就好像死亡所伴随的悲伤一样,fix一个bug是一个过程其初始化了一个事件,一开始是拒绝相信,其造就了你苦闷的情绪并开始逐步影响你的心智。这种苦闷的情结果会让你纠结要努力忍受,最终会你会找到一个满意的结果。

了解下面这几个bug-fixing的阶段,会让我们更好的生存下来,并持之以恒,最终带来……关闭我们所有的bug的结果。

第一阶段:抵触

本阶段的状态: 多疑 Skeptical. 生气 Offended. 易怒 Petulant.

1. 不理睬

也许这个bug会安静地离开。

2. 标记上“不是bug”

也许这是用户的错,或是本地配置有问题。是的,我确信就是那样,一会就会好的。

3. 就是一次小故障

我想这就是一次小故障,很奇怪地发生了一次,它不会再发生的,虽然没有搞清楚是为什么发生了,不过这就好像我们的数据库,网格,浏览器或别的什么打了几个嗝一样。一会就会好的,我确信。

4. 躲藏.

我要休几天病假,也许他们会把这个bug转给别人的。

5. 标记为“修改需求中”

你看,我是按照需求实现的。如果你们想要改这个行为和UI,就一定要修改需求。也许他们会决定就这样了。

6. 需要更多的信息

我不能确定这是一个bug,除非我能在错误日志中看到一条特定的报错信息。

7. 转给其他人

我调查这个bug中看到了其它模块中我看不懂的数据,问题很大。我应该把这个bug转给开发那个模块的人。我可以在我的模块中检查一下那个边边角角的情况,但是正确的fix应该是在别人的模块中。反正那个在别的国家,我见不着他。

第二阶段:接受

本阶段的状态: 认命 Resigned. 被打击 Defeated. 被激怒 Annoyed.

1. 接受现实

行了,行了,行了!这是我的bug,我会修正它的。

2. 把这个bug放到最后

也许,我可以在我需要fix这个bug之前找到一个新的工作。

3. 和你的经理讨价还价

好的,你看,我可以正确地fix这个问题,不过我需要一个月。也就是说,我可以给这个问题贴个创可贴,那不会真正的解决它,但是我们可以避免用户的抱怨,这可以为我们赢得几天的时间。

4. 为这个bug标记一个无耻的时间

上帝啊,我希望这时间够了。

第三阶段: 投入和沮丧

本阶段的状态: 眼花 Giddy. 头晕 Light-headed. 紧张 Nauseous.

1. 开始调查

我能搞定它,我能搞定它!只需要小小的调整一下,小小的关注一下,多一点咖啡因,再加上一点时间,我能搞定它。

2. Befuddlement.

Shit. 这太扯了。我居然没有一点进展。这代码真是乱。这样的代码居然能编译和运行,真TMD的神奇,我有机会能搞清楚它什么不正常吗?

3. 再次躲藏

你看,很对不起。我不得不要去切除我的阑尾。再一次,是的,既然你提到了它,我的确有两个阑尾。现在我一个也没有了,你高兴了吧?。

4. 犯贱

好吧,总之,你到底期望什么?想让我在一个没有高级调试器的环境下改这个BUG。我是什么?千里眼吗?我在我的Commodore 64上一个更好的调试器!

5. 瞎搞

看看我试试这么改?Kao,这样不行。要不然这样搞?也不行。那么那样搞呢?Shit,虽然再糟糕。

6. 绝望

我不可能fix这个bug了。我是个糟糕的程序员。我太笨了。我在这个满是聪明人的地方干什么?迟早他们会知道我的能力太差,那时我就玩完了,在这也混不下去了。

7.耻辱

我的经理问我为什么我用了一个月的时候来fix这个只需要两天就可以解决的bug?老实说,我不知道怎么去读日志信息,我搞坏了我们的编译脚本。现在,我不敢去让别人来帮我,因为这样只会让我显得更愚蠢。

8. 恐慌!

这事变得比我相像的要复杂!而我开始觉得复杂的事变得简单……而我觉得简单的事变成需要重定半打的类。为什么我以前在我的经理前拍着胸说我可以搞定这个事?

9. 通宵工作,远离朋友和家人

(语无论次的喃喃自语,一阵一阵地大声咒骂)

第四个阶段:愚蠢的快感

本阶段的状态: 感恩 Grateful. 安心 Relieved. 极端地自我欣赏 Awfully Impressed with Yourself.

1. 醒悟

哦!我终于明白怎么搞定它了……

2. 写正确的代码

我真NB,我是编码机器!

3. 测试

牛!通过一个测试。真牛!又通过一个测试了。靠!有测试失败了。这是为什么……

4. 隐藏测试失败

反正这完全是一个不重要的测试案例。没有人会检查它,这个测试真是毫无意义。

5. 提交代码

我太牛了,厨房里有个馅饼可以庆祝一下吗?

6. 关闭 bug.

我听说那里有个馅饼可以庆祝一下

第五个阶段: 与“完成”肉搏

本阶段的状态: 焦燥不安 Twitchy. 神经过敏 Nervous. 迷信 Superstitious.

1. 有人reopen了这个 Bug

真的?他们发现了你引入了另一个bug? Shit – 那只是一个不重要的案例永远不会发生的。

2. 修正以前的修正

是的,我甚至检查了员工的年龄是一个虚数的情况,就是为了防止出错。

3. 关闭 bug

是的,贱货,你被关闭了。全部都关了,再也不用心烦了。

4. 发誓以后再也不干这种事了

5. 大家都意识到你现在是那个模块的专家了

哦,不!现在他们又给了我三个那个模块的新bug

没关系,现在你只需要GOTO 第一个阶段。

此外,作为一个工作中的程序员,你会永远经历这些烂事,直到你――死亡,退休,或是被升到管理层。

(全文完)

转载地址:http://blogread.cn/it/article/3496?f=hot1

2013.11.13 push
#+END_HTML

关于IO的同步,异步,阻塞,非阻塞

#+BEGIN_HTML
上次写了一篇文章:Unix IO 模型学习。恰巧在这次周会的时候,@fp1203 (goldendoc成员之一) 正好在讲解poll和epoll的底层实现。中途正好讨论了网络IO的同步、异步、阻塞、非阻塞的概念,当时讲下来,大家的理解各不相同,各执己见。搜索了网络上的一些文章,观点也各不相同,甚至连wiki也将异步和非阻塞当成一个概念在解释。

虽然网络上充斥了大量关于同步、异步、阻塞、非阻塞的文章,但大都是抄来抄去,没有一个权威的说法。但我找到了这一篇文章,该文章引用了《UNIX网络编程 卷1》的介绍,这本书的作者是Richard Stevens。如果有Richard Stevens在这方面的定义或者结论,那么我想,这应该是比较有说服力的了。

关于《UNIX网络编程 卷1》这本书,我特意找了英文原版,也共享出来了:大家可以下载《UNIX网络编程 卷1》的英文原版?HM格式)。

我看了6.2这节内容,这节内容就是讲IO模型的。刚刚提到的那篇文章,几乎就是翻译这个6.2节的。应该说,这个6.2节,对同步和异步的讲解,算是很清楚的。

下面是我自己理解的重点。

IO模型

目前unix存在五种IO模型(这也和上一篇文章:Unix IO 模型 中提到的一致),分别是:

阻塞型 IO(blocking I/O)
非阻塞性IO(nonblocking I/O)
IO多路复用(I/O multiplexing)
信号驱动IO(signal driven I/O)
异步IO(asynchronous I/O)
IO的两个阶段

等待数据准备好
将数据从内核缓冲区复制到用户进程缓冲区
同步,异步的区别

那么究竟什么是同步和异步的区别呢?请重点读一下原文6.2节中的信号驱动IO和异步IO中的比较。最后总结出来是:

同步IO,需要用户进程主动将存放在内核缓冲区中的数据拷贝到用户进程中。
异步IO,内核会自动将数据从内核缓冲区拷贝到用户缓冲区,然后再通知用户。
这样,同步和异步的概念就非常明显了。以上的五种IO模型,前面四种都是同步的,只有第五种IO模型才是异步的IO。

阻塞和非阻塞

那么阻塞和非阻塞呢?注意到以上五个模型。阻塞IO,非阻塞IO,只是上面的五个模型中的两个。阻塞,非阻塞,是针对单个进程而言的。

当对多路复用IO进行调用时,比如使用poll。需注意的是,poll是系统调用,当调用poll的时候,其实已经是陷入了内核,是内核线程在跑了。因此对于调用poll的用户进程来讲,此时是阻塞的。

因为poll的底层实现,是去扫描每个文件描述符(fd),而如果要对感兴趣的fd进行扫描,那么只能将每个描述符设置成非阻塞的形式(对于用户进程来讲,设置fd是阻塞还是非阻塞,可以使用系统调用fcntl),这样才有可能进行扫描。如果扫描当中,发现有可读(如果可读是用户感兴趣的)的fd,那么select就在用户进程层面就会返回,并且告知用户进程哪些fd是可读的。

这时候,用户进程仍然需要使用read的系统调用,将fd的数据,从内核缓冲区拷贝到用户进程缓冲区(这也是poll为同步IO的原因)。

那么此时的read是阻塞还是非阻塞呢?这就要看fd的状态了,如果fd被设置成了非阻塞,那么此时的read就是非阻塞的;如果fd被设置成了阻塞,那么此时的read就是阻塞的。

不过程序已经执行到了这时候,不管fd是阻塞还是非阻塞,都没有任何区别,因为之前的poll,就是知道有数据准备好了才返回的,也就是说内核缓冲区已经有了数据,此时进行read,是肯定能够将数据拷贝到用户进程缓冲区的。

但如果换种想法,如果poll是因为超时返回的,而我们又对一个fd(此fd是被poll轮询过的)进行read调用,那么此时是阻塞还是非阻塞,就非常有意义了,对吧!

结论

判断IO是同步还是异步,是看谁主动将数据拷贝到用户进程。
select或者poll,epoll,是同步调用,进行此调用的用户进程也处于阻塞状态。
javaScript或者nodejs中的读取网络(文件)数据,然后提供回调函数进行处理,是异步IO。
转载地址:http://blogread.cn/it/article/4108?f=hot1

2013.11.14 push
#+END_HTML

概念模型、逻辑模型、物理模型的区别

#+BEGIN_HTML
概念模型

概念数据模型(Conceptual Data Model):简称概念模型,主要用来描述世界的概念化结构,它使数据库的设计人员在设计的初始阶段,摆脱计算机系统及DBMS的具体技术问题,集中精力分析数据以及数据之间的联系等,与具体的数据管理系统(Database Management System,简称DBMS)无关。概念数据模型必须换成逻辑数据模型,才能在DBMS中实现。

概念数据模型是最终用户对数据存储的看法,反映了最终用户综合性的信息需求,它以数据类的方式描述企业级的数据需求,数据类代表了在业务环境中自然聚集成的几个主要类别数据。

概念数据模型的内容包括重要的实体及实体之间的关系。在概念数据模型中不包括实体的属性,也不用定义实体的主键。这是概念数据模型和逻辑数据模型的主要区别。

概念数据模型的目标是统一业务概念,作为业务人员和技术人员之间沟通的桥梁,确定不同实体之间的最高层次的关系。

在有些数据模型的设计过程中,概念数据模型是和逻辑数据模型合在一起进行设计的。

逻辑模型

逻辑数据模型(Logical Data Model):简称数据模型,这是用户从数据库所看到的模型,是具体的DBMS所支持的数据模型,如网状数据模型(Network Data Model)、层次数据模型(Hierarchical Data Model)等等。此模型既要面向用户,又要面向系统,主要用于数据库管理系统(DBMS)的实现。

逻辑数据模型反映的是系统分析设计人员对数据存储的观点,是对概念数据模型进一步的分解和细化。逻辑数据模型是根据业务规则确定的,关于业务对象、业务对象的数据项及业务对象之间关系的基本蓝图。

逻辑数据模型的内容包括所有的实体和关系,确定每个实体的属性,定义每个实体的主键,指定实体的外键,需要进行范式化处理。

逻辑数据模型的目标是尽可能详细的描述数据,但并不考虑数据在物理上如何来实现。

逻辑数据建模不仅会影响数据库设计的方向,还间接影响最终数据库的性能和管理。如果在实现逻辑数据模型时投入得足够多,那么在物理数据模型设计时就可以有许多可供选择的方法。

物理模型

物理数据模型(Physical Data Model):简称物理模型,是面向计算机物理表示的模型,描述了数据在储存介质上的组织结构,它不但与具体的DBMS有关,而且还与操作系统和硬件有关。每一种逻辑数据模型在实现时都有起对应的物理数据模型。DBMS为了保证其独立性与可移植性,大部分物理数据模型的实现工作又系统自动完成,而设计者只设计索引、聚集等特殊结构。

2013.11.14 push
#+END_HTML

开源协议整理(BSD,Apache,GPL,LGPL,MIT)

#+BEGIN_HTML
简介

开源软件(Open source software)对我们来说越来越不陌生,开源软件一方面让我们免费享用到了“免费的午餐”,另一方面有效的利用和学习开源软件,也能促进我们开发软件时的效率、提升软件质量。但是在使用和借鉴开源软件的时候,我们不得不关心一下它对使用者的诸多限制,比较常见的方式即协议授权(licence),这些协议中明确说明了使用者应该遵循的原则。

现在开源协议众多,通过Open Source Initiative组织批准的开源协议有50多种,本文提到的五种常见协议也在其中,而且出现频率非常频繁,我们在使用开源代码或者开放自己源代码的时候,也应该尽量选择这些协议。

五种常见开源协议

BSD协议

BSD开源协议是一个给予使用者很大自由的协议。开发者可以自由使用和修改源代码,也可以讲修改后的源代码作为开源或者专有软件再发布。但是有一下几个要求:

如果再发布的产品中含有源代码,则在源代码中必须带有原来代码中的BSD协议。
如果再发布的只是二进制类库/软件,则需要再类库/软件的文档和版权申明中包含原有代码中的BSD协议。 – 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。
BSD 代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。

Apache Licence 2.0

Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同样鼓励代码共享和最终原作者的著作权,同样允许源代码修改和再发布。但是也需要遵循以下条件:

需要给代码的用户一份Apache Licence。 – 如果修改了代码,需要再被修改的文件中说明。 – 在衍生的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以再Notice中增加自己的许可,但是不可以表现为对Apache Licence构成更改。
Apache Licence也是对商业应用又好的许可。使用者也可以再需要的时候修改代码来满足并作为开源或商业产品发布/销售。

GPL

我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商业软件公司开发的免费软件了。

GPL协议的主要内容是只要在一个软件中使用(“使用”指类库引用,修改后的代码或者衍生代码)GPL 协议的产品,则该软件产品必须也采用GPL协议,既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题,还可以享受免费的优势。

由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议,对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。

其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。

LGPL

LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并发布和销售。

但是如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。

GPL/LGPL都保障原作者的知识产权,避免有人利用开源代码复制并开发类似的产品

MIT

MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制。也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的.

各协议分析图

乌克兰程序员Paul Bagwell,画了一张分析图,说明应该怎么选择。阮一峰对图进行了汉化,如下图: 协议分析图

参考

http://www.awflasher.com/blog/archives/939
http://www.ruanyifeng.com/blog/2011/05/how_to_choose_free_software_licenses.html

2013.11.14 push
#+END_HTML

产品跟技术的那些事

#+BEGIN_HTML
产品经理和程序员这两个都是苦逼的岗位,但有时候两个苦逼还经常在一起较真,成为了2B,今天我们来聊聊产品经理如何搞定程序员,使两个苦逼不再苦逼,下面我们来看一个案例:

小A是个程序员,小B是个产品经理。

小A:
1.事儿都是程序员干的
2.产品经理不会干还指挥我们干
3.还嫌程序员干的慢 ……

小B:
1.这个程序员水平好烂,比我编的代码还要差
2.如果我不告诉程序员方向是什么,程序员就是瞎子
3.程序员就一写代码的苦逼,要什么想法,按我说的做

小A VS 小B,一段2B的传说就这么展开了。

在互联网公司或软件公司,产品经理和程序员这两个角色是互相依靠,唇齿相依的,他们不是对立的,而是一个操作线上的两个环节,小A离开小B,则小A就变成了操作工,反之则小B成为空想家。

如何赢是尊重,前提是得有共同语言、得有共同的想法、共同目标。

 

1.别干涉程序员的工作

产品经理用你的沟通、用你对于产品的理解赢得程序员的尊重,而不是在技术上对于程序员有过多的苛求,术业有专攻,专业的人做专业的事儿 ,产品经理不要去干涉程序员开发的事儿,因为那不是你产品经理的专业领域,产品经理把“做什么”弄清楚,那就GOOD!

2.别轻视程序员的工作

有些产品经理往往会在有意无意之间透露出:“这个功能实现好简单,按这个弄”,他却不知道这么简单的无心之语已经触动了程序员那颗幼小的心灵,火爆点的随之争吵,阴险点的准备十年后报仇,从此结下了良子。

产品经理你可以狂,但狂一定要有资本、你够专业、够坚强,同时是低调的张狂,让程序员跟你一起狂,那才是真正的牛B。

3.帮助程序员找答案

有些功能程序员做不出来是常有的事儿,做为产品经理,你不要去打击程序员、更不能去嘲笑程序员,作为一名优秀的产品经理,应该与程序员一起想办法,用产品经理自己强大的人脉去找到专家帮助程序员去解决问题。

如果解决不了,那就用产品经理的专业技能,换个方式实现功能,你们是一起的,绝不是2个2B。

4.别动不动变需求

需求变更在很多企业里都普遍发生着,这一点经常是导致产品经理和程序员PK的导火索,有的时候,始作俑者却是运营方,产品经理是个炮灰,由此而发生了“内战”。

作为一名合格的产品经理,这个时间应该先做需求的梳理,对于无理的需求变更要坚决干掉,自己提变更时要慎重,不要随意。如果确实需要变更,必须先要征服程序员的心灵,再谈变更的事儿。

[以上内容转自 : 修泽的新浪博客]

个人觉得还可以补充几点:

5. 别拿部门经理或者老板来压人

有些时候,产品经理和程序员PK需求的时候,产品经理喜欢说“这个需求是经理提的,一级重要,你们需要全力支持,没得商量”,或许有些需求确实是经理、老板提出的,但是他们提出这样的需求一定是他们的道理,能做到这个位置上多少都有些能力。上级提出需求或者修改的建议,一定是希望产品经理能理解为什么要修改,修改的背景和目的是什么,而不仅仅是让产品经理知道这个东西要拿去修改。在互联网公司里,经理要修改的内容往往是通过产品经理传达给程序员员,如果此时产品经理自己都未能消化变更的目的,只是单方面作为一个传话筒告知,这个需求是老大们提的,必须做,那么必然遭到程序员们的反感,毕竟产品经理不是部门经理也不是老板,但是却假借经理或者老板的名义发号施令,这就是狐假虎威;而对于经理或者老板,他们想要的也不是一个没有思考能力的传话筒。

6. 产品经理是经理吗?

产品经理是不是经理?他能做什么?他的职责是啥?

在产品管理中,产品经理是领头人,是协调员,是鼓动者,但他并不是老板。作为产品经理,虽然针对产品开发本身有很大的权利,可以对产品生命周期中的各阶段工作进行干预,但从行政上讲,并不像一般的经理那样有自己的下属,但他又要调动很多资源来做事,因此如何做好这个角色是需要相当技巧的。

因为他需要对产品负责,要协调个各种资源。但是往往能听到产品经理对程序员的能力发表各种自己的评论意见。

这里产品经理只对负责的产品或者项目负责,他需要协调各种资源。但他在行政上是没有任何的权利,他不能对程序员进行人事任免,所以从一般意义上讲,他不能对程序员的工作能力发表评论。程序员有自己的上级,有自己的能力评估标准,不需要相对外行的产品经理去评估。产品经理往往在项目中跟程序员是分工不同但行政级别是一样的,他们是平级关系,所以产品经理需要摆正自己的心态和姿态,注意自己平时说话的语气,以平级关系去沟通,产品经理在行政上没有任何命令程序员的权利,那也不是你的专业领域,产品经理把“做什么”弄清楚就够了。

转载地址:http://popotang.com/blog/pdm-vs-de.html

2013.06.23 push
#+END_HTML

Date: 2014-08-29

Author: josephzeng

Created: 2014-10-31 周五 13:19

Emacs 24.4.1 (Org mode 8.2.10)

Validate