nginx+PHP+memcached+MySQL+ip-hash做memcached集群

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

1、nginx与memcached整合

#安装memcached支持的事务库libevent

1
2
3
4
5
6
7
wget https: //github .com /libevent/libevent/releases/download/release-2 .0.22-stable /libevent-2 .0.22-stable. tar .gz
tar  zxf libevent-2.0.22-stable. tar .gz 
cd  libevent-2.0.22-stable
. /configure  --prefix= /usr/local/libevent
make  &&  make  install
echo  $?
cd  ..

#接下来安装memcached:

1
2
3
4
5
6
7
wget http: //www .memcached.org /files/memcached-1 .4.35. tar .gz
tar  zxf memcached-1.4.35. tar .gz
cd  memcached-1.4.35
. /configure  --prefix= /usr/local/memcached  --with-libevent= /usr/local/libevent
make  &&  make  install
echo  $?
cd  ..

#运行memcached

[root@nginx ~]# /usr/local/memcached/bin/memcached -d -u nobody -vv

#配置nginx配置文件nginx.conf,定位user的uri交给memcached做缓存

#添加location定位:

1
2
3
4
5
location ~* user {
                 set  $memcached_key  "$uri" #设置memcached的key为uri
                 memcached_pass 192.168.146.132:11211;  #链接memcached
                 error_page 404  /callback .php;  #错误定位
         }

#加载nginx配置

nginx -s reload

#在memcached中写入一条URI数据,测试整合是否成功

1
2
3
4
5
6
7
8
[root@nginx ~] # telnet 192.168.146.132 11211
Trying 192.168.146.132...
Connected to 192.168.146.132.
Escape character is  '^]' .
add  /user1 .html 0 0 7
iamlisi 
STORED
quit

#访问http://192.168.146.132/user1.html如能看到iamlisi,那么nginx与memcache整合成功了!


2、整合PHP与memcahced

#安装PHP扩展模块memcache

1
2
3
4
5
6
7
8
wget http: //pecl .php.net /get/memcache-2 .2.7.tgz
tar  zxvf memcache-2.2.7.tgz
cd  memcache-2.2.7
/usr/local/php/bin/phpize 
. /configure  -- enable -memcache --with-php-config= /usr/local/php/bin/php-config  --with-zlib- dir
make  &&  make  install
echo  $?
cd  ..

pkill php-fpm   #杀死php-fpm进程

php-fpm   #启动php-fpm

http://192.168.146.132/test.php能看到memcache模块就成功了

#测试PHP与memcached

1
2
3
4
vim  /usr/local/nginx/html/callback .php
<?php
print_r($_SERVER);
?>php

