基于Redis缓存数据库实现lnmp架构高速访问

Redis作mysql缓存服务器

redis 是一个高性能的 key-value 数据库。 redis 的出现,很大程度补偿了memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了 Python,Ruby,Erlang,PHP 客户端,使用很方便。Redis 的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”); 也可以把每一次数据变化都写入到一个 appendonly file(aof)里面(这称为“全持久化模式”)。

Redis 的两种同步模式对比

    A>半持久化模式:RDB(全量同步)

            i>RDB是Redis默认同步方式

            ii>不定期的通过异步方式保存到磁盘上,快照最终结果( 快照二进制文件为dump.rdb)

            iii>在恢复大数据集时的速度比 AOF 的恢复速度要快。

    B>全持久化模式:(增量同步)

            i>把每一次数据变化都写入到一个 append only file(aof)里面.

            ii>没有RDB同步的快,但采用了高并发机制,对系统内存要求高.

            iii>使用方式

                #appendfsync always实时同步

                appendfsync everysec每秒同步(推荐使用)

                # appendfsync no

Redis作Mysql缓存服务器原理:

php默认从redis索取缓存数据,只有redis过期或删除,php才会从数据库索求数据。

 

详细配置如下:

实验环境:rhel6.5

server1:172.25.81.1(php)

server2:172.25.81.2(mysql)

server3:172.25.81.3(redis缓存)

server1配置:

1. 安装 lnmp 环境

安装以下软件包:

nginx php php-fpm php-cli php-common php-gd php-mbstring php-mysql
php-pdo php-devel mysql mysql-server

2. 安装 php 的 redis 扩展

  • php-5.3.3-38.el6.x86_64.rpm
  • php-cli-5.3.3-38.el6.x86_64.rpm
  • php-common-5.3.3-38.el6.x86_64.rpm
  • php-devel-5.3.3-38.el6.x86_64.rpm
  • php-fpm-5.3.3-38.el6.x86_64.rpm
  • php-gd-5.3.3-38.el6.x86_64.rpm
  • php-mbstring-5.3.3-38.el6.x86_64.rpm
  • php-mysql-5.3.3-38.el6.x86_64.rpm
  • php-pdo-5.3.3-38.el6.x86_64.rpm  

3.安装并配置nginx

[root@server1 ~]# cd /usr/local/nginx/conf/

[root@server1 conf]# vim nginx.conf

 43         location / {
 44             root   html;
 45             index  index.php index.html index.htm;
 46         }

 65         location ~ \.php$ {
 66             root           html;
 67             fastcgi_pass   127.0.0.1:9000;
 68             fastcgi_index  index.php;
 69             #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
 70             include        fastcgi.conf;
 71         }

[root@server1 conf]# ln -s /usr/local/nginx/sbin/nginx /sbin/

[root@server1 conf]# nginx -t

[root@server1 conf]# nginx

4.启动php

[root@server1 php-fpm.d]# systemctl start php-fpm

5.编辑nginx发布文件,设定server2为redis缓存,server3为mysql数据库

[root@server1 php-fpm.d]# cd /usr/local/nginx/html/
[root@server1 html]# ls
50x.html  index.html

[root@server1 html]# vim index.php

<?php
        $redis = new Redis();
        $redis->connect('172.25.81.2',6379) or die ("could net connect redis server");
  #      $query = "select * from test limit 9";
        $query = "select * from test";
        for ($key = 1; $key < 10; $key++)
        {
                if (!$redis->get($key))
                {
                        $connect = mysql_connect('172.25.81.3','redis','westos');
                        mysql_select_db(test);
                        $result = mysql_query($query);
                        //如果没有找到$key,就将该查询sql的结果缓存到redis
                        while ($row = mysql_fetch_assoc($result))
                        {
                                $redis->set($row['id'],$row['name']);
                        }
                        $myserver = 'mysql';
                        break;
                }
                else
                {
                        $myserver = "redis";
                        $data[$key] = $redis->get($key);
                }
        }

        echo $myserver;

        echo "<br>";
        for ($key = 1; $key < 10; $key++)
        {
                echo "number is <b><font color=#FF0000>$key</font></b>";

                echo "<br>";

                echo "name is <b><font color=#FF0000>$data[$key]</font></b>";

                echo "<br>";
        }
?>

 

server2配置

配置并开启redis服务

 

server3配置

配置mysql数据库

<1>清除之前安装过的mysql及其配置

[root@server3 ~]# cd /var/lib/mysql

[root@server3 mysql]# rm -fr *

[root@server3 ~]# rpm -qa | grep mysql

