日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 5.1.17 redis_redis作为mysql的缓存服务器(读写分离)

發布時間:2024/9/19 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 5.1.17 redis_redis作为mysql的缓存服务器(读写分离) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、redis簡介

Redis是一個key-value存儲系統。和Memcached類似,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎上實現了master-slave(主從)同步。在部分場合可以對關系數據庫起到很好的補充作用。它提供了Java,C/C++(hiredis),C#,PHP,JavaScript,Perl,Object-C,Python,Ruby等客戶端,使用很方便。

二、架構圖

大致結構就是讀寫分離,將mysql中的數據通過觸發器同步到redis中

三、安裝LNMP環境(這里為了省事,就是用yum來安裝)

1、修改yum源

1

2

3

4

5

6

7

8

9

10

11

12

13

[iyunv@redis ~]# vim /etc/yum.repos.d/epel.repo? ? #添加這個文件

[epel]

name=Extra Packages for Enterprise Linux 6 - $basearch

baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch

failovermethod=priority

enabled=1

gpgcheck=0

[nginx]

name=nginx repo

baseurl=http://nginx.org/packages/centos/6/$basearch/

gpgcheck=0

enabled=1

2、yum安裝

1

[iyunv@redis ~]# yum -y install nginx?php?php-fpm php-cli php-common php-gd php-mbstring php-mysql?php-pdo php-devel php-xmlrpc php-xml php-bcmath php-dba php-enchant mysql mysql-server

3、簡單配置一下nginx

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

[iyunv@redis ~]# vim /etc/nginx/nginx.conf

server {

listen? ?? ? 80;

#定義使用www.xx.com訪問

server_name??www.xx.com;

#設定本虛擬主機的訪問日志

access_log??/logs/www.xx.com.access.log??main;

#默認請求

location / {

root? ?/www/;? ?? ?#定義服務器的默認網站根目錄位置

index index.php index.html index.htm;? ?#定義首頁索引文件的名稱

}

location ~ \.php$ {

root /www/;

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME /www/$fastcgi_script_name;

include fastcgi_params;

}

}

4、啟動服務

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[iyunv@redis ~]# sed -i 's/apache/nginx/g' /etc/php-fpm.d/www.conf

[iyunv@redis ~]# /etc/init.d/php-fpm start

正在啟動?php-fpm:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???[確定]

[iyunv@redis ~]# /etc/init.d/mysqld start

正在啟動?mysqld:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?[確定]

[iyunv@redis ~]# mkdir /{logs,www}

[iyunv@redis ~]# chown -R nginx:nginx /{logs,www}

[iyunv@redis ~]# /etc/init.d/nginx start

正在啟動 nginx:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? [確定]

[iyunv@redis www]# service iptables stop

iptables: Flushing firewall rules:? ?? ?? ?? ?? ?? ?? ?? ? [??OK??]

iptables: Setting chains to policy ACCEPT: filter? ?? ?? ? [??OK??]

iptables: Unloading modules:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? [??OK??]

[iyunv@redis redis]# netstat -tnlp? ?? ?#查看監聽

Active Internet connections (only?servers)

Proto Recv-Q Send-Q Local Address? ?? ?? ?? ?? ?Foreign Address? ?? ?? ?? ? State? ?? ? PID/Program name

tcp? ?? ???0? ?? ?0 0.0.0.0:80? ?? ?? ?? ?? ?? ?0.0.0.0:*? ?? ?? ?? ?? ?? ? LISTEN? ?? ?2101/nginx

tcp? ?? ???0? ?? ?0 127.0.0.1:9000? ?? ?? ?? ???0.0.0.0:*? ?? ?? ?? ?? ?? ? LISTEN? ?? ?7544/php-fpm

tcp? ?? ???0? ?? ?0 0.0.0.0:3306? ?? ?? ?? ?? ? 0.0.0.0:*? ?? ?? ?? ?? ?? ? LISTEN? ?? ?1871/mysqld

5、給mysql授權

1

2

3

4

[iyunv@redis ~]# mysql

mysql> grant all privileges on *.* to root@localhost identified by '123456';

mysql> flush privileges;

6、測試

1

2

3

4

[iyunv@redis ~]# vim /www/index.php

phpinfo();

?>

然后訪問頁面看到php的相關信息,基礎環境就算搭建完成了。

四、安裝redis

1、安裝redis

1

2

3

4

5

6

7

8

9

10

11

12

[iyunv@redis ~]# wget -c -t 0?http://download.redis.io/releases/redis-2.8.19.tar.gz

[iyunv@redis ~]# mkdir /usr/local/redis

[iyunv@redis ~]# tar xvf redis-2.8.19.tar.gz

#安裝很簡單、直接make就可以了

[iyunv@redis ~]# cd redis-2.8.19

[iyunv@redis redis-2.8.19]# make

#編譯完成后,將src中的可執行文件拷貝到剛剛創建的目錄中

[iyunv@redis src]# cp redis-benchmark redis-check-aof redis-check-dump redis-cli redis-sentinel redis-server?/usr/local/redis/

