带你来搭建虚拟机和Redis集群,记得收藏

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!
带你来搭建虚拟机和Redis集群,记得收藏 

点击上方 Java爱好者社区 关注我们吧!

带你来搭建虚拟机和Redis集群,记得收藏



1、前言


我们看到分析 Redis 使用或原理的文章不少,但是完整搭建一套独立的 Redis 集群环境的介绍,并不是很多或者说还不够详细。

那么,本文会手把手带着大家搭建一套 Redis 集群环境,Redis 集群在公司内部生产环境,大都是使用 Linux 操作系统搭建的。

所以,本文也带领大家搭建一套虚拟机环境,虚拟机中安装 Linux,常用的 Linux 操作系统如 Ubuntu、CentOS、Redhat等等。

正好我的笔记本上以前下载过 CentOS 镜像,所以咱们就使用 CentOS 来安装操作系统,步骤也很简单,下面会具体介绍。


2、虚拟机环境搭建


如果你在公司,也可以使用公司内部现成的虚拟机来安装,但是如果你不在公司了,因为公司环境本身的限制,可能你得连接公司的VPN才可以访问公司内的服务器,并不是很方便。

所以,不如自己本机搭建个虚拟机环境,只要有操作系统镜像,任由你安装,使用和管理起来都比较方便。

本人使用的 MAC OS,MAC OS 本身就是 Unix 内核的桌面版操作系统,所以如果你的电脑是 MAC,也可以直接搭建 Redis 集群了,但是目前来看大部分同学还是使用 Windows 操作系统的居多,考虑到这一点,还是安装个虚拟机更为方便。

虚拟机可以选择 Oracle 开源的免费虚拟机软件 VirtualBox,我在使用过程中目前暂时没有发现 MAC OS 上有什么问题。

下面介绍下 VirtualBox 的安装和配置步骤:

VirtualBox 很傻瓜式,非常简单的,鉴于有的人并不是都用过,所以这里也一并介绍下。

1)官网下载并安装

到官网下载对应你电脑操作系统的 VirtualBox 软件。

下载地址:https://www.virtualbox.org/wiki/Downloads

目前 OS X 的最新版本:VirtualBox-6.0.14-133895-OSX.dmg

下载后双击直接安装。

2)新建虚拟机

这里选择的「专家模式」创建,如果选择「向导模式」(默认),安装过程会有很多提示信息。

带你来搭建虚拟机和Redis集群,记得收藏

内存按照默认选择 1024M 创建,虚拟硬盘默认 VDI,指使用 VirtualBox 的磁盘镜像。

带你来搭建虚拟机和Redis集群,记得收藏

Linux 镜像默认虚拟硬盘大小为 8g,如果要安装 windows 虚拟机,虚拟硬盘大小默认建议申请 32g 的磁盘空间。

点击「创建」完成虚拟机的创建,此时还没有提示选择操作系统镜像的安装。

3)配置虚拟机

显示缩放率调整:

本人的电脑使用默认缩放率 100%,窗口很小,进入到全局设置中,点击「显示」调整缩放率如 200% 左右,你可以根据窗口大小自行调整。

带你来搭建虚拟机和Redis集群,记得收藏

虚拟机网卡配置:

进入「网络」,连接方式选择「桥接网卡」,注意当你换了 wifi 环境,需要重新配置网络 IP 等。

带你来搭建虚拟机和Redis集群,记得收藏

4)安装操作系统

新建完虚拟机,右侧界面上点击「启动」,界面如下所示:

带你来搭建虚拟机和Redis集群,记得收藏

选择本地准备好的 CentOS Linux 操作系统镜像文件,点击「创建」开始安装过程。

安装过程的注意点,选择语言,默认 English,时区选择 Asia Shanghai,选择 INSTALLATION DESTINATION 默认自动分区。

以上确定后,点击「Begin Installation」开始安装,下一步可以设置 root 账号密码。

