Redis集群原理与搭建

Redis 集群和主从不同,是把所有的数据按照算法分布在每一个节点上。

toc
这里分别使用第三方 Twemproxy 和官方 Cluster 集群工具搭建

  • Twemproxy
    • 优点:代理的方式,不用Redis相应的设置,对持久化不友好,适合做纯缓存
    • 缺点:当添加、删除或者修改节点时,需要重新导入所有的数据。
  • Cluster
    • 优点:没有服务端,可以在任意节点进入集群,主从自动切换
    • 缺点:需要集群自行处理数据。节点之间通信,使用带宽大

Redis集群之Twemproxy(nutcracker)

Twemproxy 是Twitter开源的一个 RedisMemcache 集群工具
Twemproxy 后端的redis服务器不需要额外的配置,Twemproxy 会通过hash算法选择某个配置的后端 Redis 服务器去分配 key
Twemproxy 只有一个库,集群不支持多库
Twemproxy 不支持所有的 Redis 命令:
Twemproxy和Redis命令兼容性列表

Twemproxy 编译安装

Master1和Master2分别安装Redis并启动,不做主从

## 安装Twemproxy和使用过程需要的YUM包
[root@Twemproxy ~]# yum install gcc wget unzip libtool autoconf -y
## 下载Twemproxy源码包
[root@Twemproxy ~]# wget https://codeload.github.com/twitter/twemproxy/zip/master
## 解压Twemproxy源码包
[root@Twemproxy ~]# unzip master
## 进入到Twemproxy源码包
[root@Twemproxy ~]# cd twemproxy-master/
## 安装Twemproxy源码包
[root@Twemproxy twemproxy-master]# CFLAGS="-ggdb3 -O0" autoreconf -fvi
[root@Twemproxy twemproxy-master]# ./configure --prefix=/soft/twemproxy --enable-debug=log
[root@Twemproxy twemproxy-master]# make && make install
## 查看Twemproxy软件版本
[root@Twemproxy twemproxy-master]# /soft/twemproxy/sbin/nutcracker -V
This is nutcracker-0.4.1

配置Twemproxy

## 创建相应的目录
[root@Twemproxy ~]# mkdir -p /soft/twemproxy/{conf,log}
## 写入配置文件(遵循YAML格式)
[root@Twemproxy ~]# vim /soft/twemproxy/conf/nutcracker.yml
beta:  
  listen: 192.168.1.3:22122 ## 使用本机IP和端口
  redis: true ## 是否是Redis的proxy  
  hash: fnv1a_64 ## 指定具体的hash函数  
  hash_tag: "{}"  ## 值内有{},取括号内计算
  distribution: ketama ## 具体的hash算法  
  auto_eject_hosts: false ## 是否在结点无法响应的时候临时摘除结点  
  timeout: 4000 ## 超时时间(毫秒)  
  server_retry_timeout: 2000 ## 重试的时间(毫秒)
#  redis_auth: 认证密码  ## 如果Redis有密码认证,这里验证
  servers: ## 下面表示所有的Redis节点(IP:端口号:权重:实例)  
    - 192.168.1.1:6379:1 master0
    - 192.168.1.2:6379:1 master1
## 检测配置文件有没有语法错误
[root@Twemproxy ~]# /soft/twemproxy/sbin/nutcracker -t -c /soft/twemproxy/conf/nutcracker.yml 
nutcracker: configuration file '/soft/twemproxy/conf/nutcracker.yml' syntax is ok

Twemproxy 配置文件用的是 YAML 语法,YAML 语法主要有三个规范:

  • 缩进:和 Python 一样,YAML 使用缩进表示数据关系,建议两个空格(有的服务配置文件强制两个空格,比如 SaltStack,为了以后,还是两个空格吧),不建议使用Tab
  • 冒号:冒号后面不是空格就是换行
  • 短横线:短横线后面一定是空格,短横线表示选项

Twemproxy 启动

[root@Twemproxy ~]# /soft/twemproxy/sbin/nutcracker -d -c /soft/twemproxy/conf/nutcracker.yml -p /soft/twemproxy/log/redisproxy.pid -o /soft/twemproxy/log/redisproxy.log -a 192.168.1.3
## 验证启动
[root@Twemproxy ~]# lsof -i :22122
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nutcracke 7709 root 6u IPv4 41298 0t0 TCP bogon:22122 (LISTEN)

Twemproxy 启动的参数
-h, --help : this help
-V, --version : show version and exit
-t, --test-conf : test configuration for syntax errors and exit
-d, --daemonize : run as a daemon
-D, --describe-stats : print stats description and exit
-v, --verbose=N : set logging level (default: 5, min: 0, max: 11)
-o, --output=S : set logging file (default: stderr)
-c, --conf-file=S : set configuration file (default: conf/nutcracker.yml)
-s, --stats-port=N : set stats monitoring port (default: 22222)
-a, --stats-addr=S : set stats monitoring ip (default: 0.0.0.0)
-i, --stats-interval=N : set stats aggregation interval in msec (default: 30000 msec)
-p, --pid-file=S : set pid file (default: off)
-m, --mbuf-size=N : set size of mbuf chunk in bytes (default: 16384 bytes)

