分类存档: 数据存储

在CentOS及Ubutun下安装Percona-Server和HandlerSocket注意事项

见: http://www.percona.com/docs/wiki/repositories:start

一、CentOS下安装Percona-Server及HandlerSocket

安装Percona Yum Repository

rpm -Uhv http://www.percona.com/downloads/percona-release/percona-release-0.0-1.i386.rpm
rpm -Uhv http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
#自行选择对应的平台

yum install Percona-Server-server-51.i386
yum install Percona-Server-client-51.i386

编辑my.cnf

[mysqld]
plugin-load=handlersocket.so

loose_handlersocket_port = 9998 # 指定读请求端口号
# the port number to bind to (for read requests) 

loose_handlersocket_port_wr = 9999 # 指定写请求端口号
# the port number to bind to (for write requests)

loose_handlersocket_threads = 16 # 指定读线程数目
# the number of worker threads (for read requests)

loose_handlersocket_threads_wr = 1 # 指定写线程数目
# the number of worker threads (for write requests)

open_files_limit = 65535
# to allow handlersocket accept many concurrent
# connections, make open_files_limit as large as
# possible.

重启MySQL后,查看handlersocket是否正常运行

netstat -lnp | grep 9998
netstat -lnp | grep 9999
#查看端口是否被监听

或者在mysql中查看
mysql> INSTALL PLUGIN handlersocket SONAME "handlersocket.so";
mysql>SHOW PLUGINS; # 查看插件是否加载成
mysql>SHOW PROCESSLIST; # 查看handlersocket是否正常运行

#如果handlersocket没有正常运行, 则先关闭SELinux后再试试看看。

二、Ubuntu下安装Percona-Server及HandlerSocket

安装apt-get源

gpg --keyserver  hkp://keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A
gpg -a --export CD2EFD2A | apt-key add -

在ubuntu下其它操作同上,如果没有正常运行,
mysql> INSTALL PLUGIN handlersocket SONAME “handlersocket.so”; 提示: “errno: 2 failed to map segment from shared object: Permission denied”

可以先 /etc/init.d/apparmor stop 然后重启MySQL, 然后 /etc/init.d/apparmor start

php handlersocket

一、安装php-handlersocket模块:

php-handlersocket, PHP extension for interfacing with MySQL Handler Socket.

wget http://php-handlersocket.googlecode.com/files/php-handlersocket-0.1.0.tar.gz
tar zxvf php-handlersocket-0.1.0.tar.gz
cd php-handlersocket
phpize
./configure
make
make install

二、php-handlersocket 使用示例:

	/*
	 * String  $host:MySQL ip;
	 * String  $port:handlersocket插件的监听端口,它有两个端口可选:一个用于读、一个用于写
	 */
	$hs = new HandlerSocket($host, $port);
	打开一个数据表:
	/*
	 * Int       $index:这个数字相当于文件操作里的句柄,HandlerSocket的所有其他方法都会依据这个数字来操作由这个	 openIndex打开的表,
	 * String  $dbname:库名
	 * String  $table:表名
	 * String  $key:表的“主键”(HandlerSocket::PRIMARY)或“索引名”作为搜索关键字段,这就是说表必须有主键或索引
	 *                 个人理解:要被当做where条件的key字段,这样可以认为handlersocket只有一个where条件
	 * String  $column:'column1,column2' 所打开表的字段(以逗号隔开),就是说$table表的其他字段不会被操作
	 */
	$hs->openIndex($index, $dbname, $table, $key, $column);
	查询:
	/*
	 * Int     $index: openIndex()所用的$index
	 * String  $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '< =', '>',and '< ';可以理解为where条件
	 * Array   $value
	 * Int       $number(默认是1):获取结果的最大条数;相当于SQL中limit的第二个参数
	 * Int     $skip(默认是0):跳过去几条;相当于SQL中limit的第一个参数
	 */
	$retval = $hs->executeSingle($index, $operation, $value, $number, $skip);
	插入(注意:此处的openIndex要用$port_wr,即读写端口):
	/*
	 * Int     $index: openIndex()所用的$index
	 * Array   $arr:数字元素数与openIndex的$column相同
	 */
	$retval = $hs->executeInsert($index, $arr);
	删除(注意:此处的openIndex要用$port_wr,即读写端口):
	/*
	 * Int     $index: openIndex()所用的$index
	 * String  $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '< =', '>',and '< ';可以理解为where条件
	 * Array   $value
	 * Int     $number(默认是1):获取结果的最大条数;相当于SQL中limit的第二个参数
	 * Int     $skip(默认是0):跳过去几条;相当于SQL中limit的第一个参数
	 */
	$retval = $hs->executeDelete($index, $operation, $value, $number, $skip);
	更新(注意:此处的openIndex要用$port_wr,即读写端口):
	/*
	 * Int     $index: openIndex()所用的$index
	 * String  $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '< =', '>',and '< ';可以理解为where条件
	 * Array   $value
	 * Int       $number(默认是1):获取结果的最大条数;相当于SQL中limit的第二个参数
	 * Int     $skip(默认是0):跳过去几条;相当于SQL中limit的第一个参数
	 */
	$retval = $hs->executeUpdate($index, $operation, $value, $number, $skip);
CREATE TABLE `user` (
  `user_id` int(10) unsigned NOT NULL,
  `user_name` varchar(50) DEFAULT NULL,
  `user_email` varchar(255) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`user_id`),
  KEY `INDEX_01` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES ('1', 'aaa', 'aaa@dsf.com', '2011-04-07 18:26:03');
INSERT INTO `user` VALUES ('2', 'bbb', 'bbb@dsf.com', '2011-04-07 18:26:03');
INSERT INTO `user` VALUES ('3', 'ccc', 'ccc@test.com', '2011-04-07 18:26:03');
< ?php
$host = '192.168.5.28';
$port = 9998;
$port_wr = 9999;
$dbname = 'test';
$table = 'user';

//GET
$hs = new HandlerSocket($host, $port);
if (!($hs->openIndex(1, $dbname, $table, HandlerSocket::PRIMARY, 'user_id,user_name,user_email,created')))
{
    echo $hs->getError(), PHP_EOL;
    die();
}

$retval = $hs->executeSingle(1, '>=', array('0'), 10, 0);

var_dump($retval);

$retval = $hs->executeMulti(
    array(array(1, '=', array('1'), 1, 0),
          array(1, '=', array('2'), 1, 0)));

var_dump($retval);

unset($hs);

//UPDATE
$hs = new HandlerSocket($host, $port_wr);
if (!($hs->openIndex(2, $dbname, $table, '', 'user_name,user_email,created')))
{
    echo $hs->getError(), PHP_EOL;
    die();
}

if ($hs->executeUpdate(2, '=', array('2'), array('aaa', 'xun@dsf.com', '2011-04-07 18:26:03'), 1, 0) === false)
{
    echo $hs->getError(), PHP_EOL;
    die();
}

unset($hs);

//INSERT
$hs = new HandlerSocket($host, $port_wr);
if (!($hs->openIndex(3, $dbname, $table, '', 'user_id,user_name,user_email,created')))
{
    echo $hs->getError(), PHP_EOL;
    die();
}

if ($hs->executeInsert(3, array('5', 'aaa5', 'xun@dsf.com', '2011-04-07 18:26:03')) === false)
{
    echo $hs->getError(), PHP_EOL;
}
if ($hs->executeInsert(3, array('6', 'aaa6', 'xun@dsf.com', '2011-04-07 18:26:03')) === false)
{
    echo 'A', $hs->getError(), PHP_EOL;
}
if ($hs->executeInsert(3, array('7', 'aaa7', 'xun@dsf.com', '2011-04-07 18:26:03')) === false)
{
    echo 'B', $hs->getError(), PHP_EOL;
}

unset($hs);

//DELETE
$hs = new HandlerSocket($host, $port_wr);
if (!($hs->openIndex(4, $dbname, $table, '', '')))
{
    echo $hs->getError(), PHP_EOL;
    die();
}

if ($hs->executeDelete(4, '=', array('1')) === false)
{
    echo $hs->getError(), PHP_EOL;
    die();
}
?>

MySQL插件HandlerSocket

HandlerSocket 是MySQL的一个插件,用来实现 NoSQL 功能,用于跳过MySQL的SQL层面,直接访问内部的InnoDB存储引擎。

wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-client-5.5.11-1.rhel4.i386.rpm
wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-devel-5.5.11-1.rhel4.i386.rpm
wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-server-5.5.11-1.rhel4.i386.rpm
wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-shared-5.5.11-1.rhel4.i386.rpm

rpm -ivh MySQL-client-5.5.11-1.rhel4.i386.rpm MySQL-devel-5.5.11-1.rhel4.i386.rpm MySQL-server-5.5.11-1.rhel4.i386.rpm MySQL-shared-5.5.11-1.rhel4.i386.rpm 

wget http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.11.tar.gz

一、安装HandlerSocket
获取安装包:https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL.git

tar -zxvf ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-73-g0e63366.tar.gz
cd ahiguti-HandlerSocket-Plugin-for-MySQL-0e63366/
./autogen.sh
./configure --with-mysql-source=/home/xinze/software/mysql-5.5.11 --with-mysql-bindir=/usr/bin  --with-mysql-plugindir=/usr/lib/mysql/plugin
make && make install

修改/etc/my.cnf 配置

[mysqld]
plugin-load=handlersocket.so

loose_handlersocket_port = 9998 # 指定读请求端口号
# the port number to bind to (for read requests) 

loose_handlersocket_port_wr = 9999 # 指定写请求端口号
# the port number to bind to (for write requests)

loose_handlersocket_threads = 16 # 指定读线程数目
# the number of worker threads (for read requests)

loose_handlersocket_threads_wr = 1 # 指定写线程数目
# the number of worker threads (for write requests)

open_files_limit = 65535
# to allow handlersocket accept many concurrent
# connections, make open_files_limit as large as
# possible.

在mysql里加载HandlerSocket插件:

mysql> INSTALL PLUGIN handlersocket SONAME "handlersocket.so";
mysql>SHOW PLUGINS; # 查看插件是否加载成
mysql>SHOW PROCESSLIST; # 查看handlersocket是否正常运行

* 如果SHOW PROCESSLIST没有handlersocket 进程, 则先关闭SELinux后再试试看看。
* 在ubuntu下,可以先 /etc/init.d/apparmor stop 然后重启MySQL, 然后 /etc/init.d/apparmor start

二、安装 php-handlersocket 模块:

wget http://php-handlersocket.googlecode.com/files/php-handlersocket-0.1.0.tar.gz
tar zxvf php-handlersocket-0.1.0.tar.gz
cd php-handlersocket
phpize
./configure
make
make install

flash remoting –Amfphp

       ¶ÔAmfphpÒѾ­Á˽âºÜ¾ÃÁË£¬¾ÍÊÇûÓÐÇ×ÊÖÓùýÒ»´Î£¬½ñÌìͻȻÐÄѪÀ´³±£¬¶¯ÊÖʵ¼ùÁËÒ»·¬¡£

++++

Amfphp
      ÊÇPHPµÄRPC¹¤¾ß£¬Ëü¿ÉÒÔʹPHPÓëÏÂÊö¼¼ÊõÎÞ·ìͨÐÅ£º

      * Flash ºÍ Flex Remoting
      * JavaScript JSON ºÍ Ajax JSON
      * XML ºÍXML-RPC

      Ò»¡¢Ê²Ã´ÊÇRPC?

      Ô¶¶Ë³ÌÐòµ÷ÓÃ(RPC£¬ Remote Procedure Call) ÊÇÒ»ÖÖ¿Í»§¶ËÓë·þÎñÆ÷¶Ë½»»»Êý¾Ý·½Ê½¡£ÎÒÃÇ¿ÉÒÔµ÷Óñ¾µØ¶ÔÏó´ø¶Ô¸÷ÖÖ²ÎÊý·½·¨£¬ÉèÖûص÷²¢½ÓÊܵ÷Óýá¹û¡£ÎÒÃDz»ÓùØÐÄ·¢ËͺͽÓÊÕÊý¾ÝµÄʵÏÖϸ½Ú¡£ÊµÏÖϸ½Úͨ³£ÊdzéÏóµÄ£¬ ¾ÍÏñÎÒÃÇÔÚµ÷Óñ¾µØ·½·¨Ò»Ñù.

      ¶þ¡¢¹¤×÷Ô­Àí

      ¿Í»§¶Ë£¨Flash£©Óë·þÎñÆ÷¶Ë£¨php£©, ʹÓÃÏàͬµÄ·½Ê½ÃèÊö·½·¨µ÷Óú͸´ÔÓÊý¾Ý¡£¿Í»§¶ËÐòÁл¯ÇëÇó²¢½«Ëü·¢Ë͵½Íø¹ØAmfphp¡£AmfphpÔÙÖ´ÐУº

          * ·´ÐòÁл¯ÇëÇó
          * ÕÒµ½ÏàÓ¦µÄÔ¶³Ì·þÎñÀà
          * ʵÀý»¯Àà
          * Ö´Ðа²È«¼ì²é
          * £¨Ê¹ÓÃÖ¸¶¨²ÎÊý£©µ÷Ó÷þÎñÆ÷¶Ë·½·¨
          * ÐòÁл¯·µ»ØµÄÊý¾Ý

      Amfphp ¿ÉÒÔÕýÈ·µØÐòÁл¯¡¢·´ÐòÁл¯¸´ÔÓÀàÐÍÊý¾Ý¡£³ýÁ˶ÔÏóºÍÊý×飬Ëü»¹Ö§³Öresources Êý¾ÝÁ¬½Ó×ÊÔ´£¬Õâ¾ÍÒâζ×ÅÎÒÃÇ¿ÉÒÔͨ¹ýµ÷ÓÃÔ¶³Ì·½·¨¼òµ¥·µ»Ømysql_query£¬amfphp »á´¦ÀíÕâÒ»ÇС£ Èç¹ûƽ̨֧³Ö (ĿǰÀ´Ëµ£¬Flash Remoting ºÍFlex Remoting), phpamf»¹¿ÉÒÔ´¦ÀíÑ­»·ÒýÓúÍ×Ô¶¨ÒåÊý¾Ý¡£ËüÒ²Ö§³Ö¼òµ¥µÄÔ¶³Ìµ÷ÊÔ¡£»¹ÓÐamfphp ¸½´øÒ»¸ö·þÎñä¯ÀÀÆ÷£¬Ëü¿ÉÒÔÔÚ´´½¨¿Í»§¶Ë´úÂëǰ²âÊÔÔ¶³Ì·þÎñ¡£amfphp 1.0.1»¹Ìí¼ÓÁËÄ£°å£¬¿ÉÒÔ×Ô¶¯Éú³É¿Í»§¶Ë´úÂë¡£Amfphp 1.9 beta¸üÊÇÐÂÔöÁ˶ÔAMF3µÄÖ§³Ö¡£Ïê¼ûhttp://www.riafan.com/article.asp?id=31¡£

                ++++++

¡ôflash remotingÊÇʲô£¿

              Flash remotingÊÇÒ»ÖÖÁ¬½Óflash client Óë server¶ËµÄ¼¼Êõ£¬ËüµÄ¹¦ÓþÍÏñÊÇ web service, xml, loadVarsÒ»°ã£¬¿ÉÒÔÔÚÁ½ÕßÖ®¼ä½»»»×ÊÁÏ£¬´ïµ½¶¯Ì¬Öû»ÄÚÈݵÄÄ¿µØ¡£

              Flash remotingÌØ±ðµÄµØ·½ÔÚÓÚËü’ñÓÃmacromedia¶À¼ÒµÄAMF(Action Message Format)£¬ÕâÊÇÒ»ÖÖ binary formatµÄ×ÊÁÏÐÍ̬£¬Í¸¹ý AMF over HTTPµÄ·½Ê½½«flash¶Ë×ÊÁϱàÂëºó´«»Øserver£¬server¶ËµÄremoting adaptor½ÓÊÕµ½×ÊÁϺóÔò»á½âÂë»ØÕýÈ·µÄnativeÎï¼þ£¬½»¸øÕýÈ·µÄ³Ìʽ´¦Àí¡£

              AMF³ýÁËÓÃÓÚFlash remotingÍ⣬Ҳ¹ã·ºµÄÓÃÓÚ Local Connection Óë Flash communication server£¬Ëü×î´óµÄÌØÉ«ÔÚÓÚ¿ÉÖ±½Ó½«flash native object£¬ÀýÈçObject, Array, Date, XML£¬´«»Øserver¶Ë£¬²¢ÇÒÔÚserver¶Ë×Ô¶¯½øÐÐתÒë³ÉÊʵ±µÄÎï¼þ£¬ÀýÈçflash µÄArray´«»ØPHPʱ¾Í»á×Ô¶¯×ª»»Îª Associative Array£»Õâ¸öÌØÉ«¶Ô¿ª·¢Õß×î´óµÄºÃ´¦ÔÚÓÚ²»ÐèÒªÔÙÈ˹¤´¦Àíserialization Óë deserializationµÄ·±Ñ}¹¤×÷£¬²»µ«¾«È·¶È¸ü¸ß£¬Í¬Ê±¿ª·¢Ò²¸üʡʱ¼ä¡£

              ÓÉÓÚAMFÊÇbinary format²¢ÇÒ±àÂëʱ¾­¹ý¸ß¶ÈѹËõ£¬Òò´Ë·Ç³£ÊʺÏÓÃÀ´´«µÝ´óÁ¿µÄ×ÊÁÏ£¬¸ù¾ÝflashorbÍøÕ¾µÄ²âÊÔ(Ö÷ÒªÕë¶Ôweb serviceÓëflash remoting)£¬µ±×ÊÁÏÁ¿Ô½´óʱ£¬flash remotingµÄ´«ÊäЧÄܾÍÔ½¸ß£¬Ô¶Ô¶³¬¹ýweb serviceµÄ±íÏÖ£¬Òò´ËͬÑùµÄµÀÀíÒ²¿ÉµÃÖªxml, loadVars, loadVariables µÈʹÓÃplaine text formatµÄ´«Ê䷽ʽ×ÔȻҲÎ޿ɱÈÄâ¡£

              ÖÁÓÚÔÚserver¶Ë£¬Ä¿Ç°macromedia¹Ù·½Ö§Ô®µÄƽ̨ÓÐÈýÖÖ£¬·Ö±ðÊÇ Java Coldfusion(µ«Êµ¼ÊÉÏColdfusionÓ¦¸ÃÖ»ËãÊÇjavaµÄsubset£¬ËüÊÇÒ»ÖÖ scripting tag library)Óë.NET£¬µ«ÓÉÓÚAMF¸ñʽÒѱ»Íæ¼Ò·´×éÒë³É¹¦£¬Òò´ËºÜ¿ìµÄ¾ÍÔÚOpen SourceȦ³öÏÖ¸÷ÖÖ¡¸Ãñ¼ä°æ¡¹µÄremotingÌæ´ú·½èñ£¬ÆäÖбȽÏÓÐÃûµÄÊÇ£º

              -AMFPHP: ÕâÊÇphp°æµÄremoting       http://amfphp.org
              -OPENAMF: java°æµÄremoting         http://openamf.org
              -Flap: Perl ÓëPython°æµÄremoting       http://simonf.com/amfpython/
              -FlashORB: ÉÌÒµ°æµÄremotingÌæ´ú·½èñ£¬Ä¿Ç°Ö§Ô®javaÓë.net       http://www.themidnightcoders.com/

              Ïà¹ØÔĶÁ£º
              Ê®¸ö’ñÓÃremotingµÄÀíÓÉ: http://www.macromedia.com/software/flashremoting/productinfo/upgrade/

