Redis Cluster集群搭建实验

Redis Cluster集群搭建实验

前言

本文重点在于前面的Redis集群的知识理论与后面的集群搭建与测试,如有错误遗漏的地方,欢迎大家批评指正,谢谢。

基本理论说明

Redis Cluster简介

redis是一个开源的key value存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群,本试验使用的是redis3.0.0版本;
redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;
redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;

为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;

那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;

那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。

综上所述,每个Redis集群理论上最多可以有16384个节点。

以上描述出自redis集群搭建,如有侵权,请联系本人删除。

实验步骤

实验目的:完成Redis Cluster集群搭建

实验准备:至少4台C6虚拟机(selinux与防火墙已关闭)

实验规划:

Redis Cluster 集群正常工作至少需要 3 个主节点,同时为了保证数据的高可用性,加入了主从模式。因此至少创建 6 个节点,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点默认情况下只负责从 Master 拉取数据进行备份。当这个主节点挂掉后,集群就会通过下线检测的方式,由从节点中选举一个节点来充当主节点,实现故障转移,从而保证集群正常运行

IP地址端口用途
192.168.10.106378/6379存储数据/主节点备份
192.168.10.116378/6379存储数据/主节点备份
192.168.10.126378/6379存储数据/主节点备份
192.168.10.13python环境

ps:标准虚拟机安装见网络阶段Centos6安装指南

一、安装Redis服务

准备好Redis源码包,准备解压安装。

安装tcl脚本语言

yum install -y tcl lrzsz

解压安装redis

tar -zxvf redis-3.2.12.tar.gz
cd redis-3.2.12
make && make PREFIX=/usr/local/redis install

启动前优化内存分配策略

Overcommit_Memory 参数可选值含义:

0 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程

1 表示内核允许分配所有的物理内存,而不管当前的内存状态如何

2 表示内核允许分配超过所有物理内存和交换空间总和的内存

echo 'vm.overcommit_memory=1' >>/etc/sysctl.conf && sysctl -p

为了节省时间,先将10机器的Redis安装目录使用scp传输至相应目录。

scp -r /usr/local/redis/ root@192.168.10.11:/usr/local/
scp -r /usr/local/redis/ root@192.168.10.12:/usr/local/

二、构建 Redis-Cluster 集群节点

创建存放实例的目录

mkdir -p /data/{6378,6379}

将redis配置文件放入实例目录

cp /root/redis-3.2.12/redis.conf /data/6378/

编辑实例中的Redis配置文件

vim /data/6378/redis.conf

修改下列信息

#修改61行,指定redis 实例绑定的接口地址
bind 0.0.0.0
#修改80行,关闭严格模式
protected-mode no
#修改84行,指定端口信息
port 6378
#修改128行,是否放在后台运行
daemonize yes
#修改150行,指定pid文件存放位置
pidfile /data/6378/redis_6378.pid
#修改163行,指定日志文件存放位置
logfile "/data/6378/redis-6378.log"
#修改247行,指定持久化储存文件位置
dir /data/6378
#修改593行,开启持久化保存
appendonly yes
#取消721行注释,开启集群化
cluster-enabled yes
#取消729行注释,指定集群化配置文件
cluster-config-file nodes-6378.conf
#取消735行注释,设置节点超时时间,目标节点超过指定时间没响应,就标记为FAIL或PFAIL(可能宕机)
cluster-node-timeout 15000

将此配置文件重新命名,方便记忆。

mv /data/6378/redis.conf /data/6378/redis-6378.conf

启动Redis6378实例,查看是否启动。

/usr/local/redis/bin/redis-server /data/6378/redis-6378.conf
netstat -anpt  | grep :6378

启动成功,进行6378登陆测试。

/usr/local/redis/bin/redis-cli -h 192.168.10.10 -p 6378

登陆成功,开始构建6379实例,将redis配置文件拷贝至指定位置。

cp -a /data/6378/redis-6378.conf /data/6379/

将文件改名,方便区分。

cd /data/6379
mv redis-6378.conf redis-6379.conf 

检查redis配置文件,防止出现错误。

vim redis-6379.conf

#修改84行,指定端口信息
port 6379
#修改150行,指定pid文件存放位置
pidfile /data/6379/redis_6379.pid
#修改163行,指定日志文件存放位置
logfile "/data/6379/redis-6379.log"
#修改247行,指定持久化储存文件位置
dir /data/6379
#取消729行注释,指定集群化配置文件
cluster-config-file nodes-6379.conf

ps:或者直接搜索6378,将其全部改成6379

启动6379端口实例,进行登陆测试。

