English Sentence Loading...
英语句子加载中...
预览模式: 普通 | 列表

   上次写了一些我们在面对网站流量和并发慢慢升高的情况下,最容易做的,也可能会是很有效果的办法,这次我想继续写一些,关于缓存的使用。
    当网站流量和并发升高到一定数量,我们会发现,数据库的瓶颈出现了,它成了影响提高响应时间的罪魁祸首,所以我们要尽量少的去操作数据库,于是缓存便有了它的用武之地。我们常用的缓存大概有几种,分别简单介绍一下(纯属个人经验之谈,如有错误,欢迎指正):
   
    文件缓存:
    我们可以在读取频繁的页面模块中加上一级文件缓存,它位于程序与数据库之间,把数据库中的记录缓存到文件里,使程序在读取数据时先读取文件,可以提高页面的响应速度。对于读>>写的部分,我们完全可以采用这种方法,在写入数据库之后重新更新一下缓存文件,使数据保持一致。但是文件缓存也有它的不足之处,首先它只适用于小模块的缓存,我们最好不要把几兆的数据写到文件里去,文件越大,反而起不到缓存的效果;其次在网站并发达到一定数量级时,要保证缓存文件读写时的安全性,防止文件正在被写入的同时,还要响应读的请求。可以利用一个备份文件来避免这种情况的出现,在更新文件之前,先copy出一份文件,为了避免重复copy,可以先检测文件是否存在,然后再copy。在读取缓存文件时要先读取备份文件是否存在,如果存在就读取备份文件,不存在,刚读取原缓存文件。这种更新缓存文件的方法能达到比较高效的数据同步,也存在一个弊端,就是多个并发同时有写文件的需求时,可能会出现读取缓存文件出错的现象发生。我们也可以写在crontab里,指定每隔一段时间更新缓存,这样,我们就只有一个crontab在写文件,相对来说比较安全,但数据同步不如前者高效。
   
    memcache:
    memcache是danga.com的一个项目,是一个高性能的分布式的内存对象缓存系统。高性能是因为它是内存级的缓存,通过在内存里维护一个统一的巨大的hash表来缓存数据。它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等;而且它又是分布式的,它允许来自不同主机的用户来访问这个缓存系统。它对解决数据库瓶颈的问题很有成效,同时也使得多台主机能同时共享内存,并且它支持当今流行的多种开发语言PHP,JAVA,JSP,PYTHON等,它的使用也非常简单方便,但又非常高效灵活,是缓存技术中一个不错的选择。
   
    ADODB缓存:
    用过ADODB的朋友们一定熟悉ADODB的缓存,我们可以利用它设置数据结果的缓存,在缓存时间内ADODB不会再去检索数据库。要使用它的缓存功能,我们先要设置缓存目录:

  1. $ADODB_CACHE_DIR = '/var/www/localhost/ADODB_cache';
  2. ...
  3. $conn = &ADONewConnection('mysql');
  4. $conn->PConnect('localhost','root','123456','test');
  5. $sql = "SELECT * FROM `users`";
  6. $rs = $conn->CacheExecute(15,$sql);
 

    将第一个参数设为0,意思是更新cache数据。
   
    Smarty缓存:
    Smarty缓存也是一个文件级的缓存,它缓存的是一个已经经过smarty的模板编译并生成静态的html文件,在缓存时间之内,如果再有请求,smarty会直接给出这个文件的内容,在一些并发不是太高和对数据同没有很强的实时同步的需求的时候,我们可以考虑这种方法,当然这个要在网站开发时就要使用这个模板引擎,不然做完再套这个,可能会改掉好多哦!它的使用也比较简单,只有简单的几句设置即可。
    
  1. $smarty = new Smarty;
  2. $smarty->template_dir = dirname(__FILE__)."/../templates";
  3. $smarty->compile_dir = dirname(__FILE__)."/../templates_c";
  4. $smarty->left_delimiter = "([";
  5. $smarty->right_delimiter = "])";
  6. $smarty->cache_dir = dirname(__FILE__)."/../cache";
  7. $smarty->caching = true;

        
    Squid缓存:
    Squid很强大,呵呵,我最近也正在看它的教程,现在还没有用到多少,只是提一下,利用它可以搭建起能承受高并发的网站应用,技术方面就不多献丑啦,大家可以自己去网上查下资料。

    此外,我们还可以选择XCache,也可以选择eaccelerator来加速php,都能得到不错的效果。这些扩展安装也非常简单,以Xcache举例。