¡ôamfphpÊÇÆ½Ã´£¿

              ±¾ÎÄÖ÷Òª½éÉܵÄÊÇphpƽ̨ÉϵÄremoting·½èñ£¬Ò²¾ÍÊÇamfphp¡£

              Amfphp×îÔçÊÇÓÉJustin WatkinsËù·¢Æð²¢¸ºÔð׫дµÚÒ»°æ´ó²¿·ÝµÄ³ÌʽÂ룬¾­¹ýÈýÄê·¢Õ¹ºóÈ¥ÄêÓÉPatrick Mineault½ÓÊÖ£¬²»µ«¸ÄÁ¼Á˴󲿷ݵijÌʽÂ룬ͬʱҲ²¹ÆëÁËÐí¶àÖØÒªµÄ¹¦ÄÜ£¬ÀýÈ籾ϵÁеڶþƪҪ½éÉÜµÄ pageable recordset¡£

              AmfphpÊÇÒ»¸öÍêÈ«ÓÉphpд³ÉµÄserver¶ËÄ£×飬×î´óµÄÌØÉ«ÔÚÓÚÍêÈ«²»Óð²×°£¬ÈκÎhosting Ö÷»úÖ»ÒªÄÜÅÜphp¾ÍÄÜÖ´ÐÐflash remoting£¬ÔÙ¼ÓÉÏphpÔ­±¾¾ÍÓйã´óµÄʹÓÃÕß»ù´¡£¬Òò´ËÒ»ÍÆ³öºóºÜ¿ì¾Í»ñµÃÍæ¼ÒÃǵĽÓÊÜ¡£

              Èç¹ûÄãÏëÒª²t½âamfphpµÄ×îз½Õ¹£¬¿ÉǰÍù amfphp wiki –http://amfphp.org/wiki/һ̽¾¿¾¹£¬Èç¹ûÄãÓÐʹÓÃÉϵÄÒÉÎÊ£¬×îºÃµÄ½â´ð¾ÍÔÚamfphp mailing list  http://sourceforge.net/mailarchive/forum.php?forum_id=24803»òÊÇ forum   http://sourceforge.net/forum/?group_id=72483¡£

¡ôÏÂÔØamfphp

              Ŀǰamfphp×îаæÎª v1.0 milestone 2£¬¾ÝpatrickµÄ˵ÕâÓ¦¸ÃÊÇÕýʽ·¢±íǰ×îºóÒ»¸öbeta°æ£¬ËùÒÔÎȶ¨ÐÔÓ¦¸ÃÏ൱²»´í²ÅÊÇ¡£

              ÏÂÔØÎ»Ö· http://prdownloads.sourceforge.net/amfphp/amfphp-ms2-20050726.zip?download

¡ô°²×°amfphp

              µµèñ×¥»ØÀ´ºó½âѹËõ£¬Ó¦¸Ã»áµÃµ½ÏÂͼµÄ½á¹¹£º

              ÆäÖÐflashservices¾ÍÊÇamfphpµÄºËÐÄÄ£×飬ֻҪ½«ËüÉÏ´«µ½ÍøÒ³µÄ¸ùĿ¼Ï¼´¿É¡£±¾ÎÄÊÇÒÔwindows + apache 2ΪÀý£¬Òò´Ë·ÅÖÃλΪ£º

              E:\webroot\flashservices

              ÆäÖÐ webroot¼´ÊÇapacheÔ¤ÉèµÄÍøÒ³¸ùĿ¼£¬Èç¹ûÄãµÄλÖò»Í¬ÇëÊʵ±Ð޸ġ£
              ·ÅºÃ flashservicesºó»ù±¾ºËÐľÍÒÑÍê³É£¬µ«Õâ²»´ú±í¾Í¿ÉÒÔ¿ªÊ¼Ê¹Óã¬ÎÒÃÇ»¹ÒªÎªÃ¿¸öרèñ½¨Á¢×¨ÊôµÄ×ÊÁϼÐÀ´·ÅÖÃÆäËü±Ø±¸µÄµµèñ¡£

¡ôµÚÒ»¸ö³Ìʽ£ºhello world

              ÕâÀïÎÒÃÇÓÃÒ»¸öʵ¼ÊµÄhello world·¶ÀýÀ´Ê¾·¶ÈçºÎÈÃflash Óë php͸¹ýamfphp½øÐйµÍ¨¡£

              Ê×ÏÈÎÒÃÇÔڸղŵÄÍøÒ³¸ùĿ¼ÏÂ(htdocs)½¨Ò»¸öרèñ×ÊÁϼУ¬Ãû³ÆÎª hello£¬ÍêÕû·¾¶Îª£º
              E:\webroot\hello

              È»ºóÇëÏÂÔØ±¾Îĵķ¶Àýµµèñzipµµ£¬½«ÀïÃæµÄ¶«Î÷È«²¿½âѹËõµ½hello×ÊÁϼÐÄÚ£¬´Ëʱ×ÊÁϼеÄÄÚÈÝÓ¦¸ÃÈçÏÂͼ£º

¡ô Amfphp gatewayµÄÉ趨

              ½ÓÕßÎÒÃǾÍ×Ðϸ¿´¿´ÀïÃæÓÐЩʲô¶«Î÷£¬Ê×ÏÈÎÒÃÇÀ´¿´ gateway.php£¬³ÌʽÂëÈçÏ£º
              PHP:

ÎļþÃû³Æ£º../../amfphp/gateway.php
  1. <?php
  2.     include “/amfphp/Gateway.php”;
  3.     $gateway = new Gateway();
  4.     $gateway->setLooseMode(true);
  5.     $gateway->setCharsetHandler(“iconv”, “UTF-8″, “UTF-8″);
  6.     $gateway->setWebServiceHandler(‘php5′);
  7.     $gateway->setBaseClassPath(“services/”);
  8.     $gateway->service();
  9. ?>

              ÕâÀïÐÂÊÖ×î³£´íµÄµØ·½¾ÍÊǵÚÒ»ÐУ¬includeµÄÉ趨¡£Ò»°ãÓÉÓÚ flashservicesºËÐÄÄ£×é¶¼ÊÇ·ÅÖÃÓÚweb serverµÄ¸ùĿ¼£¬Òò´Ëÿ¸öרèñµÄ×Ó×ÊÁϼÐÖ»ÒªÓÃÏà¶Ô·¾¶ .. ¾Í¿ÉÒÔ´æÈ¡µ½¡£µ«Èç¹ûÄãµÄflashservices·¾¶²»Ò»Ñù£¬ÕâÀï¾ÍÒª×öÊʵ±µÄÐ޸ģ¬ÀýÈçÔÚÎÒʹÓõÄhostingÖ÷»úÉÏ(ʹÓÃlinuxϵͳ)£¬Õâ¸ö·¾¶¾Í¿ÉÄܱä³É£º

              /home/userrname/website.url/user/apache/htdoc/flashservices

              ×ÜÖ®ÕâÀïÇëСÐÄÈ·ÈÏ·¾¶ÎÞÎó¡£

              ½ÓÕßµÚ5ÐеÄÉ趨ҲºÜÖØÒª£¬ÕâÀïÖ÷ÒªÊÇÔÚÉ趨php¸ÃÓúÎÖÖÓïϵ´¦Àí×ÊÁÏ£¬ËüµÄ±ê×¼¸ñʽÈçÏ£º

              setCharsetHandler(string mode, string phpCharset, string sqlCharset)

              µÚÒ»¸ö²ÎÊýÊÇÉ趨ҪʹÓúÎÖÖ·½Ê½À´ÖØÐ±àÂë´«ÊäµÄ×ÊÁÏ£¬Èç¹ûÊÇphp5µÄ»°Ôò¿ÉÒÔ·ÅʹÓÃiconv£¬ÕâÊÇÄÚ½¨µÄÄ£×é¡£

              µÚ¶þ¸ö²ÎÊýÊÇÉ趨ϵͳԤ¶¨µÄÎÄ×Ö±àÂ뷽ʽ£¬Èç¹ûÒªÓÃÖÐÎĵϰ¾Í¸Ä³É utf-8¡£

              µÚÈý¸ö²ÎÊýÊÇÉ趨¸ÃÈçºÎ´¦Àísql query result£¬Ò²¾ÍÊÇrecordsetµÄÎÄ×Ö±àÂ룬ͬÑùµÄÒªÓÃÖÐÎÄÇëÉ趨³É utf-8¡£

              ±¾À´ÕâÀﻹÓеÚËĸö²ÎÊý£¬ÊÇÉ趨 wsCharset (web service charset)£¬µ«´Óms1°æ±¾¿ªÊ¼Õâ¸ö²ÎÊýÒѱ»Ô¤ÉèΪutf-8£¬½«À´²»ÂÛÊÇʹÓÃSoapClient»ò nusoap¶¼»á×Ô¶¯¶ÁÈ¡ phpCharsetµÄÉ趨ΪԤÉèÖµ¡£

              ËùÒÔ×ÜÖ®ÕÕ·¶ÀýÀïµÄÉ趨ֱ½ÓÌ×ÓþÍÒ»¶¨²»»á´í :P

              ×îºó¿´Ò»ÏµÚ7ÐУ¬ÕâÀïÊÇÉ趨server¶ËµÄ³ÌʽλÖã¬Ò»°ãÒ²¾ÍÊÇbusiness logicµÄËùÔڵأ¬»òÊÇbusiness delegateµÄclassλÖÃ(Èç¹ûÄãÏ£Íû½«server¶ËµÄlogicƒ?Á¿Òþ²ØÆðÀ´Ö»Í¸¹ýµ¥Ò»¹ÜµÀ¹©flashºô½ÐµÄ»°£¬ÕâÀï¾ÍÊÇÏÂÊֵĺõط½)£¬Ô¤ÉèÖµÊÇserver£¬ÕâÒ²¾ÍÊÇΪºÎ½âѹËõ·¶Àýµµºó»á³öÏÖÒ»¸öͬÃû×ÊÁϼеÄÔ­Òò¡£

¡ôphp classµÄÄÚÈÝ

              ½ÓÕßÎÒÃÇ¿´Ò»ÏÂservice×ÊÁϼÐÄÚµÄHello.php£¬Õâ¸ö¾ÍÊÇserver¶ËµÄ³Ìʽ£¬ËüµÄµØÎ»Ï൱ÓÚcoldfusion ÀïµÄcomponent(CFC)»òjavaÀïµÄjava bean¡£

              ËüµÄ³ÌʽÂëÈçÏ£º
              PHP:
   