[root@server3 ~]# rpm -e `rpm -qa | grep mysql` --nodeps

<2>安装mariadb-server

[root@server3 ~]# yum install -y mariadb-server

[root@server3 ~]# systemctl start mariadb

<3>安全初始化

[root@server3 ~]# mysql_secure_installation

[root@server3 ~]# mysql -p

MariaDB [(none)]> create database test;

MariaDB [(none)]> grant all on test.* to redis@'%' identified by 'westos';

MariaDB [(none)]> flush privileges;

 

<4>

[root@server3 ~]# mysql -pwestos < test.sql              ##将test数据库导入mysql

查看test数据库

 

测试:访问172.25.81.1

php默认从redis索取数据,第一次redis无缓存,则php从mysql索取数据

刷新页面,此时redis存在缓存,则php从redis索取数据

将server3中数据库内容更新

但php默从redis索取数据,redis不更新数据,故网页上数据无更新

以上redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情况。

 

Gearman实现Mysql到Redis的数据同步

mysql 触发器+gearman+php.worker

因为mysql和redis数据格式不同,不能实现直接同步,所以将MySQL数据首先放入Gearman中,然后通过一个自己编写的PHP+Gearman+Worker,将数据同步到Redis。

Gearman 是一个支持分布式的任务分发框架:

Gearman Job Server: Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。

Gearman Client:可以理解为任务的请求者。

Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行.

Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。

大致流程:

1)下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。

2)修改表,插入表就相当于直接下发任务。

3)再通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式

4)再通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中

5)最后通过redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新。

 

配置过程:

server1:

<1>php安装gearmand并开启服务

[root@server1 rhel7]# yum install -y gearmand-1.1.8-2.el6.x86_64.rpm libgearman-* libevent-*

[root@server1 ~]# systemctl start gearmand

<2>编写 gearman 的 worker 端

[root@server1 ~]# vim /usr/local/worker.php

 

<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');

$redis = new Redis();
$redis->connect('172.25.81.2', 6379);

while($worker->work());
function syncToRedis($job)
{
        global $redis;
        $workString = $job->workload();
        $work = json_decode($workString);
        if(!isset($work->id)){
                return false;
        }
        $redis->set($work->id, $work->name);
}
?>

server3:

<1>安装 lib_mysqludf_json并生成lib_mysqludf_json.so模块

[root@server3 ~]# unzip lib_mysqludf_json-master.zip

[root@server3 ~]# cd lib_mysqludf_json-master

[root@server3 lib_mysqludf_json-master]# yum install -y mariadb-devel gcc

[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

拷贝 lib_mysqludf_json.so 模块:

[root@server3 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/

<2>注册 UDF 函数

[root@server3 lib_mysqludf_json-master]# mysql -p

MariaDB [(none)]> show global variables like 'plugin_dir';   ## 查看 mysql 的模块目录:

MariaDB [(none)]> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so'; ##注册 UDF 函数

MariaDB [(none)]> select * from mysql.func;        ##查看函数

<3>编译、安装gearman

这个插件是用来管理调用 Gearman 的分布式的队列。

[root@server3 ~]# yum install -y libgearman-1.1.12-18.el7.x86_64.rpm libgearman-devel-1.1.12-18.el7.x86_64.rpm libevent-devel-2.0.21-4.el7.x86_64.rpm    ##安装编译所需的依赖包

[root@server3 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz

[root@server3 ~]# cd gearman-mysql-udf-0.6

[root@server3 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/ --with-mysql

[root@server3 gearman-mysql-udf-0.6]# make && make install

指定 gearman 的服务信息

[root@server3 plugin]# mysql -p

 

MariaDB [(none)]> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';

 

MariaDB [(none)]> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';

MariaDB [(none)]> SELECT gman_servers_set('172.25.81.1:4730');  ##指定 gearman 的服务信息

编写 mysql 触发器

[root@server3 ~]# vim test.sql

use test;

DELIMITER $$
CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN
    SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
  END$$
DELIMITER ;

[root@server3 ~]# mysql -p < test.sql

查看触发器 

[root@server3 ~]# mysql -p

MariaDB [(none)]> SHOW TRIGGERS FROM test;

测试:

server1:开启nginx、php-fpm

后台运行 worker

[root@server1 ~]# nohup php /usr/local/worker.php &> /dev/null &

server3:更改test数据库信息

[root@server3 ~]# mysql -p

 

MariaDB [(none)]> use test;

 

MariaDB [test]> update test set name='change' where id=1;

server2查看 redis

客户端:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值