羽翼未丰

技术与艺术的融合

本文中,使用的ps版本 为cs 5。 在上图中,通过XMind 工具列举出了实现这一特效的6个主要步骤。在下文中,会详细说明。

 

第一步 输入文字并转换为图形

在背景层上用文字工具,输入文字后,分别右键单击两个文字图层,选择”转换为形状”命令, 将文字图层创建为形状图层的效果。

第二步 通过变形表现出透视感

选中relationship图层,按住ctrl+t快捷键,接着按住 ctrl+alt+shift 快捷键,将左上端的调节手柄向上拖动。当上端选项栏中(设置垂直斜切)值为7.0度的时候,按enter键确定。

用同样的办法,应用到partnership图层,按住右端的调节手柄向上拖动,也实现垂直斜切7度的景深效果。

选中ralationship图层,单击鼠标右键,选中弹出菜单的栅格化图层,将其栅格化。同样办法也使partnership图层栅格化。(栅格化是为下面对图层应用滤镜等效果做准备)

栅格化图层                                                                  栅格化后的图层

第三步 创建角度区域

创建新通道:单击通道面板下方的“创建新通道”按钮:

 

创建要调节焦点的区域,选择渐变工具,如图所设置上端的选项栏:

选中alpha1通道,在图像中从中央向外拖动,如图:

第四步 表现景深

选中relationship图层,选择滤镜——模糊——镜头模糊,如图所设置:将深度影射中的源设为保存在通道中的 alpha1通道

选中partnership图层,按ctrl+f 复制与刚才相同设置的镜头滤镜。

第五步 填充颜色,应用图层样式

填充颜色,运用图层剪贴蒙版,方法简称:上为剪贴图层,下为形状图层。

新建纯色填充图:

确定后:

上图为填充图层,下形为文字partnership 图层(以下面的形状去剪上面的图像)

图层——创建剪贴蒙版

添加图层样式:

选择partnership图层,选择图层——图层样式——渐变叠加

效果为:

第六步 复制效果,完成制作

对relationship图层也应用相同的效果

首先对它也建立填充图层:按住alt,单击,并将其拖动到最上方复制。

图层——创建剪贴蒙版

右键单击partnership图层,选择弹出窗口的拷贝图层样式:

选择relationship图层,右击后选择弹出菜单,粘贴图层样式

当前图层:

最终完成效果

大功告成!

 

December 22nd, 2011

2011年度重大VC投资项目

No Comments, it杂记, 杂记, by zhanghuan.

传统行业如制药、发电等,占到投资项目的20%,其它项目全部被互联网软件行业包揽。

December 17th, 2011

心理效应一

No Comments, 心理学, by zhanghuan.

1、酝酿效应

它是说,在人们遇到问题后,如不能想到答案,将它放在一边,过段时间后才会得到满意答案。这跟解决问题的能力和效率无关。俗语叫灵感一现。这个现象的根本原因是人的潜意识。存储于记忆里的相关信息在潜意识里重组。当人遇到问题后,思考一段无果,转而先放下。而意识停着了对此问题的思考,然而潜意识却从来没有停止思考,在某个环境下,受到某种启发,脑子里就蹦出那个问题的答案。

不光是难以解决的问题适于酝酿效应。对于当时能做出解答的问题,特别的重要的事情,也应该先放到一边,过上段时间,再重新审视之前的决定或答案。往往就能有意外的收获,俗语叫三思而后行。

另外,在放段时间后,潜意识的持续思考会将答案送到你的面前。是因为潜意识在放松、无压力、愉快的环境里,才能更好发挥效力。

2、巴纳姆效应

具体应用在算命和心理测试及星座学等里面。指的是,人们常常认为一个笼统的,一般性的人格描述很适合自己。这种心理倾向称为巴纳姆效应。

有位心理学家,给一群人作为MMPI测试后,把两份结果让参与者选择,一份是自己做的测试结果,另一份是多数人回答平均的结果。而参与者居然选择后面更能符合自己。

