是一个高性能的
- Redis
数据库,现时越来越多企业与应用使用
- key-value
作为缓存服务器。楼主是一枚
- Redis
后端程序员,也算是半个运维工程师了。在
- JAVA
服务器上搭建
- Linux
,怎么可以不会呢?下面楼主就带着大家从0开始,依次搭建:
- Redis
单机服务器 ->
- Redis
主从复制 ->
- Redis
。逐步搭建出高可用的Redis缓存服务器。主要参考文章:简书:搭建一个redis高可用系统
- Redis-Sentinel高可用
楼主基于此文一步步参考着搭建,所以内容较为相似,感谢原文作者,特此申明。
首先从
官网下载
- Redis
并解压,楼主使用的版本是4.0.2。依次执行如下命令:
- Redis
- cd /usr/local/
- wget http://download.redis.io/releases/redis-4.0.2.tar.gz
- tar -zxvf redis-4.0.2.tar.gz
如果没有安装
依赖包,则安装对应依赖包
- gcc
- yum install - y gcc - c++tcl
下载并解压完毕后,则对源码包进行编译安装,楼主的
安装路径为
- Redis
,同学们可以自行修改语句:
- /usr/local/redis
- make install PREFIX=你想要安装的路径
- cd /usr/local/redis-4.0.2/
- make install PREFIX=/usr/local/redis
复制
相关命令到
- Redis
目录下,这样就可以直接执行这些命令,不用写全路径
- /usr/sbin
- cd /usr/local/redis/bin/
- sudo cp redis-cli redis-server redis-sentinel /usr/sbin/
安装完成之后将
配置文件拷贝到系统配置目录
- Redis
下,
- /etc/
是
- redis.conf
的配置文件,
- Redis
在
- redis.conf
源码目录,
- Redis
默认 6379。
- port
- cp / usr / local / redis - 4.0.2 / redis.conf / etc /
配置文件主要参数解析参考
- Redis
- daemonize no #redis进程是否以守护进程的方式运行,yes为是,no为否(不以守护进程的方式运行会占用一个终端)
- pidfile /var/run/redis.pid #指定redis进程的PID文件存放位置
- port 6379 #redis进程的端口号
- bind 127.0.0.1 #绑定的主机地址
- timeout 300 #客户端闲置多长时间后关闭连接,默认此参数为0即关闭此功能
- loglevel verbose #redis日志级别,可用的级别有debug.verbose.notice.warning
- logfile stdout #log文件输出位置,如果进程以守护进程的方式运行,此处又将输出文件设置为stdout的话,就会将日志信息输出到/dev/null里面去了
- databases 16 #设置数据库的数量,默认为0可以使用select <dbid>命令在连接上指定数据库id
- save <seconds> <changes> #指定在多少时间内刷新次数达到多少的时候会将数据同步到数据文件;
- rdbcompression yes #指定存储至本地数据库时是否压缩文件,默认为yes即启用存储;
- dbfilename dump.db #指定本地数据库文件名
- dir ./ #指定本地数据问就按存放位置;
- slaveof <masterip> <masterport> #指定当本机为slave服务时,设置master服务的IP地址及端口,在redis启动的时候他会自动跟master进行数据同步
- masterauth <master-password> #当master设置了密码保护时,slave服务连接master的密码;
- requirepass footbared #设置redis连接密码,如果配置了连接密码,客户端在连接redis是需要通过AUTH<password>命令提供密码,默认关闭
- maxclients 128 #设置同一时间最大客户连接数,默认无限制;redis可以同时连接的客户端数为redis程序可以打开的最大文件描述符,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
- maxmemory<bytes> #指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
- appendonly no #指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
- appendfilename appendonly.aof #指定跟新日志文件名默认为appendonly.aof
- appendfsync everysec #指定更新日志的条件,有三个可选参数no:表示等操作系统进行数据缓存同步到磁盘(快),always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全), everysec:表示每秒同步一次(折衷,默认值);
由于
默认是前端启动,必须保持在当前的窗口中,如果使用
- Redis
退出,那么
- ctrl + c
也就退出,不建议使用。
- Redis
- vi / etc / redis.conf
修改
配置文件把旧值
- Redis
改为 新值
- daemonize no
- daemonize yes
默认只允许本机访问,可是有时候我们也需要 Redis 被远程访问。
- Redis
- vi / etc / redis.conf
找到 bind 那行配置,默认是:
- # bind 127.0.0.1
去掉
注释并改为:
- #
此设置会变成允许所有远程访问。如果想指定限制访问,可设置对应的IP。
- bind 0.0.0.0
找到
那行配置,默认是:
- logfile
,改为
- logfile ""
- logfile /var/log/redis_6379.log
- vi / etc / redis.conf
找到默认是被注释的这一行:
- # requirepass foobared
去掉注释,把
改为你想要设置的密码,比如我打算设置为:
- foobared
,所以我改为:
- 123456
- requirepass "123456"
修改之后重启下服务
有了密码之后,进入客户端,就得这样访问:
- redis-cli -h 127.0.0.1 -p 6379 -a 123456
- /usr/local / redis / bin / redis - server / etc / redis.conf
- /usr/local / redis / bin / redis - cli - h 127.0.0.1 - p 6379 shutdown
- ps - ef | grep redis
- redis - cli
- redis - cli shutdown
- echo "/usr/local/redis/bin/redis-server /etc/redis.conf" >> /etc/rc.local
- 添加规则:iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT
- 保存规则:service iptables save
- 重启 iptables:service iptables restart
在/etc/init.d目录下添加Redis服务的启动,暂停和重启脚本:
- vi / etc / init.d / redis
脚本内容如下:
- #!/bin/sh
- #
- # redis - this script starts and stops the redis-server daemon
- #
- # chkconfig: - 85 15
- # description: Redis is a persistent key-value database
- # processname: redis-server
- # config: /usr/local/redis/bin/redis-server
- # config: /etc/redis.conf
- # Source function library.
- . /etc/rc.d/init.d/functions
- # Source networking configuration.
- . /etc/sysconfig/network
- # Check that networking is up.
- [ "$NETWORKING" = "no" ] && exit 0
- redis="/usr/local/redis/bin/redis-server"
- prog=$(basename $redis)
- REDIS_CONF_FILE="/etc/redis.conf"
- [ -f /etc/sysconfig/redis ] && . /etc/sysconfig/redis
- lockfile=/var/lock/subsys/redis
- start() {
- [ -x $redis ] || exit 5
- [ -f $REDIS_CONF_FILE ] || exit 6
- echo -n $"Starting $prog: "
- daemon $redis $REDIS_CONF_FILE
- retval=$?
- echo
- [ $retval -eq 0 ] && touch $lockfile
- return $retval
- }
- stop() {
- echo -n $"Stopping $prog: "
- killproc $prog -QUIT
- retval=$?
- echo
- [ $retval -eq 0 ] && rm -f $lockfile
- return $retval
- }
- restart() {
- stop
- start
- }
- reload() {
- echo -n $"Reloading $prog: "
- killproc $redis -HUP
- RETVAL=$?
- echo
- }
- force_reload() {
- restart
- }
- rh_status() {
- status $prog
- }
- rh_status_q() {
- rh_status >/dev/null 2>&1
- }
- case "$1" in
- start)
- rh_status_q && exit 0
- $1
- ;;
- stop)
- rh_status_q || exit 0
- $1
- ;;
- restart|configtest)
- $1
- ;;
- reload)
- rh_status_q || exit 7
- $1
- ;;
- force-reload)
- force_reload
- ;;
- status)
- rh_status
- ;;
- condrestart|try-restart)
- rh_status_q || exit 0
- ;;
- *)
- echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart| reload|orce-reload}"
- exit 2
- esac
赋予脚本权限
- chmod 755 / etc / init.d / redis
启动、停止和重启:
- service redis start
- service redis stop
- service redis restart
至此,
单机服务器已搭建完毕,下面我们看看主从架构如何搭建。
- Redis
- 172.16.2.185 : 6379主
- 172.16.2.181 : 6379从
配置文件,找到 210 行(大概),默认这一行应该是注释的:
- Redis
- # slaveof <masterip> <masterport>
,如果主机设置了密码,还需要找到
- slaveof 172.16.2.185 6379
这一行,去掉注释,改为
- masterauth <master-password>
。
- masterauth 主机密码
服务
- Redis
状态下
- redis-cli
,输入:
- redis-cli -h 127.0.0.1 -p 6379 -a 123456
可以查询到当前主机的
- INFO replication
处于什么角色,有哪些从机已经连上主机。
- Redis
主机信息
- 172.16.2.185
- # Replication
- role:master
- connected_slaves:1
- slave0:ip=172.16.2.181,port=6379,state=online,offset=28,lag=1
- master_replid:625ae9f362643da5337835beaeabfdca426198c7
- master_replid2:0000000000000000000000000000000000000000
- master_repl_offset:28
- second_repl_offset:-1
- repl_backlog_active:1
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:1
- repl_backlog_histlen:28
从机信息
- 172.16.2.181
- # Replication
- role:slave
- master_host:172.16.2.185
- master_port:6379
- master_link_status:up
- master_last_io_seconds_ago:3
- master_sync_in_progress:0
- slave_repl_offset:210
- slave_priority:100
- slave_read_only:1
- connected_slaves:0
- master_replid:625ae9f362643da5337835beaeabfdca426198c7
- master_replid2:0000000000000000000000000000000000000000
- master_repl_offset:210
- second_repl_offset:-1
- repl_backlog_active:1
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:1
- repl_backlog_histlen:210
状态,然后
- redis-cli
某个值,比如:
- set
- set myblog YouMeek.com
的状态下,获取刚刚设置的值看是否存在:
- redis-cli
,此时,我们可以发现是可以获取到值的。
- get myblog
做了备份,看上去很完美。但由于
- Redis
目前只支持主从复制备份(不支持主主复制),当主
- Redis
挂了,从
- Redis
只能提供读服务,无法提供写服务。所以,还得想办法,当主
- Redis
挂了,让从
- Redis
升级成为主
- Redis
。
- Redis
带有这个功能,当一个主
- Redis Sentinel
不能提供服务时,
- Redis
可以将一个从
- Redis Sentinel
升级为主
- Redis
,并对其他从
- Redis
进行配置,让它们使用新的主
- Redis
进行复制备份。
- Redis
注意:搭建
推荐至少3台服务器,但由于楼主偷懒,下面用例只用了2台服务器。
- Redis Sentinel
的主要功能如下:
- Redis Sentinel
和
- master
是否正常的运行。
- slave
实例发生问题时,可以通过
- Redis
通知系统管理员和其他的应用程序。
- API
不正常运行了,哨兵可以启动一个故障转移进程,将一个
- master
升级成为
- slave
,其他的
- master
被重新配置使用新的
- slave
,并且应用程序使用
- master
服务端通知的新地址。
- Redis
- Redis
- 172.16.2.185 : 6379主
- 172.16.2.181 : 6379从
- 172.16.2.185 : 26379
- 172.16.2.181 : 26379
- cp / usr / local / redis - 4.0.2 / sentinel.conf / etc /
- vi / etc / sentinel.conf
- protected-mode no
- sentinel monitor mymaster 172.16.2.185 6379 2
- # redis在搭建时设置了密码,所以要进行密码配置
- sentinel auth-pass mymaster “123456“
- #5秒内mymaster没有响应,就认为SDOWN
- sentinel down-after-milliseconds mymaster 5000
- sentinel failover-timeout mymaster 15000
- logfile /
- var / log / sentinel.log pidfile /
- var / run / sentinel.pid daemonize yes
- 添加规则:iptables -I INPUT -p tcp -m tcp --dport 26379 -j ACCEPT
- 保存规则:service iptables save
- 重启 iptables:service iptables restart
- redis - sentinel / etc / sentinel.conf
- redis - cli - h 127.0.0.1 - p 26379
- INFO sentinel
- # Sentinel
- sentinel_masters:1
- sentinel_tilt:0
- sentinel_running_scripts:0
- sentinel_scripts_queue_length:0
- sentinel_simulate_failure_flags:0
- master0:name=mymaster,status=ok,address=172.16.2.185:6379,slaves=1,sentinels=2
- redis - cli - h 172.16.2.185 - p 6379 - a 123456 shutdown
- # Sentinel
- sentinel_masters:1
- sentinel_tilt:0
- sentinel_running_scripts:0
- sentinel_scripts_queue_length:0
- sentinel_simulate_failure_flags:0
- master0:name=mymaster,status=ok,address=172.16.2.181:6379,slaves=1,sentinels=2
- protected-mode yes
- bind 172.16.2.185
- protected-mode yes
- bind 172.16.2.185
- protected-mode yes
- bind 172.16.2.185
- sentinel client - reconfig - script mymaster / opt / notify_mymaster.sh
- vi / opt / notify_mymaster.sh
- #!/bin/bash
- echo "File Name: $0"
- echo "Quoted Values: $@"
- echo "Quoted Values: $*"
- echo "Total Number of Parameters : $#"
- MASTER_IP=${6} #第六个参数是新主redis的ip地址
- LOCAL_IP='172.16.2.185' #当前服务器IP,主机172.16.2.185,从机172.16.2.181
- VIP='172.16.2.250'
- NETMASK='24'
- INTERFACE='eth1'
- if [ ${MASTER_IP} = ${LOCAL_IP} ]; then
- sudo /sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP绑定到该服务器上
- sudo /sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
- exit 0
- else
- sudo /sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP从该服务器上删除
- exit 0
- fi
- exit 1 #如果返回1,sentinel会一直执行这个脚本
- chmod 755 / opt / notify_mymaster.sh
- /sbin/ip addr add 172.16.2.250/24 dev eth1
- /sbin/arping -q -c 3 -A 172.16.2.250 -I eth1
- vi / etc / redis.conf
- vi / etc / sentinel.conf
- service redis restart`
- redis - sentinel / etc / sentinel.conf
- redis - cli - h 172.16.2.250 - p 6379 - a 123456 INFO replication
- # Replication
- role:master
- connected_slaves:1
- slave0:ip=172.16.2.181,port=6379,state=online,offset=0,lag=0
- master_replid:325b0bccab611d329d9c2cd2c35a1fe3c01ae196
- master_replid2:c1f7a7d17d2c35575a34b00eb10c8abf32df2243
- master_repl_offset:22246293
- second_repl_offset:22241024
- repl_backlog_active:1
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:22237293
- repl_backlog_histlen:9001
- redis - cli - h 172.16.2.250 - p 26379 INFO sentinel
- # Sentinel
- sentinel_masters:1
- sentinel_tilt:0
- sentinel_running_scripts:0
- sentinel_scripts_queue_length:0
- sentinel_simulate_failure_flags:0
- master0:name=mymaster,status=ok,address=172.16.2.185:6379,slaves=1,sentinels=3
- redis - cli - h 172.16.2.185 - p 6379 - a 123456 shutdown
- redis - cli - h 172.16.2.250 - p 26379 INFO sentinel
- # Sentinel
- sentinel_masters:1
- sentinel_tilt:0
- sentinel_running_scripts:0
- sentinel_scripts_queue_length:0
- sentinel_simulate_failure_flags:0
- master0:name=mymaster,status=ok,address=172.16.2.181:6379,slaves=1,sentinels=3
- redis - cli - h 172.16.2.250 - p 6379 - a 123456 INFO replication
- # Replication
- role:master
- connected_slaves:0
- master_replid:cab30a4083f35652053ffcd099d70b9aaf7a80f3
- master_replid2:3da856dd33cce4bedd54926df6797b410f1ab9e8
- master_repl_offset:74657
- second_repl_offset:36065
- repl_backlog_active:1
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:1
- repl_backlog_histlen:74657
来源: https://juejin.im/post/5a290d5af265da4304068425