完成安装后系统会自动重启,重启后输入刚刚设置的 root 密码登录,进入到虚拟机中。

5)虚拟机环境配置

编辑 ifcfg-enp0s3 文件:

vi /etc/sysconfig/network-scripts/ifcfg-enp0s3

# 修改ONBOOT为yes
ONBOOT=yes

设置静态 IP 地址:

# 默认dhcp修改为static
BOOTPROTO=static
# 静态IP地址
IPADDR=192.168.0.111
# 你的wifi网络子网掩码
NETMASK=255.255.255.0
# 你的wifi网络网关地址
GATEWAY=192.168.0.1

重启网络:

service network restart

配置 DNS:

# 检查 NetManager 状态:
systemctl status NetworkManager.service
# 检查 NetManager 管理的网络接口:
nmcli dev status
# 检查 NetManager 管理的网络连接:
nmcli connection show
# 设置 dns:
nmcli con mod enp0s3 ipv4.dns "114.114.114.114 8.8.8.8"
# 让 dns 配置生效:
nmcli con up enp0s3

配置 hosts:

编辑 hosts 文件,可以用于 ssh 免密配置。

vi /etc/hosts

# 本机 hosts 配置
192.168.0.111 host01
# 其他主机 hosts 配置
192.168.0.112 host02

关闭防火墙:默认开启,启动一些软件会导致网络无法互通

systemctl stop firewalld.service
systemctl disable firewalld.service

配置 yum:

yum 为软件包管理工具

yum clean all
# 服务器的包下载的本地缓存
yum makecache
yum install -y wget

此时,你登录到虚拟机中,执行 ifconfig 看不到网卡信息,net-tools 工具包安装一下。

yum install -y net-tools

安装 JDK:

安装方式很多,如果有 rpm 包,可以 wget 下载下来。

执行 rpm 安装命令:

rpm -ivh jdk-8u131-linux-x64.rpm

配置好 JDK 环境:

vi ~/ .bashrc
export JAVA_HOME=/usr/java/latest
export PATH=$PATH:$JAVA_HOME/bin
source .bashrc

检查安装是否成功:java -version 正常显示JDK版本信息表示安装正常。

6)其他虚拟机节点安装

VirtualBox 提供了虚拟机克隆功能,安装好一台虚拟机操作系统,通过「复制」快速的创建多台相同操作系统的虚拟机。

带你来搭建虚拟机和Redis集群,记得收藏

复制后修改下虚拟机名称,正常启动后,修改下静态 IP 地址和 hosts 配置,参考步骤5。

7)ssh 免密互信配置

ssh 互信配置后,可以通过 ssh 后跟 IP 或 主机名无需输入密码就能登录到服务器上去,运维过程中非常常用的一个配置。

执行命令:

# 生成本机的公私秘钥对
ssh-keygen -t rsa

将公钥复制为 authorized_keys 文件,此时使用 ssh 连接本机就不需要输入密码了。

cd /root/.ssh
cp id_rsa.pub authorized_keys

使用 ssh-copy-id -i hostname 命令将本机的公钥拷贝到指定机器的 authorized_keys 文件中。

比如你在 host01 机器上,以后就可以直接通过 ssh host02 命令登录到 host02 机器上了,不需要再次输入密码了。


3、Redis集群环境搭建


Redis 集群简介:

Redis 是一个开源的 key-value 分布式存储系统,由于其出众的性能,大部分互联网企业将其用来作为服务端分布式缓存使用。Redis 在 3.0 以前仅支持单实例模式,也支持主从模式、哨兵模式来达到高可用,避免单点故障。在 3.0 版本以后推出了集群模式,更好的满足业务需求。

Redis 集群采用 P2P 模式,完全去中心化。将所有 Key 分成了 16384 个 slot,每个 Redis 实例负责其中一部分 slot。集群节点之间定期同步数据保持数据一致性。然后,Redis 客户端可以向任一 Redis 实例发起请求,如果所需数据在该实例中不存在,则会通过重定向命令引导客户端访问所需的其他实例。


