文章目录
- Redis环境搭建
- 下载redis源码包
- 单机安装
- 源码编译
- 源码安装
- 第一种方式
- 第二种方式
- 集群安装(基于5.0.5)
- 主从复制集群
- 哨兵集群(sentinel)
- 集群Redis Cluster
- 集群的简单介绍:
- 集群的安装搭建
Redis环境搭建
下载redis源码包
下载库:
http://download.redis.io/releases/ 或者执行wget下载
没有wget需要先执行
//安装wget
yum install wget
//下载redis到当前目录
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
我这里下载的是redis-5.0.5.tar.gz
单机安装
源码编译
1. 将源码包上传到服务器或者wget下载,我这里是/opt
上传方式很多,可以用rz命令或者ftp工具,自己选
2. 解压源码包
tar -zxvf redis-5.0.5.tar.gz
3. 进入安装目录
cd redis-5.0.5
//执行编译
make
4. 执行make 会报错,需要依赖环境
按照提示安装依赖环境,然后安装
yum install gcc-c++ -y
再次在redis-5.0.5目录下执行make命令,仍然可能出现如下错误致命错误:jemalloc/jemalloc.h:没有那个文件或目录那么可以执行命令make MALLOC=libc解决
make MALLOC=libc
最后可以执行 make test 测试一下是否都是ok,如果有Error根据提示继续安装依赖环境即可.
到这里提示All tests passed without errors! 表示所有测试通过,那就可以执行安装了
源码安装
** 执行 make install PREFIX=你想要把redis安装到的目录**
//我安装在了/opt/redis目录
make install PREFIX=/opt/redis
第一种方式
执行完之后/opt/redis就会多出来一个bin目录,然后复制一份/opt/redis-5.0.5里边的redis.conf到/opt/redis
然后redis-5.0.5这些源码文件就可以删除了.以后操作的就是/opt/redis/bin里边的东西了.
到这里安装就结束了
启动redis
进入bin目录执行脚本即可
./redis-server …/redis.conf
但是这个不是以后台进程启动的,关掉以后也就退出了,需要修改配置文件
后台进程的方式启动
修改redis.conf的daemonize为yes即可
一般需要修改的配置有:
#开启远程访问需要用
bind 0.0.0.0
#关闭protected-mode模式,此时外部网络可以直接访问,如果开启protected-mode保护模式,需配置bind ip或者设置访问密码
protected-mode no
#以守护进程的方式运行redis
daemonize yes
然后进入bin目录重新启动即可
./redis-server …/redis.conf
如果想要停止服务,执行下边命令即可
./redis-cli shutdown
第二种方式
如果想把redis注册成服务,采用服务的方式运行,我这里以Centos7为例:
进入redis-5.0.5源码包的utils目录,有一个install_server.sh脚本,如下图
在utils目录下执行执行这个脚本,会提示如下信息:
./install_server.sh
6379这一行你可以输入自定义端口号
6379.conf这一行你可以输入自定义配置文件地址和配置文件名
redis_6379.log这一行你可以输入自定义日志文件位置和日志文件名
日志下边这一行你可以指定redis的lib位置,一般建议就在这放着直接按回车就行.
最后这一行是你redis实例的执行文件位置,也就是我前边编译到/opt/redis的可执行文件
例如:/opt/redis/bin/redis/redis-server
都输入完成之后一直敲回车即可安装完成.如果想采用默认的安装,执行这个脚本以后一直按回车,到executablee path这一行时指定你的编译位置的redis-server即可,然后一直回车到结束就可以了.
等这个脚本执行完成,那么redis会自动注册为系统服务,像第一种方式一样修改一下配置文件,默认的配置文件在/etc/redis/6379.conf,修改完成以后重启一下,可以像其他服务一样运行redis服务,比如说:
//启动redis服务,这个服务名默认为redis_端口号
systemctl start redis_6379
//停止redis服务
systemctl stop redis_6379
//重启服务
systemctl restart redis_6379
//设置开机自启动
systemctl enable redis_6379
//禁止开机自启动
systemctl disable redis_6379
到此单机安装完事,可以尽情的耍了,需要什么配置自己修改或添加即可…
6. bin目录脚本解析
脚本 | 含义 |
redis-benchmark | 性能测试工具 |
redis-check-aof | AOF文件检测工具 |
redis-check-rdb | RDB文件检测工具 |
redis-cli | Redis客户端 |
redis-sentinel -> redis-server | 服务器配置(集群) |
redis-server | Redis服务端 |
集群安装(基于5.0.5)
3.0之前不支持集群模式,只支持主从和哨兵,3.x到5.x之前,支持集群,但是通过ruby来搭建,5.x之后可以直接使用脚本创建集群,不需要ruby也可以轻松完成集群搭建.
主从复制集群
注释掉bind
daemonize yes
protected-mode no
slave配置
slaveof master的ip master的port
查看节点信息
info replication
查看同步过程
- replconf listening-port 6379
- sync
同步原理
slave在启动或重启时会发送一个sync包到master,master接收到sync包的时候会执行一个bgsave命令保存RDB快照,快照之后的命令会存在一个临时缓存中,等RDB发送给slave同步完之后slave会通过sync将没有保存到快照的命令同步过来执行,这个命令同步过程避免脏数据是通过slave-serve-stale-data yes来保证的
同步复制方式
- RDB文件复制
第一次连接或者重连的时候,master会在后台保存一个rdb快照,然后slave会接收这个RDB文件并且加载到当前的RDB数据库中,但是当master配置文件中禁用RDB模式的时候, 如果进行复制初始化操作,那么master依然会生成一个RDB文件,那么下一次启动的时候对这个RDB进行恢复的时候,会因为复制发生的时间点不确定导致数据会是任意时间点的RDB,也就造成了数据的错误 - 无磁盘复制(2.8以后)
repl-diskless-sync yes 不需要RDB文件复制,通过直接发送数据来进行恢复 - 增量复制
slave它会存储master运行时候的runid,每一个redis实例运行的时候都会拥有一个唯一的runid,然后再复制同步的时候master会把每一个命令发送到slave的同时,它会把命令存在一个内存缓冲区里边,并且记录当前存入这个命令的偏移量和偏移范围,slave接收到master传来的命令的时候它会记录这个命令的偏移量. 这种复制不会发送sync命令而是发送一个psync master run id命令,master会判断slave发送过来的runid是不是和它一样,在判断slave最后同步成功的偏移量是不是跟它内存缓冲区中同步成功的偏移量相等,如果都满足就进行offset增量复制
缺点:
master挂了就不能进行更新操作了,slave只提供读操作,不提供写操作,master挂了以后还可以读但是不能写了
哨兵集群(sentinel)
在主从的基础上加入一个哨兵节点,去监控master和slave,哨兵也可以是集群,他们会相互监控
- 监控master和slave是不是正常运行
- 当master挂掉以后会把其中一个slave升级为master
配置sentinel.conf
port不是6379,默认是26379
sentinel monitor mymaster 192.168.0.50 6379 2
sentinel monitor master名称 master的ip master的端口号 投票数(三个哨兵那就写2个,就一个哨兵那就写1个就完了)
sentinel down-after-milliseconds mymaster 30000 就是在指定时间内如果master没有响应那就说明master挂了
集群Redis Cluster
集群的简单介绍:
- 客户端连接redis集群的时候连接集群中的任意一个节点就可以了,redis集群内部的节点是相互通信(PING-PONG机制),每个节点都是一个redis实例.
- redis-cluster有一个投票容错机制来实现高可用,如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了.
- 如果集群中任意一个节点挂了,并且这个节点还没有从节点(备份节点),那么这个集群就挂了,因为redis集群是内置了16384个slot(哈希槽)的存储方式,并且把所有的物理节点映射到了这16384[0-16383]个哈希槽上,或者说把这些slot均等的分配给了各个节点,当需要在Redis集群存放一个数据的时候,redis会先对这个key进行crc16算法然后得到一个结果值,再把这个结果值对16384进行求余,这个余数会对应[0-16383]其中一个槽(类似负载均衡的取模),进而决定key-value存储到哪个节点上,所以一旦某个节点挂了并且还没有备份节点,那么该节点对应的slot就无法使用,自然也会导致集群无法正常工作,最终导致集群game over 了.
集群的安装搭建
- 上边说了,集群是靠投票过半来维持高可用的,既然投票自然1台或者2台就不完美了,所以集群部署最少也要6台,3台主3台从.
- 自我学习可以采用一台物理机多实例的方式搭建集群,生产环境建议三台或者直接6台
- 啥也不说了,直接上脚本,自己写的搭建脚本,有点shell基础的一看就懂,下边来说一下需要注意的,必须按照我说的执行,不然我不保证你可以顺利完成搭建.
> 注意点1: centos7.x的系统,低版本没有尝试,失败一般发生在编译redis源码的时候缺少依赖
> 注意点2: IPADDRS的服务器间通信必须正常,防火墙关闭或开放对应集群端口
> 注意点3: !!!!!! 必须在IPADDRS中的某一台服务器上用root账号执行此脚本 !!!!!!
执行时必须在此节点执行的命令: yum install sshpass -y
安装完成后不使用此脚本可以remove掉sshpass,自己决定
> 注意点4: EXEPATH指定的目录下不建议存在redis开头的任何文件夹,不然此脚本会影响你的
文件,删除集群时可能造成误删除.
> 注意点5: IPADDRS和PASSWORD的顺序必须一一对应,FIRSTPORT是每台服务器的起始端口号
安装几个实例取决于NODES参数,端口号以此递增
eg:NODES=3时 端口是6379 6380 6381
> 注意点6: 运行start时,redis集群创建存在交互,需要输入yes完成节点载入集群.
下边是完整脚本,此脚本默认安装的是5.0.5版本,可拿来直接使用!
#!/bin/bash
# Settings
#单台服务器起始端口号
FIRSTPORT=6379
#超时时间配置
TIMEOUT=2000
#单台服务器实例数
NODES=2
#master的备份节点数
REPLICAS=1
#服务器ip集合
IPADDRS=(192.168.92.30 192.168.92.31 192.168.92.32)
#服务器密码集合,与ip对应
PASSWORD=(root root root)
#实例安装根目录
EXEPATH=/opt
if [ -a config.sh ]
then
source "config.sh"
fi
#check for root user
#if [ "$(id -u)" -ne 0 ] ; then
# echo "You must run this script as root. Sorry!"
# exit 1
#fi
#安装redis集群依赖环境
if [ "$1" == "install" ]
then
for p in ${!IPADDRS[@]}; do
IPADDR=${IPADDRS[$p]}
echo -e "\033[43;31m install $IPADDR Start \033[0m"
sshpass -p ${PASSWORD[p]} ssh -o StrictHostKeychecking=no -n root@$IPADDR "yum install gcc-c++ tcl libstdc++-devel wget -y"
echo -e "\033[43;31m install $IPADDR End \033[0m"
done
exit 0
fi
#编译redis集群
if [ "$1" == "make" ]
then
for p in ${!IPADDRS[@]}; do
IPADDR=${IPADDRS[$p]}
echo -e "\033[43;31m download $IPADDR Start \033[0m"
sshpass -p ${PASSWORD[p]} ssh -o StrictHostKeychecking=no -n root@$IPADDR "cd $EXEPATH && wget http://download.redis.io/releases/redis-5.0.5.tar.gz && tar -zxf $EXEPATH/redis-5.0.5.tar.gz && rm -rf $EXEPATH/redis-5.0.5.tar.gz && cd $EXEPATH/redis-5.0.5 && make MALLOC=libc "
echo -e "\033[43;31m download $IPADDR End \033[0m"
for(( i=0;i<$NODES;i++)); do
PORT=$((FIRSTPORT+i))
echo -e "\033[43;31m make $IPADDR:$PORT Start \033[0m"
sshpass -p ${PASSWORD[p]} ssh -o StrictHostKeychecking=no -n root@$IPADDR "cd $EXEPATH/redis-5.0.5 && make install PREFIX=$EXEPATH/redis_$PORT && mkdir $EXEPATH/redis_$PORT/etc && mkdir $EXEPATH/redis_$PORT/pid && mkdir $EXEPATH/redis_$PORT/logs && mkdir $EXEPATH/redis_$PORT/data && cp $EXEPATH/redis-5.0.5/redis.conf $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '69c bind 0.0.0.0' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '88c protected-mode no' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '92c port $PORT' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '136c daemonize yes' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '158c pidfile $EXEPATH/redis_$PORT/pid/redis_$PORT.pid' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '171c logfile $EXEPATH/redis_$PORT/logs/redis.log' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '263c dir $EXEPATH/redis_$PORT/data' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '832c cluster-enabled yes' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '840c cluster-config-file $EXEPATH/redis_$PORT/etc/nodes_$PORT.conf' $EXEPATH/redis_$PORT/etc/redis.conf && sed -i '846c cluster-node-timeout $TIMEOUT' $EXEPATH/redis_$PORT/etc/redis.conf "
echo -e "\033[43;31m make $IPADDR:$PORT End \033[0m"
done;
sshpass -p ${PASSWORD[p]} ssh -o StrictHostKeychecking=no -n root@$IPADDR "rm -rf $EXEPATH/redis-5.0.5"
done
exit 0
fi
#运行集群
if [ "$1" == "start" ]
then
HOSTS=""
for p in ${!IPADDRS[@]}; do
IPADDR=${IPADDRS[$p]}
for(( i=0;i<$NODES;i++)); do
PORT=$((FIRSTPORT+i))
HOSTS="$HOSTS $IPADDR:$PORT"
echo -e "\033[43;31m Starting $IPADDR:$PORT Start \033[0m"
sshpass -p ${PASSWORD[$p]} ssh -o StrictHostKeychecking=no -n root@$IPADDR "$EXEPATH/redis_$PORT/bin/redis-server $EXEPATH/redis_$PORT/etc/redis.conf"
echo -e "\033[43;31m Starting $IPADDR:$PORT End \033[0m"
done;
done
echo -e "\033[43;31m create cluster: $HOSTS \033[0m"
$EXEPATH/redis_$FIRSTPORT/bin/redis-cli --cluster create $HOSTS --cluster-replicas $REPLICAS
exit 0
fi
#停止集群
if [ "$1" == "stop" ]
then
for p in ${!IPADDRS[@]}; do
IPADDR=${IPADDRS[$p]}
for(( i=0;i<$NODES;i++)); do
PORT=$((FIRSTPORT+i))
echo -e "\033[43;31m Stopping $IPADDR:$PORT Start \033[0m"
sshpass -p ${PASSWORD[$p]} ssh -o StrictHostKeychecking=no -n root@$IPADDR "$EXEPATH/redis_$PORT/bin/redis-cli -h $IPADDR -p $PORT shutdown nosave"
echo -e "\033[43;31m Stopping $IPADDR:$PORT End \033[0m"
done;
done
exit 0
fi
#删除集群
if [ "$1" == "delete" ];then
read -p "你确定要删除整个集群么?删除前请先stop,该操作会删除所有数据,输入[yes/no]?" input
echo $input
if [ $input = "yes" ];then
for p in ${!IPADDRS[@]}; do
IPADDR=${IPADDRS[$p]}
echo -e "\033[43;31m Delete $IPADDR:$PORT Start \033[0m"
sshpass -p ${PASSWORD[$p]} ssh -o StrictHostKeychecking=no -n root@$IPADDR "rm -rf redis-5.0.5.tar.gz && rm -rf redis-5.0.5 && rm -rf $EXEPATH/redis_*"
echo -e "\033[43;31m Delete $IPADDR:$PORT End \033[0m"
done
fi
exit 0
fi
echo "Usage: $0 [install|make|start|stop|delete|server]"
echo "install -- step1:yum安装redis-5.0.5集群所需要的环境,最好配置阿里的yum源"
echo "make -- step2:编译redis源码并初始化redis集群实例和配置"
echo "start -- step3:运行集群所有节点并构建成集群,注意要关闭防火墙或开放对应的端口"
echo "stop -- step4:停止集群所有节点"
echo "delete -- step5:删除整个集群所有数据(删除的是配置的个目录下所有以redis_开头的文件夹和源码包),删除前请先stop,谨慎操作!"