#访问http://1982.168.146.132/user2.html 此uri在memcached中不存在,就会回调到callback.php处理请求,结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Array
(
     [USER] => nobody
     [HOME] => /
     [FCGI_ROLE] => RESPONDER
     [SCRIPT_FILENAME] => /usr/local/nginx/html/callback.php
     [QUERY_STRING] => 
     [REQUEST_METHOD] => GET
     [CONTENT_TYPE] => 
     [CONTENT_LENGTH] => 
     [SCRIPT_NAME] => /callback.php
     [REQUEST_URI] => /user2.html
     [DOCUMENT_URI] => /callback.php
     [DOCUMENT_ROOT] => /usr/local/nginx/html
     [SERVER_PROTOCOL] => HTTP/1.1
     [REQUEST_SCHEME] => http
     [GATEWAY_INTERFACE] => CGI/1.1
     [SERVER_SOFTWARE] => nginx/1.12.1
     [REMOTE_ADDR] => 192.168.146.1
     [REMOTE_PORT] => 14187
     [SERVER_ADDR] => 192.168.146.132
     [SERVER_PORT] => 80
     [SERVER_NAME] => localhost
     [REDIRECT_STATUS] => 200
     [HTTP_HOST] => 192.168.146.132
     [HTTP_CONNECTION] => keep-alive
     [HTTP_UPGRADE_INSECURE_REQUESTS] => 1
     [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
     [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
     [HTTP_ACCEPT_ENCODING] => gzip, deflate
     [HTTP_ACCEPT_LANGUAGE] => zh-CN,zh;q=0.8
     [PHP_SELF] => /callback.php
     [REQUEST_TIME] => 1503552110
)

3、使用PHP让memcached链接MySQL查询key与value并存入memcached,

#接下来我们写个PHP程序,链接数据库,让memcached找不到的uri就回调给PHP,然后PHP去链接数据库,查找数据后给memcached:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat  html /callback .php
<?php
//print_r ($_SERVER);
// 获取UID用来做key
$uri = $_SERVER[ 'REQUEST_URI' ];
// 分析出uir中的uid号
$uid = substr($uri,5,strpos($uri, '.' )-5);
//echo  $uid;
// 链接数据库,查询并写入memcached
$conn = mysql_connect( 'localhost' , 'root' , '123.com' );
$sql =  'use test' ;
mysql_query($sql,$conn);
$sql =  'set names utf8' ;
mysql_query($sql,$conn);
$sql =  'select * from user where uid=' .$uid;
$rs = mysql_query($sql,$conn);
echo  'from mysql query<br />' ;
$user = mysql_fetch_assoc($rs);
if  (empty($user)) {
     echo  'no this user' ;
else  {
//     print_r($user);
     $html =  '<h1>' . $user[ 'uname' ]. '</h1>' ;
     echo  $html;
     $mem = new memcache();
     $mem->connect( '192.168.146.132' ,11211);
     $mem->add($uri,$html,0,300);
     $mem->close();
}

#此处我们要在数据库中建立test库和user表,并写入uid和uname字段数据:

#注意:callback.php文件调用的库和表,字段要对应建立

1
2
3
4
5
6
7
8
mysql> create database  test ;
mysql> use  test ;
mysql> create table user(
     -> uid int(11) not null,
     ->  uname  varchar(255) not null,
     -> primary key (uid));
mysql> insert into user (uid, uname ) values(1, 'i am memcached' );
mysql> insert into user (uid, uname ) values(2, 'dslajfflsaj;gljdaslgjlajfdalsjf' );

#此时访问uir,首先会转发到memcached处理,memcached中没有key就会回调给callback.php处理,然后PHP链接数据库,查询uri数据,然后memcached会写入key与value,并将数据返回给客户端。

http://192.168.146.132/user1.html

#memcached显示数据动态:

1
2
3
4
5
6
7
8
9
10
11
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 add  /user1 .html 1 300 122
>36 STORED
<36 connection closed.
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 get  /user1 .html
>36 sending key  /user1 .html
>36 END
<36 connection closed.

4、配置memcached群架,nginx和PHP使用一致性哈希(ip-hash)

#当使用memcached群集时,会遇到数据写入memcached不一致,因为nginx模式使用round-robin(轮询)方式访问memcached服务器,就会造成写入和读出数据不在同一服务器的问题,为此nginx提供了ip-hash基于Ip的一致性哈希算法,它会记录访问IP,下次访问时同一ip会访问上次记录的服务器。

官方参考文档:https://www.nginx.com/resources/wiki/modules/consistent_hash/

#下载nginx hash模块并安装:

1
2
3
cd  /root/tools
wget https: //github .com /replay/ngx_http_consistent_hash/archive/master .zip
unzip master.zip

#查看nginx编译参数

1
2
3
4
5
6
[root@LNMP tools] # nginx -V
nginx version: nginx /1 .8.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix= /usr/local/nginx  --with-http_ssl_module --with-http_stub_status_module --with-http_ssl_module --add-module= /root/tools/nginx-1 .8.1 /nginx-rtmp-module

#进入nginx源码目录,添加模块安装

1
2
3
[root@LNMP tools] # cd nginx-1.8.1
[root@LNMP nginx-1.8.1] # ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-http_ssl_module --add-module=/root/tools/nginx-1.8.1/nginx-rtmp-module --add-module=/root/tools/ngx_http_consistent_hash-master/
[root@LNMP nginx-1.8.1] #make && make install

#模拟memcache集群,区分端口启动三个memcached

1
2
3
memcached -d -u nobody -p 11211 -vv
memcached -d -u nobody -p 11212 -vv
memcached -d -u nobody -p 11213 -vv

#nginx配置文件http段添加upstram模块:

1
2
3
4
5
6
upstream mcserver {
         consistent_hash $request_uri;   #指定使用哈希算法,针对memcached,请参考文档
         server 192.168.146.132:11211;
         server 192.168.146.132:11212;
         server 192.168.146.132:11213;
         }

#并在location中反向代理到mcserver集群:

具体参考文档:http://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_pass

1
2
3
4
5
location ~*  /user  {
                 set  $memcached_key  "$uri" ;   #将uri配置为memcached的key
                 memcached_pass mcserver;     #代理到memcached集群
                 error_page 404 =  /callback .php;   #memcached中找不到key将回调到此文件
         }

#重新加载nginx配置

nginx -s reload

#修改php配置为hash查询

#具体参考文挡:http://cn2.php.net/manual/en/memcache.ini.php#ini.memcache.hash-strategy

1
2
vim  /usr/local/php/etc/php .ini
memcache.hash_strategy=consistent   #添加,使用一致性哈希

#重新启动php-fpm

1
2
3
pkill -9 php-fpm
netstat  -lntup| grep  9000
php-fpm

#修改回调代码,建立memcached集群链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
cat  html /callback .php
<?php
//print_r ($_SERVER);
// 获取UID用来做key
$uri = $_SERVER[ 'REQUEST_URI' ];
// 分析出uir中的uid号
$uid = substr($uri,5,strpos($uri, '.' )-5);
// 建立memcached集群链接
$mem = new memcache();
$mem->addServer( '192.168.146.132' ,11211);
$mem->addServer( '192.168.146.132' ,11212);
$mem->addServer( '192.168.146.132' ,11213);
// 链接数据库,查询并写入memcached
$conn = mysql_connect( 'localhost' , 'root' , '123.com' );
$sql =  'use test' ;
mysql_query($sql,$conn);
$sql =  'set names utf8' ;
mysql_query($sql,$conn);
$sql =  'select * from user where uid=' .$uid;
$rs = mysql_query($sql,$conn);
echo  'from mysql query<br />' ;
$user = mysql_fetch_assoc($rs);
if  (empty($user)) {
     echo  'no this user' ;
else  {
     $html =  '<h1>' . $user[ 'uname' ]. '</h1>' ;
     echo  $html;
     $mem->add($uri,$html,0,10);
     $mem->close();
}

#测试数据,memcached会在一个端口写入数据和查询数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 get  /user1 .html
>36 END
<36 connection closed.
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 add  /user1 .html 0 10 87
>36 STORED
<37 new auto-negotiating client connection
37: Client using the ascii protocol
<37 get  /user1 .html
>37 END
<37 connection closed.
<40 new auto-negotiating client connection
40: Client using the ascii protocol
<40 get  /user2 .html
>40 END
<40 connection closed.
<40 new auto-negotiating client connection
40: Client using the ascii protocol
<40 add  /user2 .html 0 10 40
>40 STORED
<41 new auto-negotiating client connection
41: Client using the ascii protocol
<41 get  /user2 .html
>41 END
<41 connection closed.

#到此nginx+PHP+memcached+MySQL并现象memcached群架一致性哈希算法完成!

#途中遇到一个问题:在MySQL中写入中文数据,php调用后第一次显示正常,第二次存入memcached后调用就乱码了,我用Google和Firefox浏览器都是乱码,而用360和IE则没有乱码!暂时没找到原因,有知道的忘告知,万分感谢!!!


本文转自 80后小菜鸟 51CTO博客,原文链接:http://blog.51cto.com/zhangxinqi/1961992


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
安全 关系型数据库 MySQL
PHP与MySQL交互:从入门到实践
【9月更文挑战第20天】在数字时代的浪潮中,掌握PHP与MySQL的互动成为了开发动态网站和应用程序的关键。本文将通过简明的语言和实例,引导你理解PHP如何与MySQL数据库进行对话,开启你的编程之旅。我们将从连接数据库开始,逐步深入到执行查询、处理结果,以及应对常见的挑战。无论你是初学者还是希望提升技能的开发者,这篇文章都将为你提供实用的知识和技巧。让我们一起探索PHP与MySQL交互的世界,解锁数据的力量!
|
1月前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
47 3
|
30天前
|
消息中间件 分布式计算 关系型数据库
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
38 0
|
2月前
|
NoSQL 关系型数据库 MySQL
不是 PHP 不行了,而是 MySQL 数据库扛不住啊
【9月更文挑战第8天】这段内容讨论了MySQL在某些场景下面临的挑战及其原因,并指出这些问题不能完全归咎于MySQL本身。高并发读写压力、数据量增长以及复杂查询和事务处理都可能导致性能瓶颈。然而,应用程序设计不合理、系统架构不佳以及其他数据库选择和优化策略不足也是重要因素。综合考虑这些方面才能有效解决性能问题,而MySQL通过不断改进和优化,仍然是许多应用场景中的可靠选择。
124 9
|
3月前
|
存储 SQL 关系型数据库
PHP与MySQL交互的奥秘
【8月更文挑战第29天】在编程的世界里,PHP和MySQL就像是一对默契的舞伴,共同演绎着数据的交响曲。本文将带你探索它们之间的互动,从连接数据库到执行查询,再到处理结果,每一步都充满了节奏与和谐。我们将一起走进这段代码的旅程,感受数据流动的魅力。
|
3月前
|
Java 应用服务中间件 Shell
Nginx+Keepalived+Tomcat 实现Web高可用集群
Nginx+Keepalived+Tomcat 实现Web高可用集群
108 0
|
4天前
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发深度解析####
本文作为技术性文章,深入探讨了PHP与MySQL结合在动态网站开发中的应用实践,从环境搭建到具体案例实现,旨在为开发者提供一套详尽的实战指南。不同于常规摘要仅概述内容,本文将以“手把手”的教学方式,引导读者逐步构建一个功能完备的动态网站,涵盖前端用户界面设计、后端逻辑处理及数据库高效管理等关键环节,确保读者能够全面掌握PHP与MySQL在动态网站开发中的精髓。 ####
|
5天前
|
关系型数据库 MySQL PHP
PHP与MySQL动态网站开发实战指南####
本文深入探讨了PHP与MySQL在动态网站开发中的应用实践,通过具体案例解析如何高效结合这两大技术构建数据驱动的Web应用。文章将涵盖环境搭建、基础语法回顾、数据库设计与操作、用户注册与登录系统实现等关键步骤,旨在为开发者提供一个从零到一的项目实战路径,展示PHP与MySQL协同工作的强大能力。 ####
|
1月前
|
tengine 关系型数据库 MySQL
Tengine、Nginx安装MySQL数据库命令教程
本指南详细介绍了在Linux系统上安装与配置MySQL数据库的步骤。首先通过下载并安装MySQL社区版本,接着启动MySQL服务,使用`systemctl start mysqld.service`命令。若启动失败,可尝试使用`sudo /etc/init.d/mysqld start`。利用`systemctl status mysqld.service`检查MySQL的服务状态,确保其处于运行中。通过日志文件获取初始密码,使用该密码登录数据库,并按要求更改初始密码以增强安全性。随后创建一个名为`tengine`的数据库,最后验证数据库创建是否成功以及完成整个设置流程。
|
24天前
|
SQL 关系型数据库 MySQL
PHP与MySQL协同工作的艺术:开发高效动态网站
在这个后端技术迅速迭代的时代,PHP和MySQL的组合仍然是创建动态网站和应用的主流选择之一。本文将带领读者深入理解PHP后端逻辑与MySQL数据库之间的协同工作方式,包括数据的检索、插入、更新和删除操作。文章将通过一系列实用的示例和最佳实践,揭示如何充分利用这两种技术的优势,构建高效、安全且易于维护的动态网站。