当前位置:首页 > PHP教程 > php高级应用 > 列表

php memcached mysql开发详细实例

发布:smiling 来源: PHP粉丝网  添加日期:2014-09-09 16:35:16 浏览: 评论:0 

Memcached的工作方式:以下的部分中,读者最好能准备一份memcached的源代码.

Memcached是传统的网络服务程序,如果启动的时候使用了-d参数,它会以守护进程的方式执行,创建守护进程由daemon.c完成,这个程序只有一个daemon函数,这个函数很简单,如无特殊说明,代码以1.2.1为准,代码如下:

  1. #include <fcntl.h> 
  2. #include <stdlib.h> 
  3. #include <unistd.h> 
  4.  
  5. int 
  6. daemon(nochdir, noclose) 
  7.     int nochdir, noclose; 
  8.     int fd; 
  9.  
  10.     switch (fork()) { 
  11.     case -1: 
  12.         return (-1); 
  13.     case 0:  
  14.         break;   
  15.     default
  16.         _exit(0); 
  17.     } 
  18.  
  19.     if (setsid() == -1) 
  20.         return (-1); 
  21.  
  22.     if (!nochdir) 
  23.         (void)chdir(”/”); 
  24.  
  25.     if (!noclose && (fd = open(”/dev/null”, O_RDWR, 0)) != -1) { 
  26.         (void)dup2(fd, STDIN_FILENO); 
  27.         (void)dup2(fd, STDOUT_FILENO); 
  28.         (void)dup2(fd, STDERR_FILENO); 
  29.         if (fd > STDERR_FILENO) 
  30.             (void)close(fd); 
  31.     } 
  32.     return (0); 