验证 Twemproxy

## 添加500个数据
[root@Twemproxy ~]# for line in `seq -w 500`;do
  /soft/redis/bin/redis-cli -h 192.168.1.3 -p 22122 set key_${line} value_${line}
done
## 查看Master1节点数据情况
[root@Master1 ~]# /soft/redis/bin/redis-cli info Keyspace
# Keyspace
db0:keys=100,expires=0,avg_ttl=0
## 查看Master2节点数据情况
[root@Master2 ~]# /soft/redis/bin/redis-cli info Keyspace
# Keyspace
db0:keys=400,expires=0,avg_ttl=0

Redis集群之Cluster

Cluster 在3.0之后 Redis 自带的集群工具
Cluster 集群去中心化,只要通过其中一个入口连接即可
Cluster 只有一个库,集群不支持多库。支持主从自动切换

Cluster 集群配置

这里为了效果用了三个服务器,每台服务器一对主从。其中端口7开头的为主,8开头的为从

环境搭建

源码安装Redis、相应的目录和配置文件优化简单优化就不介绍了

## 创建目录
[root@Master1 ~]# mkdir /soft/redis/7000/{conf,data,log,var} -p
## 复制配置文件到相应的目录
[root@Master1 ~]# cp /soft/redis/conf/redis.conf /soft/redis/7000/conf/
## 修改7000目录配置文件里下面几项
[root@Master1 ~]# vim /soft/redis/7000/conf/redis.conf 
cluster-enabled yes     ## 开启Cluster集群
cluster-config-file nodes-7000.conf      ## 集群内部配置文件
port 7000
logfile "/soft/redis/7000/redis.log"
pidfile /soft/redis/7000/redis.pid
dir /soft/redis/7000/data/
daemonize yes
## 拷贝7000一份目录
[root@Master1 ~]# cp -rf /soft/redis/7000/ /soft/redis/8000
## 把8000目录配置文件里所有7000改成8000
[root@Master1 ~]# sed -i 's#7000#8000#g' /soft/redis/8000/conf/redis.conf 
## 把目录复制到另外两个服务器上
[root@Master1 ~]# scp -r /soft/redis/7000/ root@192.168.1.2:/soft/redis/7001
[root@Master1 ~]# scp -r /soft/redis/7000/ root@192.168.1.2:/soft/redis/8001
[root@Master1 ~]# scp -r /soft/redis/7000/ root@192.168.1.3:/soft/redis/7002
[root@Master1 ~]# scp -r /soft/redis/7000/ root@192.168.1.3:/soft/redis/8002
## 到Master2上修改配置文件
[root@Master2 ~]# sed -i 's#7000#7001#g' /soft/redis/7001/conf/redis.conf 
[root@Master2 ~]# sed -i 's#7000#8001#g' /soft/redis/8001/conf/redis.conf 
## 到Master3上修改配置文件
[root@Master3 ~]# sed -i 's#7000#7002#g' /soft/redis/7002/conf/redis.conf 
[root@Master3 ~]# sed -i 's#7000#8002#g' /soft/redis/8002/conf/redis.conf 

启动所有Redis

## Master1
[root@Master1 ~]# /soft/redis/bin/redis-server /soft/redis/7000/conf/redis.conf 
[root@Master1 ~]# /soft/redis/bin/redis-server /soft/redis/8000/conf/redis.conf 
## Master2
[root@Master2 ~]# /soft/redis/bin/redis-server /soft/redis/7001/conf/redis.conf 
[root@Master2 ~]# /soft/redis/bin/redis-server /soft/redis/8001/conf/redis.conf 
## Master3
[root@Master3 ~]# /soft/redis/bin/redis-server /soft/redis/7002/conf/redis.conf 
[root@Master3 ~]# /soft/redis/bin/redis-server /soft/redis/8002/conf/redis.conf 

安装Redis集群管理工具 redis-trib.rb

redis-trib.rb 是redis集群的命令行工具,我们可以通过使用这个工具非常方便的创建和维护我们的集群。可以帮助我们检查槽位信息,进行槽位迁移和均衡等想过的运维操作。

安装 redis-trib.rb 需要大于2.2版本的ruby,默认源不足,这里需要增加源

## 增加yum源
[root@Master1 ~]# yum install centos-release-scl-rh -y
## 安装ruby
[root@Master1 ~]# yum install rh-ruby23 -y
 ## 选择使用ruby版本
[root@Master1 ~]# scl enable rh-ruby23 bash
## 查看ruby版本
[root@Master1 ~]# ruby -v
ruby 2.3.8p459 (2018-10-18 revision 65136) [x86_64-linux]
## 安装redis接口
[root@Master1 ~]# gem install redis

使用redis-trib.rb 创建集群

[root@Master1 ~]# /soft/redis-3.0.6/src/redis-trib.rb create --replicas 1 192.168.1.1:7000 192.168.1.1:8000 192.168.1.2:7001 192.168.1.2:8001 192.168.1.3:7002 192.168.1.3:8002

之后会给出集群方案,包含主从方案。以及槽位分配方案,我们同意方案的话,输入“yes”即可