这种现象是源于人们收到周围环境的暗示,对自己的评价产生偏差。

3、半途效应

指在激励过程到达一半时,由于环境和心理因素的相互作用而致的对于目标产生一种负面的影响。半途效应跟2个因素有关,一是:目标的合理性,越困难越易发生半途效应。二是:人的意志力。因此我们要多学习各方面的知识,锻炼各方面的能力外,还应该加强对意志力的锻炼。行为学家提出大目标,小步子的方法,对防止半途效应有预防半途效应有积极作用。

4、贝勃定律

第一次的刺激能缓解第二次的刺激。实验证明,人们对报纸涨了50块,汽车票由200涨到250块,会是非敏感,但对房子由100万涨到200万,人们都不会觉得涨幅太大。第一次的刺激太大,人们会对第二次刺激迟钝。这多用于公司人事部门的裁员。

5、比马龙效应

评估主体低估被评估主体能力。认为被评价主体不求上进,能力差等。这使得被评价主体将这种观念内化,促使被评价主体表现不良。这跟皮革马利翁效应异曲同工。只是后者表达的与此正好相反。

6、彼得原理

这也叫“向上爬”原理。这是美国学着彼得在研究人员晋升相关现象得出的发现:对习惯在某个等级的职位的人员晋升时,总是趋于晋升到不能称职、适合发挥才能的职位上。

这对于公司对人员晋升有积极的指导作用,员工在此职位做的出色,不见得晋升到了更高位置也能做的出色,这跟工作、性格等很多条件都有关系。

7、边际效应

边际效应有时也称边际贡献。指的是消费者在增加一个消费品单位时,带来的效用却是在逐渐减少的。因为后面的同类商品对消费者的效用已经不大了。这比如是口渴时的第一杯水特别解渴,但是到了第三杯可能就一口也不愿喝了,变得没有的价值。

边际效应最常见的应用是激励工资,这给收入低者比收入高者更有效果。比如给收入1K的劳动者奖1K,比收入5K劳动者奖1K更有鼓励的效果。另外,经常用增加薪水的方法激励员工的办法也明智。刚开始,员工会很有激情,但逐渐就会对此丧失热情。例如第一次管理层给员工涨工资(发奖金)1K,员工会很兴奋。第二次涨工资1k,员工会比较兴奋,第三次涨工资2K,就可能是有一点儿兴奋,第四次……直到再也对此没有感觉。不是对钱不感兴趣了,只是这种形式容易让人麻痹。人就是这样容易丧失新鲜感的动物。所以要变换着办法在激励员工热情。让员工一直有所新鲜。

8、波纹效应

指的是在学习的集体中,老师对有影响力的学生进行体罚等惩罚,会引起其他学生的反抗。老师的威严会降低。所谓一波未平一波又起。这是因为这些学生的影响力更大。

9、财富效应

指的是财富越多,消费欲越强。

 

10、长尾效应

长尾效应的根本就是强调:小利润大市场、客户力量、个性化。是指赚很多人的小钱。将市场分到很小时候,就会发现这些小市场累计会带来明显的长尾效应。有人说最大的财富孕育自最小的销售。

本文中用到的环境是windows server 2008的r2版本,Red Hat 5。这里没有利用Samba协议, 而是利用NFS协议,它的全称是Network File System。 NFS协议本身是用于Linux或者Unix操作系统之间,进行网络共享目录和文件的一种协议,由Sun公司在20世纪80年代发明。要实现Windows 和 Linux或者Unix之间的目录和文件共享,windows 需要安装支持NFS的Client for NFS。windows 既可以作为NFS的server端,Linux或者Unix作为NFS的客户端。也可以,作为NFS的客户端,Linux或者Unix作为NFS的sever端。 这里的采用后者。
首先,在windows server 2008 r2上 安装 Client for NFS。

  • 打开Start
  • 打开Server Manager,通过Administrative Tools > Server Manager
  • 在Roles Summary左侧栏中,点击Add Roles打开Add Roles对话框,点击Next
  • 选择Services for Network File System,点击Next
  • 点击Install 安装, 安装完成后,关掉对话框