/usr/local/redis/bin/redis-server ./redis-6379.conf
/usr/local/redis/bin/redis-cli -h 192.168.10.10 -p 6379

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mQ9Fri2n-1605097783704)(https://7.dusays.com/2020/11/10/c345cc0cb3720.png)]

登陆成功,其余两台开始构建其余实例。

将data目录使用scp命令传输至目标主机根目录下

scp -r /data root@192.168.10.11:/
scp -r /data root@192.168.10.12:/

分别删除各节点产生的文件,只保留conf文件。

rm -f appendonly.aof redis-6378.log nodes-6378.conf redis_6378.pid
cd ../6379
rm -f appendonly.aof redis-6379.log nodes-6379.conf redis_6379.pid

分别启动实例,查看是否正常启动。

/usr/local/redis/bin/redis-server /data/6378/redis-6378.conf
/usr/local/redis/bin/redis-server /data/6379/redis-6379.conf
/usr/local/redis/bin/redis-cli -h 192.168.10.11 -p 6378
/usr/local/redis/bin/redis-cli -h 192.168.10.11 -p 6379

ps:192.168.10.12设置同理,注意IP地址

进行跨节点连接测试。使用192.168.10.12连接192.168.10.10测试。

/usr/local/redis/bin/redis-cli -h 192.168.10.10 -p 6378

连接成功, Redis-Cluster集群节点搭建完毕。

三、创建 Redis-Cluster 集群

任选一台虚拟机安装ruby语言环境,并使用国内源。

yum -y install ruby rubygems openssl openssl-devel
gem sources --add http://mirrors.aliyun.com/rubygems/ --remove http://rubygems.org/
gem sources list

ps:需要能连接外网。

安装依赖软件

gem install redis  -v 3.3.3

拷贝创建集群软件至指定目录

cp /root/redis-3.2.12/src/redis-trib.rb /usr/local/redis/bin/

创建Redis-Cluster 集群

/usr/local/redis/bin/redis-trib.rb create --replicas 1 192.168.10.10:6378 192.168.10.10:6379 192.168.10.11:6378 192.168.10.11:6379 192.168.10.12:6378 192.168.10.12:6379

ps: create:创建一个新的集群 replicas:指定每个主节点创建多少从节点

使用集群化连接redis,并创建数据进行测试。

/usr/local/redis/bin/redis-cli -c -p 6378

去对应存储节点查看

192.168.10.11查看

/usr/local/redis/bin/redis-cli -h 192.168.10.11 -p 6378

数据写入完毕,查看key对应的槽位以及槽位与节点的对应关系。

cluster keyslot diaomao
cluster slots

数据插入至指定槽位, Redis-Cluster 集群构建完毕。

四、 Redis-Cluster 集群管理之协同测试

1.Redis与MySQL数据库协同测试

生产环境中,redis作为缓存服务器,不直接写入数据,而是通过间接手段获取数据,可能使用脚本或者其他语言从MySQL等数据库内转换成redis数据,从而充当缓存服务器的作用。

安装MySQL数据库,并进行基本设置。

yum -y install mysql mysql-server
service mysqld start
mysqladmin -uroot password 123
mysql -uroot -p123
grant all on *.* to 'root'@'%' identified by '123';

创建数据模版,插入测试数据。

use test
create table stu(sid smallint(8),sname varchar(20),address varchar(20),primary key(sid));
insert into stu values(1,'汪洋','湖南长沙'),(2,'刘川','河南洛阳'),(3,'沈超','北京市'),(4,' 任墨影','广州市'),(5,'焦子先','上海市');
select * stu;

2.数据转换

任意redis集群创建数据转换脚本,将mysql数据导入redis集群内。

touch "mysql>redis".sh

#!/bin/bash
#指定要转换的数据库地址
IP=192.168.10.13
script='/server/scripts'
if [ ! -d $script ];then
    mkdir -p $script
fi
#将查询到的MySQL数据封装成为redis数据格式进行插入
cd $script && \
/usr/bin/ssh $IP "mysql -uroot -p123 -e 'select concat(\"hmset stu_\",sid,\" sid \",sid,\" sname \",sname,\" address \",address) from test.stu;'"|grep -v '^concat'|awk '{print "/usr/local/redis/bin/redis-cli -c -p 6378",$0}' >db.cmd
#判断上一条命令是否执行成功
if [ $? -ne 0 ];then
    echo 'USAGE: Please check the Data or IP.'
    exit 1
fi
#执行命令,将结果写入缓存
cat db.cmd | while read line
do
    $line
done

赋予脚本执行权限,准备进行测试。

chmod a+x mysql\>redis.sh

redis测试机与MySQL服务主机进行免密操作

ssh-keygen -t rsa -b 2048
ssh-copy-id root@192.168.10.13

执行脚本,查看是否转换成功。

./mysql\>redis.sh
/usr/local/redis/bin/redis-cli -c --raw -p 6378 hmget stu_2 sid sname

读取成功,协同实验搭建完毕。

五、 Redis-Cluster 集群管理之故障转移

生产环境,redis集群中的主节点宕机或者出现故障,从节点会自动顶替从而成为新的主节点,宕机的主节点排除故障后,重新通过配置才能加入集群中。

1.模拟故障

任意登陆Redis集群,查询各个节点信息。

/usr/local/redis/bin/redis-cli -c -p 6378
cluster nodes

通过上述信息得知,当前登陆为192.168.10.10的主节点,使用命令将该节点停止,模拟故障。

/usr/local/redis/bin/redis-cli -c -h 192.168.10.10 -p 6378 shutdown
/usr/local/redis/bin/redis-cli -c -p 6379
cluster nodes

2.添加节点

删除故障节点信息,重新启动失效节点

cd /data/6378
rm -f appendonly.aof redis-6378.log nodes-6378.conf redis_6378.pid dump.rdb
/usr/local/redis/bin/redis-server /data/6378/redis-6378.conf

添加重新启动的节点至原有集群,然后登陆该节点查看集群信息。

/usr/local/redis/bin/redis-trib.rb add-node --slave --master-id 4af284e0b43f5823a9f1d3f24ecfa4c3e8cdc8e9 192.168.10.10:6378 192.168.10.10:6379
/usr/local/redis/bin/redis-cli -c -p 6378
cluster nodes

新添加的节点自动成为从节点,如果有无用节点信息,可用以下命令删除无效信息。

redis-cli -c -p 端口 CLUSTER FORGET 'node-id'

六、使用python连接Redis-Cluster集群

1.安装python语言

准备好实验所用源码包,安装所需依赖。

yum install -y lrzsz gcc gcc-c++ 

在第四台机器上解压安装python

tar -xf redis-cluster.tar.gz
tar -xf Python-3.5.5.tgz
cd Python-3.5.5
./configure && make && make install

进行登陆测试

python3
exit()

2.安装支持python调用类库

安装支持python调用redis类库

cd
tar -xf redis-py-2.10.6.tar.gz
cd redis-py-2.10.6
python3 setup.py install

登陆测试,如果没有报错,则代表类库安装完毕。

python3
import redis
exit()

安装支持python调用Redis-Cluster集群类库

cd
tar -xf redis-py-cluster-1.3.6.tar.gz
cd redis-py-cluster-1.3.6
python3 setup.py install

登陆测试,如果没有报错,则代表类库安装完毕。

python3
from rediscluster import StrictRedisCluster
exit()

3.使用python脚本进行读写测试

编写一个python脚本

vim redis-cluster.py

#! /usr/bin/env python3
from rediscluster import StrictRedisCluster
#从rediscluster库导入StrictRedisaCluster函数

startup_nodes = [
    {"host":"192.168.10.10", "port":6378},
    {"host":"192.168.10.10", "port":6379},
    {"host":"192.168.10.11", "port":6378},
    {"host":"192.168.10.11", "port":6379},
    {"host":"192.168.10.12", "port":6378},
    {"host":"192.168.10.12", "port":6379}
]

redis_store= StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
#构建StrictRedisCluster对象(开始节点,反向解码)

redis_store.set("name-new","daqiang")
redis_store.set("money-new","8500")
# 设置key键为name、money; value值为 '大强'、'8千5'(操作这个集群,添加)

print("My name is: ", redis_store.get('name-new'))
print("I have money: ", redis_store.get('money-new'))
# 获取键为name,money(获取)并打印出来

保存退出,运行脚本,查看是否打印相应信息。

python3 redis-cluster.py

打印成功,python脚本执行完毕。

登陆任意redis集群,查看脚本写入数据槽位。

/usr/local/redis/bin/redis-cli -c -p 6378
cluster keyslot name-new

通过命令得知该数据槽位为1807,使用以下命令查看对应槽位节点。

cluster nodes

登陆对应节点,查看数据。

/usr/local/redis/bin/redis-cli -c -h 192.168.10.12 -p 6378
keys *
get name-new

退出redis,返回192.168.10.修改python脚本,将创建语句注释,准备测试Redis高可用。

vim redis-cluster.py

#注释以下语句
#redis_store.set("name-new","daqiang")
#redis_store.set("money-new","8500")

创建while循环,使python脚本4秒运行一次。

while 2>1;
do
python3 redis-cluster.py
sleep 4s
done

将192.168.10.12:6378节点关闭,模拟故障,查看脚本运行情况。

/usr/local/redis/bin/redis-cli -c -h 192.168.10.12 -p 6378 shutdown

192.168.10.12:6378节点关闭后,python脚本无法获取数据报错,但是过了一会就又继续正常获取数据,再次证明Redis-Cluster 集群的高可用性。

本文于2020年11月10日由Vonmerlot整理。


版权声明:本文为qq_46680028原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。