liubing@liubing-flow:~$ tar -zxvf xcache-1.3.0.tar.gz
liubing@liubing-flow:~$ cd xcache-1.3.0/
liubing@liubing-flow:~/xcache-1.3.0$ /usr/local/php/bin/phpize
liubing@liubing-flow:~/xcache-1.3.0$ ./configure --enable-xcache --with-php-config=/usr/local/php/bin/php-config
liubing@liubing-flow:~/xcache-1.3.0$ make
liubing@liubing-flow:~/xcache-1.3.0$ sudo make install
liubing@liubing-flow:~/xcache-1.3.0$ sudo cat xcache.ini >> /usr/local/php/etc/php.ini


    因为我的环境是nginx + php(fastcgi),所以需要重启fastcgi。如果是apache,那重启下apache就好了。这里还有几个xcache的参数需要说明一下,在重启之前可能要做一点小的修改。

zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/xcache.so ; 指定xcache.so的路径
xcache.admin.enable_auth = Off ; XCache后台是否需要验证
xcache.mmap_path = "/tmp/xcache" ; 共享内存标识名,这是个文件,而非目录
xcache.size = 64M  ; XCache的内存缓存大小,普通网站可以设置为64MB
xcache.count = 2  ; cpu数量,可使用`cat /proc/cpuinfo |grep -c processor`查看
xcache.optimizer = Off ; 是否启用优化器

php 分页类

这个分页类融合了数据库查询的功能,用起来还比较方便。下面这个是用了ADODB类来操作数据库,关于ADODB的操作,在这里就不多说了。

下载: dbclass.php
  1. <?php
  2.     /**
  3.     * FileName   : dbclass.php
  4.     * Description: Simple db class
  5.     * Author     : Liubing(liubing@eduicc.com)
  6.     */
  7.     class dbclass
  8.     {
  9.         var $dblink;
  10.         var $_sql;
  11.         var $primary_key;
  12.       
  13.         function dbclass($primary_key='id')
  14.         {
  15.             $this->connectDB();
  16.             $this->primary_key = $primary_key;
  17.         }  
  18.       
  19.         function connectDB()
  20.         {
  21.             global $db_config;
  22.             if(is_object($this->dblink)) return;
  23.             $this->dblink = &ADONewConnection('mysql');
  24.             $this->dblink->PConnect($db_config["db_host"],$db_config["db_user"],$db_config["db_password"],$db_config["db_name"]);
  25.         }
  26.       
  27.         function E($sql='')
  28.         {
  29.             $sql != '' && $this->_sql = $sql;
  30.             $this->dblink->Execute("SET NAMES UTF8");
  31.             return $this->dblink->Execute($this->_sql);
  32.         }
  33.       
  34.         function Store($fields,$tb,$key='')
  35.         {
  36.             if(count($fields) == 0) return false;
  37.           
  38.             foreach($fields as $field => $value){
  39.                 $params[] = "`{$field}`='".$this->safestring($value)."'";
  40.             }
  41.             $key = intval($key);
  42.             if($key > 0){ //modify
  43.                 if($this->primary_key == '' || $key < 1) return false;
  44.                 $sql = "UPDATE `{$tb}` SET ".implode(",",$params)." WHERE `{$this->primary_key}`='{$key}'";
  45.             }else{ //add new record
  46.                 $sql = "INSERT INTO `{$tb}` SET ".implode(",",$params);
  47.             }
  48.             return $this->E($sql);
  49.         }
  50.       
  51.         function getResults($params,$tb,$orderfield='')
  52.         {
  53.             $sql = "SELECT * FROM `{$tb}` ";
  54.             if(is_array($params) && count($params) > 0){
  55.                 $sql.= " WHERE ".implode(" AND ",$params);
  56.             }
  57.             if($orderfield != '') $sql.= " ORDER BY `{$orderfield}`";
  58.           
  59.             $rs = $this->E($sql);
  60.             $offset = 0;
  61.             while(!$rs->EOF){
  62.                 $rs->fields["offset"] = ++$offset;
  63.                 $results[] = $rs->fields;
  64.                 $rs->MoveNext();  
  65.             }
  66.           
  67.             if(count($results) == 0) return false;
  68.             elseif(count($results) == 1) return $results[0];
  69.             else return $results;
  70.         }
  71.       
  72.         function getRow($key,$tb)
  73.         {
  74.             if($this->primary_key == '' || $key < 1) return false;
  75.             $params[] = "`{$this->primary_key}`='{$key}'";
  76.             $results = $this->getResults($params,$tb);
  77.             return $results;
  78.         }
  79.       
  80.         function delRow($key,$tb)
  81.         {
  82.             if($this->primary_key == '' || $key < 1) return false;
  83.             $sql = "DELETE FROM `{$tb}` WHERE `".$this->primary_key."`={$key}";
  84.             $this->E($sql);
  85.         }
  86.       
  87.         function getNum($tb)
  88.         {
  89.             $sql = "SELECT COUNT(*) AS `t` FROM `{$tb}`";
  90.             $rs  = $this->E($sql);
  91.             return $rs->fields['t'];
  92.         }
  93.       
  94.         function getMax($field,$table,$params=array())
  95.         {
  96.             $sql = "SELECT MAX(`{$field}`) AS `{$field}` FROM `{$table}` WHERE 1 ";
  97.             foreach($params as $f => $val){
  98.                 $sql.= " AND `{$f}`='{$val}'";
  99.             }
  100.             $rs = $this->E($sql);
  101.             return $rs->fields[$field];
  102.         }
  103.       
  104.         //html,mysql
  105.         function safestring($string,$mode="3")
  106.         {
  107.             switch($mode)
  108.             {
  109.                 case "0":
  110.                     break;
  111.                 case "1":
  112.                     $string = mysql_escape_string($string);
  113.                     break;
  114.                 case "2":
  115.                     $string = strip_tags($string);
  116.                     break;
  117.                 case "3":
  118.                     $string = strip_tags(mysql_escape_string($string));
  119.                     break;
  120.                 default:
  121.                     break;  
  122.             }
  123.             return $string;
  124.         }
  125.     }


  1. <?php
  2.     /**
  3.     * FileName   : pageclass.php
  4.     * Description: pagination class
  5.     * Author     : Liubing(liubing@eduicc.com)
  6.     */
  7.   
  8.     require_once dirname(__FILE__).'/dbclass.php';
  9.   
  10.     class pageclass extends dbclass
  11.     {
  12.         var $page;
  13.         var $pagesize;
  14.         var $pagesql;
  15.         var $results;
  16.         var $offset;
  17.         var $params;
  18.         var $totalpage;
  19.         var $totalnum;
  20.         var $pagelink;
  21.         var $pagerange;
  22.       
  23.         function pageclass($page=1,$params=array(),$pagesize=10)
  24.         {
  25.             dbclass::dbclass();
  26.             $page            = intval($page);
  27.             $pagesize        = intval($pagesize);
  28.             $this->page      = $page < 1 ? 1 : $page;
  29.             $this->pagesize  = $pagesize < 10 ? 10 : $pagesize;
  30.             $this->offset    = ($this->page - 1) * $this->pagesize;
  31.             $this->params    = $params;
  32.             $this->pagerange = 10;
  33.         }
  34.       
  35.         function loadpage($sql)
  36.         {
  37.             $sql            = preg_replace("/select/i","select",$sql);
  38.             $sqlitems       = explode("select",$sql);
  39.             unset($sqlitems[0]);
  40.             $newsql         = implode("SELECT",$sqlitems);
  41.             $newsql         = "SELECT SQL_CALC_FOUND_ROWS ".$newsql." LIMIT {$this->offset},{$this->pagesize}";
  42.             $rs             = $this->E($newsql);
  43.             $pagesql        = "SELECT FOUND_ROWS() AS `allnum`";
  44.             $pagers         = $this->E($pagesql);
  45.             $pageresult     = $pagers->fields;
  46.           
  47.             $this->totalnum = $pageresult["allnum"];
  48.             $this->setpage();
  49.           
  50.             $offset         = $this->offset;
  51.             while(!$rs->EOF){
  52.                 $offset++;
  53.                 $rs->fields['offset'] = $offset;
  54.                 $this->results[]      = $rs->fields;
  55.                 $rs->MoveNext();  
  56.             }
  57.         }
  58.       
  59.         function setpage()
  60.         {
  61.             if(count($this->params) > 0){
  62.                 foreach($this->params as $key => $value){
  63.                     $params.= "{$key}={$value}&";
  64.                 }
  65.             }
  66.           
  67.             $this->totalpage = ceil($this->totalnum/$this->pagesize);
  68.           
  69.             $this->pagelink = "<span class='nolink'>".$this->page."/".$this->totalpage."</span>";
  70.           
  71.             //FIRST PREV
  72.             if($this->page > 1){
  73.                 $this->pagelink.= " <a href='?{$params}page=1'>FIRST</a> ";
  74.                 $this->pagelink.= " <a href='?{$params}page=".($this->page - 1)."'>PREV</a> ";
  75.             }else{
  76.                 $this->pagelink.= " <span class='nolink'>FIRST</span> ";
  77.                 $this->pagelink.= " <span class='nolink'>PREV</span> ";
  78.             }
  79.           
  80.             for($i = $this->page - $this->pagerange; $i <= $this->page + $this->pagerange; $i++){
  81.                 if($i < 1 || $i > $this->totalpage) continue;
  82.                 $this->pagelink.= $i == $this->page ? " <span class='currentpage'>[{$i}]</span> " : "<a href='?{$params}page={$i}'>[{$i}]</a> ";
  83.             }
  84.           
  85.             //NEXT LAST
  86.             if($this->page < $this->totalpage){
  87.                 $this->pagelink.= " <a href='?{$params}page=".($this->page + 1)."'>NEXT</a> ";
  88.                 $this->pagelink.= " <a href='?{$params}page={$this->totalpage}'>LAST</a> ";
  89.             }else{
  90.                 $this->pagelink.= " <span class='nolink'>NEXT</span> ";
  91.                 $this->pagelink.= " <span class='nolink'>LAST</span> ";
  92.             }
  93.         }
  94.     }