如下图所示:
然后,在Red hat server上创建通过NFS分享到windows的文件夹。

  • 打开命令行终端
  • 输入:mkdir /vmsnfs 创建文件夹vmsnfs
  • 输入:chown -R nfsnobody /vmsnfs
  • 输入:chgrp -R nfsnobody /vmsnfs
  • 输入:vi /etc/exports
  • 添加:/vmsnfs *(rm,async), 保存,退出
  • 输入:service nfs restart
  • 可以通过命令:showmount -e 来查看,/vmsnfs已经export成功

最后一个步骤是在windows server 2008 中,mount red hat共享出来的文件夹vmsnfs。

  • 在windows的cmd line 里输入 mount -o mtype=hard -o fileaccess=7 -u:root -
    p:***** \\192.168.1.190\vmsnfs z: 来挂载Red共享的vmsnfs文件夹
  • 可以通过mount命令产看,当前系统的mount情况。

如图所示:

错误诊断:
有可能mount成功,但是在windows 访问mount的文件夹时,会遇到access denied的错误。在nfs server 端可能需要给文件夹读写的权限:chmod 777 /vmsnfs/

参考文章:

October 30th, 2011

配置Apache 使其支持伪静态url

No Comments, Apache, LAMP, by zhangxin.

最近在linode 上搭建了一个站点:孩他娘,http://www.haitaniang.com
站点是搭建在LAMP 平台之上。

  • 首先,需要知道Apache 是否将mod_rewrite模块打包进来。可以使用命令apache2ctl -M 查看rewrite_module 是否显示在模块安装列表里。如果没有安装, 有两种方法可以安装这个模块:

    • 通过在Apache配置文件里,添加LoadModule rewrite_module modules/mod_rewrite.so
      AddModule mod_rewrite.c,然后重新编译Apache
    • 另外也可以不修改任何文件,通过命令a2enmod rewrite来加载rewrite模块。

    重启Apache,使修改生效。

  • 其次,在Apache的配置文件里,添加:

    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all

  • 最后,在.htaccess 文件里添加:
    DirectoryIndex index.php
    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

好了,做完以上三个步骤,就实现了伪静态的url。

October 26th, 2011

安装php gd扩展

No Comments, PHP, by zhangxin.

如果网站需要图片分享的功能,就需要安装php gd的扩展模块。
在ubuntu下,可以轻松的通过sudo apt-get install php5-gd 来实现

October 26th, 2011

给网站加favicon?

No Comments, LAMP, by zhangxin.

在浏览器地址栏里,经常看到很精致的favicon. 其实这个很简单:
1、用photoshop 做一个32 * 32 px 的icon。
2、将icon放在网站的根目录下。
3、将这两行代码加到 网页的head里边,就可以了。
<link rel=”bookmark” href=”http://你的网址/favicon.ico” type=”image/x-icon”>

<link rel=”shortcut icon” href=”http://你的网址/favicon.ico” type=”image/x-icon”>

注意:该图标的路径一定要使用绝对路径。

要做social publishing的项目了,之前自己积累的一些social media 和web分析基础终于用上了。但是对概念的理解还是不够细,所以准备系统学习下这方面的东西。顺道也作为某个同学学习的科普读物,若真如此,再好不过。

主要结构:1、定义 2、 应用

跳出率

跳出率指单页访问次数或访问者从进入(目标)页离开网站的访问次数百分比。可使用跳出率来衡量访问质量,高跳出率通常表示网站进入页对您的访问者不具针对性。 目标网页越有吸引力,就会有更多访问者在您的网站上停留并进行转换。 通过针对各个关键字和您所投放的各个广告来分别定制目标网页,可最大限度地降低跳出率。 目标网页应提供广告中承诺的信息和服务。