ÎļþÃû³Æ£º../../amfphp\\services\\Hello.php
  1. <?
  2. class Hello
  3. {
  4.            function Hello()
  5.            {
  6.         $this->methodTable = array(
  7.             “sayHello” => array(
  8.                 “description” => “Return hello message to client”,
  9.                 “access”      => “remote”,
  10.                 “arguments”   => array(“”)
  11.                    ),
  12.                );
  13.            }
  14.            function sayHello($msg)
  15.            {
  16.                return “Amfphp welcomes you: ” . $msg . ” current time_” . time();
  17.            }
  18. }
  19. ?>

              Èç¹ûÄãÓÐ׫дphp classµÄ¾­Ñ飬Ӧ¸ÃÂíÉϻᷢÏÖÕâ¸öHello ¾ÍÊÇÒ»¸ö±ê×¼µÄphp classµµ£¬Í¸¹ýclass keywordÀ´Ðû¸æclassµÄÆôʼ£¬²¢ÇÒÔÚconstructorÀïÓÐÒ»¸ömethod tableÃèÊöÕû¸öclassÒª¹©Íâ½ç²Ù×÷µÄmethod¡£

              ×¢ÒâÕâ¸ömethod tableÀﻹÓÐÐí¶à¹Ø¼ü×Ö¿ÉÓã¬ÔÚδÀ´µÄ½ÌѧÎÄÕÂÀï»áÒÀÐò½éÉÜ¡£ÕâÀïÎÒÃÇÖ»Óõ½description, access, argumentsÈýÑù¡£ÆäÖÐaccessÒ»¶¨ÒªÉ趨³Éremote£¬Õâ¸ömethod²ÅÄÜΪÍâ½çËù´æÈ¡£¬²»È»¾Í»á³öÏÖ´íÎóѶϢ¡£

              µÚ17ÐпªÊ¼ÎÒÃÇдÁËÒ»¸ösayHello($msg) £¬Ëü»á½ÓÊÕÔ¶¶Ë´«À´µÄÒ»¸ö²ÎÊý$msg£¬È»ºóÎÒÃǽ«Õâ¸ö$msg¼ÓÁϺóÔÙ´«»ØÈ¥¡£¼ÓÁϵIJ¿·ÝÊÇ19ÐÐ×îºóµÄtime()£¬ÎÒÃǽ«Ä¿Ç°serverµÄʱ¼ä´«»Øflash¡£

¡ôflash¶Ë³Ìʽ

              ½ÓÕßÎÒÃÇ¿´Ò»ÏÂflash¶ËµÄ³Ìʽ¡£Ê×ÏÈÇë×¢ÒâÎÒÔÚtimelineµÄµÚ1¸ñÓÃincludeµÄ·½Ê½½«³ÌʽÂë¼Ó½øÈ¥£¬ÕâÑùÎҾͲ»ÓÃÔÚflash Àï¿ÉÁ¯µÄд³ÌʽÂ룬¶ø¿ÉÒÔÓà eclipse»òprimailscirptµÈ³¬Ç¿Î޵б༭Æ÷¿ìÀÖµÄд×÷£»ËùÒÔÄãÒªÕÒ³ÌʽÂëµÄ»°£¬Ö±½Ó´ò¿ªcode.asÕâ¸öµµèñ¼´¿É¡£

              Code.asµÄÄÚÈÝ£º

ÎļþÃû³Æ£º../../amf/code.as
  1. /*
  2. @author: jeremy@richtechmedia.com
  3. @website: http://ria.richtechmedia.com
  4. released under CC 2.5.
  5. */
  6. //remoting related classes
  7. import mx.remoting.Service;
  8. import mx.remoting.PendingCall;
  9. import mx.remoting.RecordSet;
  10. import mx.remoting.debug.NetDebug;
  11. import mx.rpc.RelayResponder;
  12. import mx.rpc.ResultEvent;
  13. import mx.rpc.FaultEvent;
  14. //start debugging so we can see debug info in NCD.
  15. NetDebug.initialize();
  16. //gateway settings
  17. var gateway:String = “http://localhost/amfphp/gateway.php”;
  18. respGeneral = new RelayResponder(this, “resultReceived”, “resultFailure”);
  19. _service = new Service(gateway, null, “Hello”, null, respGeneral);
  20. //callback when result was returned from server
  21. function resultReceived(re:ResultEvent):Void{
  22.     trace(“message from server > “ + re.result);
  23.     //php returns time in seconds, but flash Date class needs ms hence * 1000
  24.     var tmp = re.result.split(“_”)[1]*1000;
  25.     trace(“server time > “ + new Date(tmp));
  26. };
  27. //send message to server
  28. btnSend.clickHandler = function(){
  29.     var pc:PendingCall = _service.sayHello(inputText.text);
  30. }

      

              Ò»¿ªÊ¼ÎÒÃÇÏȽ«flash remotingÐèÒªµÄclass¶¼import½øÀ´£¬ÕâÀïҪעÒâµÄÊÇ£¬flash remotingÐèÒªÁíÍâÏÂÔØÓë°²×°£¬ÏÂÔØµÄ·½Ê½ÓÐÁ½ÖÖ£º

              1¡¢ ÏÂÔØflash remoting components (v2)²¢×°Èëflash
              2¡¢ ÏÂÔØflash remoting sources²¢½âѹËõµ½ mxĿ¼Ï¡£Flash Remoting AS2 Classes http://download.macromedia.com/pub/flashremoting/mx2004/components/actionscript_2.0/flashremoting_comp_sourcecode.zip

              µÚÒ»ÖÖ·½Ê½±È½Ï¼òµ¥£¬Ö»Òª°²×°mxp¼´¿É½«remotingÔª¼þ×°Èëflash£¬ÈÕºóʹÓÃʱֻҪֱ½ÓÍÏ·ÅÕâ¸öÔª¼þµ½»­ÃæÉϼ´¿É¡£µÚ¶þÖÖ·½Ê½ÔòÊÇÖ±½ÓÈ¡»Øremoting classes²¢·ÅÈëflashÔ¤ÉèµÄmx·¾¶ÖУ¬ÕâÑù×öµÄºÃ´¦Óкܶ࣬ÀýÈç¿ÉÒÔÈý²»ÎåʱÐÞ¸ÄһЩµØ·½ÒÔ·ûºÏ×ÔÒѵÄÐèÇ󣬻òÊǽ«À´ÏëÓÃFAME¿ª·¢Ê±£¬Ò²¿ÉÒÔÈÃMTASCÕýÈ·µÄ±àÒë¡£

              ÕâÀïÎÒ¼ÙÉèÄãÒѾ­×°ºÃflash remoting Ôª¼þµÄ°æ±¾£¬ÔÚcomponentsÀïÒ²¿ÉÒÔ¿´µ½ flash remoting connectorÕâ¸öÔª¼þ¡£

              µÚ17ÐÐÎÒÃÇÆô¶¯NetDebugÕâ¸öÕì´í³Ìʽ£¬Ëü»á½«ËùÓеĴ«Êä½»Ò×ѶϢ¶¼ÏÔʾÔÚNetConnection Debugger(¿ªÆô·½Ê½ Window > Other Panel > NetConnection Debugger) À·½±ã³ý´í£¬ËüÊǹ¤³ÌʦµÄºÃÅóÓÑ£¬ÊµÔÚ²»ÄÜÒ»ÌìûÓÐËü¡­

              µÚ20ÐпªÊ¼ÎÒÃÇÉ趨Á˽«À´Á¬Ïߵķ¾¶£¬×¢ÒâÀïÃæµÄhello¾ÍÊǵ±³õÎÒÃÇÔÚhtdocsÀィµÄhello×ÊÁϼУ¬¶øgateway.php¾ÍÊÇǰһ½ÚËù½éÉܵÄphpµµèñ¡£

              µÚ21ÐÐÎÒÃÇÉ趨ÁËÒ»¸ögeneral responder£¬Ò²¾ÍÊÇÒ»¸öcatch-allµÄ»ØÓ¦Îï¼þ£¬Ö»Òªserver¶ËÓлش«Ñ¶Ï¢£¬¾ÍÓÉÕâÀïÉ趨µÄÁ½Ö§functionÈ¥³Ð½ÓÓë´¦Àí¡£µ±È» remoting´¦Àí»Ø´«Ñ¶Ï¢µÄ·½Ê½»¹ÓкܶàÖÖ£¬ÕâÀïÒòΪÊÇhello world¼¶µÄ·¶Àý¾ÍÏȰ´Ï²»±í¡£

              µÚ22ÐÐÎÒÃǽ¨Á¢ÁËÒ»¸ö _service object£¬ÕâÊÇÄ£ÄâÔ¶¶ËclassµÄÒ»¸öÎï¼þ£¬ÇëÌØ±ð×¢ÒâµÚÈý¸ö²ÎÊý Hello£¬ËüÊÇÖ¸ E:\webroot\amfphp\services\Hello.php Ò²¾ÍÊÇǰһ½Ú½éÉܹýµÄphp class¡£

              ¾­¹ýÕâÈýÐеÄÉ趨£¬ÎÒÃǾÍÍê³ÉflashÄÚµÄÁ¬ÏßÉ趨£¬½ÓÏÂÀ´¾Í¿ÉÒÔ¿ªÊ¼ºô½ÐÔ¶¶ËµÄmethod‡Ó£¡

              ÎÒÃÇÏÈÌøµ½µÚ33ÐУ¬ÕâÀïÎÒÃÇÉ趨ÁËÒ»¸ö°´Å¥£¬µ±°´ÏÂʱËü»áÖ´ÐÐ
              var pc:PendingCall = _service.sayHello(inputText.text);
              Ò²¾ÍÊÇ͸¹ýÏÈǰ½¨Á¢µÄ _seriveÎï¼þÈ¥ºô½Ðserver¶ËµÄsayHello method, ²¢ÇÒ½«ÎÄ×Ö¿òÄÚÊäÈëµÄÄÚÈÝ´«»ØÈ¥¡£

              Õâ±ßÁíÍâҪעÒâµÄÊÇPendingCallµÄʹÓã¬ÓÉÓÚÎÒÃÇ¿ÉÄÜͬʱ¶Ôserver·¢Éú¶à¸örequest£¬µ«Ô¶¶ËÁ¬Ïß»ØÓ¦µÄËÙ¶Èͨ³£²»ÊǼ´Ê±µÄ£¬Òò´ËÐèÒªPendingCallÀ´¸ö±ðÖ¸¶¨Ã¿¸örequestµÄcallback function£¬½«À´Ò»¶ÑѶϢ´«»ØÊ±²ÅÄÜÕýÈ·µÄ´¦Àí¡£

              ×îºóÎÒÃǻص½µÚ25ÐУ¬Õâ¸öfunction¾ÍÊǸºÔð½ÓÊÕ²¢´¦Àíserver»Ø´«×ÊÁϵĵط½¡£Ê×ÏÈÎÒÃÇÔÚµÚ26Ðн«server´«»ØµÄѶϢֱ½Ótrace³öÀ´£¬×¢ÒâÕâÀïҪʹÓà re.result²ÅÄÜ´æÈ¡µ½ÕýÈ·µÄѶϢ£¬ÕâÊdz£¼ûµÄ´íÎóÖ®Ò»¡£
              ½ÓÕßµÚ28¡¢29ÐÐÔòÊǽ«php´«»ØµÄdate stringת»»»ØflashµÄDate¸ñʽ£¬ÓÉÓÚphpÊÇÒÔ stringµÄ·½Ê½´¦Àíʱ¼ä¸ñʽ£¬Òò´ËÕâÀïÎÒÃǵÃÐÁ¿àµã×ÔÒѽ«ËüÔÙת»ØDate object¡£

              µ½ÕâÀï³ÌʽÂë¾Í¸æÒ»¸ö¶ÎÂ䣬ÎÒÃÇÀ´Ö´Ðп´¿´°É£¡

              ÕâÊdzÌʽִÐеĻ­Ã棬ÎÒÃÇÊäÈëһЩÎÄ×Öºó°´ÏÂsend.

              ÕâÊÇflash½«ÊäÈëÎÄ×Ö´«»ØphpµÄ»­Ã棬Çë×¢Òâ²ÎÊý²¿·ÝÕýÊÇÎÒÃÇÊäÈëµÄÎÄ×Ö

              ÕâÊÇphp»Ø´«Ñ¶Ï¢µÄ»­Ã棬ѶϢµÄβ¶ËÒѼÓÉÏϵͳµÄʱ¼ä

