文件的同步镜像在很多地方都需要用到,因此rsync这款免费软件得到了广泛的应用,包括在Windows平台上,都已经有了支持rsync的“cwRsyncServer”。
但是,我们一般都是通过结合crontab计划任务来实现文件同步的,这样做的缺点是效率低,不能做到实时同步。
现在,在Linux平台下我们可以利用2.6内核的inotify监控文件系统机制,通过inotify-tools来实现实时同步了。
具体操作如下:

1.安装所需软件
目前各大Linux发行版本都已经具有了rsync与inotify-tools的软件包,推荐通过RPM,yum,apt-get等方式进行安装。
RHEL:
[root@server1 ~]# rpm -ivh rsync-*
[root@server1 ~]# rpm -ivh inotify-tools-*

CentOS:
[root@server1 ~]# yum install rsync inotify-tools

Ubuntu:
[root@server1 ~]# apt-get install rsync inotify-tools

采用源码方式安装的步骤如下:
[root@server1 ~]# wget ftp://ftp.samba.org/pub/rsync/rsync-3.0.8.tar.gz
[root@server1 ~]# tar xzvf rsync-3.0.8.tar.gz
[root@server1 ~]# cd rsync-3.0.8
[root@server1 ~]# ./configure
[root@server1 ~]# make
[root@server1 ~]# make install

[root@server1 ~]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
[root@server1 ~]# tar xzvf inotify-tools-3.14.tar.gz
[root@server1 ~]# cd inotify-tools-3.14
[root@server1 ~]# ./configure
[root@server1 ~]# make
[root@server1 ~]# make install

2.配置ssh key信任
建议通过普通用户进行操作,理由是通过root操作本身就危险,免密码登陆的root就更危险了。

在两台服务器上创建rsync用户
[root@server1 ~]# useradd -m rsync
[root@server1 ~]# passwd rsync
[root@server2 ~]# useradd -m rsync
[root@server2 ~]# passwd rsync

[root@server1 ~]# su - rsync
[rsync@server1 ~]$ ssh-keygen -t rsa
在提示保存私钥(key)和公钥(public key)的位置时,使用默认值;
在提示是否需要私钥密码(passphrase)时,直接敲回车,即不使用私钥密码。
之后,将生成一对密钥,id_rsa(私钥文件)和id_rsa.pub(公钥文件),保存在/home/rsync/.ssh/目录下。

将公钥添加到远程主机的 authorized_keys 文件中
将文件上传到远程主机(假设远程主机IP为192.168.10.4)
[rsync@server1 ~]$ scp ~/.ssh/id_rsa.pub rsync@192.168.10.4:/home/rsync/

使用rsync用户SSH到登陆到远程主机,并将公钥添加到 authorized_keys 文件中
[rsync@server2 ~]$ mkdir .ssh
[rsync@server2 ~]$ chmod 700 .ssh
[rsync@server2 ~]$ mv ~/id_rsa.pub ~/.ssh/authorized_keys

重启SSH服务
[root@server1 ~]# /etc/init.d/sshd restart
[root@server2 ~]# /etc/init.d/sshd restart

3.创建inotify_rsync.sh脚本
[root@server1 ~]# vim inotify_rsync.sh

#!/bin/sh
SRC=/home/rsync/test
DST=rsync@192.168.10.4:/home/rsync/test

/bin/su - rsync
/usr/local/bin/inotifywait -mrq -e modify,delete,create,attrib ${src} | while D E F
do
/usr/bin/rsync -ahqzt --delete $SRC $DST
done

相关注解如下:
/usr/local/bin/inotifywait -mrq -e modify,delete,create,attrib ${src}
-m 是保持一直监听
-r 是递归查看目录
-q 是打印出事件
-e create,move,delete,modify,attrib 是指 “监听 创建 移动 删除 写入 权限” 事件

/usr/bin/rsync -ahqzt --delete $SRC $DST
-a 存档模式
-h 保存硬连接
-q 制止非错误信息
-z 压缩文件数据在传输
-t 维护修改时间
-delete 删除于多余文件

要排除同步某个目录时,为rsync添加--exculde=PATTERN参数,注意,路径是相对路径,具体查看man rsync。
要排除某个目录的事件监听的处理时,为inotifywait添加--exclude或--excludei参数,具体查看man inotifywait。

