在做redis-cluster群集之前,我已经安装好redis并做好sentinel了,所以,我关掉了之前启动的redis。
在做redis-cluster的时候,发现了之前版本使用的大多是memcache群集,因为它是另一种内存式数据库,因为它不能持久化的特点,所以公司并没有采用它。或者只能称之为缓存, 不能说它是库
1、创建redis节点
我们将在一台服务器上面创建6个节点,通过它们自主选举,会产生3个master和3个slave。
mkdir redis_cluster //创建集群目录
mkdir 7000 7001 7002 7003 7004 7005 //分别代表六个节点 其对应端口 7000 7001 7002 7003 7004 7005
#创建7000节点为例,
cd ./7000
cp /opt/redis/redis.conf ./ //拷贝到当前7000目录
vi redis.conf //编辑配置 主要修改一下几个参数
#包含通用配置
#include /opt/redis/redis-common.conf
daemonize yes # yes 为后台启动
pidfile /var/run/redis_7000.pid
port 7000 # 制定端口号 监听tcp端口
tcp-backlog 511
timeout 0
tcp-keepalive 0
loglevel notice
logfile ""
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
slave-serve-stale-data yes
slave-read-only yes #slave只读
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no #use default
slave-priority 100
#最大可用内存
#maxmemory 100m
#内存耗尽时采用的淘汰策略:
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key accordingly to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys-random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
maxmemory-policy allkeys-lru
appendonly yes #打开aof持久化
#aof存储文件
appendfilename "appendonly.aof"
appendfsync everysec #每秒一次aof写
no-appendfsync-on-rewrite no #关闭在aof rewrite的时候对新的写操作进行fsync
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
cluster-enabled yes #打开redis集群
cluster-config-file nodes-7000.conf #cluster配置文件(启动自动生成)
#部署在同一机器的redis实例,把auto-aof-rewrite搓开,防止瞬间fork所有redis进程做rewrite,占用大量内存
cluster-node-timeout 5000 #节点互连超时的阀值
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
配置好了,就相应地把这个修改后的配置文件拷贝到 7001 7002 7003 7004 7005目录,注意要修改为相应的监听端口,例:port 7001。
2、接下来,启动服务,进入节点目录
依次执行 redis-server redis.conf 就可以看到生成了appendonly.aof nodes.conf。
ps -ef | grep redis 查看是否启动成功
netstat -tnlp | grep redis 可以看到redis监听端口
我们除了看到 配置文件中设置的端口700* 还有700*+10000 (1700*), 前者是客户端访问的, 后者是集群内部节点之间访问的.
注意:在多台Server间搭建集群,如果开了防火墙的,需要设置iptables开放上面所有端口.
3、创建集群
官方提供了一个工具:redis-trib.rb 看后缀就知道这鸟东西不能直接执行,它是用ruby写的一个程序,所以我们还得安装ruby.
ubuntu安装ruby如下:
# sudo apt-get update
# sudo apt-get install ruby
或者
# sudo apt-get install ruby2.0
再用 gem 这个命令来安装 redis接口,gem貌似是ruby的一个工具包 反正没错就是了。
# gem install redis //等一会儿就好了
/opt/redis-3.0.0/src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7002
注意:127.0.0.1改为本机地址。
如果有报错,如下
解释下, --replicas 1 表示 自动为每一个master节点分配一个slave节点 上面有6个节点,程序会按照一定规则生成 3个master(主)3个slave(从)。前面已经提醒过的 防火墙一定要开放监听的端口,否则会创建失败。
如果不先开启相应的redis,则启动集群发现报错如下:
所以要先启动redis,再启动群集。
运行中,提示Can I set the above configuration? (type 'yes' to accept): yes //输入yes
4. 测试
1)get 和 set数据
redis-cli -c -p 7000
进入命令窗口,直接 set hello howareyou
直接根据hash匹配切换到相应的slot的节点上。
还是要说明一下,redis集群有16383个slot组成,通过分片分布到多个节点上,读写都发生在master节点。
2)假设测试
哥果断先把Server2服务Down掉,(Server2有1个Master, 2个Slave) , 跑回Server1, 查看一下 发生了什么事,Server1的3个节点全部都是Master,其他几个Server2的不见了
测试一下,依然没有问题,集群依然能继续工作。
原因: redis集群 通过选举方式进行容错,保证一台Server挂了还能跑,这个选举是全部集群超过半数以上的Master发现其他Master挂了后,会将其他对应的Slave节点升级成Master.
疑问: 要是挂的是Server1怎么办? 哥试了,cluster is down!! 没办法,超过半数挂了那救不了了,整个集群就无法工作了。 要是有三台Server,每台两Master,切记对应的主从节点
不要放在一台Server,别问我为什么自己用脑子想想看,互相交叉配置主从,挂哪台也没事,你要说同时两台crash了,呵呵哒......
3)关于一致性
我还没有这么大胆拿redis来做数据库持久化哥网站数据,只是拿来做cache,官网说的很清楚,Redis Cluster is not able to guarantee strong consistency.
4)项目中实践
项目是java的,选了 Jedis 这个开发包,哥先去跑跑看,就写到这里啦。有什么重大发现再续写喔。
2016.3.30
今天公司需要又搭建一套redis集群,而且一个是centos 另一个是ubuntu
在centos中,yum源里面的ruby没有更新,导致gem无法安装redis接口,从而无法进行集群操作。出现如下图的现象:
报错如上,通过公司的牛人,把这个弄好了,具体的我没有问。通过gem list发现有redis 3.xxx了,所以成功了。(牛人给的解决的网址 https://ruby.taobao.org/)
然后我继续弄,发现报错如下:
首先,我以为是像第一次安装一样出的错,于是我删了里面多余的东西,重启又重启,发现还是有问题。于是用1.143远程1.142的不同端口,发现报错如下:
解决1:把1.142写进1.143的hosts里面,还是没法解决。
解决2:我把selinux关掉,然后重启,发现还是没解决。
解决3:systemctl stop firewalld.service ,good ,问题解决。
总结解决办法,gem安装redis接口是必须,所以要保证源的正确性,也就是最新版的最好。然后必须关掉selinux和firewalld,就可以解决no route to host的问题了。
然而……
还是得把里面多出来的东西删了,然后重启,就ok了。
____________________________________________________________________________________________________________________________________
redis-cluster需要正常运行至少需要3个主几点,不然会报如下的错误: