linux redis集群管理及lnmp环境下测试

**

为什么使用redis?

**

redis是一种典型的no-sql 即非关系数据库 像python的字典一样 存储key-value键值对 工作在memory中

所以很适合用来充当整个互联网架构中各级之间的cache 比如lvs的4层转发层 nginx的7层代理层

尤其是lnmp架构应用层如php-fpm或者是Tomcat到mysql之间 做一个cache 以减轻db的压力

因为有相当一部分的数据 只是简单的key-value对应关系,而且在实际的业务中常常在短时间内迅速变动

如果用关系数据库mysql之类存储 会大大增加对db的访问 导致db的负担很重 因为所有的require中的大部分最后都要汇聚到db

所以如果想要业务稳定 那么解决db的压力 就是关键 所以现在大部分的解决方案就是在db层之上的各级使用多级的no-sql

像memcache redis 等 来为db提供缓冲

2.为什么使用redis-cluster?

为了在大流量访问下提供稳定的业务,集群化是存储的必然形态

未来的发展趋势肯定是云计算和大数据的紧密结合 只有分布式架构能满足要求

如果没有集群化 何来的分布式?

3.顺带一提总结一波今天的redis原理之数据持久化

虽然redis这种no-sql一般都是作为cache来服务 但是如果完全没有数据可持久化的方法 那么显得有些单薄

就像memcache 由于这种no-sql是工作在memory的 那么由于memory的实体是ram

所以如果重启或者宕机 memory中的数据就全没了 数据的一致性的不到保障

但是 redis不同 redis有相对的数据持久化的方案 由两种方式构成 aof & rdb

aof就像关系数据库中的binlog一样 把每一次写操作以追加的形式记录在其中以文件的形式刷到磁盘里

并且可以使用不同的fsync策略 无fsync,每秒fsync,每次写的时候fsync.

使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求)

一旦出现故障,最多丢失1秒的数据.

但是缺点也随之而来 那就是aof文件的大小会随着时间线性增长 一段时间之后 就会变得很大

如果要在一端以AOF的形式来恢复数据 那么由于AOF文件的巨大体积 可能会让进程如同假死一样 十分的慢

rdb则是一种快照机制

redis工作在内存中 rdb就是每隔一段时间 对内存中的数据做一次快照 保存在rdb文件中

而且redis的主从同步可以实现异步 也是由于rdb的机制 他在做快照时会fork出一个子进程 由子进程来做快照

父进程完全处理请求 毫不影响 很适合数据的备份

但是问题是 如果数据量很大的话 rdb它要保存一个完整的数据集 是一个大的工作 如果时间间隔设置的太短

那么严重影响redis的性能 但是按照常规设置的话 如5分钟一次 那么如果宕机或者重启 就会基于上次做rdb的时间

从而丢失分钟级的数据

point:在redis4.0的新特性中 采用了aof-rdb的混合方案来保障数据的持久性 但是官方的说法是还不成熟

是一个长期的工作 所以有待观察吧
**

安装redis

**

   yum install  gcc 

  240  tar  zxf redis-4.0.8.tar.gz 
  241  cd  redis-4.0.8
  242  make
  243  make install
  244  ls
  245  redis
  246  cd  utils/
  247  ls
  248  ./install_server.sh 
  249  redis-cli

修改监控端口
这里写图片描述
这里写图片描述

设置主从
server3主机写入数据
这里写图片描述
server4修改配置文件
这里写图片描述
这里写图片描述

**

sentinel 高可用

**

sentinel配置监控主机

将配置文件发送至其他主机同一目录下
所有服务关机后操作 配置文进到为再重启

这里写图片描述

10000为默认停止的时间
1为默认同时进行数据恢复的主机数量 数量越大恢复越快
这里写图片描述
在主机查看如下

redis-cli
127.0.0.1:6379> info

主机
这里写图片描述

这里写图片描述

备机1
这里写图片描述
这里写图片描述

如图加入进去

redis cluster 集群管理
redis的集群化方案 目前有三种

(1)Twitter开发的twemproxy

(2)豌豆荚开发的codis

(3)redis官方的redis-cluster

