1.redis的集群部署
关于redis:
redis 是一个高性能的 key-value 数据库。 redis 的出现,很大程度补偿了
memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很
好的补充作用。它提供了 Python,Ruby,Erlang,PHP 客户端,使用很方便。
Redis 的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上
(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个 append
only file(aof)里面(这称为“全持久化模式”)。
主机环境 rhel6.5 selinx and iptales disabled
#
[root@server1 ~]# cd redis-4.0.8
[root@server1 redis-4.0.8]# ls
00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests
BUGS deps MANIFESTO runtest sentinel.conf utils
CONTRIBUTING INSTALL README.md runtest-cluster src
[root@server1 redis-4.0.8]# cd /usr/local/
[root@server1 local]# ls
bin etc games include lib lib64 libexec sbin share src
[root@server1 local]# mkdir cluster
[root@server1 local]# cd cluster/
[root@server1 cluster]# mkdir 7001
[root@server1 cluster]# mkdir 7002
[root@server1 cluster]# mkdir 7003
[root@server1 cluster]# mkdir 7004
[root@server1 cluster]# mkdir 7005
[root@server1 cluster]# mkdir 7006
[root@server1 cluster]# cd 7001
[root@server1 7001]# vim redis.conf
port 7001
cluster-enbled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
[root@server1 7001]# cd
[root@server1 ~]# cd redis-4.0.8
[root@server1 redis-4.0.8]# cd src/
[root@server1 src]# cp redis-trib.rb /usr/local/bin
[root@server1 bin]# ls
redis-benchmark redis-check-rdb redis-sentinel redis-trib.rb
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 是集群管理工具,主要负责主从切换。
[root@server1 bin]# cd
[root@server1 ~]# redis-trib.rb
[root@server1 ~]# yum install rubygems-1.3.7-5.el6.noarch.rpm redis-4.0.1.gem ruby-2.2.3-1.el6.x86_64.rpm libyaml-0.1.3-4.el6_6.x86_64.rpm -y
[root@server1 ~]# gem install --local redis-4.0.1.gem
Successfully installed redis-4.0.1
Parsing documentation for redis-4.0.1
Installing ri documentation for redis-4.0.1
Done installing documentation for redis after 1 seconds
1 gem installed
[root@server1 ~]# gem list --local
*** LOCAL GEMS ***
bigdecimal (1.2.6)
io-console (0.4.3)
json (1.8.1)
minitest (5.4.3)
power_assert (0.2.2)
psych (2.0.8)
rake (10.4.2)
rdoc (4.2.0)
redis (4.0.1)
test-unit (3.0.8)
[root@server1 ~]# /etc/init.d/redis_6379 stop
Stopping ...
Redis stopped
[root@server1 ~]# cd /usr/local/cluster/7001
[root@server1 7001]# vim redis.conf
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7001/redis.pid
logfile /usr/local/cluster/7001/redis.log
[root@server1 7001]# redis-server redis.conf
[root@server1 7001]# ls
appendonly.aof nodes.conf redis.conf redis.log redis.pid
[root@server1 7001]# cat redis.log
[root@server1 7001]# echo 511 > /proc/sys/net/core/somaxconn
[root@server1 7001]# sysctl -w vm.overcommit_memory=1
vm.overcommit_memory = 1
[root@server1 7001]# vim /etc/sysctl.conf
42 vm.overcommit_memory = 1
[root@server1 7001]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@server1 7001]# cp redis.conf ../7002
[root@server1 7001]# cp redis.conf ../7003
[root@server1 7001]# cp redis.conf ../7004
[root@server1 7001]# cp redis.conf ../7005
[root@server1 7001]# cp redis.conf ../7006
[root@server1 7001]# cd ..
[root@server1 cluster]# cd 7002
[root@server1 7002]# vim redis.conf
port 7002
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7002/redis.pid
logfile /usr/local/cluster/7002/redis.log
[root@server1 7002]# vim /usr/local/cluster/7003/redis.conf
port 7003
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7003/redis.pid
logfile /usr/local/cluster/7003/redis.log
[root@server1 7002]# vim /usr/local/cluster/7003/redis.conf
port 7004
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7004/redis.pid
logfile /usr/local/cluster/7004/redis.log
[root@server1 7002]# vim /usr/local/cluster/7005/redis.conf
port 7005
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7005/redis.pid
logfile /usr/local/cluster/7005/redis.log
[root@server1 7002]# vim /usr/local/cluster/7006/redis.conf
port 7006
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7006/redis.pid
logfile /usr/local/cluster/7006/redis.log
[root@server1 7002]# redis-server redis.conf
[root@server1 7002]# cd /usr/local/cluster/7003
[root@server1 7003]# redis-server redis.conf
[root@server1 7003]# cd /usr/local/cluster/7004
[root@server1 7004]# redis-server redis.conf
[root@server1 7004]# cd /usr/local/cluster/7005
[root@server1 7005]# redis-server redis.conf
[root@server1 7005]# cd /usr/local/cluster/7006
[root@server1 7006]# redis-server redis.conf
[root@server1 7006]# redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
[root@server1 cluster]# redis-trib.rb check 127.0.0.1:7001
[root@server1 7006]# redis-cli -c -p 7001
127.0.0.1:7001> info
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=7005,state=online,offset=350,lag=1 #7005是7001的slave
master_replid:fc3984d9756f2fcba704b88308824c0a441fc6b8
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:350
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:350
127.0.0.1:7001> set name wzt
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
"wzt"
[root@server1 7002]# ps ax
[root@server1 ~]# kill -9 3192 #把7002kill,则7005看不到7001上的东西,而且7005会接管7001的工作,成为了master
[root@server1 ~]# redis-cli -c -p 7005 #7005是7001的slave
127.0.0.1:7005> get name
(error) CLUSTERDOWN The cluster is down
127.0.0.1:7005>
2.redis + mysql + nginx
#在nginx和php端
##配置nginx和php(这里的nginx只是提供了负载均衡,所以版本要求不高)
[root@server1 ~]# ls
nginx-1.8.0-1.el6.ngx.x86_64.rpm php-fpm-5.3.3-38.el6.x86_64.rpm
php-5.3.3-38.el6.x86_64.rpm php-gd-5.3.3-38.el6.x86_64.rpm
php-cli-5.3.3-38.el6.x86_64.rpm php-mbstring-5.3.3-38.el6.x86_64.rpm
php-common-5.3.3-38.el6.x86_64.rpm php-mysql-5.3.3-38.el6.x86_64.rpm
php-devel-5.3.3-38.el6.x86_64.rpm php-pdo-5.3.3-38.el6.x86_64.rpm
[root@server1 ~]# yum install * -y
[root@server1 ~]# vim /etc/php.ini
946 date.timezone =Asia/Shanghai
[root@server1 ~]# cd /etc/php-fpm.d/
[root@server1 php-fpm.d]# ls
www.conf
[root@server1 php-fpm.d]# vim www.conf
39 user = nginx
40 ; RPM: Keep a group allowed to write in log dir.
41 group = nginx
[root@server1 php-fpm.d]# /etc/init.d/php-fpm start
Starting php-fpm: [ OK ]
[root@server1 php-fpm.d]# netstat -antlp #查看php的端口
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 3370/php-fpm
[root@server1 php-fpm.d]#vim /etc/nginx/conf.d/default.conf
10 index index.php index.html index.htm;
30 location ~ \.php$ {
31 root html;
32 fastcgi_pass 127.0.0.1:9000;
33 fastcgi_index index.php;
34 fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
35 include fastcgi_params;
36 }
[root@server1 php-fpm.d]# /etc/init.d/nginx start
Starting nginx: [ OK ]
[root@server1 php-fpm.d]# cd /usr/share/nginx/html/
[root@server1 html]# ls
50x.html index.html
[root@server1 html]# vim index.php
<?php
phpinfo()
?>
php配置成功
[root@server1 html]# vim index.php
3 $redis->connect('172.25.44.3',6379) or die ("could net connect redis server");
10 $connect = mysql_connect('172.25.44.4','redis','westos');
[root@server1 ~]# yum install unzip -y
[root@server1 ~]# unzip phpredis-master.zip
[root@server1 ~]# cd phpredis-master
[root@server1 phpredis-master]# ls
common.h debian.control mkdeb-apache2.sh redis_session.c
config.m4 igbinary php_redis.h redis_session.h
CREDITS library.c README.markdown serialize.list
debian library.h redis.c tests
[root@server1 phpredis-master]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@server1 phpredis-master]# ls
acinclude.m4 config.sub library.c README.markdown
aclocal.m4 configure library.h redis.c
autom4te.cache configure.in ltmain.sh redis_session.c
build CREDITS Makefile.global redis_session.h
common.h debian missing run-tests.php
config.guess debian.control mkdeb-apache2.sh serialize.list
config.h.in igbinary mkinstalldirs tests
config.m4 install-sh php_redis.h
#源码编译
[root@server1 phpredis-master]# ./configure
[root@server1 phpredis-master]# make && make install
[root@server1 phpredis-master]# cd /usr/lib64/php/modules/
[root@server1 modules]# ls
curl.so json.so mysql.so pdo_sqlite.so sqlite3.so
fileinfo.so mbstring.so pdo_mysql.so phar.so zip.so
gd.so mysqli.so pdo.so redis.so
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# cp mysql.ini redis.ini
[root@server1 php.d]# vim redis.ini
1 extension=redis.so
[root@server1 php.d]# /etc/init.d/php-fpm reload
Reloading php-fpm: [12-Aug-2018 12:45:48] NOTICE: configuration file /etc/php-fpm.conf test is successful
[ OK ]
#mysql端操作
[root@server4 ~]# yum install mysql-server -y
[root@server4 ~]# /etc/init.d/mysqld start
[root@server4 ~]# mysql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.00 sec)
mysql> grant all on test.* to redis@'%' identified by 'westos';
Query OK, 0 rows affected (0.00 sec)
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
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)
[root@server4 ~]# mysql < test.sql
[root@server4 ~]# vim test.sql
#redis端操作
[root@server2 ~]# /etc/init.d/redis_6379 start
[root@server2 ~]# vim /etc/redis/6379.conf
283
[root@server2 ~]# redis-cli #确保server2是master
127.0.0.1:6379> info
#测试:
server2也可以查看到
#但是有一个问题,mysql更新后,redis无法同步
mysql> update test set name='westos' where id =1;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test;
+----+--------+
| id | name |
+----+--------+
| 1 | westos |
| 2 | test2 |
| 3 | test3 |
| 4 | test4 |
| 5 | test5 |
| 6 | test6 |
| 7 | test7 |
| 8 | test8 |
| 9 | test9 |
+----+--------+
解决问题,配置 gearman 实现数据同步
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 数据库的更新。
#
[root@server1 ~]# ls
gearmand-1.1.8-2.el6.x86_64.rpm
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
libgearman-1.1.8-2.el6.x86_64.rpm
libgearman-devel-1.1.8-2.el6.x86_64.rpm
lib_mysqludf_json-master.zip
libyaml-0.1.3-4.el6_6.x86_64.rpm
[root@server1 ~]# yum install gearmand-1.1.8-2.el6.x86_64.rpm lib* -y #安装 gearman 软件包
[root@server1 ~]# /etc/init.d/gearmand start #启动服务
Starting gearmand: [ OK ]
[root@server1 ~]# netstat -antlp
tcp 0 0 0.0.0.0:4730 0.0.0.0:* LISTEN 5826/gearmand
#安装 php 的 gearman 扩展,安装 lib_mysqludf_json,lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映射为 JSON 格式,是通过程序来转换的。
[root@server4 ~]# ls
gearman-mysql-udf-0.6.tar.gz test.sql lib_mysqludf_json-master.zip
[root@server4 ~]# yum install unzip -y
[root@server4 ~]# unzip lib_mysqludf_json-master.zip
[root@server4 lib_mysqludf_json-master]# yum install gcc mysql-devel -y
[root@server4 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
[root@server4 lib_mysqludf_json-master]# ll
total 100
-rw-r--r-- 1 root root 25921 2月 22 2013 lib_mysqludf_json.c
-rw-r--r-- 1 root root 20576 2月 22 2013 lib_mysqludf_json.html
-rwxr-xr-x 1 root root 22223 8月 12 14:35 lib_mysqludf_json.so
-rw-r--r-- 1 root root 1431 2月 22 2013 lib_mysqludf_json.sql
-rw-r--r-- 1 root root 16416 2月 22 2013 README.md
[root@server4 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
[root@server4 lib_mysqludf_json-master]# cd /usr/lib64/mysql/plugin/
[root@server4 plugin]# ll lib_mysqludf_json.so
-rwxr-xr-x 1 root root 22223 8月 12 14:44 lib_mysqludf_json.so
#查看 mysql 的模块目录:
mysql> show global variables like 'plugin_dir';
+---------------+-------------------------+
| Variable_name | Value |
+---------------+-------------------------+
| plugin_dir | /usr/lib64/mysql/plugin |
+---------------+-------------------------+
1 row in set (0.00 sec)
#注册 UDF 函数
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME
-> 'lib_mysqludf_json.so';
Query OK, 0 rows affected (0.00 sec)
mysql> Bye
#安装 gearman-mysql-udf,这个插件是用来管理调用 Gearman 的分布式的队列。
[root@server4 plugin]# cd
[root@server4 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz
[root@server4 ~]# cd gearman-mysql-udf-0.6
[root@server4 gearman-mysql-udf-0.6]# ./configure #有报错,依赖性没解决完
configure: error: At least version 0.33 of libgearman is required for gearman-mysql-udf
[root@server4 gearman-mysql-udf-0.6]# cd
[root@server4 ~]# ls
gearman-mysql-udf-0.6
gearman-mysql-udf-0.6.tar.gz
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
libgearman-1.1.8-2.el6.x86_64.rpm
libgearman-devel-1.1.8-2.el6.x86_64.rpm
lib_mysqludf_json-master
lib_mysqludf_json-master.zip
redis-4.0.8
redis-4.0.8.tar.gz
test.sql
[root@server4 ~]# yum install lib* -y #解决依赖性
[root@server4 ~]# cd gearman-mysql-udf-0.6
[root@server4 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/
[root@server4 gearman-mysql-udf-0.6]# make && make install
[root@server4 gearman-mysql-udf-0.6]# cd /usr/lib64/mysql/plugin/
[root@server4 plugin]# ll
lrwxrwxrwx 1 root root 29 8月 12 15:05 libgearman_mysql_udf.so -> libgearman_mysql_udf.so.0.0.0
lrwxrwxrwx 1 root root 29 8月 12 15:05 libgearman_mysql_udf.so.0 -> libgearman_mysql_udf.so.0.0.0
-rwxr-xr-x 1 root root 114597 8月 12 15:05 libgearman_mysql_udf.so.0.0.0
-rwxr-xr-x 1 root root 22223 8月 12 14:44 lib_mysqludf_json.so
[root@server4 plugin]# mysql
#注册 UDF 函数
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME
-> 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME
-> 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)
#查看函数
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('172.25.44.1:4730');
+--------------------------------------+
| gman_servers_set('172.25.44.1:4730') |
+--------------------------------------+
| 172.25.44.1:4730 |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> Bye
#编写 mysql 触发器(根据实际情况编写)
[root@server4 plugin]# cd
[root@server4 ~]# vim test.sql
[root@server4 ~]# mysql < test.sql
#编写 gearman 的 worker 端
[root@server1 ~]# cd /usr/local/
[root@server1 local]# vim worker.php
7 $redis->connect('172.25.44.1', 6379);
[root@server1 local]# cd
[root@server1 ~]# tar zxf gearman-1.1.2.tgz
[root@server1 ~]# cd gearman-1.1.2
[root@server1 gearman-1.1.2]# ls
ChangeLog examples php_gearman.h tests
config.m4 LICENSE README test_worker.php
CREDITS php_gearman.c test_client.php
[root@server1 gearman-1.1.2]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@server1 gearman-1.1.2]# ./configure
[root@server1 gearman-1.1.2]# make && make install
[root@server1 gearman-1.1.2]# cd
[root@server1 ~]# cd /usr/lib64/php/modules/
[root@server1 modules]# ls
curl.so gearman.so mysqli.so pdo.so redis.so
fileinfo.so json.so mysql.so pdo_sqlite.so sqlite3.so
gd.so mbstring.so pdo_mysql.so phar.so zip.so
[root@server1 modules]# ll gearman.so
-rwxr-xr-x 1 root root 280170 8月 12 15:23 gearman.so
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# ls
curl.ini json.ini mysql.ini pdo_sqlite.ini sqlite3.ini
fileinfo.ini mbstring.ini pdo.ini phar.ini zip.ini
gd.ini mysqli.ini pdo_mysql.ini redis.ini
[root@server1 php.d]# cp redis.ini gearman.ini
[root@server1 php.d]# vim gearman.ini
1 extension=gearman.so
[root@server1 php.d]# /etc/init.d/php-fpm reload
Reloading php-fpm: [12-Aug-2018 15:28:09] NOTICE: configuration file /etc/php-fpm.conf test is successful
[ OK ]
[root@server1 php.d]# cd /usr/local/
[root@server1 local]# ls
bin etc include lib64 sbin src
cluster games lib libexec share worker.php
[root@server1 local]# vim worker.php
$redis->set($work->id, $work->name); #这条语句就是将 id 作 KEY 和name 作 VALUE 分开存储,需要和前面写的 php 测试代码的存取一致。
#
#后台运行 worker
[root@server1 local]# nohup php /usr/local/worker.php &
#测试:
更新 mysql 中的数据
查看 redis
刷新测试页面数据同步