• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 利用Gearman進行Mysql到Redis的復制

    redis與數據庫結合,作為數據庫數據的緩存提供給前端

    一.實現數據庫,php,nginx和redis的架構

    server1提供nginx服務,使用php語言,server2提供redis緩存服務,server3提供后端數據庫服務…
    整體思想是:客戶端通過nginx和php訪問后端數據庫時,先在redis這個數據庫緩存中查找,看是否含有想要的數據,如果沒有就去后端數據庫查找,將查找到數據返回給客戶端一份,另外在redis中緩存一份….下次如果訪問相同的數據就直接去redis,縮短時間同時也減輕數據庫的查找壓力

    (一)在server1前端中
    1.安裝nginx和php

     yum install -y nginx-1.8.0-1.el6.ngx.x86_64.rpm php-*

    2.在php的配置文件中修改時區為上海

     cd /etc/php.d/  
     vim /etc/php.ini
      timezone = “Asia/Shanghai”

    3.因為php作為nginx的前端服務,我們將php網頁代碼也限制在nginx的用戶空間中

     cd /etc/php-fpm.d/ 
      vim www.conf  修改用戶為nginx

    這里寫圖片描述
    4.查看端口情況
    netstat -antlp
    5.修改nginx的配置文件

    cd /etc/nginx/conf.d   
    vim default.conf   
        location / {
            root   /usr/share/nginx/html;
            index  index.php index.html index.htm;      # 設置index.php為默認發布文件
    
    
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
            include        fastcgi_params;
        }

    6.將php測試頁面的代碼(該代碼是查詢數據庫中數據)放在默認發布目錄下

    cd /usr/share/nginx/html/ 
    cp test.php /usr/share/nginx/html/index.php
    test.php代碼如下(僅供參考):
      <?php
            $redis = new Redis();
            $redis->connect('127.0.0.1',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('127.0.0.1','redis','westos');  # 利用redis用戶訪問數據庫
                            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>";
            }
    ?>

    7.源碼編譯php與redis的連接軟件—phpredis-master.zip

    yum install unzip      # 安裝解壓工具
    unzip phpredis-master.zip 
    cd phpredis-master   
    phpize                 # 創建預編譯環境
    ./configure     
    make  
    make install           # 源碼編譯安裝

    這里寫圖片描述
    8.在php中動態加載redis模塊

    cd /etc/php.d   
    cp mysql.ini redis.ini      # 拷貝數據庫的模版
    vim redis.ini
    extension=redis.so          # 將redis模塊加入php中

    這里寫圖片描述
    9.重新加載nginx,php和redis服務

    /etc/init.d/php-fpm reload
    nginx-s reload
    /etc/init.d/redis stop 
    /etc/init.d/redis start

    10.在數據庫中建數據庫建表,對所有ip上的nginx用戶授權(因為在php前端我們是利用nginx用戶來訪問數據庫的)
    這里寫圖片描述
    11.在瀏覽器處輸入提供nginx服務和php服務的主句ip,因為redis里邊沒有數據緩存,所以得去后端服務器拿數據,刷新頁面,會看到第二次是去redis中拿數據,同時我們在提供redis的主機中利用redis-cli命令行也可以看到數據(說明數據是真的存在了redis緩存中)
    數據庫:
    這里寫圖片描述
    網頁第二次去redis:
    這里寫圖片描述
    提供redis服務的主機:
    這里寫圖片描述

    可是做到這兒,我們可以發現問題,當在數據庫中修改了數據之后,網頁中的數據和 redis緩存處的數據均不改變,這樣當然是不行的,所以我們解決這個問題…

    二.利用Gearman進行Mysql到Redis的同步復制:
    Gearman是一個開源的Map/Reduce分布式計算框架,具有豐富的client sdk,而且它支持MySQL UDF。
    這里寫圖片描述

    當有數據發生變化時,通過MySQL Trigger實時異步調用Gearman的UDF提交一個job給JobServer,當job執行的時候會去更新redis;從而保證redis與MySQL中的數據是同步的。

    (一)在server1中:

    1.安裝Gearmand(服務端)及其很多很多的依賴項,之后打開gearmand服務

    yum install  -y gearmand-1.1.8-2.el6.x86_64.rpm libgearman-* libevent-*
    yum install php-devel-5.3.3-38.el6.x86_64.rpm  php-5.3.3-38.el6.x86_64.rpm
    
    /etc/init.d/gearmand start
    netstat -antlp   # 查看對應端口是否打開

    2.scp gearman-mysql-udf-0.6.tar.gz server3:
    scp lib_mysqludf_json-master.zip server3:
    scp libgearman-* server3:
    scp libevent-* server3:
    3.在php中動態加入模塊gearman

    cp worker.php  /usr/local/   # work是中間搬運數據的“進程”,由php語言編寫
    ll gearman-1.1.2.tgz 
    tar zxf gearman-1.1.2.tgz     # 在php中動態加入Gearman的模塊,并進行源碼編譯
    cd gearman-1.1.2  
    phpize  
    make make 
    install
    
    
    vim worker.php
    <?php
    $worker = new GearmanWorker();
    $worker->addServer();
    $worker->addFunction('syncToRedis', 'syncToRedis');
    
    $redis = new Redis();
    $redis->connect('172.25.1.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);
            # 這條語句就是將 id 作 KEY 和name 作 VALUE 分開存儲,需要和前面寫的 php 測試代碼的存取一致。
    }
    ?>

    4.將添加的動態模塊加進php的模塊目錄中,當然也可選擇直接寫入配置文件中

    cd /usr/lib64/php/modules/    # php的模塊目錄
    ll gearman.so                 # 剛剛源碼編譯成功的gearman模塊
    cp redis.ini gearman.ini      # 利用redis的模版,編寫gearman的模塊配置文件
    vim gearman.ini
      gearman.so

    5.查看個gearman模塊是否添加成功

    /etc/init.d/php-fpm reload    # 重載服務
    php -m | grep gearman         # 如果有則表明成功

    6.啟動worker進程并將其打入后臺

    nohup  php /usr/local/worker.php  &
    ps ax

    (二)在server3(后端數據庫)中:
    1.安裝把mysql關系型數據轉換成json格式的UDF工具—lib_mysqludf_json-master
    (mysql里的數據格式轉成json格式,通常使用php的json擴展實現。如果使用udf,會有更快的速度。)

    unzip lib_mysqludf_json-master.zip     # 解壓源碼包
    cd lib_mysqludf_json-master   
    yum install gcc mysql-devel -y         # 安裝依賴性
    gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
    cd /usr/lib64/mysql/plugin/            # 存放數據庫服務的所有插件位置
    cd /root/lib_mysqludf_json-master
    cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/  # 拷貝 lib_mysqludf_json.so 模塊到數據庫的插件目錄中

    這里寫圖片描述
    2.登陸mysql,注冊 json_object函數:

    show global variables like 'plugin_dir';     # 查看數據庫服務存放插件的目錄
    CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';  # 注冊 UDF 函數 json_object(作用是利用該函數可以將數據庫中的數據構造為json格式)

    這里寫圖片描述

    3.安裝 gearman-mysql-udf,這個插件是用來管理調用 Gearman 的分布式的隊列。

    tar zxf gearman-mysql-udf-0.6.tar.gz
    cd gearman-mysql-udf-0.6
    yum install libgearman-* libevent-*    # 解決依賴性
    ./configure --libdir=/usr/lib64/mysql/plugin/     # 創建預編譯環境,指定安裝目錄在默認數據庫插件目錄中
    make     # 源碼編譯
    make install

    這里寫圖片描述
    4.登陸mysql,再次注冊函數

    CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';     # 用Gearman做隊列來實現消息推送
    CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';
    select * from mysql.func;     # 查看數據庫中注冊的函數
    SELECT gman_servers_set('172.25.1.1:4730');     # 指定 gearman 的服務信息

    這里寫圖片描述
    這里寫圖片描述
    5.編輯觸發器文件

    什么是觸發器: 觸發器(trigger)是SQL server
    提供給程序員和數據分析員來保證數據完整性的一種方法,它是與表事件相關的特殊的存儲過程,它的執行不是由程序調用,也不是手工啟動,而是由事件來觸發,比如當對一個表進行操作(insert,delete, update)時就會**它執行。觸發器經常用于加強數據的完整性約束和業務規則等

    vim test.sql   
    use test;       # 取數據程序段
    #CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    #INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9');
    
    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 ;

    將觸發器程序導入數據庫中:mysql < test.sql
    登陸mysql:SHOW TRIGGERS FROM test; 查看觸發器是否導入
    這里寫圖片描述

    測試:
    在數據庫中修改數據,在redis和網頁中查看數據是否更新….
    數據庫中:
    這里寫圖片描述
    網頁:
    這里寫圖片描述
    redis:
    這里寫圖片描述
    說明三處數據已經達到一致!!!

    版權聲明:本文為jay_youth原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/jay_youth/article/details/81632153

    智能推薦

    redis 基于主從復制的 rce 利用方式

    在2019年7月7日結束的WCTF2019 Final上,LC/BC的成員Pavel Toporkov在分享會上介紹了一種關于redis新版本的RCE利用方式,比起以前的利用方式來說,這種利用方式更為通用,危害也更大,下面就讓我們從以前的redis RCE利用方式出發,一起聊聊關于redis的利用問題。 https://2018.zeronights.ru/wp-content/uploads/m...

    Redis主從復制的配置并進行場景測試

    Redis主從復制的配置并進行場景測試 為什么要使用主從復制? Redis雖然讀寫的速度相對于傳統的關系型數據庫較快,但是也會出現讀取壓力比較大的情況,為了避免出現這種情況的發生,以免給用戶造成不好的體驗,這時候就要考慮Redis的主從復制了。所謂主從復制,就是一個master下有多個slave節點。用戶對于數據的操作,都是讀遠遠大于寫的,所以我們只在master節點下進行寫的操作,而讀就交給sl...

    利用mysql進行集群的操作

    本文中使用的mysql是在VM虛擬機上搭建的三臺機器的集群,其中一臺機器作為主機器,另外兩臺作為從機器,ip分別為: 主機器:192.168.159.136   從機: 192.168.159.135、192.168.159.137 首先我們需要在互聯網上下載mysql的安裝包(mysql從5.7開始已經開始支持集群的配置):  wget http://repo.my...

    win:mycat進行MySQL的讀寫分離,主從復制

    如果要做MySQL的讀寫分離,先要進行幾個庫之間進行主從復制,做到數據一致,MySQL的主從復制可以看我上一篇文章 MySQL主從復制:https://blog.csdn.net/xiaoxiaobai250/article/details/103989555   下來進入mycat讀寫分離 一:首先去官網下載需要的mycat; 官網:http://www.mycat.io/ 二:配置:...

    redis入門到精通系列(八):redis的高可用--主從復制詳解

    (一)主從復制介紹 前面所講的關于redis的操作都屬于單機操作,單機操作雖然操作簡單,但是處理能力有限,無法高可用。所謂高可用性,就是指當一臺服務器宕機的時候,有備用的服務器能頂替上,在單機操作上這是無法實現的,因此就出現了主從復制。 我們把一臺服務器看作是主服務器(master),把另外多臺服務器看作是從服務器(slave),主從復制就是將master中的數據即時有效的復制到slave中。 &...

    猜你喜歡

    Unity_Shader高級篇_13.1_Unity Shader入門精要

    13.4 再談邊緣檢測 在12.3中,我們曾使用Sobel算子對屏幕圖像進行邊緣測試,實現描邊的效果。但是,這種直接利用顏色信息進行邊緣檢測的方法會產生很對我們不希望得到的邊緣線,如圖13.8所示。 可以看出,物體的紋理、陰影等位置也被描上黑邊,而這往往不是我們希望看到的。在本節中,我們將學習如何在深度和法線上進行邊緣檢測,這些圖像不會受紋理和光照的影響,而僅僅保存了當前渲染物體的模型信息,通過這...

    Seata AT 模式 原理詳解

    目錄 前提 整體機制 寫隔離 讀隔離 工作機制 一階段 二階段-回滾 二階段-提交 附錄 回滾日志表 前提 基于支持本地 ACID 事務的關系型數據庫。 Java 應用,通過 JDBC 訪問數據庫。 整體機制 兩階段提交協議的演變: 一階段:業務數據和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源。 二階段: 提交異步化,非常快速地完成。 回滾通過一階段的回滾日志進行反向補償。 寫隔離 ...

    Python爬蟲 | 滑動驗證碼**

    極驗驗證碼:需要手動拼合滑塊來完成的驗證,相對圖形驗證碼識別難度上升了幾個等級。下面用程序識別并通過極驗驗證碼的驗證,其中有分析識別思路、識別缺口位置、生成滑塊拖動、模擬實現滑塊拼合通過驗證等步驟。需要用到Chrome 瀏覽器,并配置 ChromeDriver ,要用到的 Python 庫是 Selenium。 1、 對極驗驗證碼了解   極驗驗證碼官網:http://www.geetest.co...

    MobaXterm root用戶連接虛擬機時出現Access denied

    1.linux打開ssh服務 2.新建連接 首先在romote host中填入要連接的主機ip specify username中填入連接的用戶名 port為連接端口默認為22 輸入連接用戶的密碼 linux默認不顯示密碼 發現密碼正確但是連接不上 問題解決 /etc/ssh/sshd_config 配置問題: #PermitRootLogin prohibit-password將該行改為Perm...

    Linux C 預處理命令

    預處理命令 一、宏定義 C語言標準允許在程序中用一個標識符來表示一個字符串,成為宏。標識符為宏名 ,在編譯預處理時,將程序中所有的宏名用相應的字符串來替換,這個過程稱為宏替換,宏分為兩種:無參數的宏和有參數的宏。 1.無參數的宏 無參數宏定義的一般形式為:#define 標識符字符串 “#”代表本行是編譯預處理命令。define是宏定義的關鍵詞,標識符是宏名。字符串是宏名所...

    精品国产乱码久久久久久蜜桃不卡