redis分布式集群数据库

redis分布式集群数据库

1.介绍

redis 是一个高性能的 key-value 数据库。 redis 的出现,很大程度补偿了memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP 客户端,使用很方便。Redis 的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为半持久化模式”);也可以把每一次数据变化都写入到一个 append only file(aof)里面(这称为全持久化模式”)

 

2.环境:

rhel6.5 selinx and iptales disabled

master:server1-172.25.4.1

slave:  server4-172.25.4.4

 

3.redis安装

master slvae都做下面操作

tar zxf redis-3.0.2.tar.gz

cd redis-3.0.2

yum install gcc -y

make

make install

cd redis-3.0.2/utils

./install_server.sh   #全部使用默认

 

# 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 是集群管理工具,主要负责主从切换。

 

4. Redis 客户端使用

redis-cli   命令行

127.0.0.1:6379> config get *

1) "dbfilename"

2) "dump.rdb"

3) "requirepass"

4) ""

5) "masterauth"

你可以通过修改 redis.conf 文件或使用 CONFIG set 命令来修改配置,但重启服务后会读取 redis.conf 文件配置。

[root@server1 ~]# redis-cli

127.0.0.1:6379> CONFIG GET loglevel1) "loglevel"

2) "notice"

127.0.0.1:6379> CONFIG SET loglevel "debug"

OK

127.0.0.1:6379> quit

 

5.redis集群的基本搭建

slave

vim /etc/redis/6379.conf

207 slaveof 172.25.4.1 6379

/etc/init.d/redis_6379 restart

 

然后在master

redis-cli

127.0.0.1:6379> set name redhat

OK

127.0.0.1:6379> set pass westos

OK

slave

redis-cli 

127.0.0.1:6379> get name

"redhat"

127.0.0.1:6379> get pass

"westos"

 

6.sentinel配置

master

cp /redis-3.0.2/sentinel.conf  /etc/redis/

vim /etc/redis/sentinel.conf 

port 26379

dir /tmp

sentinel monitor mymaster 172.25.4.1 6379 2

sentinel down-after-milliseconds mymaster 10000

sentinel parallel-syncs mymaster 1

sentinel failover-timeout mymaster 180000

 

scp /etc/redis/sentinel.conf 172.25.4.4:/etc/redis/  #必须在启动sentinel之前复制,不然启动以后配置文件就会自动修改

scp /etc/redis/sentinel.conf 172.25.4.2:/etc/redis/

 

然后在每个节点打开sentinel

redis-server /etc/redis/sentinel.conf  --sentinel

就会发现所有的节点都已经加上了

 

测试:

master

redis-cli 

127.0.0.1:6379> shutdown

not connected> quit

slave上就会发现,172.25.4.1已经下线了,然后开始投票,选出新的master

+switch-master mymaster 172.25.4.1 6379 172.25.4.2 6379

 

172.25.4.1变成了slave,并且时down状态

+sdown slave 172.25.4.1:6379 172.25.4.1 6379 @ mymaster 172.25.4.2 6379

如果要打开172.25.4.1,就去

vim /etc/redis/6379.conf

207 slaveof 172.25.4.2 6379

/etc/init.d/redis_6379 restart  重启服务,172.25.4.1就加入了slave

-sdown slave 172.25.4.1:6379 172.25.4.1 6379 @ mymaster 172.25.4.2 6379

 

重新开一个终端

redis-cli -h 172.25.4.2 -p 26379

172.25.4.2:26379> info  

master0:name=mymaster,status=ok,address=172.25.4.2:6379,slaves=2,sentinels=3

或者

redis-cli -h 172.25.4.2 -p 6379

172.25.4.2:6379> info replication

slave0:ip=172.25.4.4,port=6379,state=online,offset=278736,lag=1

slave1:ip=172.25.4.1,port=6379,state=online,offset=278736,lag=1

可以查看你的master,还有slave数,还有你的sentinels

 

7.多个sentinels管理

mkdir  /usr/local/cluster

cd /usr/local/cluster

mkdir 3000{1,2,3,4,5,6}

cd 30001/

 

vim redis.conf

daemonize yes

pidfile "/usr/local/cluster/30001/redis.pid"

port 30001

logfile "/usr/local/cluster/30001/redis.log"

dir "/usr/local/cluster/30001"

cluster-enabled yes

cluster-config-file nodes-30001.conf

cluster-node-timeout 15000