使用举例:
下载: list.php
  1. <?php
  2.     //引入ADODB
  3.     require_once dirname(__FILE__)."/../lib/adodb/adodb.inc.php";
  4.   
  5.     //DB configuration
  6.     $db_config = array("db_host"=>"localhost","db_user"=>"root","db_password"=>"123456","db_name"=>"flow");
  7.   
  8.     $page    = intval($_REQUEST['page']);
  9.     $sql     = "SELECT * FROM `flow_bulletins` WHERE 1=1 ";
  10.     $keyword != "" && $sql.= " AND (`bulletin_title_en` LIKE '%{$keyword}%' OR `bulletin_title_cn` LIKE '%{$keyword}%' OR `bulletin_title_fr` LIKE '%{$keyword}%') ";
  11.     $status  != "" && $sql.= " AND `enabled`='{$status}' ";
  12.     $sql    .= " ORDER BY `ordering`";
  13.     $pageparams = compact("keyword","status");
  14.     $pageobj = new pageclass($page, $pageparams);
  15.     $pageobj->loadpage($sql);
  16.     var_dump($pageobj);
  17. ?>
标签: php 分页

对于一个小型的个人网站或企业网站来说,可能很少有机会能遇到高并发的流量。但是随着网络信息爆炸,越来越多的人喜欢在网上搜寻自己需要的资源,这也就给我们的服务器提出了更高的要求。也是随着SNS类网站的热潮,越来越多的网站也正面对更加复杂的逻辑关系,可能一个页面要进行十几次查询才能完成。那么我们就要提供更加稳定、安全、高效的网络服务。