简介:twemproxy架构简单 就是用proxy对后端redis server进行代理 但是由于代理层的消耗性能很低 而且通常涉及多个key的操作都是不支持的 而且本身不支持动态扩容和透明的数据迁移 而且也失去维护 Twitter内部已经不使用了

      redis-cluster是三个里性能最强大的 因为他使用去中心化的思想 使用hash slot方式 将16348个hash slot 覆盖到所有节点上 对于存储的每个key值 使用CRC16(KEY)&16348=slot 得到他对应的hash slot 并在访问key时就去找他的hash slot在哪一个节点上 然后由当前访问节点从实际被分配了这个hash slot的节点去取数据 节点之间使用轻量协议通信 减少带宽占用 性能很高 自动实现负载均衡与高可用 自动实现failover  并且支持动态扩展 官方已经玩到可以1000个节点 实现的复杂度低 总之个人比较喜欢这个架构 因为他的去中心化思想免去了proxy的消耗 是全新的思路

       但是它也有一些不足 例如官方没有提供图形化管理工具 运维体验差 全手工数据迁移 并且自己对自己本身的redis命令支持也不完全等 但是这些问题 我觉得不能掩盖他关键的新思想所带来的的优势 随着官方的推进 这些问题应该都能在一定时间内得到解决 那么这时候去中心化思想带来的高性能就会表现出他巨大的优势 

      codis使用的也是proxy思路 但是做的比较好 是这两种之间的一个中间级 而且支持redis命令是最多的 有图形化GUI管理和监控工具 运维友好 这个过段时间会详细另外写出来原理 工作机制和搭建实现

官方文档
http://www.redis.cn/topics/cluster-tutorial.html

搭建步骤

mkdir {7001,7002,7003,7004,7005,7006}
 cd /mnt/redis-4.0.8
 cd  src/
 cp  redis-trib.rb   /usr/local/bin/
 yum install  ruby-2.2.3-1.el6.x86_64.rpm -y
 yum install  libyaml-0.1.3-4.el6_6.x86_64.rpm 
 gem install  --local redis-4.0.1.gem
 /etc/init.d/redis_6379 stop
 vim  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**

开启服务
redis-server redis.conf 
ps  ax
 1495 ?        Ssl    0:00 redis-server *:7001 [cluster]
 1508 ?        Ssl    0:00 redis-server *:7002 [cluster]
 1517 ?        Ssl    0:00 redis-server *:7005 [cluster]
 1522 ?        Ssl    0:00 redis-server *:7004 [cluster]
 1527 ?        Ssl    0:00 redis-server *:7003 [cluster]
 1533 ?        Ssl    0:00 redis-server *:7006 [cluster]

创建集群  可以直接回车查看帮助  replicas  每个master对应的slave数量
 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:7004 127.0.0.1:7006  

echo 511> /proc/sys/net/core/somaxconn 
sysctl   -w  vm.overcommit_memory=1(同时写入 sysctl.conf文件)
vim  /etc/sysctl.conf 
echo  never > /sys/kernel/mm/transparent_hugepage/enabled 

查看集群状态
redis-trib.rb    check  127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: 53c4378bd2d05bb01e2185c1f0afc5f26b0de923 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: db3dc2d4117cad66375eb1b5a596b2eba41172e9 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: 74dcd037be088583ced8d2df2f669e32e7e1d0d4 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 2c27d3acc7dca8654ac91448dbf37591cf3b370e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 53c4378bd2d05bb01e2185c1f0afc5f26b0de923
S: e8811c4adf747c0cd3844081a733142f113e8046 127.0.0.1:7006
   slots: (0 slots) slave
   replicates 74dcd037be088583ced8d2df2f669e32e7e1d0d4
S: f76a41892638ed7d4863c31e4f9149902833f62b 127.0.0.1:7004
   slots: (0 slots) slave
   replicates db3dc2d4117cad66375eb1b5a596b2eba41172e9
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.


如果在测试中对某一个节点没有添加slave
可以通过命令添加

redis-trib.rb  add-node   --slave  127.0.0.1:7005  127.0.0.1:7001
>>> Adding node 127.0.0.1:7005 to cluster 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: 53c4378bd2d05bb01e2185c1f0afc5f26b0de923 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
M: db3dc2d4117cad66375eb1b5a596b2eba41172e9 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: 74dcd037be088583ced8d2df2f669e32e7e1d0d4 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: e8811c4adf747c0cd3844081a733142f113e8046 127.0.0.1:7006
   slots: (0 slots) slave
   replicates 74dcd037be088583ced8d2df2f669e32e7e1d0d4
S: f76a41892638ed7d4863c31e4f9149902833f62b 127.0.0.1:7004
   slots: (0 slots) slave
   replicates db3dc2d4117cad66375eb1b5a596b2eba41172e9
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 127.0.0.1:7001
>>> Send CLUSTER MEET to node 127.0.0.1:7005 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 127.0.0.1:7001.
[OK] New node added correctly.

可以查看是否添加成功
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=308,lag=0
master_replid:6b907915c876a1330060b3870aa132729af499b1
master_replid2:0000000000000000000000000000000000000000

同时在7001处写入数据 可以看到将数据转入了7002 说明在所有及其slave上都可以看到
127.0.0.1:7001> set name bobo
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
"bobo"
查看数据
[root@server2 7001]# redis-cli -c -p  7002
127.0.0.1:7002> get name
"bobo"
127.0.0.1:7002> 
[root@server2 7001]# redis-cli -c -p  7003
127.0.0.1:7003> get name
-> Redirected to slot [5798] located at 127.0.0.1:7002
"bobo"
127.0.0.1:7002> 
[root@server2 7001]# redis-cli -c -p  7006
127.0.0.1:7006> get name
-> Redirected to slot [5798] located at 127.0.0.1:7002
"bobo"

**

集群重新分片

**

现在, 让我们来试试对集群进行重新分片操作。在执行重新分片的过程中, 请让你的 example.rb 程序处于运行状态, 这样你就会看到, 重新分片并不会对正在运行的集群程序产生任何影响, 你也可以考虑将 example.rb 中的 sleep 调用删掉, 从而让重新分片操作在近乎真实的写负载下执行 重新分片操作基本上就是将某些节点上的哈希槽移动到另外一些节点上面, 和创建集群一样, 重新分片也可以使用 redis-trib 程序来执行 执行以下命令可以开始一次重新分片操作:

redis-trib.rb reshard 127.0.0.1:7001 (指定一个地址即可)

**

搭建lnmp环境结合redis

**
rpm安装即可


 nginx.x86_64 0:1.8.0-1.el6.ngx       php.x86_64 0:5.3.3-38.el6          php-cli.x86_64 0:5.3.3-38.el6      php-common.x86_64 0:5.3.3-38.el6       
  php-devel.x86_64 0:5.3.3-38.el6      php-fpm.x86_64 0:5.3.3-38.el6      php-gd.x86_64 0:5.3.3-38.el6       php-mbstring.x86_64 0:5.3.3-38.el6     
  php-mysql.x86_64 0:5.3.3-38.el6      php-pdo.x86_64 0:5.3.3-38.el6     

yum install  nginx-1.8.0-1.el6.ngx.x86_64.rpm   php-* -y

关闭redis所有进程
kill -9 1618 1623  1628  1633 1640  1647

编辑php配置文件
修改 php.ini  修改时区
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
date.timezone =Asia/Shanghai

vim  /etc/php-fpm.d/www.conf 
修改用户 组即可
 38 ; RPM: apache Choosed to be able to access some dir as httpd
 39 user = nginx
 40 ; RPM: Keep a group allowed to write in log dir.
 41 group = nginx

/usr/local/share/nginx/htm 添加php测试文件即可
测试文件如下

<?php
        $redis = new Redis();
        $redis->connect('172.25.15.12',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.15.15','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 初始化配置即可 为master
第三台主机配置mysql 使用较为低版本
根据一号机php测试文件在mysql重添加授权用户即可
grant all on test.* to redis@’%’ identified by ‘westos’;

在浏览器输入地址访问即可
第一次打开没有缓存到数据 需要刷新一次可以看到数据
这里写图片描述

这里写图片描述

基于gearman 来实现数据更新
主机端(查看数据端)

yum install gearmand-1.1.8-2.el6.x86_64.rpm libgearman-* -y libevent-devel-1.4.13-4.el6.x86_64.rpm 
yum install gearmand-1.1.8-2.el6.x86_64.rpm libgearman-* -y libevent-*

tar zxf gearman-1.1.2.tgz 

 cd gearman-1.1.2
 phpize 
 ./configure 
 make
 make install
cd gearman-1.1.2
cp redis.ini gearman.ini
vim gearman.ini 
/etc/init.d/php-fpm reload
 php -m |grep gearman
 cp worker.php /usr/local/

[root@server2 mnt]#  php -m |grep gearman
gearman

mysql端

 yum install gearmand-1.1.8-2.el6.x86_64.rpm  gearman-mysql-udf-0.6.tar.gz libevent-*   libgearman-* -y
yum install unzip -y

unzip  lib_mysqludf_json-master.zip 

gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

cp lib_mysqludf_json.so  /usr/lib64/mysql/plugin/
 mysql

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

# 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


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 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)


mysql> SELECT gman_servers_set('172.25.15.12:4730')
    -> ;
+---------------------------------------+
| gman_servers_set('172.25.15.12:4730') |
+---------------------------------------+
| 172.25.15.12:4730                     |
+---------------------------------------+
1 row in set (0.00 sec)

编辑work文件

<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');

$redis = new Redis();
$redis->connect('172.25.15.12', 6379);######redis地址  

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);
}
?>
开启服务
/etc/init.d/gearmand start

打开网页测试数据刷新

这里写图片描述

mysql> update  test set name='linux';
Query OK, 9 rows affected (0.02 sec)
Rows matched: 9  Changed: 9  Warnings: 0

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值