appendonly yes

 

cd /usr/local/cluster

cp 3001/redis.conf  30002/

cp 3001/redis.conf  30003/

cp 3001/redis.conf  30004/

cp 3001/redis.conf  30005/

cp 3001/redis.conf  30006/

 

把里面的配置内容修改  >> vim 编辑模式下,%s/30001/30002/g

 

redis-server 30001/redis.conf   #启动所有服务

 

cd /root/redis-3.0.2/src

cp redis-trib.rb  /usr/local/bin/

 

yum install -y rubygems-1.3.7-5.el6.noarch.rpm

gem install redis-3.3.1.gem 

 

redis-trib.rb create --replicas 1 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006

 

redis-cli -p 30001

127.0.0.1:30001> cluster info

127.0.0.1:30001> cluster nodes

 

[root@server1 ~]# redis-cli 

127.0.0.1:6379> get user1

"123"

127.0.0.1:6379> get user2

"456"

127.0.0.1:6379> get user3

"789"

 

redis-trib.rb import --from 127.0.0.1:6379 127.0.0.1:30001

 

如果同shutdown掉一半的master节点,整个集群就会挂掉

redis-cli -c -p 30004

127.0.0.1:30004> get name

(error) CLUSTERDOWN The cluster is down

 

1-4 2-5 3-6 如果down掉一个master节点,他对应的slave节点会接管他

 

添加slave节点到某master的管理里面

redis-trib.rb add-node --slave --master-id a76de1df1fe4d2d7eb0ca4f2b38f427682a7d93a  127.0.0.1:30008 127.0.0.1:30001

删除节点

redis-trib.rb del-node  127.0.0.1:30001

a76de1df1fe4d2d7eb0ca4f2b38f427682a7d93a   

 

删除数据库rpm

rpm -e --nodeps `rpm -qa|grep mysql`

cd /var/lib/mysql

rm -fr *

yum install mysql-server  -y

 

8.redis结合lnmp架构

Redis 作 mysql 的缓存服务器

1. 安装 lnmp 环境,安装以下软件包:

nginx php php-fpm php-cli php-common php-gd php-mbstring php-mysql

php-pdo php-devel mysql mysql-server

http://download.fedoraproject.org/pub/epel/6/

http://mirrors.163.com/centos/6/os/x86_64/

http://nginx.org/packages/centos/6/

2. 安装 php 的 redis 扩展

https://github.com/owlient/phpredis

 

cd phpredis-master

phpize

./configure --with-php-config=/usr/bin/php-config

make && make install

# vim /etc/php.ini    #添加以下行

extension=redis.so   #加载 redis 模块

date.timezone = Asia/Shanghai  #设置时区

# sed -i 's/apache/nginx/g' /etc/php-fpm.d/www.conf

# service php-fpm start

3. 简单配置 nginx

# vim /etc/nginx/conf.d/default.conf

server {

listen

80;

server_name localhost;

#修改 php-fpm 用户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;

}

}

# service nginx start

4. 配置 mysql

# service mysqld start

mysql> grant all on test.* to redis@localhost identified by 'westos';

Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

5. 创建 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";

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

}

?>

测试结果:


 

到这里,我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情况。所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。

配置 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 数据库的更新。

1. 安装 gearman 软件包:

gearmand libgearman-devel libgearman libevent libevent-devel

libevent-doc libevent-headers tokyocabinet

# service gearmand start

#启动服务

# netstat -antlp |grep gearmand

tcp

0

0 0.0.0.0:4730

7304/gearmand

0.0.0.0:*

LISTEN

2. 安装 php 的 gearman 扩展

https://pecl.php.net

 

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

# vim /etc/php.ini

extension=gearman.so

# service php-fpm reload

3. 安装 lib_mysqludf_json

lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映射为 JSON 格式,是通过程序来转换的。

https://github.com/mysqludf/lib_mysqludf_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 |

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

拷贝 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 的分布式的队列。

https://launchpad.net/gearman-mysql-udf

# 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 |

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

指定 gearman 的服务信息

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

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

| gman_servers_set('127.0.0.1:4730') |

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

| 127.0.0.1:4730

|

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

5. 编写 mysql 触发器(根据实际情况编写)

# vim test.sql

use 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 |

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

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

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='hello' where id=1;查看 redis

# redis-cli

127.0.0.1:6379> get 1

"hello"

刷新测试页面数据同步

 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值