本文基于 Redis4.0.1 版本搭建集群。

当然,如果你有 Docker 或 K8S 环境,直接从镜像仓库拉取现成的 Redis 镜像后,通过一些参数配置启动后,就可以很快的搭建一套集群环境。

但这种方式使用对你来说是黑盒的,也就是安装过程你是了解不到的。

为了大家方便学习了解,我们还是使用原始的,通过安装包的形式来部署 Redis。

我们准备三台虚拟机,搭建一个三主三从的 Redis 集群。

带你来搭建虚拟机和Redis集群,记得收藏

Redis 目前最新版本到了 5.0.6,本次安装使用了 Redis4.0.1 版本,Redis4.0 版本也是目前很多企业在用的,经过生产环境大量验证的版本,比较稳定。

搭建集群过程如下:

1)下载并安装

下载安装包:

# wget下载安装包
wget http://download.redis.io/releases/redis-4.0.14.tar.gz
# 解压缩
tar xzf redis-4.0.14.tar.gz
# 重命名为redis,并拷贝到/usr/local目录
mv redis-4.0.14 redis
cp -r redis /usr/local

安装依赖包:

yum install -y tcl gcc zlib-devel openssl-devel

编译:

make MALLOC=libc

将常用命令添加到系统PATH:

cp -a /usr/local/redis/src/redis-server
/usr/local/redis/src/redis-cli
/usr/local/redis/src/redis-sentinel
/usr/local/redis/src/redis-trib.rb
/usr/local/redis/src/redis-check-aof
/usr/local/redis/src/redis-check-rdb
/usr/local/redis/src/redis-benchmark
/usr/local/bin/

这样就可以直接在服务器上任意目录使用命令了。

2)集群目录创建并添加配置

创建 Redis 集群目录:

mkdir -p /opt/redis-cluster/nodes-{7001,7002}

执行命令后,在 /opt/redis-cluster 目录会创建 nodes-7001 和 nodes-7002 两个目录。

在上述两个目录下新建 redis.conf 文件,添加文件内容:

# 当前机器IP地址绑定设置port
bind 192.168.0.111
# redis 监听端口
port 7001
# 使用 yes 启用守护进程
daemonize yes
# 当 Redis 以守护进程方式运行时,Redis 默认会把 pid
pidfile redis_7001.pid
# 日志记录级别,共4个级别:debug、verbose、notice(默认)、warning
loglevel notice
# 日志目录
logfile "/opt/redis-cluster/nodes-7001/redis_7001.log"
# 本地数据库存放目录
dir /opt/redis-cluster/nodes-7001/
# 保存节点配置,自动创建,自动更新
cluster-config-file nodes-7001.conf
# 通过upstart和systemd管理Redis守护进程,与具体的操作系统相关的
supervised no
# 每次更新操作后进行日志记录,默认:no
appendonly yes
# 开启集群模式
cluster-enabled yes
# 集群超时时间,节点超过这个时间没反应就断定是宕机
cluster-node-timeout 15000
# 多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
save 900 1
save 300 10
save 60 10000
# 本地数据库的名字
dbfilename dump.rdb
# 存储到本地文件开启压缩,默认:yes
rdbcompression yes
# 更新日志文件名
appendfilename "appendonly.aof"
# 指定更新日志条件:
# no: 等操作系统进行数据缓存同步到磁盘(快)
# always: 每次更新操作后手动调用 fsync() 将数据写磁盘(慢,安全)
# everysec: 每秒同步一次(折中,默认值)
appendfsync everysec
# 密码暂未设置,给出配置
# 当 master 服务设置了密码保护时,slav 服务连接 master 的密码
#masterauth
# 连接密码,客户端需使用AUTH <password>命令连接
#requirepass

此外,还有很多配置项,可自行查阅官网文档。

3)下载并安装 ruby

搭建 Redis 集群会使用到 redis-trib.rb 脚本来协助创建,所以需要依赖 ruby。

当然,三台虚拟机都可以安装,或者你选择其中一台虚拟机安装,并记住它,到时就从这台机器上执行命令来创建 Redis 集群。

我们使用的 Centos 7 操作系统,默认没有带 ruby,所以需要单独下载安装。

下载并安装 ruby:

# wget下载ruby安装包
wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.4.tar.gz
# 解压缩
tar xzf ruby-2.3.4.tar.gz
# 拷贝到/usr/local目录下,重命名为ruby目录
mv ruby-2.3.4 /usr/local/ruby
# 编译
cd /usr/local/ruby/ && ./configure && mark && make install
# 查看下安装的版本
ruby -v

如果你的 ruby 版本过低,卸载重装:

ruby -v
rpm -qa | grep ruby
yum erase ruby

安装 ruby-redis.gem:

# 安装 ruby-redis.gem
cd /usr/local/redis && gem install redis

安装过程如果报错如下:

ERROR: Loading command: install (LoadError) cannot load such file -- zlib ERROR: While executing gem ... (NoMethodError) undefined method invoke_with_build_args for nil:NilClass

解决办法:

cd /usr/local/ruby/ext/zlib
ruby extconf.rb
make && make install

再次执行 gem install redis,如果报错如下:

ERROR: While executing gem ... (Gem::Exception) Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources

解决办法:

cd /usr/local/ruby/ext/openssl
ruby extconf.rb
将上个步骤生成的MakeFile文件中的${top_srcdir}都替换为../..
make && make install

3)其他两台虚拟机上重复上述步骤1和2

请记得修改下 redis.conf 文件的端口:

不需要一个个端口修改,编辑文件

vi redis.conf

直接输入如下命令:

:%s/7001/7002/g

就可以批量将 7001 修改为 7002,然后输入 :wq! 退出保存。

4)创建 Redis 集群

使用 redis-trib.rb 脚本创建 Redis 集群,执行如下命令后,会自动分配集群中的 3 个 master 和 3 个 slave。

cd /usr/local/redis/src
./redis-trib.rb create --replicas 1 192.168.0.111:7001 192.168.0.111:7002 192.168.0.112:7001 192.168.0.112:7002 192.168.0.113:7001 192.168.0.113:7002

创建集群过程中遇到:

>>>Creating cluster [ERR] Sorry, can't connect to node 192.168.0.111:7001

解决办法:

关闭防火墙,上文中也已提到过。

安装集群执行结果示例:

带你来搭建虚拟机和Redis集群,记得收藏

输入yes,回车,如下示例:

带你来搭建虚拟机和Redis集群,记得收藏

我们从图中看到了,三个 M(Master)分配了三台虚拟机的 7001 端口,三个 S(Slave)分配了三台虚拟机的 7002 端口。

如果虚拟机重启后,需要再次创建 Redis 集群或者集群中新增节点,可能遇到如下问题:

 ./redis-trib.rb create --replicas 1 192.168.0.111:7001 192.168.0.111:7002 192.168.0.112:7001 192.168.0.112:7002 192.168.0.113:7001 192.168.0.113:7002
>>> Creating cluster
[ERR] Node 192.168.0.111:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

解决方法:

删除节点下面的 dump.rdb、appendonly.aof、nodes-7001.conf 文件,并重启 Redis。

cd /opt/redis-cluster/nodes-7001 && rm -rf dump.rdb appendonly.aof nodes-7001.conf 
cd /opt/redis-cluster/nodes-7002 && rm -rf dump.rdb appendonly.aof nodes-7002.conf
# 重启redis,开机自启动,下文中会有详细描述
service redis restart

如果是新增节点,除执行上述命令外,可能会需要登录到节点上删除数据库。

redis-cli -c -h 192.168.0.114 -p 7001
192.168.0.114:7001> flushall
OK

5)测试 Redis 集群