一、优化我们的SQL语句
   在我们的开发过程中,我们可能由于种种原因,没有来得及对SQL的优化考虑得那么周全(当然以下这些有好多都是我们在开发中需要考虑的)。那么在我们网站的测试环节中,就要着重先来考虑这一点。如果我们用的是Mysql,可以开启它的慢查询功能,把所以查询比较耗时的语句记录下来,以便我们分析。在Mysql的初始安装时,这个功能是不开启的,我们可以在my.cnf中加入以下语句,来启动这个功能:
[mysqld]
...
#Slow Queries
long_query_time = 3
log-slow-queries = /var/log/mysql-slow-queries.log

此外我们平时在写SQL时有以下几点需要注意:

1.多表的联合查询尽量不要超过三个。
在网站正式上线运营后,表记录在短时间内突破数以万计是非常非常有可能的,由于连接查询是在产生的笛卡尔积中筛选记录,那么我们的SQL有可能会让数据库在10000*10000*10000个记录甚至更多记录中筛选符合条件的几个。当然这些都是查询分析器中来运行的,我们也会有where来限制记录条数,但是还是需要注意,表连接的个数不要太多。

2.给表中常用的排序和检索字段加上索引。
索引的确能提高数据库的查询速度,有的时候我们用show processlist会发现有几十个查询在等待的时候,可能就需要在表中加几个索引,便解决问题了。在某些情况下,这是个事半功倍的解决办法。但是我们也不可能给每个字段全部都加索引,索引对LIKE '%xx%'是不生效的,另外在插入和修改记录时,数据库要去更新索引,如果索引加的过多,那反倒降低了数据库的效率。另外我们要注意,order by的字段我们一定要加上索引,不然会把数据库累瘫的,尤其是多表联合查询还带有order by的语句,如果没有索引,就等着哪天听数据库呼哧呼哧喘吧~。

3.Mysql中SQL_CALC_FOUND_ROWS的应用。
Mysql Manaul: A SELECT statement may include a LIMIT clause to restrict the number of rows the server returns to the client. In some cases, it is desirable to know how many rows the statement would have returned without the LIMIT, but without running the statement again. To obtain this row count, include a SQL_CALC_FOUND_ROWS  option in the SELECT  statement, and then invoke FOUND_ROWS() afterward
我们看Mysql的手册,它说,一个SELECT语句可能包含一个LIMIT限制。但是在某些情况下,我们需要不再次运行语句,而得知在LIMIT限制之外还有多少条记录没有被返回回来。那么获得这个记录条数,我们就可以引入SQL_CALC_FOUND_ROWS选项,然后调用FOUND_ROWS()函数。

这个是很有用的,我们在普通的分页程序中,会调用两次数据库查询,一次是查询总数,接下来才是查询真正的记录。但是有了SQL_CALC_FOUND_ROWS我们就可以通过一次数据库查询完成这两个功能。稍候我会发一个我写的分页类,大家可以参考一下。

分页类地址:http://www.eduicc.com/read-27.html

4.除了上述之外,我们最先要考虑的,可能就是读写分离了。因为它比较简单,写主库,读从库。这样首先能减轻各服务器的压力,其他我们可以去掉主库的索引,以加快写的速度;而在从库上多加几个索引,从而提高查询的速度。但是这个选择会有个缺陷,就是在主从库还没有来得及同步期间,我们就去读从库的数据,会发生一些错误信息。当然这也不是不可解决的问题,第一我们可以采用一些缓存机制,如memcache来缓存这些数据。其次我们也可以限制用户读取的时间。这要看我们的网站应用的着重点在哪里。

Mysql主从库的搭建:http://www.eduicc.com/read-18.html

 

二、选择服务器与动静分离
我们在使用php开发网站时,Apache可能就成了首选的web服务器,它以配置方便、扩展灵活而深受广大程序开发人员的喜爱。我们当然也可以选择高性能的nginx来代替Apache,并发量也会得到意想不到的提升,前一段时间我写过一篇Nginx+PHP(FastCGI)的配置,这里就不多说了,只是想说明一下,我在相同的系统下做过Apache和Nginx的压力测试,在大并发量的连接下,Nginx表现的比较优秀一些。
说到Nginx,它是一个轻量级的Web 服务器/反向代理服务器,它与Apache的查询原理不同,Apache是Select模型,而Nginx是epoll模型,这个在网上也有好多讲解,我就不再多赘述了。我们在这里值得提的它的第一个优点是对静态文件的响应速度特别高效,我们可以利用这一点,把网站上的图片和Js分到Nginx上,可以减少运行PHP服务器的压力,目前许多大的网站都有自己的独立的图片服务器。第二个优点是因为它也是一个优秀的反向代理服务器,我们可以用它来做服务器的负载均衡,这个我在后面也准备要写到这些。