连接 Cluster 集群

因为 Cluster 是去中心化(没有服务端),所以连接任意节点都可以连接集群。这里要注意的是,需要加 -c 代表操作集群

## -c 代表对集群操作,在操作过程会根据写入数据自动切换节点
[root@Master1 ~]# /soft/redis/bin/redis-cli -c -h 192.168.1.3 -p 7002
## 导入500条数据查看节点存储情况
[root@Master1 ~]# for line in `seq -w 500`;do /soft/redis/bin/redis-cli -h 192.168.1.3 -p 7002 -c set key_${line} value_${line}; done
## Master1主
[root@Master1 ~]# /soft/redis/bin/redis-cli -h 192.168.1.1 -p 7000 info Keyspace
# Keyspace
db0:keys=168,expires=0,avg_ttl=0
## Master2主
[root@Master1 ~]# /soft/redis/bin/redis-cli -h 192.168.1.2 -p 7001 info Keyspace
# Keyspace
db0:keys=167,expires=0,avg_ttl=0
## Master3主
[root@Master1 ~]# /soft/redis/bin/redis-cli -h 192.168.1.3 -p 7002 info Keyspace
# Keyspace
db0:keys=165,expires=0,avg_ttl=0

检测集群角色

## 每个节点会生成一个40位的16进制的ID,从是指向主的ID
[root@Master1 ~]# /soft/redis-3.0.6/src/redis-trib.rb check 192.168.1.2:7001
/soft/redis-3.0.6/src/redis-trib.rb:1573: warning: key "threshold" is duplicated and overwritten on line 1573
>>> Performing Cluster Check (using node 192.168.1.1:7000)
M: 57fc1b96be5acecc9d6576942fd26e54da51af18 192.168.1.1:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: a3c6917cfd88ce1dedc1b33a3ac4166c3d45281d 192.168.1.3:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: 185fb47cd71fb0d0f23eba02af4f05e8c9769c9d 192.168.1.2:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: da4cfe5f3277368393bad87853366fa0703a27ce 192.168.1.3:8002
   slots: (0 slots) slave
   replicates a3c6917cfd88ce1dedc1b33a3ac4166c3d45281d
S: 282b4b7ea7c6dc24f5c4a1c2f31ebd39c4e1b692 192.168.1.1:8000
   slots: (0 slots) slave
   replicates 185fb47cd71fb0d0f23eba02af4f05e8c9769c9d
S: 4513285491f62aaf2cb944e68dd0af4559e94a04 192.168.1.2:8001
   slots: (0 slots) slave
   replicates 57fc1b96be5acecc9d6576942fd26e54da51af18
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

我们把Master1主库down掉,看看角色变化

[root@Master1 ~]# /soft/redis/bin/redis-cli -h 192.168.1.1 -p 7000 shutdown
## 从会顶上去
[root@Master1 ~]# /soft/redis-3.0.6/src/redis-trib.rb check 192.168.1.2:7001
/soft/redis-3.0.6/src/redis-trib.rb:1573: warning: key "threshold" is duplicated and overwritten on line 1573
>>> Performing Cluster Check (using node 192.168.1.2:7001)
M: 185fb47cd71fb0d0f23eba02af4f05e8c9769c9d 192.168.1.2:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 282b4b7ea7c6dc24f5c4a1c2f31ebd39c4e1b692 192.168.1.1:8000
   slots: (0 slots) slave
   replicates 185fb47cd71fb0d0f23eba02af4f05e8c9769c9d
M: a3c6917cfd88ce1dedc1b33a3ac4166c3d45281d 192.168.1.3:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: 4513285491f62aaf2cb944e68dd0af4559e94a04 192.168.1.2:8001
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
S: da4cfe5f3277368393bad87853366fa0703a27ce 192.168.1.3:8002
   slots: (0 slots) slave
   replicates a3c6917cfd88ce1dedc1b33a3ac4166c3d45281d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

原来down掉的主库启动也不会再切换,主库会变成从库。手动切换可以执行 cluster failover

使用 Python 操作 Redis-Cluster 集群

需要安装 Python 扩展 redis-py-cluster 来操作集群

## 安装Python包管理工具pip
[root@Master1 ~]# yum install python-pip
## 安装redis-py-cluster
[root@Master1 ~]# pip install redis-py-cluster
## 写一个Python脚本
[root@Master1 ~]# vim edit_redis.py
# -*- coding:utf-8 -*-
from rediscluster import StrictRedisCluster
redis_nodes = [{'host':'192.168.1.1','port':7000},
                    {'host':'192.168.1.2','port':7001},
                    {'host':'192.168.1.3','port':7002},
                    {'host':'192.168.1.1','port':8000},
                    {'host':'192.168.1.2','port':8001},
                    {'host':'192.168.1.3','port':8002}
]
redisconn = StrictRedisCluster(startup_nodes=redis_nodes)
redisconn.set('username','zhaoliu')
print(redisconn.get('username'))
## 执行一下脚本
[root@Master3 ~]# python edit_redis.py
zhaoliu

posted on 2019-11-18 18:40  云襄  阅读(254)  评论(0编辑  收藏  举报

导航