[iyunv@redis redis-2.8.19]# cp redis.conf sentinel.conf /usr/local/redis/

Redis-benchmark? ?? ?壓力測試工具

Redis-check-aof? ?? ?檢查redis持久化命令文件的完整性

Redis-check-dump? ???檢查redis持久化數據文件的完整性

Redis-cli? ?? ?? ?? ?redis在linux上的客戶端

Redis-sentinel? ?? ? redis-sentinel是集群管理工具,主要負責主從切換。

Redis-server? ?? ?? ?Redis服務器的daemon啟動程序

2、安裝php的redis擴展

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

[iyunv@redis ~]# wget -c -t 0?https://github.com/owlient/phpredis/archive/master.zip

[iyunv@redis ~]# unzip master.zip

[iyunv@redis ~]# cd phpredis-master/

[iyunv@redis?phpredis-master]# phpize

[iyunv@redis phpredis-master]# ./configure --with-php-config=/usr/bin/php-config

[iyunv@redis phpredis-master]# make && make install

#修改php的配置文件,如果沒有“extension=redis.so”,就加上這一行

[iyunv@redis ~]# vim /etc/php.ini

extension=redis.so

[iyunv@redis ~]# /etc/init.d/php-fpm restart

停止 php-fpm:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?[確定]

正在啟動?php-fpm:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???[確定]

3、是否安裝成功

還是訪問phpinfo的那個界面

看到這個就是安裝完成了。

五、讀寫分離

這里只是簡單的做了一下讀,沒有寫操作的相關代碼,過一會測試,直接到數據庫里執行update來模擬寫操作。

1、在mysql中插入一些測試數據

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

[iyunv@redis ~]# mysql -u root -p123456

mysql> create database mytest;

mysql> CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

mysql> INSERT INTO `test` VALUES (1,'sven'),(2,'jim'),(3,'zhu'),(4,'wang'),(5,'ftd'),(6,'test'),(7,'test01'),(8,'test02'),(9,'test03');

mysql> select * from mytest.test;

+----+--------+

| id | name? ?|

+----+--------+

|??1 | sven? ?|

|??2 | jim? ? |

|??3 | zhu? ? |

|??4 | wang? ?|

|??5 | ftd? ? |

|??6 | test? ?|

|??7 | test01 |

|??8 | test02 |

|??9 | test03 |

+----+--------+

2、編寫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

35

36

37

38

39

40

$redis = new Redis();

$redis->connect('127.0.0.1',6379) or die ("could net connect redis?server");

$query = "select * from test limit 8";

//為了簡單一點,這里就讀取了8條數據

for ($key = 1; $key < 9; $key++)

