redis 是一个高性能的 key-value 数据库。 redis 的出现,很大程度补偿了memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了 Python,Ruby,Erlang,PHP 客户端,使用很方便。Redis 的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个 appendonly file(aof)里面(这称为“全持久化模式”)。
主机环境 rhel6.5 selinx and iptales disabled.
1. Redis 安装(server2,server3,server4)
[root@server2 ~]# yum install gcc -y
[root@server2 ~]# tar zxf redis-4.0.8.tar.gz
[root@server2 ~]# cd redis-4.0.8
[root@server2 redis-4.0.8]# make && make install
[root@server2 redis-4.0.8]# cd /usr/local/bin/
这些可执行文件的作用如下:
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@server2 ~]# cd redis-4.0.8/utils/
[root@server2 utils]# ./install_server.sh
[root@server2 utils]# netstat -antlp |grep redis
[root@server2 utils]# vim /etc/redis/6379.conf
[root@server2 utils]# /etc/init.d/redis_6379 restart
[root@server3 utils]# vim /etc/redis/6379.conf
[root@server3 utils]# /etc/init.d/redis_6379 restart
测试:在主端更改名字在从端测试
[root@server2 utils]# redis-cli
127.0.0.1:6379> set name westos
[root@server3 utils]# redis-cli
127.0.0.1:6379> get name
server4与server3配置相同
3.配置监控服务Sentinel
Sentinel是redis高可用的方案,通过设立一个或多个Sentinel监视服务器,可以在主服务器下线的时候及时选举切换到从服务器,保证可用性。
Sentinel本身也是服务器,只是运行在特殊模式下,监听其他服务器而已。
[root@server2 ~]# cd redis-4.0.8
[root@server2 redis-4.0.8]# cp sentinel.conf /etc/redis/
[root@server2 redis-4.0.8]# cd /etc/redis/
[root@server2 redis]# vim sentinel.conf
[root@server2 redis]# scp sentinel.conf server3:/etc/redis/
[root@server2 redis]# scp sentinel.conf server4:/etc/redis/
[root@server2 redis]# redis-server /etc/redis/sentinel.conf --sentinel ---监控
再次连接一个server2,将server2关闭
[root@server2 ~]# redis-cli
127.0.0.1:6379> SHUTDOWN
通过监控可以看到,master 跳到了 server4上。接着去server4文件里查看,发现master的ip随着改变了。
server2需要手动启动并修改配置文件。
[root@server2 redis]# vim 6379.conf
[root@server2 redis]# /etc/init.d/redis_6379 start
server4中查看两个slave已经回来。
redis集群
[root@server2 7001]# /etc/init.d/redis_6379 stop
[root@server2 redis]# cd /usr/local/
[root@server2 local]# mkdir cluster
[root@server2 local]# cd cluster/
[root@server2 cluster]# mkdir 700{1..6}
[root@server2 cluster]# cd 7001/
[root@server2 7001]# vim redis.conf
port 7001 #默认值 6379,指定 redis 服务的端口号。
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes #默认值 no,指定是否启用只写模式;
daemonize yes #默认值 no,该参数用于定制 redis 服务是否以守护模式运行
[root@server2 7001]# cp redis.conf ../7002/ #修改端口为7002,以此类推每个文件改为对应的端口号
...
[root@server2 7001]# cp redis.conf ../7006/
[root@server2 7001]# redis-server redis.conf #启动各自的redis服务
...
[root@server2 7006]# ps ax
安装
[root@server2 ~]# yum install ruby-2.2.3-1.el6.x86_64.rpm libyaml-0.1.3-4.el6_6.x86_64.rpm -y
[root@server2 ~]# cp redis-4.0.8/src/redis-trib.rb /usr/local/bin/
[root@server2 ~]# gem install --local redis-4.0.1.gem
[root@server2 ~]# 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
一个master分别对应一个slave。
查看master和slave信息:
[root@server2 ~]# redis-trib.rb check 127.0.0.1:7001
测试:
[root@server2 ~]# redis-cli -c -p 7001
127.0.0.1:7001> set name redhat
可以看出实现了数据同步.
将其中一个服务关闭,查看master信息
[root@server2 ~]# ps ax
[root@server2 ~]# kill -9 4555
[root@server2 ~]# redis-cli -c -p 7001
[root@server2 ~]# redis-trib.rb check 127.0.0.1:7006
此时7006已经成为新的master。
再将7001开启:
[root@server2 ~]# cd /usr/local/cluster/
[root@server2 cluster]# cd 7001
[root@server2 7001]# redis-server redis.conf
已自动成为slave。
Redis 作 mysql 的缓存服务器
server4:redis(master)
server2:php+nginx+redis
server3:mysql
[root@server2 ~]# yum install php-* nginx-1.8.0-1.el6.ngx.x86_64.rpm -y
[root@server2 ~]# vim /etc/php.ini
[root@server2 ~]# cd /etc/php-fpm.d/
[root@server2 php-fpm.d]# vim www.conf
[root@server2 php-fpm.d]# /etc/init.d/php-fpm start
[root@server2 php-fpm.d]# cd /etc/nginx/conf.d/
[root@server2 conf.d]# vim default.conf
[root@server2 conf.d]# /etc/init.d/nginx start
[root@server2 conf.d]# netstat -antlp|grep nginx
[root@server2 conf.d]# netstat -antlp|grep php
[root@server2 conf.d]# cd /usr/share/nginx/html/
[root@server2 html]# vim index.php
[root@server2 ~]# cp test.php /usr/share/nginx/html/index.php
[root@server2 ~]# vim /usr/share/nginx/html/index.php
<?php
$redis = new Redis();
$redis->connect('172.25.0.119',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.0.118','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>";
}
?>
[root@server2 ~]# unzip phpredis-master.zip
[root@server2 ~]# cd phpredis-master
[root@server2 phpredis-master]# phpize
[root@server2 phpredis-master]# ./configure
[root@server2 phpredis-master]#make && make install
[root@server2 phpredis-master]# cd /usr/lib64/php/modules/
[root@server2 modules]# cd /etc/php.d/
[root@server2 php.d]# cp mysql.ini redis.ini
[root@server2 php.d]# vim redis.ini
[root@server2 php.d]# /etc/init.d/php-fpm restart
[root@server2 php.d]# php -m |grep redis
server3:数据库安装配置
[root@server3 ~]# rpm -e --nodeps `rpm -qa|grep mysql` ##删除已经存在的mysql
[root@server3 ~]# yum install mysql-server -y
[root@server3 ~]# /etc/init.d/mysqld start
[root@server3 ~]# mysql < test.sql ##导入测试数据库
数据库授权:
mysql> show databases;
mysql> grant all on test.* to redis@'%' identified by 'westos';
1、php默认从redis 索取数据,第一次redis无缓存,则php从mysql’索取数据
第一次无缓存
第二次索取数据后:
更改数据库信息后,在网页查看信息
mysql> update test set name='redhat',where id=1;
网页并没有更新数据,此时php从redis中读取缓存数据
redis的master主机删除节点内容,更新后继续访问
以上redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情况。
Gearman 完成 redis 数据库的更新
mysq 触发器+gearman+php.worker
1.php装载gearman插件
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
libyaml-0.1.3-4.el6_6.x86_64.rpm
[root@server2 ~]# yum install gearmand-1.1.8-2.el6.x86_64.rpm libevent-* libgearman-* -y
[root@server2 ~]# /etc/init.d/gearmand start
[root@server2 ~]# tar zxf gearman-1.1.2.tgz
[root@server2 ~]# cd gearman-1.1.2
[root@server2 gearman-1.1.2]# phpize
[root@server2 gearman-1.1.2]# ./configure
[root@server2 gearman-1.1.2]# make && make install
安装完成后配置文件:
[root@server2 gearman-1.1.2]# cd /etc/php.d/
[root@server2 php.d]# cp redis.ini gearman.ini
[root@server2 php.d]# vim gearman.ini
[root@server2 php.d]# /etc/init.d/php-fpm reload
查看php加载的模块
[root@server2 php.d]# php -m |grep gearman
2、php.worker配置
[root@server2 ~]# vim worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.0.119', 6379); ##master的IP
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);
}
?>
后台运行 worker:
[root@server2 ~]# cp worker.php /usr/local/
[root@server2 ~]# nohup php /usr/local/worker.php &
3、mysql端配置
mysql端需要的安装包
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.zip
1)、生成lib_mysqludf_json.so模块
[root@server3 ~]# yum install gcc mysql-devel -y
[root@server3 ~]# unzip lib_mysqludf_json-master.zip
[root@server3 ~]# cd lib_mysqludf_json-master
[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
[root@server3 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
注册json函数
mysql> show global variables like 'plugin_dir'; #查看模块目录
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so'; #注册 json 函数
mysql> select * from mysql.func; #查看函数
注册udf函数
[root@server3 ~]# yum install libevent-* libgearman-* -y
[root@server3 gearman-mysql-udf-0.6]# tar zxf gearman-mysql-udf-0.6.tar.gz
[root@server3 gearman-mysql-udf-0.6]# cd gearman-mysql-udf-0.6
[root@server3 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/
[root@server3 gearman-mysql-udf-0.6]# make && make install
[root@server3 gearman-mysql-udf-0.6]# mysql -p
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;
mysql> SELECT gman_servers_set('172.25.0.117:4730'); ##指定gearman的服务信息
2)编写mysql触发器
[root@server3 ~]# 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 ;
查看触发器
[root@server3 ~]# mysql -p < test.sql
mysql> show triggers from test;
测试:
数据库写入:
mysql> update test.test set name='redhat';
刷新测试页面:
此时数据实现同步。