inotifywait 命令产生三个返回值,分别是“日期,时间,文件” 这3个返回值会做为参数传给read,因此脚本中的“while read D E F” 写法细化了返回值。

赋予脚本可执行权限
[root@server1 ~]# chmod +x inotify_rsync.sh
执行脚本
[root@server1 ~]# /root/inotify_rsync.sh &
设置脚本开机自启动
[root@server1 ~]# cat "/root/inotify_rsync.sh &" >> /etc/rc.local

4.测试
首先在server1服务器的/home/rsync/test目录下创建文件或目录,然后再到server2的/home/rsync/test目录下查看,如果看到就说明成功了。
[rsync@server1 ~]$ cd test
[rsync@server1 test]$ touch a.txt
注意:第一次SSH连接的时候可能需要输入一次密码,之后就不需要输入了。

[rsync@server2 ~]$ cd test
[rsync@server2 test]$ ls
a.txt

看到了a.txt文件,说明文件同步已经成功!


本文章只对目前主流的五款知识管理类服务(以下简称云笔记)进行数据对比和分析。

名称容量使用量文件限制支持系统
onenote25GB无限制无限制windows、Windows Mobile
evernote无限60M25MMAC、windows、iphone/ipod Touch/iPad、Android、Palm Pre&Pixi、Sony EricssonX、Windows Mobile
麦库500M无限制无限制windows、Android、iphone/ipod Touch
为知10GB100M10Mwindows、iphone/iPad、Android、Windows Mobile
有道笔记1GB无限制无限制windows、iphone

然后我们对使用功能体验进行对比

名称安全功能独有功能
onenote本地密码与office集成
evernote可新建手写与摄像笔记,手机版可录音
麦库本地密码
为知证书加密朗读、日历、日记功能
有道笔记白板

然后我们再对粘贴内容进行对比

名称表格网页图片本地文档
onenote√可编辑
evernote√可编辑
麦库√图片形式
为知√可编辑
有道笔记√可编辑

分析:

由以上三个对比表的比较,可分析得:

如果你比较在意安全性,可以选择:onenote、麦库、为知

如果你喜欢记日记,可以选择:为知

如果你喜欢手写或摄像记事,可以选择:evernote

如果你平时要保存表格并编辑,可以选择:onenote、evernote、为知、有道笔记

如果你要使用到会议白板记录功能,可以选择:有道笔记

总体来说,个人用户推荐为知,因为有记日记和朗读功能;上班族推荐onenote,因为和office2010集成;如果你是会议记录者推荐有道笔记或evernote,因为有道笔记有白板功能,evernote有录音功能;如果你是简洁控,那就用有道笔记吧;如果你想用evernote,可又怕被墙,就用麦库吧。

1、Nginx
# nginx -V
nginx: nginx version: nginx/1.0.0
nginx: built by gcc 4.1.2 20080704 (Red Hat 4.1.2-50)
nginx: TLS SNI support disabled
nginx: configure arguments: --user=www --group=www --add-module=/opt/ngx_cache --prefix=/opt/nginx --with-http_stub_status_module --with-http_ssl_module

2、PHP
# $PATH/php -r "phpinfo();" | grep configure

3、Apache
#  cat /usr/local/apache2/build/config.nice

4、MySQL
# cat /usr/local/mysql/bin/mysqlbug | grep CONFIGURE_LINE

也谈铁路订票系统的优化

[不指定 2012/01/17 12:10 | by ipaddr ]

近来诸多牛人在讨论12306.cn网站的优化,做为一名电商网站的技术人员,以及多次在12306.cn网站购票成功的IT人士,也参与大致分析一下。

网上传播较广的优化文章主要有两篇:
1. 云风同学设计的排队系统:  http://blog.codingnow.com/2012/01/ticket_queue.html
没细看,个人觉得这系统意义不大,解决不了关键问题,再牛B的排队系统,队伍排得再漂亮,没人插队,没人攻击,用户登录后,你提醒他前面还有8亿人在等待,再过2小时后来试试运气,照样骂声一片。当然适当运用队列系统来缓解后端压力,避免雪崩,也是可以参考的。(比如现在的12306,后端处理不过来,直接拒绝登录,让你在门外排队)