¡ôending

              Õâ¸öÀý×ÓÖÐÎÒÃǺܼòµ¥µÄÅÜÁËÒ»±éflash + amfphp + php µÄÖ´Ðз¶Àý£¬´Óflash´«Ò»¸öÎÄ×Ö´®»Øphp£¬²¢´Óphp´«Ò»¸ödateÎï¼þ»ØÀ´¡£

              ÔÚÕæÊµèñÀýÖÐÃæ¶ÔµÄÇé¿öÍùÍù»á±ÈÕâ¸öÑ}ÔÓÐí¶à£¬ÀýÈçÖÁÉÙ»á¸údatabase»¥¶¯ÀÌ×ÊÁÏ»¥´«£¬»òÊǽøÐÐauthenticationµÄÈÏÔ^µÈ£¬µ«ÕâЩ¶¼ÊǺ󻰣¬ÔÚÖ®ºóµÄ·¶ÀýÖж¼»á½âÊÍ¡£

Õª³­–http://ria.richtechmedia.com/index.php?cat=25&paged=2

Memcache的使用和协议分析详解

【Memcache初试】

[ 接口介绍 ]
服务器端和客户端都安装配置好了,现在我们就来测试以下我们的成果。Memcache 客户端包含两组接口,一组是面向过程的接口,一组是面向对象的接口,具体可以参考PHP手册 “LXXV. Memcache Functions” 这章。我们为了简单方便,就使用面向对象的方式,也便于维护和编写代码。Memcache面向对象的常用接口包括:

Memcache::connect — 打开一个到Memcache的连接
Memcache::pconnect — 打开一个到Memcache的长连接
Memcache::close — 关闭一个Memcache的连接
Memcache::set — 保存数据到Memcache服务器上
Memcache::get — 提取一个保存在Memcache服务器上的数据
Memcache::replace — 替换一个已经存在Memcache服务器上的项目(功能类似Memcache::set)
Memcache::delete — 从Memcache服务器上删除一个保存的项目
Memcache::flush — 刷新所有Memcache服务器上保存的项目(类似于删除所有的保存的项目)
Memcache::getStats — 获取当前Memcache服务器运行的状态

[ 测试代码 ]
现在我们开始一段测试代码:
//连接
$mem = new Memcache;
$mem->connect(’192.168.0.200′, 12000);

//保存数据
$mem->set(‘key1′, ‘This is first value’, 0, 60);
$val = $mem->get(‘key1′);
echo ‘Get key1 value: ‘ . $val .’
‘;

//替换数据
$mem->replace(‘key1′, ‘This is replace value’, 0, 60);
$val = $mem->get(‘key1′);
echo ‘Get key1 value: ‘ . $val . ‘
‘;

//保存数组
$arr = array(‘aaa’, ‘bbb’, ‘ccc’, ‘ddd’);
$mem->set(‘key2′, $arr, 0, 60);
$val2 = $mem->get(‘key2′);
echo ‘Get key2 value: ‘;
print_r($val2);
echo ‘
‘;

//删除数据
$mem->delete(‘key1′);
$val = $mem->get(‘key1′);
echo ‘Get key1 value: ‘ . $val . ‘
‘;

//清除所有数据
$mem->flush();
$val2 = $mem->get(‘key2′);
echo ‘Get key2 value: ‘;
print_r($val2);
echo ‘
‘;

//关闭连接
$mem->close();
?>

如果正常的话,浏览器将输出:
Get key1 value: This is first value
Get key1 value: This is replace value
Get key2 value: Array ( [0] => aaa [1] => bbb [2] => ccc [3] => ddd )
Get key1 value:
Get key2 value:

基本说明我们的Memcache安装成功,我们再来分析以下上面的这段程序。

[ 程序分析 ]

初始化一个Memcache的对象:
$mem = new Memcache;

连接到我们的Memcache服务器端,第一个参数是服务器的IP地址,也可以是主机名,第二个参数是Memcache的开放的端口:
$mem->connect(’192.168.0.200′, 12000);

保存一个数据到Memcache服务器上,第一个参数是数据的key,用来定位一个数据,第二个参数是需要保存的数据内容,这里是一个字符串,第三个参数是一个标记,一般设置为0或者MEMCACHE_COMPRESSED就行了,第四个参数是数据的有效期,就是说数据在这个时间内是有效的,如果过去这个时间,那么会被Memcache服务器端清除掉这个数据,单位是秒,如果设置为0,则是永远有效,我们这里设置了60,就是一分钟有效时间:
$mem->set(‘key1′, ‘This is first value’, 0, 60);

从Memcache服务器端获取一条数据,它只有一个参数,就是需要获取数据的key,我们这里是上一步设置的key1,现在获取这个数据后输出输出:
$val = $mem->get(‘key1′);
echo ‘Get key1 value: ‘ . $val;

现在是使用replace方法来替换掉上面key1的值,replace方法的参数跟set是一样的,不过第一个参数key1是必须是要替换数据内容的key,最后输出了:
$mem->replace(‘key1′, ‘This is replace value’, 0, 60);
$val = $mem->get(‘key1′);
echo ‘Get key1 value: ‘ . $val;

同样的,Memcache也是可以保存数组的,下面是在Memcache上面保存了一个数组,然后获取回来并输出
$arr = array(‘aaa’, ‘bbb’, ‘ccc’, ‘ddd’);
$mem->set(‘key2′, $arr, 0, 60);
$val2 = $mem->get(‘key2′);
print_r($val2);

现在删除一个数据,使用delte接口,参数就是一个key,然后就能够把Memcache服务器这个key的数据删除,最后输出的时候没有结果
$mem->delete(‘key1′);
$val = $mem->get(‘key1′);
echo ‘Get key1 value: ‘ . $val . ‘
‘;

最后我们把所有的保存在Memcache服务器上的数据都清除,会发现数据都没有了,最后输出key2的数据为空,最后关闭连接
$mem->flush();
$val2 = $mem->get(‘key2′);
echo ‘Get key2 value: ‘;
print_r($val2);
echo ‘
‘;

【Memcache协议分析】

如果你不喜欢 php_memcache.dll 扩展或者服务器器目前不支持这个扩展,那么就可以考虑自己构建,需要构建Memcahe的客户端,要先了解Memcache协议的交互,这样才能开发自己的客户端,我这里就简单的分析以下Memcache的协议。
(更详细的协议内容请在Memcache服务器端的源码的 doc/protocol.txt 文件中,本文基本来源于此)

Memcache既支持TCP协议,也支持UDP协议,不过我们这里是以TCP协议的协议作为主要考虑对象,想了解UDP协议的过程,请参考 doc/protocol.txt 文件。

[ 错误指令]
Memcache的协议的错误部分主要是三个错误提示之提示指令:
普通错误信息,比如指令错误之类的
ERRORrn

客户端错误
CLIENT_ERROR < 错误信息>rn

服务器端错误
SERVER_ERROR < 错误信息>rn

[ 数据保存指令]
数据保存是基本的功能,就是客户端通过命令把数据返回过来,服务器端接收后进行处理。
指令格式:
< 命令> < 键> < 标记> < 有效期> < 数据长度>rn

< 命令> – command name
主要是三个储存数据的三个命令, set, add, replace
set 命令是保存一个叫做key的数据到服务器上
add 命令是添加一个数据到服务器,但是服务器必须这个key是不存在的,能够保证数据不会被覆盖
replace 命令是替换一个已经存在的数据,如果数据不存在,就是类似set功能