这个函数 fork 了整个进程之后,父进程就退出,接着重新定位 STDIN 、 STDOUT 、 STDERR 到空设备,daemon 就建立成功了,代码如下:

  1. <?php  
  2. class Memcached  
  3. {  
  4. private $mem;  
  5. public $pflag=''// memcached pconnect tag  
  6. private function memConnect($serkey){  
  7. require 'config.php';  
  8. $server = $memcached;  
  9. $this->mem = new Memcache;  
  10. $link = !$this->pflag ? 'connect' : 'pconnect' ;  
  11. $this->mem->$link($server[$serkey][0],$server[$serkey][1]) or $this->errordie('memcached connect error');  
  12. }  
  13. public function set($ser_key,$values,$flag='',$expire=''){  
  14. $this->memConnect($this->tag($ser_key));  
  15. if($this->mem->set($ser_key,$values,$flag,$expire)) return true;  
  16. else return false;  
  17. }  
  18. public function get($ser_key){  
  19. $this->memConnect($this->tag($ser_key));  
  20. if($var=$this->mem->get($ser_key)) return $var;  
  21. else return false;  
  22. }  
  23. private function tag($ser_key){  
  24. $tag=explode('_',$ser_key);  
  25. return $tag[0];  
  26. }  
  27. private function errordie($errmsg){  
  28. die($errmsg);  
  29. }  
  30. }  
  31. ?> 
  32.  
  33. class Mysql  
  34. {  
  35. private $mysqlmaster;  
  36. private $myssqlslave;  
  37. private static $auid=0;  
  38. public function __construct(){  
  39. require 'config.php';  
  40. $msg = $mysql
  41.  
  42. $this->mysqlmaster = new mysqli($msg['master'][0],$msg['master'][1],$msg['master'][2],$msg['master'][3]); //master mysql  
  43. $this->mysqlslave = $this->autotranscat($msg); // slave mysql  
  44. if(mysqli_connect_errno()){  
  45. printf("Connect failed: %s ",mysqli_connect_error());  
  46. exit();  
  47. }  
  48. if(!$this->mysqlmaster->set_charset("latin1") && !$this->mysqlslave->set_charset("latin1")){  
  49. exit("set charset error");  
  50. }  
  51. }  
  52. private function autotranscat($mysql){  
  53. session_start();  
  54. $_SESSION['SID']!=0 || $_SESSION['SID']=0 ;  
  55. if($_SESSION['SID'] >=count($mysql)-1) $_SESSION['SID'] = 1;  
  56. else $_SESSION['SID']++;  
  57. $key = 'slave_'.$_SESSION['SID'];  
  58. echo($_SESSION['SID']);  
  59. return new mysqli($mysql[$key][0],$mysql[$key][1],$mysql[$key][2],$mysql[$key][3]);  
  60. }  
  61. public function mquery($sql){ //insert update  
  62. if(!$this->mysqlmaster->query($sql)){  
  63. return false;  
  64. }  
  65. }  
  66. public function squery($sql){  
  67. if($result=$this->mysqlslave->query($sql)){  
  68. return $result;  
  69. }else{  
  70. return false;  
  71. };  
  72. }  
  73. public function fetArray($sql){  
  74. if($result=$this->squery($sql)){  
  75. while($row=$result->fetch_array(MYSQLI_ASSOC)){  
  76. $resultraa[] = $row;  
  77. };  
  78. return $resultraa;  
  79. }  
  80. }  
  81. }  
  82. ?> 
  83. require 'init.php';  
  84. $mem = new Memcached;  
  85. /* $mem->set('en_xx','bucuo');  
  86. echo($mem->get('en_xx'));  
  87. $mem->set('cn_jjyy','wokao');  
  88. echo($mem->get('cn_jjyy'));  
  89. */  
  90. $sq = new Mysql;  
  91. $sql = "insert into mybb(pid) values(200)";  
  92. $mdsql = md5($sql);  
  93. if(!$result=$mem->get('cn_'.$mdsql)){  
  94. $sq->mquery("insert into mybb(pid) values(200)"); //插入到主mysql  
  95. $result = $sq->fetArray("select * from mybb"); //查询 是 从mysql  
  96. foreach($result as $var){  
  97. echo $var['pid'];  
  98. }  
  99. $mem->set('cn_'.$mdsql,$result); //添加到 名为 cn 的 memcached 服务器  
  100. }else{  
  101. foreach($result as $var){  
  102. echo $var['pid'];  
  103. }  
  104. }  
  105. ?> 
  106.  
  107. <?php  
  108. $memcached = array//用memcached 的 多 进程模拟 多台memcached 服务器 cn en 为 内存服务器名  
  109. 'cn'=>array('192.168.254.144',11211),  
  110. 'en'=>array('192.168.254.144',11212)  
  111. ); //开源代码phpfensi.com 
  112. $mysql = array// mysql 的主从 我的环境是 : xp 主 linux 从 mysql 5 php5  
  113. 'master'=>array('192.168.254.213','root','1','mydz'),  
  114. 'slave_1'=>array('192.168.254.144','root','1','mydz'//可以灵活添加多台从服务器  
  115. );  
  116. ?>   

Memcached 本身的启动过程,在 memcached.c 的 main 函数中顺序如下:

1 、调用 settings_init() 设定初始化参数

2 、从启动命令中读取参数来设置 setting 值

3 、设定 LIMIT 参数

4 、开始网络 socket 监听(如果非 socketpath 存在)( 1.2 之后支持 UDP 方式)

5 、检查用户身份( Memcached 不允许 root 身份启动)

6 、如果有 socketpath 存在,开启 UNIX 本地连接(Sock 管道)

7 、如果以 -d 方式启动,创建守护进程(如上调用 daemon 函数)

8 、初始化 item 、 event 、状态信息、 hash 、连接、 slab

9 、如设置中 managed 生效,创建 bucket 数组

10 、检查是否需要锁定内存页

11 、初始化信号、连接、删除队列

12 、如果 daemon 方式,处理进程 ID

13 、event 开始,启动过程结束,main 函数进入循环.

在 daemon 方式中,因为 stderr 已经被定向到黑洞,所以不会反馈执行中的可见错误信息.

memcached.c 的主循环函数是 drive_machine,传入参数是指向当前的连接的结构指针,根据 state 成员的状态来决定动作.

Tags: memcached mysql缓存开发

分享到: