mysql 键值存储_键值存储之redis

本文介绍了Redis相比Memcached的优势,并通过实例展示了如何配置Redis作为MySQL的缓存服务器。此外,还探讨了Redis的主从同步和哨兵机制,以确保高可用性和数据一致性。
摘要由CSDN通过智能技术生成

MySQL通过Memcached将热点数据加载到cache,加速访问,但随着业务数据量的不断增加,和访问量的持续增长会遇到很多问题:

1.MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。

2.Memcached与MySQL数据库数据一致性问题。

3.Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。

4.跨机房cache同步问题。

如果简单地比较Redis与Memcached的区别,redis会有如下优点:

1  Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

2  Redis支持数据的备份,即master-slave模式的数据备份。

3  Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

下面简单的对redis进行实验,参考“www.runoob.com/redis”

安装:

#tar zxf redis-3.0.2.tar.gz

#cd redis-3.0.2

#yum install jemalloc-3.6.0-1.el6 jemalloc-devel-3.6.0-1.el6 gcc -y  //安装插件

#make && make install

#cd utils/

#./install_server_sh   //配置redis,选择默认即可

#service redis_6379 start   //启动redis服务

#redis-cli     //客户端命令行工具,可以对数据库和各种数据类型进行操作

set myKey abc   //设置键值对

get myKey      //取出键值对

config get loglevel  //查看配置项loglevel

fed53cdc5ff0e0eea50c4674bd6a7b09.png

将redis作为mysql的缓存服务器

安装lnmp环境

#yum install -y nginx-1.8.0.1.el6.ngx.x86_64.rpm php-5.3.3-38.el6.x86_64 php-cli-5.3.3-38.el6 php-common php-devel php-fpm php-gd php-mbstring php-mysql  php-pdo   //安装nginx,php,在web上显示redis缓存的mysql数据。

#vim /etc/php.ini

修改时区为亚洲上海

#vim /etc/php-fpm.d/www.conf

设置uer与group为nginx。

#/etc/init.d/php-fpm start      //启动phpfastcgi

#cd /usr/share/nginx/html

#vim index.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 

{

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

for ($key = 1; $key 

{

echo "number is $key";

echo "
";

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

echo "
";

}

?>

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

将fastcgi_param后面的/scripts改为/usr/share/nginx/html   //修改首页路径

在locatin /模块的index行添加index.php   //添加php首页

启动nginx服务

添加php的redis控件

#cd ~/redis

#unzip phpredis-master.zip

#cd phpredis-master

#phpize   //建立php扩展模块,生成configure文件

#./configure

#make && make install

#cd /etc/php.d

#cp mysql.ini redis.ini   //建立redis.ini

#vim redis.ini

内容为extension=redis.so

#/etc/init.d/php-fpm reload

#php -m | grep redis

显示redis表示php添加redis插件成功

580379645a945e6605070019ac4eec8d.png

编辑测试用的数据库文件test.sql

8f34687e7c20347c1ae278563d266ede.png

#mysql

#mysql

>use test

>select * from test;

093b8c4f614f8b0e0b6a3651f44d4620.png

>grant all on test.* to redis@localhost identified by ‘redhat’;  //mysql绑定redis

这时在web上能看到对应数据

3f6cda9771f3fa1b943aee8f7315754c.png

#redis-cli

>get 1

test1

Web上的数据即为redis缓存的mysql的数据。

Gearman

如果更新了mysql,redis中仍然会有之前对应的KEY,数据就不会更新,此时就会出现mysql和redis数据不一致的情况。所以接下来就要通过mysql触发器(gearman)将改变的数据同步到redis中。

一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。

Client:请求的发起者,可以是C,PHP,Perl,MySQL UDF等等。

Job:请求的调度者,用来负责协调把Client发出的请求转发给合适的Worker。

Worker:请求的处理者,可以是C,PHP,Perl等等。

下面要编写的 mysql触发器,就相当于Gearman的客户端;

修改表,插入表就相当于直接下发任务;

通过 lib_mysqludf_json UDF库函数将关系数据映射为JSON格式,然后在通过gearman-mysql-udf插件将任务加入到Gearman的任务队列中;

最后通过redis_worker.php,也就是Gearman的worker端来完成redis数据库的更新。

注:适合mysql7之前的版本。

#yum install gearmand libgearman -y

#/etc/init.d/gearmand start    //启动gearman服务

Netsat可看出它是4730端口

集成gearman到php

#tar zxf gearman-1.1.2.tgz

#cd gearman-1.1.2

#phpize

#yum install libevent-devel libevent-doc libevent-headers libgearman-devel   //安装相应组件

#./configure

#make && make install

#cd /etc/php.d

#cp redis.ini gearman.ini   //建立gearman.ini

#vim gearman.ini

内容为extension=gearman.so

#/etc/init.d/php-fpm reload     //重载phpfastcgi

#php -m | grep gearman

显示gearman表示gearman以集成到php

安装lib_mysqludf_json

#yum install 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'

de44bb57f7b66e9abb8d85d235a76d8e.png

拷贝lib_mysqludf_json.so模块到mysql的plugin目录中

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

323ad954179aa2d898fcdaa5d08d40bf.png

安装 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;

11e09f20ef8ac2c8a149bb3ead652647.png

指定 gearman的服务信息

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

b52ed0c82dfa9088896cb0c2b07debb1.png

编写 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 

查看触发器

mysql> SHOW TRIGGERS FROM test;

5dd09e2d5de661ab2a67592a2dda229c.png

可以看到“syncToRedis”,即mysql中的数据同步到redis中。

编写 gearman的worker端

# vim worker.php

a581b772dcbcbab6fc0e48578ff863e1.png

文件中的$redis->set($work->id, $work->name);这条语句就是将id作KEY和

name 作VALUE分开存储,需要和前面写的php测试代码的存取一致。

# nohup php worker.php &     //后台运行worker

更新mysql中的数据

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

查看 redis

# redis-cli

> get 1

"redhat"

刷新测试页面数据同步

5ae276f58f70b63540c996051a25f26d.png

Redis的主从同步和“哨兵”机制

主从同步:

令server4为主机,server5和server6为从机,都安装redis

在主机上

#vim /etc/redis/6379.conf

在slaveof 下面添加主机ip+端口

Slaveof 172.25.0.4 6379

#/etc/init.d/redis_6379 restart

在从机上执行一样的操作

然后,在Server6上

#redis-cli

>get 1

f9ee4bd4501ad9677507db9904f32966.png

表明Server4的redis数据同步到servef6上

Redis的sentinel(哨兵)

sentinel哨兵是集群管理工具,主要负责主从切换

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自懂切换。

Redis的Sentinel系统用于管理多个Redis服务器(instance), 该系统执行以下三个任务:

·监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否运作正常。

·提醒(Notification): 当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。

·自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个Sentinel进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。

虽然 Redis Sentinel释出为一个单独的可执行文件redis-sentinel, 但实际上它只是一个运行在特殊模式下的Redis服务器, 你可以在启动一个普通Redis服务器时通过给定--sentinel选项来启动Redis Sentinel。

在server4上,

#cd redis-3.0.2

#vim sentinel.conf

添加下列配置:

sentinel monitor mymaster 172.25.0.4 6379 2  (2表示2个从机)

sentinel down-after-milliseconds resque 10000      // 指定了Sentinel认为服务器已经断线所需的毫秒数(判定为主观下线SDOWN)。

sentinel parallel-syncs mymaster 1  //指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长,但越大就意味着越多的从服务器因为复制而不可用。可以通过将这个值设为1来保证每次只有一个从服务器处于不能处理命令请求的状态。

sentinel failover-timeout mymaster 3000  //故障转移延迟,单位ms

这里有两个对服务器下线的判断:

主观下线(Subjectively Down, 简称SDOWN)指的是单个Sentinel实例对服务器做出的下线判断。

客观下线(Objectively Down, 简称ODOWN)指的是多个Sentinel实例在对同一个服务器做出SDOWN判断, 并且通过SENTINEL is-master-down-by-addr命令互相交流之后, 得出的服务器下线判断。

客观下线条件只适用于主服务器: 对于任何其他类型的 Redis实例,Sentinel在将它们判断为下线前不需要进行协商, 所以从服务器或者其他Sentinel永远不会达到客观下线条件。

只要一个 Sentinel发现某个主服务器进入了客观下线状态, 这个Sentinel就可能会被其他Sentinel推选出, 并对失效的主服务器执行自动故障迁移操作。

#grep -v ^# sentinel.conf  //显示内容,过滤开头的#

f07249596dbaab845d6fcd89d1114f2b.png

可看出sentinel的端口为26379.

#grep -v ^# sentinel.conf > /etc/sentinel.conf    //生成etc下的sentinel.conf

将该文件发送给两从机,从机并都启动redis服务

在从机上

#/etc/init.d/redis_6379 start

#redis-sentinel /etc/sentinel.conf

#redis-cli -h 172.25.0.4 -p 26379 info      //显示redis详细信息

0ae4b31c0ad846558e605465d9f6773c.png

停掉主机server4的redis服务,sentinel会自动从从机中选出新的主机

c412218b73ab49fc1e573d1ee328b1f1.png

由图可看出,sentinel通过投票机制选出server6为新的主机。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值