北国春色
by Elton on 2012年04月17日, under Photography
4-5月是北方姹紫嫣红的月份,各色的花争奇斗艳,树木、小草都绽放出嫩绿,甚是好看。





在xcode4.2中手工添加GPX文件,指定位置。
by Elton on 2012年03月11日, under iPhone, Mac
XCode 4.2终于支持地点模拟了,不用忍受真机调试的各种不便了,模拟方法也很简单(恕我盗用几个别人的图):
当Debug一个需要地理位置信息的App时,在Debug栏默认就会有地点模拟的图标,如下图所示:

这个有一个前提:必须是iOS5的模拟器.
默认只提供了几个地点,但是可以通过GPX文件来添加.你可以选择到网上找现成的GPX,但是Apple还是很为广大开发者考虑的,提供了GPX的模版,创建方法 新建>>Resource>>GPX File 如下图:

其实所谓的GPX就是一XML文件,默认的内容如下:
1 | <?xml version="1.0"?> <gpx version="1.1" creator="Xcode"> <wpt lat="37.331705" lon="-122.030237"> <name>Cupertino</name> </wpt> </gpx> |
添加了GPX文件后就可以在之前选择地点那里看到你的GPX文件了.
注意:每次重新启动模拟器,需要重指定位置⋯⋯
Apple LLVM 4.0的新特性
by Elton on 2012年02月22日, under Mac
最新的LLVM 4.0添加了几个比较有用的特性:
- @synthesize: 自动为@property添加synthesize
- 语法: 创建NSArray, NSDictionary, NSNumber的时候, 可以像NSString那样写 (下面例子解释!)
- 容器下标: 用’[]‘来访问容器(例如NSArray和NSDictionary), 就像你在第一节C语言课上学的”arr[0]“, “arr[1]“那样. 不过这个似乎是允许在’[]‘中填入字符串的(NSDictionary).
下面举例解释下第二条:
NSArray
Previously:
1 | array = [NSArray arrayWithObjects:a, b, c, nil]; |
Now:
1 | array = @[a, b, c]; |
NSDictionary
Previously:
1 | dict = [NSDictionary dictionaryWithObjects:@[o1, o2, o3] forKeys:@[k1, k2, k3]]; |
Now:
1 | dict = @{k1: o1, k2: o2, k3: o3}; |
NSNumber
Previously:
1 2 3 4 5 6 7 8 | NSNumber *number; number = [NSNumber numberWithChar:'X']; number = [NSNumber numberWithInt:12345]; number = [NSNumber numberWithUnsignedLong:12345ul]; number = [NSNumber numberWithLongLong:12345ll]; number = [NSNumber numberWithFloat:123.45f]; number = [NSNumber numberWithDouble:123.45]; number = [NSNumber numberWithBool:YES]; |
Now:
1 2 3 4 5 6 7 8 | NSNumber *number; number = @'X'; number = @12345; number = @12345ul; number = @12345ll; number = @123.45f; number = @123.45; number = @YES; |
引自:http://seymourdev.com/?p=302#more-302
Thrift简析
by Elton on 2012年02月12日, under Web
RPC技术及实现简介
首先思考一下分布式系统中的 RPC (Remote Procedure Call) 问题,一个完整的 RPC 模块需要可以分为三个层次
- 服务层(service):RPC 接口定义与实现
- 协议层(protocol):RPC 报文格式和数据编码格式
- 传输层(transport):实现底层的通信(如 socket)以及系统相关的功能(如事件循环、多线程)
在实际的大型分布式系统中,不同的服务往往会使用不同的语言来实现,所以一般的 RPC 系统会提供一种跨语言的过程调用功能,比如一段用C++实现的客户端代码可以远程调用一个用 Java 实现的服务。实现跨语言 RPC 有两种方法:
- 静态代码生成:开发者用一种中间语言(IDL,接口定义语言)来定义 RPC 的接口和数据类型,然后通过一个编译器来生成不同语言的代码(如C++, Java, Python),并由生成的代码来负责 RPC 协议层和传输层的实现。例如,服务的实现用C++,则服务端需要生成实现RPC协议和传输层的C++代码,服务层使用生成的代码来实现与客户端的通信;而如果客户端用 Python,则客户端需要生成Python代码。
- 基于“自省”的动态类型系统来实现:协议和传输层可以只用一种语言实现成一个库,但是这种语言需要关联一个具备“自省”或者反射机制的动态类型系统,对外提供其他语言的绑定,客户端和服务端通过语言绑定来使用 RPC。比如,可以考虑用 C 和 GObject 实现一个 RPC 库,然后通过 GObject 实现其他语言的绑定。
第一种方法的优点是RPC的协议层和传输层的实现不需要和某种动态类型系统(如GObject)绑定在一起,同时避免了动态类型检查和转换,程序效率比较高,但是它的缺点是要为不同语言提供不同的 RPC 协议层和传输层实现。第二种方法的主要难度在于语言绑定和通用的对象串行化机制的实现,同时也需要考虑效率的问题。
Thrift 是一个基于静态代码生成的跨语言的RPC协议栈实现,它可以生成包括C++, Java, Python, Ruby, PHP 等主流语言的代码,这些代码实现了 RPC 的协议层和传输层功能,从而让用户可以集中精力于服务的调用和实现。Cassandra 的服务访问协议是基于 Thrift 来实现的。
Thrift介绍
Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基金会将Thrift作为一个开源项目,对于当时的facebook来说创造thrift是为了解决facebook系统中各系统间大数据量的传输通信以及系统之间语言环境不同需要跨平台的特性。所以thrift可以支持多种程序语言,例如: C++, C#, Cocoa, Erlang, Haskell, Java, Ocami, Perl, PHP, Python, Ruby, Smalltalk. 在多种不同的语言之间通信thrift可以作为二进制的高性能的通讯中间件,支持数据(对象)序列化和多种类型的RPC服务。Thrift适用于程序对程 序静态的数据交换,需要先确定好他的数据结构,他是完全静态化的,当数据结构发生变化时,必须重新编辑IDL文件,代码生成,再编译载入的流程,跟其他IDL工具相比较可以视为是Thrift的弱项,Thrift适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输相对于JSON和xml无论在性能、传输大小上有明显的优势。
Thrift 主要由5个部分组成:
- 类型系统以及 IDL 编译器:负责由用户给定的 IDL 文件生成相应语言的接口代码
- TProtocol:实现 RPC 的协议层,可以选择多种不同的对象串行化方式,如 JSON, Binary。
- TTransport:实现 RPC 的传输层,同样可以选择不同的传输层实现,如socket, 非阻塞的 socket, MemoryBuffer 等。
- TProcessor:作为协议层和用户提供的服务实现之间的纽带,负责调用服务实现的接口。
- TServer:聚合 TProtocol, TTransport 和 TProcessor 几个对象。
上述的这5个部件都是在 Thrift 的源代码中通过为不同语言提供库来实现的,这些库的代码在 Thrift 源码目录的 lib 目录下面,在使用 Thrift 之前需要先熟悉与自己的语言对应的库提供的接口。
Thrift 官方网站:http://thrift.apache.org
延迟加载图片的jQuery插件-Lazy Load Plugin for JQuery
by Elton on 2012年02月11日, under Javascrip
Lazy Load是一个用Javascript写得jQuery插件。它可以使一个长网页中,不在当前视图中的图片延迟加载,以提高页面的载入速度。
使用方法
在页面头部加入插件
1 2 | <script src="jquery.js" type="text/javascript"></script> <script src="jquery.lazyload.js" type="text/javascript"></script> |
在使用图片的地方,使用下面的设置
1 | <img class="lazy" src="img/grey.gif" alt="" width="640" data-original="img/example.jpg" data-pinit="registered" /> |
src是替换图片,一般使用1*1像素的图片替代。后面data-original才是真正的图片。
然后在你的代码中加入,就可以了
1 | $("img.lazy").lazyload(); |
设置延迟加载参数
1 | $("img.lazy").lazyload({ threshold : 200 }); |
这样,图片就可以在距离显示区域200像素的时候就开始预先加载。这个值可以是负值,表示提前加载。
使用特效
1 2 3 | $("img.lazy").lazyload({ effect : "fadeIn" }); |
默认延迟加载使用show方法来显示图片,可以用这个方法来改变图片的显示方法。
插件主页:http://www.appelsiini.net/projects/lazyload
Nginx使用Linux内存加速静态文件访问
by Elton on 2012年02月5日, under Linux, Web
Nginx是一个非常出色的静态资源web服务器。如果你嫌它还不够快,可以把放在磁盘中的文件,映射到内存中,减少高并发下的磁盘IO。
先做几个假设。nginx.conf中所配置站点的路径是/home/wwwroot/res,站点所对应文件原始存储路径:/opt/web/res
shell脚本非常简单,思路就是拷贝资源文件到内存中,然后在把网站的静态文件链接指向到内存中即可。具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #! /bin/bash res_path="/opt/web/res" mem_path="/dev/shm/res" lk_path="/home/wwwroot/res" if [ ! -d "$mem_path" ]; then cp -r "$res_path" "$mem_path" fi if [ ! -L "$lk_path" ]; then ln -s "$mem_path" "$lk_path" fi |
===================
更新测试数据
利用上述方法,在公司的测试服务器上做了个测试,速度提升明显,速度几乎翻倍。
测试前提:将测试网站的首页全部内容包括html,图片,js,css等所有元素都拷贝到内存中,并且每次用户请求静态资源文件都不会缓存。使用LoadRunner按照200和100并发分别进行压力测试。
测试结果:
- 在高并发下全部使用磁盘文件200人并发 2分钟 平均每次事务响应时间为19.96秒 每秒处理事务数为9.26个
使用内存200人并发 2分钟 平均每次事务响应时间为11.3秒 每秒处理事务数为15.8个 - 在低并发下全部使用磁盘文件100人并发 2分钟 平均每次事务响应时间为10.27秒 每秒处理事务数为9.32个
使用内存100人并发 2分钟 平均每次事务响应时间为5.84秒 每秒处理事务数为16.17个
可伸缩性架构常用技术——之数据切分(Data Sharding/Partition)
by Elton on 2012年01月29日, under Database
1. 简介
我们知道,为了应对不断增长的数据,我们对数据进行切分,存储在不同的数据库里,本文提到的数据库在非特定指明的情况下,均指一个逻辑数据库(是一组数据库,比如Master-Slave),而非单一各个物理数据库。
其主要有两种方式:
垂直切分(Vertical Partition/Sharding):就是把不同格式的数据,存储到不同的数据库。
水平切分(Horizontal Partition/Sharding):就是把相同的数据格式的数据,存储到不同的数据库,本文将侧重这点进行讲述。
2. 垂直切分(Vertical Partition/Sharding)
对于垂直切分,其实应用非常广泛,主旨是把那些关系依赖非常紧密的数据保存到同一数据库,主要包含如下几种应用方式:
不同的应用使用不同数据库:这个非常容易理解,即对于一个企业来讲,往往有多个应用,甚至有些应用逐渐演变成两个或者多个应用,这其实就是一种垂直切分应用。
应用的不同模块使用不同的数据库:为同一应用的不同模块分别使用不同的数据库,之间提供低耦合的API进行访问。
同一应用相同模块使用不同数据库:在一些应用中,对于适合关系查询的数据,保存在关系数据库,而另外一些适合以NoSQL数据库保存的数据(例如key-value数据库),保存在NoSQL数据库中,方便数据扩展。这里给出一个例子,比如一个论坛应用,可以对个人用户信息保存在关系数据库,例如,其访问次数,个人信息等等,而对于发表的帖子和回帖,则可以保存在一个NoSQL里,方便扩展。注意,这里给出的例子并非真实例子,只是为了易于说明给出一个假设性的例子。
3. 水平切分(Horizontal Partition/Sharding)
水平切分相对比较复杂,我们还是从水平切分的策略谈起。
3.1 水平切分策略主要分为以下几种:
1. Round-Robin(轮询式)算法
顾名思义,就是把数据按照轮流的方式依次存放在的数据库节点上,比如,有2个节点,N0和N1,那么Data0放在N0节点上,Data1放在N1上,Data2放在N0上,依次类推……。
这种方式实现起来非常容易,对于数字键,我们有:n = key mod N。其中,key为数据的键,N为节点的数量,n为存放数据的节点编号;对于那些非数字键,我们可以让其转变为数字键,比如通过某些hash函数,让键值均匀分布,于是有:n = f (key) mod N。
这种方式有个缺点非常明显,不容易应对数据节点的变化,即不易进行二次切分。所谓二次分片是指,当数据的增长超过数据库容量时,需要增加数据库,或者系统故障导致某些数据库不能使用时,这时需要重新切分数据库。例如,有两个节点,N0和N1,现在需要增加一个节点N2,这时候,都需要吧N0上的数据和N1上的数据迁移到N2上,这个工作量是巨大的;并且可能导致上层应用对数据的改变,比如,之前数据Data5存储在N1上面,上层应用访问该数据时,根据key=5知道其存储在数据库N1里,那么便会在N1里查询数据,现在增加另外一个节点N2,那么这条数据被迁移到N2上了,上层应用就应该去N2上查询此数据了,这个看似简单,其实往往导致应用程序的复杂性很高。
2. 虚拟分片技术
为了保证二次分片时,避免对上层应用因为实际物理数据库发生改变而引起对数据访问逻辑的改变,中间加入了一个虚拟片段—物理片段映射表,数据对象存储在虚拟分片上,每个虚拟片段通过这个映射表找到相应的物理片段。这时间,上层应用依赖于虚拟分片,而非物理分片,只要保证虚拟片段足够多,就能避免上层应用的依赖。
3. 一致性Hash算法
为了避免数据库数量发生变化,引起大规模的数据迁移问题,而引入了一致性Hash算法。此算法由David Karger等人发表于1997年,论文题目为《Consistent hashing and random trees: distributed caching protocols for relieving hot spots on the World Wide Web》,这里有一篇文章讲述Java语言简单实现一致性Hash算法http://weblogs.java.net/blog/2007/11/27/consistent-hashing。
一致性Hash算法的主要思想是不改变Hash函数本身,当减少节点时,临近的节点接手该节点,因此,消失节点上的数据迁移只迁移到临近节点上面;而增加节点时,只接手其临近的一个节点的部分数据,因此,只有一部分临近节点的数据被迁移至新加节点。
我们来详细了解一下具体实现:我们的Hash函数生成的数据都有一个值区间[min,max],我们把该区间用一个环来表示,每个节点的hash值都映射到这个环上,如下图所示:

假设我们的值区间是[1,12],我们有三个节点,1,4,9,数据的键也映射到这个环上,a的键值介于1~4之间,则存储在节点4上,即按照顺时针方向存储数据,同样b存储于节点9,而c存储于节点1。
假设节点4不可用时,那么数据a就会被迁移至节点9,其他节点的数据不发生迁移,如下图所示:

假设增加节点7,那么将把节点9上的部分数据迁移至节点7,其他节点数据不发生改变,如下图所示:

4. 按照数据的特点进行切分数据
最常见的就是按照地理位置切分数据,那么我们按照用户的注册信息或者用户数据提交的ip地址等来把它们放置于离它们地理位置最近的数据库中。
3.2 实际应用
在真实的应用中,往往会结合这些策略,甚至提供更为抽象的接口让开发人员实现适合自己的切分方法。我们这里讲述Mongodb和Hibernate Shards的分片方式。
3.2.1 Mongodb Sharding
Mongo db是基于文档的NoSQL数据库,查询方式和关系数据库非常接近。
Mongodb把数据存放在称为Chuncks数据结构上面,Chunck的默认大小是64M,每个Chunck上面存储一定切分范围的数据,当数据超过64M时,会自行分裂成两个Chunks,相当于一致性Hash算法添加了一个节点,只是这个节点不是DB。而每台物理db(称为Shard)上含有多个Chunks,为了达到更好的负载均衡,这些物理db上的Chunks会自动迁移,使得db上的Chunks发布均衡。
3.2.2 Hibernate Shards
Hibernate Shards是在Hibernate Core上做的一层扩展,目的是在关系数据库上封装和降低水平切分的复杂性。
Hibernate Shards为开发者提供了抽象接口,开发人员可以实现自己想要的切分策略,为了避免物理数据库发生改变引起应用程序的改变,其采用虚拟分片技术。
Hibernate Shards参考中文文档请参见:http://redhat.iteye.com/blog/328032
3.3 应注意的问题
水平切分数据库之后,会给查询造成一定的困难,特别是Aggregation查询。Mongodb采用Map/Reduce方式,能够比较高效进行Aggregation查询。
4 总结
对于大规模,可伸缩,海量数据的应用,数据切分是其架构必须考虑的一个重点内容,我们在进行数据切分时,往往采用先垂直,再水平方式对数据分片。
摘自:http://blog.csdn.net/co0der/article/details/7217974
Bangkok春节游
by Elton on 2012年01月27日, under Photography
趁着春节长假,抽空走马观花看了两个东盟邻国。
24号清晨坐上开往机场的MRT,中午时分到达曼谷。
“曼谷”(Bangkok)是泰国首都,东南亚第二大城市,主要港口和政治、经济、文化中心,被誉为是“佛教之都”。这是一个充满矛盾的地方。一方面,作为东南亚第二大城市,曼谷高楼林立,轻轨和高架桥在钢铁丛林间蜿蜒,商务区的白领步履匆忙,一面抱怨着高峰时段的交通堵塞,一面筹划着周末的欢乐时光;另一方面,数以千计的大小寺庙仍然遍布街头巷尾、高楼大厦间,仍然深深影响着每个人的世俗生活和精神世界,使它无愧为“黄袍佛国”的首都。这里的人仍旧谦和友善,并且不吝以最直白的方式——黄衫——来表达对国王的衷心爱戴。