在web分析的产品中,跳出率都是要追踪的核心数据。google analytics 在这方面不错,感兴趣的朋友们可以使用。
对于一些常做站点推广的站长来说,分析跳出率增加的原因,并提供相关的优化方案,则是更加实际的话题。
以下的六点来自于文章:王继顺:浅析如何降低网站的跳出率 http://www.tui18.com/201108/2318098.html
第一:网站的打开速度

  当访客来到网站的第一次操作就是打开网站的首页或者某个内页,网站的打开速度将直接影响着这个访客还是否想打开其他的网页,假如一个网站的打开速度很快,他会很自然的点击其他好奇的内容页,因为这毫不费功夫。

  第二:网站的内部优化

  在首页或者内页添加相关文章、上一篇、下一篇、推荐您阅读XX文章、最新文章、最热评论等这样的版块和设置是非常有利于访客的二次操作的,通过设置合理的网站的内部优化,引导访客点击其他的页面,从而大大的降低了网站的跳出率。

  第三:做一个标题党

  很多时候,我是不建议大家做一个标题党的,但是在事实上,一个有吸引力的标题是会给网站带来大的流量和二次点击的,人都有好奇心,当一个标题很吸引人的时候,他必定好奇的去看看写的是什么,或者发生了什么事。这也是一个不错的降低网站跳出率的好方法。吸引眼球法!

  第四:做好网站的内部锚文本

  很多同学在写内容的时候,不太注重锚文本的建设,其实合理的设置网站内容的关键词锚文本,对于网站内容页面的交互性有很大的提升,同时也在吸引着用户的二次操作。从而降低了网站的跳出率。

第五:减少网站的广告投放

  一个网站为了盈利,站长在网站上投放大量的广告,或者弹窗,这对网站的用户体验度是致命的。当访客打开一个网站,弹出了很多其他的网站,不知道的还以为自己的电脑中毒了呢。下次访客也不敢来了,想必网站被立刻关掉了吧。

  第六:减少网站的死链接

  在前面,我们就降到死链接对于网站的影响,当访客来到网站发现很多打不开的网站,不禁造成用户体验度降低,也直接影响着网站的跳出率和流量的流失。这些都是我们不希望看到的。应该注意。

Adobe air 2.0 及其以上版本开始支持Air应用调用并且与native process进行通信。不同的操作系统可以执行不同的文件格式,Mac OS: dmg; Windows: exe; Linux: rpm 或者deb。
下面的例子是 在windows 7 上,通过运行cmd.exe 执行一个bat文件以修改 windows的代理。


public function enableProxy(event:Event):void {
if (NativeProcess.isSupported) {
trace("NativeProcess supported");
var OS:String = Capabilities.os.toLocaleLowerCase();
var file:File;
if (OS.indexOf('win') > -1) {
//Executable in windows
file = new File('C:\\Windows\\System32\\cmd.exe');
} else if (OS.indexOf('mac') > -1 ) {
//Executable in mac
} else if (OS.indexOf('linux')) {
//Executable in linux
}
var p:NativeProcess = new NativeProcess();
var s:NativeProcessStartupInfo = new NativeProcessStartupInfo();
s.workingDirectory = new File("C:\\test");
s.executable = file;
var args:Vector. = new Vector.();
args.push("/c");
args.push("C:\\test\\ModifyProxy.bat");
args.push(true);
s.arguments = args;
p.addEventListener(NativeProcessExitEvent.EXIT, onExit);
p.start(s);
} else {
trace("NativeProcess not supported");
}
}

private function onExit(evt:NativeProcessExitEvent):void {
trace("NativeProcess exit");
}

通过修改注册表更改代理的bat文件
@echo off
@rem This bat file is used to modify proxy in registry

IF /I "%1"=="true" (
ECHO Value is "%1" and Proxy enabled...
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /d "1" /t REG_DWORD /f
) ELSE (
ECHO Value is "%1" and Proxy disabled...
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /d "0" /t REG_DWORD /f
)
exit /B 1

