redis

Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了 memcached這類key/value存儲的不足,在部 分場合能夠對關係數據庫起到很好的補充做用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便
Redis 的全部數據都是保存在內存中,而後不按期的經過異步方式保存到磁盤上,(這稱爲「半持久化模式」);也能夠把每一次數據變化都寫入到一個 append,only file(aof)裏面(這稱爲「全持久化模式」)。

它的大概框架有點像這樣: php

主機環境 rhel6.5 selinx and iptales disabled
# tar zxf redis-3.0.2.tar.gz
# yum install -y gcc
# cd redis-3.0.2
make
make    install

安裝完後會在/usr/local/bin下產生以下文件
# ls /usr/local/bin/
redis-benchmark  redis-check-dump  redis-sentinel
redis-check-aof  redis-cli         redis-server

這些可執行文件的做用以下:
redis-server: Redis 服務主程序。
redis-cli: Redis 客戶端命令行工具,也能夠用 telnet 來操做。
redis-benchmark: Redis 性能測試工具,用於測試讀寫性能。
redis-check-aof:檢查 redis aof 文件完整性,aof 文件持久化記錄服務器執行的全部寫操做命令,用於還原數據。
redis-check-dump:檢查 redis rdb 文件的完整性,rdb 就是快照存儲,即按照必定的策略週期性的將數據保存到磁盤,是默認的持久化方式。
redis-sentinel: redis-sentinel 是集羣管理工具,主要負責主從切換。

2. 配置並啓動服務
# /root/redis/redis-3.0.2/utils/install_server.sh
redis服務配置及安裝,能夠直接回車,採起默認方式
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!

查看網絡狀態會發現已經自動開啓了redis的6379端口
# netstat -antulp | grep redis
tcp        0      0 0.0.0.0:6379                0.0.0.0:*                   LISTEN      4197/redis-server *
tcp        0      0 :::6379                     :::*                        LISTEN      4197/redis-server *

# ls /etc/redis/
6379.conf    #這個就是它的配置文件

Redis 客戶端使用:
127.0.0.1:6379> config get *
  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) ""
  5) "masterauth"
  6) ""

當須要作redis擴展時,咱們能夠這樣作
# vim /etc/redis/6379.conf
        # slaveof <masterip> <masterport>
        slaveof    masterip       6379
便可實現redis的高可用

Redis 做 mysql 的緩存服務器

1. 安裝 lnmp 環境,安裝如下軟件包:
 這一步可能會出現版本不兼容問題,建議安裝最新穩定版rpm包,若是曾經安裝過能夠進行更新
# yum localinstall nginx-1.8.0-1.el6.ngx.x86_64.rpm
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

# yum install mysql-server -y
2. 簡單配置 nginx
# vim /etc/nginx/conf.d/default.conf
 location / {
        root   /usr/share/nginx/html;
        index  index.php index.html index.htm;
    }
location ~ \.php$ {
        root           /usr/share/nginx/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;
    }
# nginx -t             #檢測是否出現語法問題
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# service nginx start

3:php-fpm簡單配置
  # vim /etc/php-fpm.d/www.conf
修改其用戶和用戶組爲nginx
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx

# vim /etc/php.ini        #修改其時區爲亞洲上海
date.timezone = Asia/Shanghai

# service  php-fpm  start

# vim /usr/share/nginx/html/index.php
<?php
phpinfo()
?>

# nginx -s reload



4:安裝 php 的 redis 擴展
# unzip  phpredis-master.zip
# cd phpredis-master
[root@server1 phpredis-master]# phpize

# ./configure --with-php-config=/usr/bin/php-config
# make && make install
; Enable mysql extension module

# cp mysql.ini redis.ini
# vim redis.ini
extension=redis.so

# vim /etc/php.ini
extension=redis.so    #加載 redis 模塊

5.配置 mysql

mysql> grant all on test.* to redis@localhost identified by 'redis';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

編輯測試sql語句腳本
# 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');

# mysql < test.sql              # 導入mysql數據庫

# mysql       #查看導入數據
mysql> use test
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+
1 row in set (0.00 sec)

mysql> select * from test;
+----+-------+
| id | name  |
+----+-------+
|  1 | test1 |
|  2 | test2 |
|  3 | test3 |
|  4 | test4 |
|  5 | test5 |
|  6 | test6 |
|  7 | test7 |
|  8 | test8 |
|  9 | test9 |
+----+-------+
9 rows in set (0.00 sec)
mysql> desc test;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(7)  | NO   | PRI | NULL    | auto_increment |
| name  | char(8) | YES  |     | NULL    |                |
+-------+---------+------+-----+---------+----------------+

6. 建立 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');
                        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>";
        }
?>

# cp test.php  /usr/share/nginx/html/
測試結果:
第一次揮發現其數據來自mysql,當再次刷新後其數據即是來自redis存儲了



到這裏,咱們已經實現了 redis 做爲 mysql 的緩存服務器,可是若是更新了 mysql,redis中仍然會有對應的 KEY,數據就不會更新,此時就會出現 mysql 和 redis 數據不一致的情
況。因此接下來就要經過 mysql 觸發器將改變的數據同步到 redis 中

配置 gearman 實現數據同步
Gearman 是一個支持分佈式的任務分發框架:

html