{

if (!$redis->get($key))

{

$connect = mysql_connect('127.0.0.1','root','123456');

mysql_select_db(mytest);

$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 "
";

for ($key = 1; $key < 9; $key++)

{

echo "number is $key";

echo "
";

echo "name is $data[$key]";

echo "
";

}

?>

第一次訪問,redis中沒有對應的KEY時

再次訪問,此時redis中已有相關數據

到這里,我們已經實現了redis作為mysql的緩存服務器,但是如果更新了mysql,redis中仍然會有對應的KEY,數據就不會更新,此時就會出現mysql和redis數據不一致的情況。所以接下來就要通過mysql觸發器將改變的數據同步到redis中。

六、通過gearman實現同步

1、介紹

Gearman是一個支持分布式的任務分發框架:

Gearman Job Server:Gearman核心程序,需要編譯安裝并以守護進程形式運行在后臺。

Gearman Client:可以理解為任務的請求者。

Gearman Worker:任務的真正執行者,一般需要自己編寫具體邏輯并通過守護進程方式運行,Gearman Worker接收到Gearman Client傳遞的任務內容后,會按順序處理。

大致流程:

下面要編寫的mysql觸發器,就相當于Gearman的客戶端。修改表,插入表就相當于直接下發任務。然后通過lib_mysqludf_json UDF庫函數將關系數據映射為JSON格式,然后在通過gearman-mysql-udf插件將任務加入到Gearman的任務隊列中,最后通過redis_worker.php,也就是Gearman的worker端來完成redis數據庫的更新。

2、安裝啟動

1

2

3

4

5

[iyunv@redis ~]# yum -y install gearmand libgearman-devel

[iyunv@redis ~]# /etc/init.d/gearmand start

正在啟動 gearmand:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? [確定]

[iyunv@redis ~]# /etc/init.d/gearmand status

gearmand (pid??7702) 正在運行...

3、安裝php的gearman擴展

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

[iyunv@redis ~]# wget -c -t 0?https://pecl.php.net/get/gearman-1.1.1.tgz

[iyunv@redis ~]# tar xvf gearman-1.1.1.tgz

[iyunv@redis ~]# cd gearman-1.1.1

[iyunv@redis gearman-1.1.1]# phpize

[iyunv@redis gearman-1.1.1]# ./configure --with-php-config=/usr/bin/php-config

[iyunv@redis gearman-1.1.1]# make

[iyunv@redis gearman-1.1.1]# make install

#如果php的配置文件中沒有extension = gearman.so,就加上此行

[iyunv@redis ~]# vim /etc/php.ini

extension = gearman.so

[iyunv@redis ~]# /etc/init.d/php-fpm restart

停止 php-fpm:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?[確定]

正在啟動?php-fpm:? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???[確定]

這樣就是安裝成功了

4、安裝lib_mysqludf_json

lib_mysqludf_json UDF庫函數將關系數據映射為JSON格式。通常,數據庫中的數據映射為JSON格式,是通過程序來轉換的。

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

[iyunv@redis ~]# wget -c -t 0?https://github.com/mysqludf/lib_mysqludf_json/archive/master.zip

[iyunv@redis ~]# unzip master.zip

[iyunv@redis ~]# cd lib_mysqludf_json-master/

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

lib_mysqludf_json.c:40:23: 錯誤:my_global.h:沒有那個文件或目錄

lib_mysqludf_json.c:41:20: 錯誤:my_sys.h:沒有那個文件或目錄

lib_mysqludf_json.c:43:19: 錯誤:mysql.h:沒有那個文件或目錄

lib_mysqludf_json.c:44:21: 錯誤:m_ctype.h:沒有那個文件或目錄

lib_mysqludf_json.c:45:22: 錯誤:m_string.h:沒有那個文件或目錄

#這里編譯報錯是因為沒有安裝mysql的開發包,如果是源碼安裝的mysql,需要在/etc/ld.so.conf.d/

#目錄下新建一個文件告訴系統mysql的頭文件在哪里

[iyunv@redis lib_mysqludf_json-master]# yum -y install mysql-devel

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

mysql> show global variables like 'plugin_dir';

+---------------+-------------------------+

| Variable_name | Value? ?? ?? ?? ?? ?? ? |

+---------------+-------------------------+

| plugin_dir? ? | /usr/lib64/mysql/plugin |

+---------------+-------------------------+

#將模塊拷貝到插件目錄下

[iyunv@redis lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/

#注冊UDF函數

mysql> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';

5、安裝gearman-mysql-udf

這個插件是用來管理調用 Gearman 的分布式的隊列。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

[iyunv@redis ~]# wget -c -t 0?https://launchpad.net/gearman-my ... ysql-udf-0.6.tar.gz

[iyunv@redis ~]# tar xvf gearman-mysql-udf-0.6.tar.gz

[iyunv@redis ~]# cd gearman-mysql-udf-0.6

[iyunv@redis gearman-mysql-udf-0.6]# ./configure --with-mysql=/usr/bin/mysql_config --libdir=/usr/lib64/mysql/plugin/

[iyunv@redis gearman-mysql-udf-0.6]# make

[iyunv@redis gearman-mysql-udf-0.6]# 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 |

+--------------------+-----+-------------------------+----------+

#指定gearman的服務信息

mysql> SELECT gman_servers_set('127.0.0.1:4730');

6、編寫mysql觸發器(根據實際情況編寫)

1

2

3

4

5

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 ;

7、編寫gearman的worker端

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

[iyunv@redis ~]# vim /www/redis_worker.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);

}

?>

#后臺運行

[iyunv@redis www]# nohup?php?redis_worker.php &

"$redis->set($work->id, $work->name);"這條語句就是將id作KEY和name作VALUE分開存儲,需要和前面寫的php測試代碼的存取一致。

8、更新mysql中的數據

1

2

3

4

5

6

7

8

9

10

11

12

13

14

mysql> set @RECV = 1;

mysql> select @RECV;

+------+

| @RECV|

+------+

|? ? 1 |

+------+

mysql> update test set name = 'ssss' where id = 1;

mysql> select @RECV;

+------+

| @RECV|

+------+

| NULL |

+------+

從返回值可以看到,觸發器是觸發成功的(這里的@RECV是上面mysql TIGGER的返回值)。我們在redis中查看數據:

1

2

3

[iyunv@redis redis]# ./redis-cli

127.0.0.1:6379> get 1

"sven"

這里的數據居然沒有變化,這是我們就要排錯了。

1

2

3

4

5

6

7

8

9

10

11

[iyunv@redis ~]# vim /var/log/audit/audit.log

type=AVC msg=audit(1427807674.425:107): avc:??denied??{ name_connect } for??pid=12453 comm="mysqld" dest=4730 scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=system_u:o

bject_r:port_t:s0 tclass=tcp_socket

#看到這樣一條日志,就知道是selinux阻止了同步

#現在將selinux的模式調成Permissive

[iyunv@redis ~]# getenforce

Enforcing

[iyunv@redis ~]# setenforce 0

[iyunv@redis ~]# getenforce

Permissive

設置完成以后,再次執行update,進入redis進行查看

1

2

127.0.0.1:6379> get 1

"ssss"

刷新一下剛剛的php界面

到這里就基本算是大功告成了,只要application將數據寫到mysql中,mysql觸發器檢測到更新,就會通過Gearman將

總結

以上是生活随笔為你收集整理的mysql 5.1.17 redis_redis作为mysql的缓存服务器(读写分离)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。