入住酒店Bhiman Inn旁边的泰国小寺庙

走到湄南河边





湄南河又名昭披耶河,是泰国河流中水量最大、长度最长的河流,有泰国“河流之母”之称。湄南河全长1352千米,纵穿泰国东南部,流经大城,贯穿曼谷市区,在城市交通运输及岸边居民生活中扮演着重要角色。

这个就是在湄南河上穿梭的水上公交车


曼谷Downtown,车水马龙啊。


大王宫始建于1782年,紧偎湄南河的大王宫位于曼谷市中心,占地22万平方米。这里共有22座错落分布的古建筑群,汇集了泰国建筑、绘画、雕刻和园林艺术的精粹,是泰国曼谷王朝一世王至八世王的王宫,又称“大皇宫”或者“故宫”,也是曼谷保存最完美、最壮观、规模最大、最有民族特色的王宫。


郑王庙(又称黎明寺)是泰国皇家寺庙之一,通称郑王寺。始建于大城王朝,当时名皇冠寺,后改称昌寺。郑王庙是纪念泰国第41代君王、民族英雄郑昭的寺庙。郑昭是华裔,于1768年,曾领导泰国各族人民奋驱外敌,重整江山,建立了吞武里王国。
郑王庙又名黎明寺,据说郑王驱逐缅甸军队后,顺湄南河经过此寺时正好是黎明时刻,便下令上岸到寺里参拜,后来登上王位后便称此寺为黎明寺。另一个说法是高79米的高塔每天最先接触到阳光,所以称之为黎明寺。
曼谷之前听说有恐怖袭击,但是去了之后,发现治安很好,甚至好过北京。物价又比北京上海便宜,特别是所有商品标签都除以5,感觉很爽。
Singapore春节游
by Elton on 2012年01月27日, under Photography
趁着春节长假,抽空走马观花看了两个东盟邻国。
腊月二十八在首都机场登上午夜的航班,经过近7个小时的飞行,在早上9点到达新加坡。新加坡是一个汇聚了现代与传统的风格特色,融合东西文化之精粹。在这里,可以感受华人文化、马来文化及印度文化等多元民族特色。