2. 陈皓同学的整站性能分析: http://www.udpwork.com/item/6708.html
对业务场景的分析很到位,12306.cn网站,与新闻门户,IM聊天工具,网游,微博业务完全不一样;根据CAP理论,后者由于对数据一致性要求不是很高,或者没有集中的数据资源,所以对数据做分区和平行扩展是容易很多很多的。另外,此文的结论也高度赞同。

这类电商网站具有很强的事务性,对数据一致性要求极高,不可能同一个座位卖给两个人,也不可能卖得超载,否则非在车上打起来不可。订单逻辑比淘宝之类的还要复杂一些,因为还有一个分配座位这个逻辑。

而且还有一个极其变态的规则:票是稀缺资源,不可能人手一张,只能靠抢;这就直接导致大家在放票的那段时间,全部登录到系统抢票,注定这类系统容易雪崩,系统设计时一定要考虑极端情况,在达到性能瓶颈时必须快速的丢掉一些用户请求,保证系统可用。

强事务的系统,数据层的分区设计和优化才是关键;
WEB层优化比较容易,js,css,image之类的使用常规的压缩、合并、客户端缓存、CDN分布,基本上没啥难度;
逻辑层也不复杂,不存在数据,可以很容易的平行扩展,但设计很关键;
数据层会是整个系统的性能瓶颈,因为最底层下订单时,必须会有锁表,可能在车次,或者是车箱级别锁表,下订单是串行的,这里没法并发。

以下简单讲一下核心业务逻辑(下订单)的一个优化思路。

主要有二个核心操作:
a. 查询车次
b. 下订单和分配座位

几个关键的数据:
1.库存表(余票信息)
2.订单表

数据库的优化:
1. 库存表
a. 数据按日期分区,因为前端入口是按日期来查询的,所以按日期分区是相当容易的。
b. 余票信息,分两张表:
     表A:  用来实时生成订单,这张表会锁表
     关键字段如下: 日期 | 车次 | 席别(坐,卧,无) | 余票数
     注意,这里同一个车次,将不同席别分成了多条记录,以避免单行锁表时,不影响其它席别的购票。可根据机器性能情况,按车次再进行数据分区。如果性能仍不能满足要求,可以再细分到车箱级别进行锁表。

     表B:  用于用户订票的第一个查询车次的页面,需要将表A的数据,定期同步过来,做些汇总给用户查询,这里的数据只读,并且可以复制N多份,数据量不大,可全内存化,以优化查询性能。
     关键字段如下:日期 | 车次 |坐余票数 |卧余票数| 无坐余票数
     注意,数据是旁路进程从表A同步过来的,非实时数据,同步粒度可以是秒级或分钟级,这地方没有实时数据的要求,因为这类系统库存信息变化太快,用户在第一个页面看到的库存,一定不等于下订单页面的库存。

2. 订单表

分两张表,分别为实时订单,以及取票订单表
     实时订单表:在下订单页面,只存在写操作,性能问题不大
     关键字段:日期 |证件号|车次 | 席别 | 数量(1)| 所属用户 | 其它信息
     注意:这里没有座位号信息,下订单时,不需要分配座位号


     取票订单表:用户支付成功后,由一个旁路进程(位置分配进程),将实时订单表的数据,按坐位分配规则,写入到这张表。为便于取票,可以按证件号将数据进行分区。
     关键字段: 日期 |证件号|车次 |席别 | 座位号

业务逻辑优化:

根据上面的表设计,基本可以看出业务如何实现了:
1. 查询车次页面:读余票B表,只读,可复制N份,平行扩展。
2. 下订单:根据用户请求,对余票A表进行锁表,行级锁,读出余票数,判断是否有余票,有的话,余票数减1,订票成功,写实时订单表。这地方千万不要去分配座位
3. 用户支付
4. 支付成功后,通知用户订票成功,后端进程再去分配座位。分配座位实时性要求不高,可以几小时后完成,发邮件或短信通知用户都OK。
5. 除此之外,以上逻辑没有考虑单个证件订多张票的问题,这个可以将订单A表的非实时数据,多复制几份进行查询。

经过以上优化,性能应该有很大提升,数据层也有了很大的平行扩展的能力了。

总结一下:

A.  经过以上调整,性能会有较大提升,但肯定还会有骂声,因为核心问题是票不够抢,假设10分钟内所有票都卖完了,估计没抢到的会骂娘,民工兄弟也会骂娘。
B.  不管骂声多大,铁老大开通网站卖票,并承诺不断改进,这绝对是一个进步
C.  核心问题是运力不足,如果车次能增加一倍的话,估计啥问题都解决了,也没人抢票了。(是车次增加一倍,不是铁轨增加一倍,要加强调度能力了)
D. 再深层点的原因,是地区发展不平衡导致,如果大家都在离家100公里内的地方工作,没必要这么折腾了。


http://code.google.com/p/fqueue/

FQueue是一个高性能、基于磁盘持久存储的队列消息系统。兼容memcached协议,能用memcached的语言都可以良好的与它通信。 FQueue为你提供一个不需要特别优化,高性能的一个消息系统。

特性

  • 基于磁盘持久化存储。
  • 支持memcached协议。
  • 支持多队列,密码验证功能。
  • 高性能,能达到数十万qps。
  • 低内存消耗。100-300M内存即可工作得很好。
  • 高效率IO读写算法,IO效率高。
  • 纯JAVA代码。支持进程内JVM级别的直接调用。
  • 在不需要强顺序的场景下,支持多机负载均衡。

不支持

  • 不支持topic方式的订阅功能。
  • 不支持主从复制。

POCO C++ Libraries

[不指定 2011/12/30 22:45 | by ipaddr ]
Modern, powerful open source C++ class libraries and frameworks for building network- and internet-based applications that run on desktop, server and embedded systems.

Instagram 架构分析笔记

[不指定 2011/12/07 19:30 | by ipaddr ]

Instagram 团队上个月才迎来第 7 名员工,是的,7个人的团队。作为 iPhone 上最火爆的图片类工具,instagram 用户数量已经超过 1400 万,图片数量超过 1.5 亿张。不得不说,这真他妈是个业界奇迹。

几天前,只有三个人的 Instagram 工程师团队发布了一篇文章:What Powers Instagram: Hundreds of Instances, Dozens of Technologies,披露了 Instagram 架构的一些信息,足够勾起大多数人的好奇心。读罢做点笔记,各种线索还是有一定参考价值的。能打开原文的建议直接读原文。

Instragram.png

Instagram 开发团队奉行的三个核心原则:

  • Keep it very simple (极简主义)
  • Don't re-invent the wheel (不重复发明轮子)
  • Go with proven and solid technologies when you can(能用就用靠谱的技术)

OS/主机

操作系统的选择,在Amazon EC2上跑 Ubuntu Linux 11.04 (Natty Narwhal) ,这个版本经过验证在 EC2 上够稳定。因为只有三名工程师,只有三名工程师,所以自己部署机器到 IDC 是不靠谱的事情。幸好有亚马逊。

负载均衡

此前曾用过两台 Nginx 做 DNS 轮询承载前端请求,这样做会有副作用,现在已经迁移到Amazon的ELB(Elastic Load Balancer),起了三个 Nginx 实例,在 ELB 层停掉了 SSL , 以缓解 CPU 压力。DNS 服务使用 Amazon Route53 服务。
 

应用服务器

启用了 25 个 Django 实例,运行在 High-CPU Extra-Large 类型的服务器实例上,之所以用 High-CPU Extra-Large 实例是因为应用请求是 CPU 密集型而非 IO 密集型。

使用 Gunicorn 作为 WSGI 服务器。过去曾用过 Apache 下的 mod_wsgi 模块,不过发现 Gunicorn 更容易配置并且节省 CPU 资源。使用 Fabric 加速部署。

数据存储

用户信息、图片元数据、标签等大部分数据存储在 PostgreSQL 中。主要的 Shard 数据库集群有 12个节点。

实践中发现 Amazon 的网络磁盘系统单位时间内寻道能力不行,所以有必要将数据尽量放到内存中。创建了软 RAID 以提升 IO 能力,使用的 Mdadm 工具进行 RAID 管理。

管理内存中的数据,vmtouch 这个小工具值得推荐。

PostgreSQL 设置为 Master-Replica 方式,流复制模式。利用 EBS 的快照进行数据库备份。使用 XFS 文件系统,以便和快照服务充分配合。 使用 repmgr 这个小工具做 PostgreSQL 复制管理器器。