May 30th, 2011

Memcached实践

No Comments, Memcached, 分布式架构, by gaochuan.

Memcached是什么?

Memcached是使用C语言编写的开源高效分布式对象缓存系统(Free & open source, high-performance, distributed memory object caching system)。官网地址:http://memcached.org/[1]。

现在已经实现的开源Memcached客户端版本从C到PHP应有尽有,详情:http://code.google.com/p/memcached/wiki/Clients

Memcached的Logo很像QB,我一直想吐槽,至今终于有了机会能够一吐为快!请看图1的对比:

图1 QB和Memcached Logo的对比

无论是单个造型还是对应于QB无限增殖的万马奔腾式设计,皆神韵十足。当然小圆烂尾了……于是不提了……

形象地比喻, Database就像是硬盘,Memcached就像是内存。一个可以长期保存数据,一个可以不断电的快速访问。(或者Memcached是cache,Database是内存,相关的研究可以参考关于NoSQL的文章。)

最为原始的数据库应用方法是,针对每一次数据操作都直接存取Database,但是很明显这样消耗非常大。通过测试计时你会发现,一次用户数据读取所花费的2ms中可能有1.5ms甚至更多都在进行数据库I/O操作。

针对这样的问题,数据持久层框架(例如Hibernate)针对Database操作进行了封装,其中之一的改进是其提供了缓存机制。简单解释,一次数据操作将优先针对框架提供的缓存进行,如果缓存命中失败才会访问数据库。不过尽管如此,框架自带缓存机制的可用性和扩展性十分有限。

于是我们便有了Memcached。Memcached可以看成是一种完全脱离于Database层的缓存机制。和Hibernate等框架提供的缓存机制的不同之处在于,数据存取的命中和填充规则将完全由我们来定义,额外劳动换来的会是非凡的性能和自由。

当然了Memcached中的数据无法长期保存,Memcached进程一停止,数据即会消失。想象一下我们在Word中编写blog,最后在没有存盘的前提下就关闭了电源。除非是新版的Word,否则作者你就只能重敲一遍键盘了。为了减少这种情况发生时给我们带来的损失,还需额外制作一个定时Memcached抓取程序(其原理和新版Microsoft Office所提供的定时缓存文件的机制很类似,在文章的后续会有介绍)。

memcached协议

memcached支持的协议有二:UDP、TCP。

TCP不多说了,有连接的传输协议,保证传输的正确性和顺序性。当客户端和Memcached建立TCP连接之后,直接发送命令本身即可。

实际上当我们搭建起Memcached服务之后,本地可以直接通过telnet工具与之连接,操作的过程完全和TCP协议的实现相同。

UDP协议较之稍微复杂一些,UDP的传输特点:无连接,不保证传输正确性和顺序性。也因为这样的特点使得使用者自己需要定义传输协议来保证实际传输的可用性。

Memcached专门定义了一套UDP的传输协议,包括了消息头和消息体两部分。用户制作自己的MC客户端时需要实现它提供的UDP协议,在发送消息内容之前还需要包装一个UDP包头以填充成完整UDP包。

同时,Memcached对于单个UDP包的大小也做了限制,虽然在相关文档中没有提到过……但是通过阅读C源码得出的限制是1408 Bytes。这也就意味着如果需要接收Memcached发送的较大的数据包,你还需要进行拼包的操作。

Memcached自定义的UDP协议包头如图2:

图2 UDP包头

Memcached使用技巧

数据转储

Memcached的实用价值在于其访问速度。但是单靠它最终无法构建一个完整的数据持久层。Memcached中存储的数据无法长期断电保存。因此在Memcached之外需要自己制作数据转储程序。据本人了解市面上有一款MemcacheDB的数据持久框架[2]。它是采用了new BSD license协议,由新浪开发的Memcached改进框架。在Memcached作为前端缓存的前提下集合了Berkeley DB作为持久存储组件。也就是其在框架内实现了数据转储的功能。看相关博客介绍号称是钢铁般的品质,不过本人没有什么研究不过多评论。