为了测试方便,暂时没有设置集群密码,在上文配置中也有提到了密码设置参数。

使用 redis-cli 客户端登录:

# 直接通过redis-cli命令连接
redis-cli -c -h 192.168.0.111 -p 7001
192.168.0.111:7001> set name zhangsan
-> Redirected to slot [5798] located at 192.168.0.112:7001
OK
192.168.0.112:7001> get name
"zhangsan"

找到其他节点任一 IP 和端口连接查询这个 key:

redis-cli -c -h 192.168.0.113 -p 7001
192.168.0.113:7001> get name
-> Redirected to slot [5798] located at 192.168.0.112:7001
"zhangsan"

说明我们测试的数据在集群之间同步完成了。

查看下集群配置信息:

# redis-cli命令连接节点
redis-cli -c -h 192.168.0.111 -p 7001
# 执行 CLUSTER nodes,看到了集群节点分配的信息
192.168.0.112:7001> CLUSTER nodes
f3b21c6377853c8da63ac6a55fecb1937715ec3b 192.168.0.111:7002@17002 slave 6e81b09991104bf09129aa2bbd226d94d3fcdbe7 0 1574004839302 3 connected
75dec349e2b7fcbcad4d5f5d7979aadefdf69514 192.168.0.113:7002@17002 slave d32ab53d8f93661b09a3c31513fce8c4ed6cbf2b 0 1574004838284 6 connected
6388d80cd9f0a1fbf03d0ac2a309cfedfdb79dc4 192.168.0.111:7001@17001 master - 0 1574004836251 1 connected 0-5460
59f25e64a8ab1fc3309e15d51ea630f439793a94 192.168.0.112:7002@17002 slave 6388d80cd9f0a1fbf03d0ac2a309cfedfdb79dc4 0 1574004840322 1 connected
d32ab53d8f93661b09a3c31513fce8c4ed6cbf2b 192.168.0.113:7001@17001 master - 0 1574004839000 5 connected 10923-16383
6e81b09991104bf09129aa2bbd226d94d3fcdbe7 192.168.0.112:7001@17001 myself,master - 0 1574004837000 3 connected 5461-10922
# 执行 CLUSTER info,看到集群自身的信息
192.168.0.112:7001> CLUSTER info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:3
cluster_stats_messages_ping_sent:1256
cluster_stats_messages_pong_sent:1275
cluster_stats_messages_meet_sent:3
cluster_stats_messages_sent:2534
cluster_stats_messages_ping_received:1273
cluster_stats_messages_pong_received:1259
cluster_stats_messages_meet_received:2
cluster_stats_messages_received:2534

6)设置开机自启动

由于咱们使用的虚拟机,不用的时候可以直接关机,避免一直占用着系统的资源。

当重启虚拟机的时候,如果你不嫌繁琐,可以登录到虚拟机里,直接运行 redis-server 命令启动服务。

更为优雅的方式,当然是开机后自动启动 Redis 服务,这也是生产环境上,研发或运维都必须要关注的,服务器重启,对应的服务也要跟着自动启动,而不需要人为手动干预了。

进入 /etc/init.d/ 目录,创建并编辑 redis 文件:

#!/bin/bash
#chkconfig: 22345 10 90
#description: Start and Stop redis

IP=`ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/'`

REDISPORT_1=7001
REDISPORT_2=7002

PIDFILE_1=/opt/redis-cluster/nodes-7001/redis_7001.pid
PIDFILE_2=/opt/redis-cluster/nodes-7002/redis_7002.pid
CONF_1="/opt/redis-cluster/nodes-7001/redis.conf"
CONF_2="/opt/redis-cluster/nodes-7002/redis.conf"

EXEC=/usr/local/redis/src/redis-server
CLIEXEC=/usr/local/redis/src/redis-cli