< 键> – key
就是保存在服务器上唯一的一个表示符,必须是跟其他的key不冲突,否则会覆盖掉原来的数据,这个key是为了能够准确的存取一个数据项目

< 标记> – flag
标记是一个16位的无符号整形数据,用来设置服务器端跟客户端一些交互的操作

< 有效期> – expiration time
是数据在服务器上的有效期限,如果是0,则数据永远有效,单位是秒,Memcache服务器端会把一个数据的有效期设置为当前Unix时间+设置的有效时间

< 数据长度> – bytes
数据的长度,block data 块数据的长度,一般在这个个长度结束以后下一行跟着block data数据内容,发送完数据以后,客户端一般等待服务器端的返回,服务器端的返回:

数据保存成功
STOREDrn

数据保存失败,一般是因为服务器端这个数据key已经存在了
NOT_STOREDrn

[ 数据提取命令]
从服务器端提取数据主要是使用get指令,格式是:
get < 键>*rn

< 键>* – key
key是是一个不为空的字符串组合,发送这个指令以后,等待服务器的返回。如果服务器端没有任何数据,则是返回:
ENDrn

证明没有不存在这个key,没有任何数据,如果存在数据,则返回指定格式:
VALUE < 键> < 标记> < 数据长度>rn
< 数据块>rn

返回的数据是以VALUE开始的,后面跟着key和flags,以及数据长度,第二行跟着数据块。

< 键> -key
是发送过来指令的key内容

< 标记> – flags
是调用set指令保存数据时候的flags标记

< 数据长度> – bytes
是保存数据时候定位的长度

< 数据块> – data block
数据长度下一行就是提取的数据块内容

[ 数据删除指令]
数据删除指令也是比较简单的,使用get指令,格式是:
delete < 键> < 超时时间>rn

< 键> – key
key是你希望在服务器上删除数据的key键

< 超时时间> – timeout
按照秒为单位,这个是个可选项,如果你没有指定这个值,那么服务器上key数据将马上被删除,如果设置了这个值,那么数据将在超时时间后把数据清除,该项缺省值是0,就是马上被删除

删除数据后,服务器端会返回:
DELETEDrn
删除数据成功
NOT_FOUNDrn
这个key没有在服务器上找到

如果要删除所有服务器上的数据,可以使用flash_all指令,格式:
flush_allrn

这个指令执行后,服务器上所有缓存的数据都被删除,并且返回:
OKrn

这个指令一般不要轻易使,除非你却是想把所有数据都干掉,删除完以后可以无法恢复的。

[其他指令]
如果想了解当前Memcache服务器的状态和版本等信息,可以使用状态查询指令和版本查询指令。

如果想了解当前所有Memcache服务器运行的状态信息,可以使用stats指令,格式
statsrn
服务器将返回每行按照 STAT 开始的状态信息,包括20行,20项左右的信息,包括守护进程的pid、版本、保存的项目数量、内存占用、最大内存限制等等信息。

如果只是想获取部分项目的信息,可以指定参数,格式:
stats < 参数>rn
这个指令将只返回指定参数的项目状态信息。

如果只是想单独了解当前版本信息,可以使用version指令,格式:
versionrn
将返回以 VERSION 开头的版本信息

如果想结束当前连接,使用quit指令,格式:
quitrn

将断开当前连接

另外还有其他指令,包括incr, decr 等,我也不太了解作用,就不做介绍了,如果感兴趣,可以自己去研究。

【Memcache在中型网站的使用】

使用Memcache的网站一般流量都是比较大的,为了缓解数据库的压力,让Memcache作为一个缓存区域,把部分信息保存在内存中,在前端能够迅速的进行存取。那么一般的焦点就是集中在如何分担数据库压力和进行分布式,毕竟单台Memcache的内存容量的有限的。我这里简单提出我的个人看法,未经实践,权当参考。

[ 分布式应用]
Memcache本来支持分布式,我们客户端稍加改造,更好的支持。我们的key可以适当进行有规律的封装,比如以user为主的网站来说,每个用户都有User ID,那么可以按照固定的ID来进行提取和存取,比如1开头的用户保存在第一台Memcache服务器上,以2开头的用户的数据保存在第二胎 Mecache服务器上,存取数据都先按照User ID来进行相应的转换和存取。

但是这个有缺点,就是需要对User ID进行判断,如果业务不一致,或者其他类型的应用,可能不是那么合适,那么可以根据自己的实际业务来进行考虑,或者去想更合适的方法。

[ 减少数据库压力]
这个算是比较重要的,所有的数据基本上都是保存在数据库当中的,每次频繁的存取数据库,导致数据库性能极具下降,无法同时服务更多的用户,比如MySQL,特别频繁的锁表,那么让Memcache来分担数据库的压力吧。我们需要一种改动比较小,并且能够不会大规模改变前端的方式来进行改变目前的架构。

我考虑的一种简单方法:
后端的数据库操作模块,把所有的Select操作提取出来(update/delete/insert不管),然后把对应的SQL进行相应的hash算法计算得出一个hash数据key(比如MD5或者SHA),然后把这个key去Memcache中查找数据,如果这个数据不存在,说明还没写入到缓存中,那么从数据库把数据提取出来,一个是数组类格式,然后把数据在set到Memcache中,key就是这个SQL的hash值,然后相应的设置一个失效时间,比如一个小时,那么一个小时中的数据都是从缓存中提取的,有效减少数据库的压力。

缺点是数据不实时,当数据做了修改以后,无法实时到前端显示,并且还有可能对内存占用比较大,毕竟每次select出来的数据数量可能比较巨大,这个是需要考虑的因素。

上面只是我两点没有经过深思熟虑的简单想法,也许有用,那就最好了。

【Memcache的安全】

我们上面的Memcache服务器端都是直接通过客户端连接后直接操作,没有任何的验证过程,这样如果服务器是直接暴露在互联网上的话是比较危险,轻则数据泄露被其他无关人员查看,重则服务器被入侵,因为Mecache是以root权限运行的,况且里面可能存在一些我们未知的bug或者是缓冲区溢出的情况,这些都是我们未知的,所以危险性是可以预见的。

为了安全起见,我做两点建议,能够稍微的防止黑客的入侵或者数据的泄露。

[ 内网访问]
最好把两台服务器之间的访问是内网形态的,一般是Web服务器跟Memcache服务器之间。普遍的服务器都是有两块网卡,一块指向互联网,一块指向内网,那么就让Web服务器通过内网的网卡来访问Memcache服务器,我们Memcache的服务器上启动的时候就监听内网的IP地址和端口,内网间的访问能够有效阻止其他非法的访问。

# memcached -d -m 1024 -u root -l 192.168.0.200 -p 11211 -c 1024 -P /tmp/memcached.pid

Memcache服务器端设置监听通过内网的192.168.0.200的ip的11211端口,占用1024MB内存,并且允许最大1024个并发连接

[ 设置防火墙]
防火墙是简单有效的方式,如果却是两台服务器都是挂在网的,并且需要通过外网IP来访问Memcache的话,那么可以考虑使用防火墙或者代理程序来过滤非法访问。
一般我们在Linux下可以使用iptables或者FreeBSD下的ipfw来指定一些规则防止一些非法的访问,比如我们可以设置只允许我们的Web服务器来访问我们Memcache服务器,同时阻止其他的访问。

# iptables -F
# iptables -P INPUT DROP
# iptables -A INPUT -p tcp -s 192.168.0.2 –dport 11211 -j ACCEPT
# iptables -A INPUT -p udp -s 192.168.0.2 –dport 11211 -j ACCEPT

上面的iptables规则就是只允许192.168.0.2这台Web服务器对Memcache服务器的访问,能够有效的阻止一些非法访问,相应的也可以增加一些其他的规则来加强安全性,这个可以根据自己的需要来做。

【Memcache的扩展性】

Memcache算是比较简洁高效的程序,Memcache 1.2.0 的源代码大小才139K,在Windows平台上是不可想象的,但是在开源世界来说,这是比较正常合理的。
Memcache目前都只是比较简单的功能,简单的数据存取功能,我个人希望如果有识之士,能够在下面两方面进行扩展。

1. 日志功能
目前Memcache没有日志功能,只有一些命令在服务器端进行回显,这样是很不利于对一个服务器的稳定性和负载等等进行监控的,最好能够相应的加上日志的等功能,便于监控。

2. 存储结构
目前的数据形式就是: key => data 的形式,特别单一,只能够存储单一的一维数据,如果能够扩展的话,变成类似数据库的格式,能够存储二维数据,那样会让可以用性更强,使用面更广,当然相应的可能代码效率和存取效率更差一些。

3. 同步功能
数据同步是个比较重要的技术,因为谁都不能保证一台服务器是持久正常的运行的,如果能够具有类似MySQL的 Master/Slave 的功能,那么将使得Memcache的数据更加稳定,那么相应的就可以考虑存储持久一点的数据,并且不用害怕Memcache的down掉,因为有同步的备份服务器,这个问题就不是问题了。

以上三点只是个人拙见,有识之士和技术高手可以考虑。

【结束语】

我上面的内容都只是自己安装和使用的一些想法,不能保证绝对正确,只是给需要的人一个参考,一个推广Memcache的文章,希望更多的人能够认识和了解这个技术,并且为自己所用。

我花费了整整一个晚上的时间洋洋洒洒的写了这么长,无非是对于这项开源技术的热爱,我想开源世界能够繁荣起来,就是源于大家的热爱并且愿意做出贡献,开源世界才这么精彩。

希望本文能够给需要的人一些帮助,希望不会误导他们,呵呵。

附加:(我操作Memcache相应对应上面文章内容的图片)

[ 启动Memcache]

[ Memcache的PHP测试代码]

[测试代码执行效果]

[ 通过Telnet连接到Memcache ]

[ 基本的Memcache的数据存取协议交互]

[ Memcache状态信息协议交互]

MySQL优化简明指南 (转载)

一、在编译时优化MySQL  
如果你从源代码分发安装MySQL,要注意,编译过程对以后的目标程序性能有重要的影响,不同的编译方式可能得到类似的目标文件,但性能可能相差很大,因此,在编译安装MySQL适应仔细根据你的应用类型选择最可能好的编译选项。这种定制的MySQL可以为你的应用提供最佳性能。

