搭建一个高可用的redis环境
一.环境准备
我的环境: Fedora 25 server 64位版 6台:
192.168.10.204
192.168.10.205
192.168.10.206
192.168.10.203
192.168.10.207
192.168.10.208
redis版本:3.2.9
二.Redis单机的安装
为了方便,我自己都用root用户
官方下载地址:
https://redis.io/download,这里我安装在/usr/local/redis这个目录,官网安装参考如下:
cd /usr/local
mkdir redis
cd redis
wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar xzf redis-3.2..tar.gz
cd redis-3.2.
make
执行时发现报了2个错,如下:
cd src && make all
make[1]: Entering directory '/usr/local/redis/redis-3.2.9/src'
rm -rf redis-server redis-sentinel redis-cli redis-benchmark redis-check-rdb redis-check-aof *.o *.gcda *.gcno *.gcov redis.info lcov-html
(cd ../deps && make distclean)
make[2]: Entering directory '/usr/local/redis/redis-3.2.9/deps'
(cd hiredis && make clean) > /dev/null || true
(cd linenoise && make clean) > /dev/null || true
(cd lua && make clean) > /dev/null || true
(cd geohash-int && make clean) > /dev/null || true
(cd jemalloc && [ -f Makefile ] && make distclean) > /dev/null || true
(rm -f .make-*)
make[2]: Leaving directory '/usr/local/redis/redis-3.2.9/deps'
(rm -f .make-*)
echo STD=-std=c99 -pedantic -DREDIS_STATIC='' >> .make-settings
echo WARN=-Wall -W >> .make-settings
echo OPT=-O2 >> .make-settings
echo MALLOC=jemalloc >> .make-settings
echo CFLAGS= >> .make-settings
echo LDFLAGS= >> .make-settings
echo REDIS_CFLAGS= >> .make-settings
echo REDIS_LDFLAGS= >> .make-settings
echo PREV_FINAL_CFLAGS=-std=c99 -pedantic -DREDIS_STATIC='' -Wall -W -O2 -g -ggdb -I../deps/geohash-int -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src -DUSE_JEMALLOC -I../deps/jemalloc/include >> .make-settings
echo PREV_FINAL_LDFLAGS= -g -ggdb -rdynamic >> .make-settings
(cd ../deps && make hiredis linenoise lua geohash-int jemalloc)
make[2]: Entering directory '/usr/local/redis/redis-3.2.9/deps'
(cd hiredis && make clean) > /dev/null || true
(cd linenoise && make clean) > /dev/null || true
(cd lua && make clean) > /dev/null || true
(cd geohash-int && make clean) > /dev/null || true
(cd jemalloc && [ -f Makefile ] && make distclean) > /dev/null || true
(rm -f .make-*)
(echo "" > .make-cflags)
(echo "" > .make-ldflags)
MAKE hiredis
cd hiredis && make static
make[3]: Entering directory '/usr/local/redis/redis-3.2.9/deps/hiredis'
gcc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb net.c
make[3]: gcc: Command not found
Makefile:118: recipe for target 'net.o' failed
make[3]: *** [net.o] Error 127
make[3]: Leaving directory '/usr/local/redis/redis-3.2.9/deps/hiredis'
Makefile:46: recipe for target 'hiredis' failed
make[2]: *** [hiredis] Error 2
make[2]: Leaving directory '/usr/local/redis/redis-3.2.9/deps'
Makefile:156: recipe for target 'persist-settings' failed
make[1]: [persist-settings] Error 2 (ignored)
CC adlist.o
/bin/sh: cc: command not found
Makefile:211: recipe for target 'adlist.o' failed
make[1]: *** [adlist.o] Error 127
make[1]: Leaving directory '/usr/local/redis/redis-3.2.9/src'
Makefile:6: recipe for target 'all' failed
make: *** [all] Error 2
其中一个是缺少gcc编译环境,那就安装gcc, 执行:
dnf -y install gcc
发现又出现了错误:
[root@localhost redis-3.2.9]# make
cd src && make all
make[1]: Entering directory '/usr/local/redis/redis-3.2.9/src'
CC adlist.o
In file included from adlist.c:34:0:
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory
#include <jemalloc/jemalloc.h>
^
compilation terminated.
Makefile:211: recipe for target 'adlist.o' failed
make[1]: *** [adlist.o] Error 1
make[1]: Leaving directory '/usr/local/redis/redis-3.2.9/src'
Makefile:6: recipe for target 'all' failed
make: *** [all] Error 2
关于这个错误,网上很多小伙伴都碰到过,也都有解答。
也就是安装时需要指定MALLOC这个参数,google一下,这个参数是用于管理内存的,官方推荐使用jemalloc,解释说jemalloc比libc会有更少的碎片问题 , redis安装包里面的README.MD文件有这么一段:
Allocator
--------- Selecting a non-default memory allocator when building Redis is done by setting
the `MALLOC` environment variable. Redis is compiled and linked against libc
malloc by default, with the exception of jemalloc being the default on Linux
systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc. To force compiling against libc malloc, use: % make MALLOC=libc To compile against jemalloc on Mac OS X systems, use: % make MALLOC=jemalloc Verbose build
也就是说, 因为redis默认使用jemalloc做内存管理,但是系统没有自带这个库,对于这个库我个人不是太清楚,既然推荐用这个内存分配库,那就安装吧
先创建安装目录,再下载资源包 jemalloc 的源代码托管在github(https://github.com/jemalloc/jemalloc)上,但是我这连不上亚马逊仓库,下载不下来,就直接从另一个站点下载了,这个站点没有最新的5.0版本。
cd /usr/local
mkdir jemalloc
cd jemalloc
wget http://www.canonware.com/download/jemalloc/jemalloc-4.2.1.tar.bz2 解压: tar xjf jemalloc-4.2..tar.bz2
下面安装到/usr/local/jemalloc这个目录,进入解压目录执行:
./configure make & make install
执行完,发现解压目录多了个lib目录,说明jemalloc这个库安装成功了。
安装完成,再次切换到redis解压目录,执行时 指定这个库的位置:
make MALLOC=/usr/local/jemalloc/jemalloc-4.2.1/lib
这样等待它安装完成。
或者如果不想用jemalloc内存管理,嫌麻烦,就指定使用libc去管理内存,如下执行:
make MALLOC=libc
上面二者选其一即可,然后控制台上一系列日志啪啪啪的打,直到安装完成没有再次出现问题就说明安装成功了
至此单台redis安装完了。
重复上面的安装,依次在其他机器都安装。
三.搭建Cluster多机环境
首先在每一台机器上创建一个目录,用于存放Cluster中每一台redis产生的配置文件nodes.conf文件,为了方便查看,把redis启动的redis.conf文件也放在这,日志文件,产生的数据文件也放在这
这里我分别在六台机器上创建目录,并将安装目录下的redis.conf文件分别拷到这个目录:
cd /usr/local/redis
mkdir redis-cluster
cd redis-cluster
cp /usr/local/redis/redis-3.2./redis.conf ./
编辑redis.conf , 去掉多余的配置,如我的204这台机器的配置文件内容如下:
#取消保护模式,,默认是yes,组织redis-cli 等其他客户端连接
protected-mode no(必须)
#对外端口
port (必须)
#是否以守护进程启动 跟命令行后面加个&一个意思
daemonize yes(可选)
#指定进程的pid路径(可选)
pidfile /var/run/redis_7001.pid #支持cluster的配置
cluster-enabled yes(必须)
#这就是刚才创建的目录,存放node.conf,这个文件是redis启动时自动生成的
cluster-config-file /usr/local/redis/redis-cluster/nodes.conf(必须)
#节点与节点之间连接不上的超时时间ms(必须)
cluster-node-timeout
依次编辑其他机器上的配置如上,修改对应的端口,进程pid的路径即可我的分别是7001,7002,7003,7004,7005,7006
编辑好配置文件,就可以启动每台机器的redis了
cd /usr/local/redis/redis-3.2./src ./redis-server /usr/local/redis/redis-cluster/redis.conf #检查一下是否启动成功:
ps -eaf | grep redis
出现的状态与单机启动redis不同,后面多了个【cluster】,端口开放:7001说明启动成功了
ps -eaf | grep redis
root 1246 1 0 00:36 ? 00:00:00 ./redis-server *:7001 [cluster]
root 1250 1083 0 00:37 pts/0 00:00:00 grep --color=auto redis
依次启动其他5台机器。
这里测试一下机器的端口是否开发,在208这台机器上用redis提供的客户端连接204的server
cd /usr/local/redis/redis-3.2./src
#-h参数是要连接的redis server的主机ip, -p参数是要连接的redis server的主机开放的端口
./redis-cli -h 192.168.10.204 -p
出现了:
# ./redis-cli -h 192.168.10.204 -p 7001
Could not connect to Redis at 192.168.10.128:6379: No route to host
Could not connect to Redis at 192.168.10.128:6379: No route to host
说明了从208连接到204的7001端口是行不通的,检查是否能ping通:
ping 192.168.10.204
结果是通的。猜想是204这台机器防火墙没有开放7001端口,因为之前编辑配置文件是改了protected-mode 这个参数的。执行下面的命令,开放7001端口:
iptables -I INPUT -p tcp --dport -j ACCEPT
再次从208的客户端连接到204的7001,发现是OK的。
最后将这些节点加入的cluster中,还是参考官方文档:
Creating the cluster
Now that we have a number of instances running, we need to create our cluster by writing some meaningful configuration to the nodes.
This is very easy to accomplish as we are helped by the Redis Cluster command line utility called redis-trib, a Ruby program executing special commands on instances in order to create new clusters,
check or reshard an existing cluster, and so forth.
The redis-trib utility is in the src directory of the Redis source code distribution. You need to install redis gem to be able to run redis-trib.
gem install redis
这一段说创建一个redis cluster需要 安装ruby,它是通过ruby的一个gems的插件去执行的,同时安装ruby和这个插件,还有这个插件写的redis创建cluster的工具:
dnf -y install ruby rubygems gem install redis
安装完成,最后切换到任意一台机器上进入redis安装目录的src 目录下执行:
官方解释说 -- replicas 后面的参数 1 是 给每一个master分配一个slaver
./redis-trib.rb create --replicas 192.168.10.204: 192.168.10.205: 192.168.10.206: 192.168.10.203: 192.168.10.207: 192.168.10.208:
出现 下图,默认将前三台服务器分配为Master:
输入yes,等待加入Cluster
这里会一直出现等待加入Cluster,如下:
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join.....................................................
出现这个问题的原因是redis服务器防火墙没有开放cluster所需要的端口,去官网 教程(点我查看) 一查,果然有这么一段儿描述:
Redis Cluster TCP ports
Every Redis Cluster node requires two TCP connections open. The normal Redis TCP port used to serve clients, for example 6379,
plus the port obtained by adding 10000 to the data port, so 16379 in the example.
This second high port is used for the Cluster bus, that is a node-to-node communication channel using a binary protocol.
The Cluster bus is used by nodes for failure detection, configuration update, failover authorization and so forth.
Clients should never try to communicate with the cluster bus port, but always with the normal Redis command port,
however make sure you open both ports in your firewall, otherwise Redis cluster nodes will be not able to communicate.
The command port and cluster bus port offset is fixed and is always 10000.
Note that for a Redis Cluster to work properly you need, for each node:
The normal client communication port (usually 6379) used to communicate with clients to be open to all the clients that need to reach the cluster,
plus all the other cluster nodes (that use the client port for keys migrations).
The cluster bus port (the client port + 10000) must be reachable from all the other cluster nodes.
If you don't open both TCP ports, your cluster will not work as expected.
The cluster bus uses a different, binary protocol, for node to node data exchange, which is more suited to exchange information between nodes using little bandwidth and processing time.
意思是说在Cluster环境,每个节点不仅要对外开放客户端连接的端口,还需要开放一个用于Cluster通信的端口,这个端口一般是对外客户端端口 加上10000,如:节点对外端口,我这里是7001 ,需要把 17001这个端口开放,于是在防火墙里增加端口开放:
分别对应每一台节点执行:
在192.168.10.204上 执行:
iptables -I INPUT -p tcp --dport -j ACCEPT
在192.168.10.205上 执行:
iptables -I INPUT -p tcp --dport -j ACCEPT
在192.168.10.206上 执行:
iptables -I INPUT -p tcp --dport -j ACCEPT
在192.168.10.203上 执行:
iptables -I INPUT -p tcp --dport -j ACCEPT
在192.168.10.207上 执行:
iptables -I INPUT -p tcp --dport -j ACCEPT
在192.168.10.208上 执行:
iptables -I INPUT -p tcp --dport -j ACCEPT
再次进入其中的一台,进入src目录执行:
./redis-trib.rb create --replicas 192.168.10.204: 192.168.10.205: 192.168.10.206: 192.168.10.203: 192.168.10.207: 192.168.10.208:
出现:
>>> Creating cluster
>>> Performing hash slots allocation on nodes...
Using masters:
192.168.10.204:
192.168.10.205:
192.168.10.206:
Adding replica 192.168.10.203: to 192.168.10.204:
Adding replica 192.168.10.207: to 192.168.10.205:
Adding replica 192.168.10.208: to 192.168.10.206:
M: 3335ad139839a644ea593942fd02c2df1dca3d24 192.168.10.204:
slots:- ( slots) master
M: e359b1d676fafc49de2c2ce22ad8052cbc4c8c34 192.168.10.205:
slots:- ( slots) master
M: 727ddc5d4349007824cb8a382feeda699a8727f8 192.168.10.206:
slots:- ( slots) master
S: e99c70d79d1ecc062e0f0beec6c413b0cb679d1a 192.168.10.203:
replicates 3335ad139839a644ea593942fd02c2df1dca3d24
S: 57479c4575f718417e68aee3d25ae75fcfc2cfdb 192.168.10.207:
replicates e359b1d676fafc49de2c2ce22ad8052cbc4c8c34
S: b19f429b3815ca6e69115e1d40c380e09908a3c4 192.168.10.208:
replicates 727ddc5d4349007824cb8a382feeda699a8727f8
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 192.168.10.204:)
M: 3335ad139839a644ea593942fd02c2df1dca3d24 192.168.10.204:
slots:- ( slots) master
additional replica(s)
S: b19f429b3815ca6e69115e1d40c380e09908a3c4 192.168.10.208:
slots: ( slots) slave
replicates 727ddc5d4349007824cb8a382feeda699a8727f8
S: e99c70d79d1ecc062e0f0beec6c413b0cb679d1a 192.168.10.203:
slots: ( slots) slave
replicates 3335ad139839a644ea593942fd02c2df1dca3d24
M: e359b1d676fafc49de2c2ce22ad8052cbc4c8c34 192.168.10.205:
slots:- ( slots) master
additional replica(s)
S: 57479c4575f718417e68aee3d25ae75fcfc2cfdb 192.168.10.207:
slots: ( slots) slave
replicates e359b1d676fafc49de2c2ce22ad8052cbc4c8c34
M: 727ddc5d4349007824cb8a382feeda699a8727f8 192.168.10.206:
slots:- ( slots) master
additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All slots covered.
大概经过2s到3s,会出现上图,将16384个slots分配到6台机器上,至此cluster环境搭好了,来检查一下状态,随便选一台服务器,用redis自带的redis-cli客户端连上一台机,用 cluster info ,cluster nodes看一下结果:
./redis-cli -h 192.168.10.207 -p 192.168.10.207:> cluster info
cluster_state:ok
cluster_slots_assigned:
cluster_slots_ok:
cluster_slots_pfail:
cluster_slots_fail:
cluster_known_nodes:
cluster_size:
cluster_current_epoch:
cluster_my_epoch:
cluster_stats_messages_sent:
cluster_stats_messages_received:
192.168.10.207:> cluster nodes
57479c4575f718417e68aee3d25ae75fcfc2cfdb 192.168.10.207: myself,slave e359b1d676fafc49de2c2ce22ad8052cbc4c8c34 connected
3335ad139839a644ea593942fd02c2df1dca3d24 192.168.10.204: master - connected -
e99c70d79d1ecc062e0f0beec6c413b0cb679d1a 192.168.10.203: slave 3335ad139839a644ea593942fd02c2df1dca3d24 connected
727ddc5d4349007824cb8a382feeda699a8727f8 192.168.10.206: master - connected -
b19f429b3815ca6e69115e1d40c380e09908a3c4 192.168.10.208: slave 727ddc5d4349007824cb8a382feeda699a8727f8 connected
e359b1d676fafc49de2c2ce22ad8052cbc4c8c34 192.168.10.205: master - connected -
说明Cluster搭建成功了, 不放心,写一条数据测试一下:
192.168.10.207:> set testKey testValue
(error) MOVED 192.168.10.204:
192.168.10.207:> set a b
(error) MOVED 192.168.10.206:
192.168.10.207:>
看来不放心是对的,连续写进2个值都报错了。OK ,还是看官网:
$ redis-cli -c -p
redis 127.0.0.1:> set foo bar
-> Redirected to slot [] located at 127.0.0.1:
OK
redis 127.0.0.1:> set hello world
-> Redirected to slot [] located at 127.0.0.1:
OK
redis 127.0.0.1:> get foo
-> Redirected to slot [] located at 127.0.0.1:
"bar"
redis 127.0.0.1:> get hello
-> Redirected to slot [] located at 127.0.0.1:
"world"
嗯,多了个参数 -c ,一查,一看c 肯定就是cluster的简写,这意思肯定是在Cluster模式下操作redis 得以Cluster的方式连接.OK ,再来:
./redis-cli -c -h 192.168.10.203 -p
192.168.10.203:> set a a.value
-> Redirected to slot [] located at 192.168.10.206:
OK
192.168.10.206:> get a
"a.value"
192.168.10.206:>
这下就真的放心了,至此整个Cluster高可用环境搭建好了.
搭建一个高可用的redis环境的更多相关文章
- SpringCloud学习系列之一 ----- 搭建一个高可用的注册中心(Eureka)
前言 本篇主要介绍的是SpringCloud相关知识.微服务架构以及搭建一个高可用的服务注册与发现的服务模块(Eureka). SpringCloud介绍 Spring Cloud是在Spring B ...
- 阿里云有奖体验:用PolarDB-X搭建一个高可用系统
体验简介 场景将提供一台配置了CentOS 8.5操作系统和安装部署PolarDB-X集群的ECS实例(云服务器).通过本教程的操作,带您体验如何使用PolarDB-X搭建一个高可用系统,通过直接ki ...
- 三分钟快速搭建分布式高可用的Redis集群
这里的Redis集群指的是Redis Cluster,它是Redis在3.0版本正式推出的专用集群方案,有效地解决了Redis分布式方面的需求.当单机内存.并发.流量等遇到瓶颈的时候,可以采用这种Re ...
- Nginx系列篇四:Nginx+keepalived搭建一个高可用的双机双主热备
建议:先阅读Nginx+keepalived主从配置,因为此篇是接着上篇开始的 上一篇我们简单的介绍了主从配置及其缺点,我们看一下双主热备配置: 2台Nginx+keepalived互为主备,各自绑定 ...
- 基于CentOS 8服务器来搭建FastDFS高可用集群环境
服务器版本 我们在服务器的命令行输入如下命令来查看服务器的内核版本. [root@localhost lib]# cat /etc/redhat-release CentOS Linux releas ...
- 搭建高可用的Redis服务,需要注意这些方面!
搭建高可用的Redis服务,需要注意这些方面! HorstXu 占小狼的博客 今天 ◎作者 | HorstXu www.cnblogs.com/xuning/p/8464625.html 基于内存的R ...
- Apache httpd和JBoss构建高可用集群环境
1. 前言 集群是指把不同的服务器集中在一起,组成一个服务器集合,这个集合给客户端提供一个虚拟的平台,使客户端在不知道服务器集合结构的情况下对这一服务器集合进行部署应用.获取服务等操作.集群是企业应用 ...
- Nginx+Keepalived(双机热备)搭建高可用负载均衡环境(HA)
原文:https://my.oschina.net/xshuai/blog/917097 摘要: Nginx+Keepalived搭建高可用负载均衡环境(HA) http://blog.csdn.ne ...
- Nginx+Keepalived(双机热备)搭建高可用负载均衡环境(HA)-转帖篇
原文:https://my.oschina.net/xshuai/blog/917097 摘要: Nginx+Keepalived搭建高可用负载均衡环境(HA) http://blog.csdn.ne ...
随机推荐
- Session Timeout 与 $.ajaxSetup
对于session过期跳转的问题,很简单,就是一个过滤器,然后判断session为空?跳转:继续.但是对于ajax的请求,需要做特殊处理,见下面代码中的 // 此处考虑ajax操作session过期的 ...
- 求a + aa + aaa + aaaa + aaaaa ...的值,例如:1 + 11 + 111,2 + 22 + 222 + 2222 + 22222
#include <stdio.h> unsigned superposition(unsigned m, unsigned n); int main() { printf("1 ...
- [翻译]Unity中的AssetBundle详解(三)
构建AssetBundles 在AssetBundle工作流程的文档中,我们有一个示例代码,它将三个参数传递给BuildPipeline.BuildAssetBundles函数.让我们更深入地了解我们 ...
- HDU4289 Control —— 最小割、最大流 、拆点
题目链接:https://vjudge.net/problem/HDU-4289 Control Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- vue开发购物车,解决全选单选问题
实现全选单选,在vue中无法通过this获取input中的checkbox的checked属性,但是可以通过vue对input的特殊方式v-model来实现对应数据的绑定,同样也可以通过这种方式实现购 ...
- codeforces 690C1 C1. Brain Network (easy)(水题)
题目链接: C1. Brain Network (easy) time limit per test 2 seconds memory limit per test 256 megabytes inp ...
- Centos Missing Library: QtWebKit.so.4
/******************************************************************** * Centos Missing Library: QtWe ...
- html&css题
1.对WEB标准以及W3C的理解与认识?(1)web标准规范要求,书写标签必须闭合.标签小写.不乱嵌套,可提高搜索机器人对网页内容的搜索几率:(2)建议使用外链css和js脚本,从而达到结构与行为.结 ...
- this调用属性
示例: class Person{ private String name; private int age; public Person(String name,int age){ this.nam ...
- LNMP+Zabbix的安装与部署
LNMP+Zabbix的安装与部署 一.Zabbix简介 1.zabbix是一个基于WEB界面的,并提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务 ...