数据转存的步骤:

1. 获取Memcached中所有项目的keyset。

2. 遍历keyset,逐个key访问Memcached获取其value。

3. 调用DB接口将项目存储到Database中。

其中存在的问题是,如何获取Memcached中所有项目的keyset?

有人说Memcached有命令stats cachedump,这个命令可以获取Memcached一个指定的内存槽中存储的所有数据的keyset。

这个方法固然还不错,但是,stats cachedump命令的返回包是有大小限制的,一般来说能返回50000个左右的key。如果你存储在Memcached中的key远小于50000时倒是可以试一试,但是对较大型的Web应用来说,这一点很不靠谱。并且 stats cachedump采用的算法效率低下。

一个替代方案是在另一个地方存储你的keyset。

图3 keyset的存储设计

理论上说Memcached中存储的所有数据都是上层逻辑写入的。假设我们有一个DataCenter模块,所有上层的逻辑都调用DataCenter暴露出去的set和get方法对数据进行存储,那么我们也可以在DataCenter中找到一个合适的内存位置存放上层每次访问的key,组成keyset。也就是由上层逻辑自己负责keyset的存储,这样虽然显得逻辑层次不够清楚,但是在内存中操作keyset使得它效率足够高。

如果项目的架构像图4所示的一样(比图3更实际的情况),也即全局存在多个Database、Memcached、上层server的结构。那么上文中所提到的由上层逻辑server来管理keyset的方法将无法使用,因为第一你无法知道玩家每次都从哪一个server登录,第二每一台server都存着keyset也就意味着数据转存服务器需要在转存的时候连接所有的server获取keyset,即耗时又不好统一管理。找个好位置存每个Memcached的keyset,并且要保证你的转存程序能够访问到这些keyset。例如自己编写一个独立的key server。如此一来,存储数据的流程中变增加了一项:向key server中存储key。坏处是每次存储操作都多进行了一次网络I/O处理,好处是key server完全独立于上层逻辑server和底层Memcached server。逻辑独立,并且日后的服务器扩展也可以做的更加轻松。

图4实际项目更可能出现的情况

并行访问时数据的同步

Memcached只有一个,但是其对应的上层访问线程可能不止一个。

例如:

item1 = 0

线程A:get item1                                         // item1 = 0

线程B:get item1                                         // item1 = 0

线程A:item1++; set item1              // item1 = 1

线程B:item1–; set item1                // item1 = -1

最终Memcached中item1的值是什么取决于线程A和B到底哪个后写入Memcached。线程A和线程B就像是两个上层Server,它们都以为自己获取的是最新的Memcached数据,但是实际上它们并不知道这个值在别的地方已经被修改过了。

这种问题可以通过加锁解决,很多人听到加锁就皱眉头,加锁并不意味着程序效率难以接受,处理的重点在于对什么东西加锁和对什么样的操作加锁。

针对数据加悲观锁,那么在占用线程释放此数据之前别的线程是无法访问该数据的。从底层否定了并行的可能性,但同时安全性也最高。

针对修改添加标记,例如Memcached中提供的命令cas和gets。不同于普通的set和get,cas在set之后还会修改一个数据对应的version值。每一次修改都会将这个version值加1,。同时,修改之前也会判断数据修改者所持有的version是否有权令其修改该数据。(较小的version持有者将无法修改该数据,只能重新获取。)

至于最终使用什么方法,我的建议是根据不同的业务逻辑情况分类处理。想要一刀切的话固然简单方便,但是效率和适用性会受影响。甚至可以说根据业务的特性,如果可以带来大量的性能提升,牺牲一些安全性也未尝不可(这一点很重要,不是所有的数据都需要你的层层保护,有时候性能更加重要)。

故障处理