case "$1" in
start)
if [ -f $PIDFILE_1 ];then
echo "$PIDFILE_1 exists,process is already running or crashed"
else
echo "Starting Redis server... $CONF_1"
$EXEC $CONF_1
fi
if [ -f $PIDFILE_2 ];then
echo "$PIDFILE_2 exists,process is already running or crashed"
else
echo "Starting Redis server... $CONF_2"
$EXEC $CONF_2
fi
;;
stop)
if [ ! -f $PIDFILE_1 ];then
echo "$PIDFILE_1 does not exist,process is not running"
else
PID=$(cat $PIDFILE_1)
echo "Stopping..."
$CLIEXEC -h $IP -p $REDISPORT_1 shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown..."
sleep 1
done
echo "Redis stopped $CONF_1"
fi

if [ ! -f $PIDFILE_2 ];then
echo "$PIDFILE_2 does not exist,process is not running"
else
PID=$(cat $PIDFILE_2)
echo "Stopping..."
$CLIEXEC -h $IP -p $REDISPORT_2 shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown..."
sleep 1
done
echo "Redis stopped $CONF_2"
fi
;;
restart)
"$0" stop
sleep 3
"$0" start
;;
*)
echo "Please use start or stop or restart as first argument"
;;
esac

每台虚拟机有两个 Redis 端口 7001 和 7002,所以对上述脚本做了修改,如果一台机器就一个 Redis 服务就简单多了,大家可自行拷贝脚本修改。

Redis 文件修改为可执行文件:

chmod +x /etc/init.d/redis

添加到系统服务列表:

# 将 /etc/init.d/redis 添加到系统服务列表
chkconfig --add redis
# 设置开机自启动
chkconfig redis on
# 查看所有注册的脚本文件
chkconfig --list

然后,你就不需要去找 Redis 启动命令和配置文件了,方便管理和运维。

有点 low 的启动方式:

/usr/local/redis/src/redis-server /opt/redis-cluster/nodes-7001/redis.conf
/usr/local/redis/src/redis-server /opt/redis-cluster/nodes-7002/redis.conf

比较优雅的启动方式:

# 启动服务
service redis start
# 停止服务
service redis stop
# 重启服务
service redis restart

另外一种开机自启动方式:

将启动命令直接添加到 /etc/rc.d/rc.local 文件中。

修改 rc.local 文件为可执行文件,否则重启后不执行:

chmod +x /etc/rc.d/rc.local


4、小结


本文使用 VirtualBox 免费开源的虚拟机软件,一步一步来完成虚拟机环境的搭建。

然后基于三台虚拟机环境,搭建了一套 Redis 集群环境。

通过 redis-trib.rb 脚本来创建 Redis 集群环境,三台机器,6个通讯端口,自动构建为三主三从的集群架构。

根据执行 redis-trib.rb 脚本日志结果,自动分配IP的 Redis 集群架构如下所示:

带你来搭建虚拟机和Redis集群,记得收藏

对虚拟机安装配置和 Redis 集群安装配置过程中,遇到的问题给出了相应的解决办法,如果你安装过程中还遇到一些新的问题,也可以自行查询相关资料解决。

并且,从上述安装实践过程中,也能学习到很多常用的 Linux 命令。

大家自行搭建虚拟机或 Redis 集群环境时,可以#收藏#本文作为参考!



END

往期精选

通过一个生活中的案例场景,揭开并发包底层AQS的神秘面纱

由一次线上故障来理解下TCP三握、四挥 & Java堆栈分析到源码的探秘

有了 CompletableFuture,使得异步编程没有那么难了!

这个注册的 IP 网络都不通了,Eureka 注册中心竟然无法踢掉它!


这个场景下使用 Skywalking 调用链,发现 JVM 老年代内存没办法回收了!(下篇)


作为一名程序员,你真正了解CDN技术吗?

扫码关注,原创干货及时推送!


带你来搭建虚拟机和Redis集群,记得收藏


嗨,我就知道你在看!

原文始发于微信公众号(Java爱好者社区):带你来搭建虚拟机和Redis集群,记得收藏