[Ubuntu]BDB安装

1. 我们先去下载一个最新的BDB安装包。
    http://www.oracle.com/technology/software/products/berkeley-db/htdocs/popup/db/5.0.21/db-targz.html

2.安装
这里我们启用BDB的SQL接口和它的测试套件。查看手册我们会发现启用测试套件需要tcl接口的支持。所以我们先来安装tcl。

原文:To build the Berkeley DB test suite, enter --enable-test as an argument to configure. To run the Berkeley DB test suite, you must also build the Tcl API. This argument should not be specified when configuring to build production binaries.
$sudo apt-get install tcl8.5-dev
$cd ~/softs/
$tar -zxvf db-5.0.21.tar.gz
$cd db-5.0.21/build_unix
$../dist/configure --prefix=/usr/local/bdb --enable-sql --enable-test --with-tcl=/usr/lib/tcl8.5/
$make
$sudo make install

然后我们把它加入到系统的动态链接库的配置文件中。编辑/etc/ld.so.conf,在文件尾加入一行:
include /usr/local/bdb/lib

安装成功!
标签: ubuntu BDB linux

Ubuntu rsync同步文件实例

环境:
服务器端:Ubuntu 9.10 - 192.168.1.3
客户端:Ubuntu 10.04 - 192.168.1.73

我们先来设置一下服务器端的配置

1.ubuntu系统安装完之后,rsync服务默认不是启动的,我们要修改下面的文件。
$sudo vi /etc/default/rsync
RSYNC_ENABLE=true


2.修改配置文件
$sudo cp /usr/share/doc/rsync/examples/rsyncd.conf /etc
我们先来查看一下这个文件
$sudo cat /etc/rsyncd.conf

# sample rsyncd.conf configuration file

# GLOBAL OPTIONS

#motd file=/etc/motd #登录欢迎信息
#log file=/var/log/rsyncd #日志文件
# for pid file, do not use /var/run/rsync.pid if
# you are going to run rsync out of the init.d script.
pid file=/var/run/rsyncd.pid

#指定rsync发送日志消息给syslog时的消息级别,常见的消息级别是:uth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, sys-log, user, uucp, local0, local1, local2, local3,local4, local5, local6和local7。默认值是daemon。
#syslog facility=daemon

#自定义tcp选项,默认是关闭的
#socket options=

#以下是模块信息,我们可以创建多个模块
# MODULE OPTIONS

[ftp]

        comment = public archive #模块描述
        path = /var/www/pub #需要同步的路径
        use chroot = yes #默认是yes|true,如果为true,那么在rsync在传输文件以前首先chroot到path参数指定的目录下。这样做的原因是实现额外的安全防护,但是缺点是需要root权限,并且不能备份指向外部的符号连接指向的目录文件。
#       max connections=10 #最大连接数
        lock file = /var/lock/rsyncd #指定支持max connections参数的锁文件。
# the default for read only is yes...
        read only = yes #只读选项
        list = yes #客户请求时可用模块时是否列出该模块
        uid = nobody #设定该模块传输文件时守护进程应该具有的uid
        gid = nogroup #设定该模块传输文件时守护进程应具有的gid,此项与uid配合可以确定文件的访问权限