鱼尾狮(The Merlion)是新加坡的旅游标志,是新加坡最高的自由式结构建筑。

莱佛士大酒店(Raffles Hotel)是新加坡地标性建筑,在1887年由来自于亚美尼亚的富豪薛克兹兄弟修建。从那时起,这座代表新加坡殖民地时期建筑风格的酒店便吸引了大量游客。毛姆、吉卜林、卓别林等人都曾在此下榻。1987年新加坡政府将这家酒店列为国家历史文物,并在1991年斥资1600万新币翻新。

新加坡和平纪念碑(Civilian War Memorial)位于美芝路纪念公园,象征新加坡四大种族在二战期间(1942年2月15日至1945年9月12日)共同挣扎求存的精神。同时也悼念在二次大战日军占领新加坡期间死难的平民。

圣安德烈教堂(St.Andrew’s Cathedral)位于哥里门街,1862年由隆纳德·麦克佛逊上校设计并兴建,用以代替早先为纪念史丹福·莱佛士爵士所建的旧教堂。



贯穿于整个城市的新加坡河是新加坡的生命之河,早期移民都是依靠这条河流来维持生计。漫步在河畔,您可以参观许多富纪念性的标志和建筑如鱼尾狮公园、莱佛士登岸遗址和旧国会大厦艺术之家,宗教机构如奥马清真寺、保赤宫,还有驳船码头、克拉码头等繁华的街区。

滨海艺术中心是新加坡首屈一指的艺术表演场地。造型独特的圆顶为它赢得了“榴莲”的称号。滨海艺术中心毗邻滨海湾,艺术中心内有音乐厅、剧院、演奏厅和排练室,还有户外表演空间。此外,这里还有购物中心、国际风味餐馆及新加坡首家艺术图书馆——滨海艺术中心图书馆,馆内收藏了大量关于音乐、舞蹈、电影和戏剧的书籍和多媒体资料。

滨海湾夜景


小印度是新加坡印度族群的聚集地,犹如印度的缩影。在屠妖节(Deepavali),即兴都教光节(HinduFestivalofLights),小印度被装点成金碧辉煌的神话世界。


甘榜格南是以生长在沼泽地周围的树木“gelam”树为名的,是新加坡穆斯林的聚居区。
新加坡真的很干净,一尘不染。天气跟北方的夏天一样热,每天30多度,但是一个苍蝇蚊子都没有。令人敬佩。