一個Gearman請求的處理過程涉及三個角色:Client -> Job -> Worker。
Client:請求的發起者,能夠是 C,PHP,Perl,MySQL UDF 等等。
Job:請求的調度者,用來負責協調把 Client 發出的請求轉發給合適的 Work。
Worker:請求的處理者,能夠是 C,PHP,Perl 等等

大體流程:
下面要編寫的 mysql 觸發器,就至關於 Gearman 的客戶端。修改表,插入表就至關於直接下發任務。而後經過 lib_mysqludf_json UDF 庫函數將關係數據映射爲 JSON 格式,而後
在經過 gearman-mysql-udf 插件將任務加入到 Gearman 的任務隊列中,最後經過redis_worker.php,也就是 Gearman 的 worker 端來完成 redis 數據庫的更新

1. 安裝 gearman 軟件包
yum localinstall gearmand-1.1.8-2.el6.x86_64.rpm
libgearman-devel-1.1.8-2.el6.x86_64.rpm
libgearman-1.1.8-2.el6.x86_64.rpm
libevent-libevent-1.4.13-4.el6.x86_64.rpm
libevent-devel-1.4.13-4.el6.x86_64.rpm
libevent-doc-1.4.13-4.el6.noarch.rpm
libevent-headers-1.4.13-4.el6.noarch.rpm

# service gearmand start     #啓動服務

# netstat -antlp | grep gearmand
tcp        0      0 0.0.0.0:4730                0.0.0.0:*                   LISTEN      7009/gearmand       
tcp        0      0 :::4730                     :::*                        LISTEN      7009/gearmand

2. 安裝 php 的 gearman 擴展
# yum install -y db*-devel
# tar zxf gearman-1.1.2.tgz
# cd gearman-1.1.2
# ./configure --with-php-config=/usr/bin/php-config
# make && make install
# cd /etc/php.d/
# cp redis.ini gearman.ini
#  vim gearman.ini
extension=gearman.so

# service php-fpm reload

3. 安裝 lib_mysqludf_json
lib_mysqludf_json UDF 庫函數將關係數據映射爲 JSON 格式。一般,數據庫中的數據映射爲 JSON 格式,是經過程序來轉換的。
# yum install -y mysql-devel
# unzip   lib_mysqludf_json-master.zip
# cd lib_mysqludf_json-master
# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
查看 mysql 的模塊目錄:
mysql> show global variables like 'plugin_dir';
+---------------+-------------------------+
| Variable_name | Value                   |
+---------------+-------------------------+
| plugin_dir    | /usr/lib64/mysql/plugin |
+---------------+-------------------------+
1 row in set (0.00 sec)
拷貝 lib_mysqludf_json.so 模塊:
# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/

註冊 UDF 函數
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME   'lib_mysqludf_json.so';
查看函數
mysql> select * from mysql.func;
+-------------+-----+----------------------+----------+
| name        | ret | dl                   | type     |
+-------------+-----+----------------------+----------+
| json_object |   0 | lib_mysqludf_json.so | function |
+-------------+-----+----------------------+----------+

4. 安裝 gearman-mysql-udf
這個插件是用來管理調用 Gearman 的分佈式的隊列。
# tar zxf gearman-mysql-udf-0.6.tar.gz
# cd gearman-mysql-udf-0.6
# ./configure --with-mysql=/usr/bin/mysql_config
--libdir=/usr/lib64/mysql/plugin/

# make && make install
註冊 UDF 函數
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME  'libgearman_mysql_udf.so';
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME   'libgearman_mysql_udf.so';
查看函數
mysql> select * from mysql.func;
+--------------------+-----+-------------------------+----------+
| name               | ret | dl                      | type     |
+--------------------+-----+-------------------------+----------+
| json_object        |   0 | lib_mysqludf_json.so    | function |
| gman_do_background |   0 | libgearman_mysql_udf.so | function |
| gman_servers_set   |   0 | libgearman_mysql_udf.so | function |
+--------------------+-----+-------------------------+----------+
3 rows in set (0.00 sec)

指定 gearman 的服務信息
mysql> SELECT gman_servers_set('127.0.0.1:4730');
+------------------------------------+
| gman_servers_set('127.0.0.1:4730') |
+------------------------------------+
| 127.0.0.1:4730                     |
+------------------------------------+
1 row in set (0.00 sec)

5. 編寫 mysql 觸發器(根據實際狀況編寫)
ues 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 ;
# mysql < test.sql

查看觸發器
mysql>  SHOW TRIGGERS FROM test;
| datatoredis | UPDATE | test  | BEGIN
    SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
  END | AFTER  | NULL    |          | root @localhost | latin1               | latin1_swedish_ci    | latin1_swedish_ci  | +-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+ 1 row in set (0.00 sec) 6. 編寫 gearman 的 worker 端 # vim worker.php <?php $worker = new GearmanWorker(); $worker->addServer(); $worker->addFunction('syncToRedis', 'syncToRedis'); $redis = new Redis(); $redis->connect('127.0.0.1', 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 測試代碼的存取一致。 } ?> 後臺運行 worker # nohup php worker.php & 7. 更新 mysql 中的數據 mysql> update test set name='linux' where id=1; 查看 redis # redis-cli 127.0.0.1:6379> get 1 "linux" 127.0.0.1:6379> 刷新測試頁面數據同步
相關文章
相關標籤/搜索