#       exclude = #用来指定多个由空格隔开的多个模式列表,并将其添加到exclude列表中。这等同于在客户端命令中使用--exclude来指定模式,不过配置文件中指定的exlude模式不会传递给客户端,而仅仅应用于服务器。一个模块只能指定一个exlude选项,但是可以在模式前面使用"-"和"+"来指定是exclude还是include
#       exclude from = #可以指定一个包含exclude模式定义的文件名
#       include = #与exclude相似
#       include from = #可以指定一个包含include模式定义的文件名
#       auth users = #该选项指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块。这里的用户和系统用户没有任何关系。如果"auth users"被设置,那么客户端发出对该模块的连接请求以后会被rsync请求challenged进行验证身份这里使用的 challenge/response认证协议。用户的名和密码以明文方式存放在"secrets file"选项指定的文件中。默认情况下无需密码就可以连接模块(也就是匿名方式)
#       secrets file = /etc/rsyncd.secrets #该文件每行包含一个username:password对,以明文方式存储,只有在auth users被定义时,此选项才生效。同时我们需要将此文件权限设置为0600
        strict modes = yes #该选项指定是否监测密码文件的权限,如果该选项值为true那么密码文件只能被rsync服务器运行身份的用户访问,其他任何用户不可以访问该文件。默认值为true
#       hosts allow = #允许的主机
#       hosts deny = #拒绝访问的主机
        ignore errors = no #设定rsync服务器在运行delete操作时是否忽略I/O错误
        ignore nonreadable = yes #设定rysnc服务器忽略那些没有访问文件权限的用户
        transfer logging = no #使rsync服务器使用ftp格式的文件来记录下载和上载操作在自己单独的日志中
#       log format = %t: host %h (%a) %o %f (%l bytes). Total %b bytes. #设定日志格式
        timeout = 600 #超时设置(秒)
        refuse options = checksum dry-run #定义一些不允许客户对该模块使用的命令选项列表
        dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz #告诉rysnc那些文件在传输前不用压缩,默认已设定压缩包不再进行压缩

       

日志格式选项列表:
%h:远程主机名
%a:远程IP地址
%l:文件长度字符数
%p:该次rsync会话的进程id
%o:操作类型:"send"或"recv"、”del.”
%f:文件名
%P:模块路径
%m:模块名
%t:当前时间
%u:认证的用户名(匿名时是null)
%b:实际传输的字节数
%c:当发送文件时,该字段记录该文件的校验码


下面我们来定义自己的conf文件

# [GLOBAL OPTIONS]

#motd file=/etc/motd
log file=/var/log/rsyncd
# for pid file, do not use /var/run/rsync.pid if
# you are going to run rsync out of the init.d script.
pid file=/var/run/rsyncd.pid
syslog facility=daemon

#socket options=

# [MODULE OPTIONS]

[serverdb]

        comment = Server Databases
        path = /home/flow/Documents/db_backup
        use chroot = no
#       max connections=10
        lock file = /var/lock/rsyncd
# the default for read only is yes...
        read only = true
        list = true
        uid = nobody
        gid = nogroup
        exclude = db_backup.sh
#       exclude from =
#       include =
#       include from =
        auth users = liubing
        secrets file = /etc/rsyncd.secrets
        strict modes = true
        hosts allow = 192.168.1.73
#       hosts deny =
        ignore errors = true
        ignore nonreadable = true
        transfer logging = true
        log format = %t[%p]: host %h (%a) %o %f (%l bytes). Total %b bytes.
        timeout = 600
        refuse options = checksum dry-run
        dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz


创建一个密码文件
$sudo vi /etc/rsyncd.secrets
liubing:123456
$sudo chmod 0600 /etc/rsyncd.secrets


启动rsync
sudo /etc/init.d/rsync start


我们再来看一下客户端的操作,一般客户端不需要进行特殊的配置,直接同步即可
$rsync -vzrtopg --progress liubing@192.168.1.3::serverdb .
password

成功!

我们把这个同步工作交给crontab去执行。首先我们要创建一个密码文件
$sudo vi /etc/rsync.pwd输入123456,保存

!注意:下面这两步操作是必须的
sudo chmod 0600 /etc/rsync.pwd
sudo chown liubing:liubing /etc/rsync.pwd


然后我们打开crontab,加入以下任务
$crontab -e
* */1 * * * rsync -a --password-file=/etc/rsync.pwd liubing@192.168.1.3::serverdb /home/liubing/Documents/db_backup


更多内容:rsync 常见错误及解决方法

标签: ubuntu rsync linux