Memcached的数据是存储在内存中的,直到这些数据被转存到磁盘之前,它们都很不完全。一台物理服务器可能会出现各种各样的故障情况,网络断开,硬盘损坏,服务器电源松动(如果检测人员每天都需要漫步在服务器机房里,这个不是天方夜谭)。同时如果项目应用所占有的服务器数量众多,那么整体的故障几率会更高。

同时,不同的故障对系统带来的影响也不近相同。

网络断开:Memcached中存储的数据不会丢失。如果是上层服务和Memcached之间网络断开,那么上层服务需要将数据缓存下来,恢复连接之后立刻写入Memcached(此处省略了无数需要详细考虑的问题,缓存的同时也会带来数据同步和上层服务器内存容量的问题… …)。如果是Memcached和数据转存程序之间的网络断开,这个影响并不算大,保证网络连接尽快恢复即可(不得不说的是Memcached容量也是有限的,持续写入数据而不将它们存入数据库中,旧有内容很可能被替换)。

Memcached机器硬损坏:这种尴尬的情况就不需要多说什么了,老天用雷劈你你能如何。用户数据回档时间取决于你数据转存程序的运行周期… …好在发生几率不大。

服务器电源松动:同机器硬损坏(同时你可以有机会暴揍一顿某人)。这也从另一个角度对各位设计的数据转存效率提出了要求,数据转存的周期越小,用户数据的损失也越小。

Memcached服务器组的维护

假设我们面对的是一个真正大型的网络应用,全局将会存在多个Memcached服务器。那么,第一,每一个Memcached负责的数据范围是我们需要设计的。第二,当某个Memcached内存吃紧时,如何扩容也是一个问题。

考虑一下下面的这个情形:

假设我们将所有男性用户的数据存在Memcached1中,女性存在Memcached2中。应用开始没多久,我们就发现由于男性的数据远大于女性数据,Memcached1的内存占用超过80%并开始报警。

我们需要进行的操作是:开启新的Memcached服务器Memcached3,将男性数据部分划分到Memcached3中。

于是我们开启了服务器Memcached3,同时也做出了划分,30岁以下的男性用户数据将继续存储在Memcached1中,30岁以上的男性数据将由Memcached3处理。

通过动态修改Memcached地址解析配置,现在所有的上层应用在面对新的男性大叔数据的时候都会定位到Memcached3中(旧有的Memcached1中的男性大叔数据怎么办?什么情况下访问Memcached3,什么情况下访问Memcached1?这些都是各位需要考虑的问题)。

如此便是一次简单的Memcached扩容过程,同理的还有针对某个Memcached服务器的停止操作。

个人感悟

所谓的额外劳动换取大量效能提升,其中的“额外劳动”也会是大量的… …这也正是等价交换之原理。

一个完整的程序架构可能是图5这样的:

图5一个可能完整的程序架构

加入Memcached对数据持久层的代码结构所可能带来的影响有:

1. 增加一个数据转存程序。其定时连接Memcached,获取所有的数据,拉入到Database中。

2. 增加MCClient。这个是提供给上层逻辑的数据存取接口,这个Client需要将上层的访问转换成Memcached协议,并与Memcached通信。现在MCClient针对各种语言已经有很多开源的实现了,但是这些开源包都只是实现了Memcached的基本协议。就我上面所提到的转存,同步等问题,还需要各位针对项目自己考虑完善了。

3. 一系列的Memcached维护工具,以及数据持久层错误应急处理方案。这个才是最麻烦的东西,Memcached网断了怎么办,MemcachedClient线程挂了怎么办,是否支持某些数据跳过Memcached直接即时存储Database,数据转存程序连接不上Database怎么办,数据转存程序进程挂了怎么办?… …当然了你也可以不考虑这些或者其中的部分问题,但假如你要制作一个面向百万在线用户的应用… …一切都需要详细规划。

参考

[1]What is memcached:http://code.google.com/p/memcached/wiki/NewOverview

[2] MemcacheDB官网:http://memcachedb.org/