连接池管理,用了 PgbouncerChristophe Pettus 的文章包含了不少 PostgreSQL 数据库的信息。

TB 级别的海量图片存储在 Amazon S3 上,CDN 采用的也是 Amazon 的服务,CloudFront。

Instagram 也是 Redis 的重度用户,Feed 以及 Session 信息都用 Redis 处理,Redis 也是以 Master-Replica 方式部署。在 Replica 节点上进行数据备份。

使用了 Apache Solr 承担 Geo-search API 的工作,Solr 简单的 JSON 接口也不错。

缓存使用了 6 个 Memcached 实例,库使用 pylibmc 和 libmemcached。亚马逊也提供缓存服务-Elastic Cache service ,Instagram 也有尝试,不过不便宜。

任务队列/发布通知

队列服务使用 Gearman ,通知系统则使用 pyapns 来实现。

监控

前面提及的服务器实例数量加起来,的确有100多个,有效的监控是相当有必要的。使用 Munin 作为主要监控工具 , 也写了不少定制插件,外部监控用 Pingdom 的服务。通知服务使用 PagerDuty

对于 Python 的错误报告,使用 Disqus 团队开源的 Sentry 来处理。

几个感想

0)轻装上阵说起来容易,做起来非常难。这也是 Instagram 团队目前最令人着迷的地方;

1)Python 社区已经足够成熟,各个环节上都已经有不错的解决方案了。

2)如果要问我最大的一个感慨,我要说:Amazon 真是一家伟大的公司,甚至比 Google 还伟大

写JAVA程序时用到了在一个构造函数里调用另一个构造函数的方法。在JAVA里的使用方法是:this(参数...)。当时脑子里冒出一个问题:在C++里构造函数如何调用另构造函数?因此本人写了如下一段程序来看测试:

#include<iostream>
using namespace std;

class A{
    public:
        int a;
    public:
    A(int _a)  {
        a = _a;
    }
    A()  {
        A(11);
    }
};
int main(int argc,char* argv[])
{
    A aa;
    cout<<aa.a<<endl;
    return 0;
}

该程序的运行结果让我傻眼了,结果输出a的值不确定。为什么在默认构造函数中调用另一个构造函数确没有改变a的值呢???后来才明白,其实A(11)是调用另一构造函数并产生一临时变量,而不是去用另一构造函数去构造默认构造函数。
1)在c++里,由于构造函数允许有默认参数,使得这种构造函数调用构造函数来重用代码的需求大为减少。

2)如果仅仅为了一个构造函数重用另一个构造函数的代码,那么完全可以把构造函数中的公共部分抽取出来定义一个成员函数(推荐为private),然后在每个需要这个代码的构造函数中调用该函数即可。

3)偶尔我们还是希望在类的构造函数里调用另一个构造函数,可以按下面方式做:

在构造函数里调用另一个构造函数的关键是让第二个构造函数在第一次分配好的内存上执行,而不是分配新的内存,这个可以用标准库的placement new做到。
最近在CDT中发现一些include提示“Unresolved inclusion“,但编译正常,经网上搜索可按以下方法修复:
打开 Windows-->Preferences-->C/C++-->Build-->Environment增加Environment variables to set

及点Add添加:

Name: C_INCLUDE_PATH

Value: /usr/include:/usr/include/i386-linux-gnu


Name: CPLUS_INCLUDE_PATH

Value: /usr/include/c++/4.6  (如gcc版本不同,需改为正确的路径)

重启CDT后问题解决。

Balsamiq Mockups完全手册

[不指定 2011/11/07 14:30 | by ipaddr ]

http://www.hanjunxing.com/balsamiq-mockups-one-for-all

Balsamiq Mockups出自加利福尼亚州的Balsamiq工作室,创始人Peldi在2008年6月推出了这款手绘风格的产品原型设计工具,并广受好评。2年多来,Balsamiq工作作为一个微型独立软件开发商,专注于Mockups的开发设计,仅3周便实现了盈利,18个月内销售额达到200万美元,用户端数量超过10万个,这与Balsamiq Mockups的市场用户细分的成功以及产品特性是分不开的。

分页: 7/57 第一页 上页 2 3 4 5 6 7 8 9 10 11 下页 最后页 [ 显示模式: 摘要 | 列表 ]