技巧:选用较好的编译器和较好的编译器选项,这样应用可提高性能10-30%。(MySQL文档如是说)

1.1、使用pgcc(Pentium GCC)编译器  
该编译器(http://www.goof.com/pcg/)针对运行在奔腾处理器系统上的程序进行优化,用pgcc编译MySQL源代码,总体性能可提高10%。当然如果你的服务器不是用奔腾处理器,就不必用它了,因为它是专为奔腾系统设计的。

1.2、仅使用你想使用的字符集编译MySQL  
MySQL目前提供多达24种不同的字符集,为全球用户以他们自己的语言插入或查看表中的数据。却省情况下,MySQL安装所有者这些字符集,热然而,最好的选择是指选择一种你需要的。如,禁止除Latin1字符集以外的所有其它字符集:

——————————————————————————–
%>./configure -with-extra-charsets=none [--other-configuration-options]  
——————————————————————————–

1.3、将mysqld编译成静态执行文件  
将mysqld编译成静态执行文件而无需共享库也能获得更好的性能。通过在配置时指定下列选项,可静态编译mysqld。

——————————————————————————–
%>./configure -with-mysqld-ldflags=-all-static [--other-configuration-options]  
——————————————————————————–

1.4、配置样本  
下列配置命令常用于提高性能:

——————————————————————————–
%>CFLAGS=”-O6 -mpentiumpro -fomit-frame-pointer” CXX=gcc CXXFLAGS=”-O6 -mpentiumpro -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti” ./configure –prefix=/usr/local –enable-assembler –with-mysqld-ldflags=-all-static –disable-shared  
——————————————————————————–

二、调整服务器  
确保运用正确的编译固然重要,但这只是成功的第一步,配置众多的MySQL变量同样对服务器的正常运行起关键作用。你可以将这些变量的赋值存在一个配置文件中,以确保它们在每次启动MySQL时均起作用,这个配置文件就是my.cnf文件。

MySQL已经提供了几个my.cnf文件的样本,可在/usr/local/mysqld/share/mysql/目录下找到。这些文件分别命名为my-small.cnf、 my-medium.cnf、my-large.cnf和my-huge.cnf,规模说明可在描述配置文件适用的系统类型标题中找到。如果在只有相当少内存的系统上运行MySQL,而且只是偶尔的用一下,那么my-small.cnf会比较理想,因为它命令mysqld只使用最少的资源。类似地,如果你计划构建电子商务超市,而且系统拥有2G内存,那么你可能要用到mysql-huge.cnf文件了。

为了利用这些文件中的一个,你需要复制一个最适合需求的文件,改名为my.cnf。你可以选择使用配置文件三种作用范围的一种:

Global:将my.cnf文件复制到服务器的/etc目录下,这使得配置文件中的变量作用于全局,即对所有服务器上的MySQL数据库服务器有效。  
Local:将my.cnf文件复制到[MYSQL-INSTALL-DIR]/var/目录下,使得my.cnf作用于特定的服务器。[MYSQL-INSTALL-DIR]表示MySQL安装目录。  
User:你可以再限制作用于特定的用户,将my.cnf复制到用户的根目录下。  
究竟如何设置my.cnf中的这些变量呢?更进一步说,你可以设置哪一个变量。虽然所用变量对MySQL服务器相对通用,每一个变量与MySQL的的某些组件有更特定的关系。如变量max_connects归在mysqld类别下。执行下列命令即可知道:

——————————————————————————–
%>/usr/local/mysql/libexec/mysqld –help  
——————————————————————————–

它显示大量的选项及与mysqld相关的变量。你可以很容易地在该行文字之下找出变量:

——————————————————————————–
Possible variables for option –set-variable (-O) are  
——————————————————————————–

然后你可以如下设置my.cnf中的那些变量:  

——————————————————————————–
set-variable = max_connections=100  
——————————————————————————–

它设置MySQL服务器的最大并发连接数为100。要确保在my.cnf文件中的[mysqld]标题下插入变量设置。  
三、表类型

很多MySQL用户可能很惊讶,MySQL确实为用户提供5种不同的表类型,称为DBD、HEAP、ISAM、MERGE和MyIASM。DBD归为事务安全类,而其他为非事务安全类。

3.1、事务安全

DBD  
Berkeley DB(DBD)表是支持事务处理的表,由Sleepycat软件公司(http://www.sleepycat.com)开发。它提供MySQL用户期待已久的功能-事务控制。事务控制在任何数据库系统中都是一个极有价值的功能,因为它们确保一组命令能成功地执行。

3.2、非事务安全

HEAP  

HEAP表是MySQL中存取数据最快的表。这是因为他们使用存储在动态内存中的一个哈希索引。另一个要点是如果MySQL或服务器崩溃,数据将丢失。  

ISAM  

ISAM表是早期MySQL版本的缺省表类型,直到MyIASM开发出来。建议不要再使用它。  

MERGE  

MERGE是一个有趣的新类型,在3.23.25之后出现。一个MERGE表实际上是一个相同MyISAM表的集合,合并成一个表,主要是为了效率原因。这样可以提高速度、搜索效率、修复效率并节省磁盘空间。  

MyIASM  

这是MySQL的缺省表类型。它基于IASM代码,但有很多有用的扩展。MyIASM比较好的原因:  

MyIASM表小于IASM表,所以使用较少资源。  
MyIASM表在不同的平台上二进制层可移植。  
更大的键码尺寸,更大的键码上限。  
3.3、指定表类型

你可在创建表时指定表的类型。下例创建一个HEAP表:

——————————————————————————–

mysql>CREATE TABLE email_addresses TYPE=HEAP (
     ->email char(55) NOT NULL,
     ->name char(30) NOT NULL,
     ->PRIMARY KEY(email) );

——————————————————————————–

BDB表需要一些配置工作,参见http://www.mysql.com/doc/B/D/BDB_overview.html。  

3.4、更多的表类型  

为了使MySQL管理工作更有趣,即将发布的MySQL 4.0将提供两种新的表类型,称为Innobase和Gemeni。  

4、优化工具  

MySQL服务器本身提供了几条内置命令用于帮助优化。  

4.1、SHOW  

你可能有兴趣知道MySQL服务器究竟更了什么,下列命令给出一个总结:  

——————————————————————————–
mysql>show status;  
——————————————————————————–

它给出了一个相当长的状态变量及其值的列表。有些变量包含了异常终止客户的数量、异常终止连接的数量、连接尝试的次数、最大并发连接数和大量其他有用的信息。这些信息对找出系统问题和低效极具价值。  
SHOW还能做更多的事情。它可以显示关于日志文件、特定数据库、表、索引、进程和权限表中有价值的信息。详见MySQL手册。

4.2、EXPLAIN

当你面对SELECT语句时,EXPLAIN解释SELECT命令如何被处理。这不仅对决定是否应该增加一个索引,而且对决定一个复杂的Join如何被MySQL处理都是有帮助的。

4.3、OPTIMIZE

OPTIMIZE语句允许你恢复空间和合并数据文件碎片,对包含变长行的表进行了大量更新和删除后,这样做特别重要。OPTIMIZE目前只工作于MyIASM和BDB表。  

MySQL数据库安装指定my.ini配置文件

       以前安装几个MySQL数据库,都将my.ini写在系统目录中,一个my.ini文件中配置多个数据库信息,刚才在管理工具->服务->MySQL41中,见到如下一句话:

       “D:\MySQL4.1\bin\mysqld-nt”      –defaults-file=”D:\MySQL4.1\my.ini” MySQL41

        启动MySQL41的时候。调用”D:\MySQL4.1\my.ini”这个配置文件。

     安装的时候,运行如下即可:

     “D:\MySQL4.1\bin\mysqld-nt”    –install MySQL41    –defaults-file=”D:\MySQL4.1\my.ini”

FOUND_ROWS()£¬ ROW_COUNT()

        ¸Õ²ÅÉÏÍø²é×ÊÁÏ£¬·¢ÏÖÈçÏÂ×ÊÁÏ£º

  • FOUND_ROWS()

    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 SQL_CALC_FOUND_ROWS * FROM tbl_name
             -> WHERE id > 100 LIMIT 10;
    mysql> SELECT FOUND_ROWS();
    

    The second SELECT returns a number indicating how many rows the first SELECT would have returned had it been written without the LIMIT clause.

    In the absence of the SQL_CALC_FOUND_ROWS option in the most recent SELECT statement, FOUND_ROWS() returns the number of rows in the result set returned by that statement.

    The row count available through FOUND_ROWS() is transient and not intended to be available past the statement following the SELECT SQL_CALC_FOUND_ROWS statement. If you need to refer to the value later, save it:

    mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
    mysql> SET @rows = FOUND_ROWS();
    

    If you are using SELECT SQL_CALC_FOUND_ROWS, MySQL must calculate how many rows are in the full result set. However, this is faster than running the query again without LIMIT, because the result set need not be sent to the client.

    SQL_CALC_FOUND_ROWS and FOUND_ROWS() can be useful in situations when you want to restrict the number of rows that a query returns, but also determine the number of rows in the full result set without running the query again. An example is a Web script that presents a paged display containing links to the pages that show other sections of a search result. Using FOUND_ROWS() allows you to determine how many other pages are needed for the rest of the result.

    The use of SQL_CALC_FOUND_ROWS and FOUND_ROWS() is more complex for UNION statements than for simple SELECT statements, because LIMIT may occur at multiple places in a UNION. It may be applied to individual SELECT statements in the UNION, or global to the UNION result as a whole.

    The intent of SQL_CALC_FOUND_ROWS for UNION is that it should return the row count that would be returned without a global LIMIT. The conditions for use of SQL_CALC_FOUND_ROWS with UNION are:

    • The SQL_CALC_FOUND_ROWS keyword must appear in the first SELECT of the UNION.

    • The value of FOUND_ROWS() is exact only if UNION ALL is used. If UNION without ALL is used, duplicate removal occurs and the value of FOUND_ROWS() is only approximate.

    • If no LIMIT is present in the UNION, SQL_CALC_FOUND_ROWS is ignored and returns the number of rows in the temporary table that is created to process the UNION.

  • ROW_COUNT()

    ROW_COUNT() returns the number of rows updated, inserted, or deleted by the preceding statement. This is the same as the row count that the mysql client displays and the value from the mysql_affected_rows() C API function.

    mysql> INSERT INTO t VALUES(1),(2),(3);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3        Duplicates: 0        Warnings: 0
    
    mysql> SELECT ROW_COUNT();
    +-------------+
    | ROW_COUNT() |
    +-------------+
    |                 3 |
    +-------------+
    1 row in set (0.00 sec)
    
    mysql> DELETE FROM t WHERE i IN(1,2);
    Query OK, 2 rows affected (0.00 sec)
    
    mysql> SELECT ROW_COUNT();
    +-------------+
    | ROW_COUNT() |
    +-------------+
    |                 2 |
    +-------------+
    1 row in set (0.00 sec)
    

    ROW_COUNT() was added in MySQL 5.0.1.

  • Ó¦ÓÃÀý×Ó£º

          ²éѯ·ÖÒ³£¬ÎÒÃÇÏÈÒªµÃµ½·ûºÏÌõ¼þµÄ×ÜÌõÊý£¬È»ºóÈ¡¼Ç¼£¬ÐèÒªÁ½´ÎÓÐWHEREÔ¼ÊøµÄ²éѯ£¬ÀýÈ磺

    ÎļþÃû³Æ£ºexample.sql

    /* ²éѯµÃµ½·ûºÏÌõ¼þµÄÌõÊý£¬ÓÃÓÚ·ÖÒ³ £º¼ÙÈçµÃµ½1000Ìõ¼Ç¼ */
    SELECT
        COUNT(*)
    FROM
            `mobile_mobile`
    WHERE
            `mobile_title` LIKE '%88%';

    /* ²éѯʮÌõ¼Ç¼ */
    SELECT
            `mobile_id`,
            `mobile_number`
    FROM
            `mobile_mobile`
    WHERE
            `mobile_title` LIKE '%88%'
    LIMIT 10;

    Èç½ñ£¬¿ÉÒÔʹÓÃÈçÏ·½·¨ÊµÏÖ£º

    ÎļþÃû³Æ£ºexample.sql
    /**
    * ÉÏÃæµÄÁ½²½²Ù×÷£¬ÎÒÃÇ¿ÉÒÔÓÃÈçϵÄÁ½²½²Ù×÷ʵÏÖ£¬
    * SQL_CALC_FOUND_ROWS ûÓÐLIMITÏÞÖÆµÄ¼Ç¼Êý
    */

    SELECT
            SQL_CALC_FOUND_ROWS
            `mobile_id`,
            `mobile_number`
    FROM
            `mobile_mobile`
    WHERE
            `mobile_title` LIKE '%88%'
    LIMIT 10;

    /* ÈçÏÂÓï¾ä»áµÃµ½1000Ìõ¼Ç¼ */
    SELECT FOUND_ROWS();

    ²Î¿¼£ºhttp://dev.mysql.com/doc/refman/5.0/en/information-functions.html#id2890708

  • MySQL 数据库同步

    我的数据库版本:mysql-5.0.37.
    注释:你不能从使用新二进制日志格式的主服务器向使用旧二进制日志格式的从服务器复制(例如,从MySQL 5.0到MySQL 4.1)。

    master: 192.168.1.115:3308
    slave: 192.168.1.115:3309

    一、master操作
          1、修改my.ini
          ##############
          server-id=11
          log-bin=mysql-bin
          binlog-do-db=bak_test
          binlog-ignore-db=mysql
          ##############

          说明
          binlog-do-db=bak_test 允许同步的数据库
          binlog-ignore-db=mysql 不允许同步的数据库

          2、然后重启mysql

          3、在master上增加一个同步的用户名

          mysql> GRANT REPLICATION SLAVE ON *.* TO ‘backup’@'%’ IDENTIFIED BY ’123456′;
          注:
          如果mysql版本在4.0.2以前的版本请用
          mysql> GRANT FILE ON *.* TO ‘backup’@'%’ IDENTIFIED BY ’123456′;

          4、接下来操作要master上要同步的数据库
          mysql> USE bak_test;
          mysql> FLUSH TABLES WITH READ LOCK; #锁定要同步的bak_test表,然后导出数据结构

          执行如下命令查看master的状态
          mysql> SHOW MASTER STATUS;

          得到如下结果
          Code:
          +———————-+———-+————–+——————+
          | File | Position | Binlog_do_db | Binlog_ignore_db |
          +———————-+———-+————–+——————+
          | mysql-bin.000005 | 79 | bak_test | mysql |
          +———————-+———-+————–+——————+
          1 row in set (0.00 sec)

          接下来备份要同步数据库(为导入slave作准备)
          $ mysqldump –opt bak_test > bak_test.sql

          mysql> UNLOCK TABLES; #已做好同步数据库结构导出后,解锁这个表

    二、slave操作
          1、把master里导出的同步数据库结构再导入slave的mysql里
          mysql bak_test < bak_test.sql

          2、修改slave的my.ini
          ####################
          log-bin=mysql-bin
          server-id=12
          master-host=192.168.1.115
          master-user=backup
          master-password=123456
          master-port = 3308
          master-connect-retry=60
          replicate-do-db=bak_test
          ####################

          说明:
          master-host=192.168.1.115 #master的IP
          master-user=backup #master上作为同步用的用户名
          master-password=123456 #同步用户名的密码
          master-connect-retry=60 #设置同步的时间
          replicate-do-db=bak_test #需要同步的数据库

          3、重新启用mysql
          c:\mysql\bin\mysql restart 或 /etc/init.d/mysql restart

          4、进入slave的mysql,对mysql进行操作
          mysql> stop slave; #停止slave服务器

          mysql> CHANGE MASTER TO
          -> MASTER_HOST=’192.168.1.115′,
          -> MASTER_PORT=3308,
          -> MASTER_USER=’backup’,
          -> MASTER_PASSWORD=’123456′,
          -> MASTER_LOG_FILE=’mysql-bin.000005′,
          -> MASTER_LOG_POS=79;

          mysql> START SLAVE; #开启slave服务器就可以同步了

         

          注:
          MASTER_LOG_FILE=’mysql-bin.000005′,
          MASTER_LOG_POS=79;
          上面这两条是一开始从master上进入mysql,运行 SHOW MASTER STATUS; 查看到的,在实际操作中也可以不加的。

         

         

    ##############################################
    在主服务器上,SHOW PROCESSLIST的输出看上去应为:

    mysql> SHOW PROCESSLIST\G
    *************************** 1. row ***************************
           Id: 2
         User: root
         Host: localhost:32931
           db: NULL
    Command: Binlog Dump
         Time: 94
        State: Has sent all binlog to slave; waiting for binlog to
               be updated
         Info: NULL
    这儿,线程2是一个连接从服务器的复制线程。该信息表示所有主要更新已经被发送到从服务器,主服务器正等待更多的更新出现。

    在从服务器上,SHOW PROCESSLIST的输出看上去应为:

    mysql> SHOW PROCESSLIST\G
    *************************** 1. row ***************************
           Id: 10
         User: system user
         Host:
           db: NULL
    Command: Connect
         Time: 11
        State: Waiting for master to send event
         Info: NULL
    *************************** 2. row ***************************
           Id: 11
         User: system user
         Host:
           db: NULL
    Command: Connect
         Time: 11
        State: Has read all relay log; waiting for the slave I/O
               thread to update it
         Info: NULL
    该信息表示线程10是同主服务器通信的I/O线程,线程11是处理保存在中继日志中的更新的SQL线程。SHOW PROCESSLIST运行时,两个线程均空闲,等待其它更新。

    **********************

    MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。(这与同步复制可以进行对比,同步复制是MySQL簇的一个特征)。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。

    如果你想要设置链式复制服务器,从服务器本身也可以充当主服务器。

    请注意当你进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。

    单向复制有利于健壮性、速度和系统管理:

    ・          主服务器/从服务器设置增加了健壮性。主服务器出现问题时,你可以切换到从服务器作为备份。

    ・          通过在主服务器和从服务器之间切分处理客户查询的负荷,可以得到更好的客户响应时间。SELECT查询可以发送到从服务器以降低主服务器的查询处理负荷。但修改数据的语句仍然应发送到主服务器,以便主服务器和从服务器保持同步。如果非更新查询为主,该负载均衡策略很有效,但一般是更新查询。

    ・          使用复制的另一个好处是可以使用一个从服务器执行备份,而不会干扰主服务器。在备份过程中主服务器可以继续处理更新。参见5.9.1节,“数据库备份”。

    MySQL实现表中取出随机数据

    SELECT * FROM table_name ORDER BY rand() LIMIT 5;

    rand在手册里是这么说的:
    RAND()
    RAND(N)
    返回在范围0到1.0内的随机浮点值。如果一个整数参数N被指定,它被用作种子值。

    mysql> select RAND();
    -> 0.5925
    mysql> select RAND(20);
    -> 0.1811
    mysql> select RAND(20);
    -> 0.1811
    mysql> select RAND();
    -> 0.2079
    mysql> select RAND();
    -> 0.7888
    你不能在一个ORDER BY子句用RAND()值使用列,因为ORDER BY将重复计算列多次。然而在MySQL3.23中,你可以做: SELECT * FROM table_name ORDER BY RAND(),这是有利于得到一个来自SELECT * FROM table1,table2 WHERE a=b AND c

    但我试了一下,8千条记录的表,执行一次需要0.08 sec,.慢了些

    后来请教了google,得到如下代码

    SELECT *
    FROM table_name AS r1 JOIN
    (SELECT ROUND(RAND() *
    (SELECT MAX(id)
    FROM table_name)) AS id)
    AS r2
    WHERE r1.id >= r2.id
    ORDER BY r1.id ASC
    LIMIT 5;
    执行效率需要0.02 sec.可惜的是,只有mysql 4.1.*以上才支持这样的子查询.

    Page 1 of 212