Redis集群、高可用
     分类:环境搭建     有: 0 条评论

Redis集群、高可用

     分类:环境搭建     有: 0 条评论

Predixy(代理,先搭建Redis Cluster集群)

高可用:可以让每一个Predixy和一个Redis Cluster组合,在程序里设置故障转移到其它地址;也可让Predixy跨机房组网(跨机房的节点不能是Redis Cluster),然后做keepalived或加haproxy。

Predixy支持redis-sentinel和redis-cluster,使用简单直接用redis官网推荐的框架也行,就像使用单个redis是一样的,客户端无法感知到服务端变化,对于扩容什么的也很方便,后端直接支持redis-cluster集群;性能也是优于目前主流的代理Codis,Twemproxy等。唯一的缺点可能就是小项目容易死吧,后期没人维护。

项目地址https://github.com/joyieldInc/predixy

# 先升级gcc到最新版本,低版本不支持C++11,无法编译成功。
# 升级gcc,参考:https://www.leolan.top/index.php/posts/199.html

yum install -y redis                #安装redis,方便使用redis-cli
systemctl disable redis

# 开始安装
git clone https://github.com/joyieldInc/predixy.git
cd predixy
make
# 编译完成就生成可执行文件了,拷贝到你需要的目录
mkdir /usr/local/predixy
cp src/predixy /usr/local/predixy   #拷一份到这里备份
cp src/predixy /usr/bin             #拷一份到这里方便直接执行命令
cp -r conf /usr/local/predixy

##########################################################################
# 修改配置文件(引用文档)
predixy的配置类似redis, 具体配置项的含义在配置文件里有详细解释,请参考下列配置文件:

predixy.conf,   整体配置文件,会引用下面的配置文件
cluster.conf,   用于Redis Cluster时,配置后端redis信息
sentinel.conf,  用于Redis Sentinel时,配置后端redis信息
auth.conf,      访问权限控制配置,可以定义多个验证密码,可每个密码指定读、写、管理权限,以及定义可访问的健空间
dc.conf,        多数据中心支持,可以定义读写分离规则,读流量权重分配
latency.conf,   延迟监控规则定义,可以指定需要监控的命令以及延时时间间隔

提供这么多配置文件实际上是按功能分开了,所有配置都可以写到一个文件里,也可以写到多个文件里然后在主配置文件里引用进来。
具体参考:https://github.com/joyieldInc/predixy/blob/master/doc/config_CN.md

##########################################################################
# 按需求修改配置文件
cd /usr/local/predixy/conf/
vim predixy.conf
启用:Include cluster.conf
关闭:Include try.conf
其他可以默认,需要改端口的可以改bind

vim cluster.conf

ClusterServerPool {
    MasterReadPriority 60
    StaticSlaveReadPriority 50
    DynamicSlaveReadPriority 50
    RefreshInterval 1
    ServerFailureLimit 10
    ServerRetryTimeout 1
    Servers {
        + 192.168.18.36:7001
        + 192.168.18.36:7002
        + 192.168.18.36:7003
        + 192.168.18.36:7004
        + 192.168.18.36:7005
        + 192.168.18.36:7006
    }
}


# 保存退出、运行
cd ~
#前台运行,会打印消息,默认端口是7617,用测试环境测试,IP:7617
predixy /usr/local/predixy/conf/predixy.conf

# OK的话以后用脚本启动
vim /root/start-predixy.sh

#!/bin/bash
nohup predixy /usr/local/predixy/conf/predixy.conf &

chmod +x /root/start-predixy.sh


Codis(代理)

项目地址https://github.com/CodisLabs/codis
高可用:可以参考官方文档,搭建多个proxy(可用ansible快速部署);用zookeeper或etcd获取可用的 proxy 列表实现高可用。轮流请求所有的proxy实现负载均衡。Redis做一主多从或哨兵模式,其余全部在codis中进行控制。Codis不支持Redis Cluster集群。有个很严重的缺点是不支持SLOTSINFO命令(文档中有提到),这旧意味着节点不能跨主机、跨机房,在本机上的redis才可以被管理。

以下内容只是简单测试,真实机部署见Codis集群部署:https://www.leolan.top/index.php/posts/219.html

# 安装GO(1.7以上),修改环境变量
yum install -y go && yum update -y
echo "GOPATH=/home/codis/gopath;export GOPATH" >> /etc/profile
echo "PATH=\$PATH:\$GOPATH/bin;export PATH" >> /etc/profile
source /etc/profile

# 检测
go env GOPATH
输出:/home/codis/gopath

# 安装Codis
mkdir -p $GOPATH/src/github.com/CodisLabs
cd $_ && git clone https://github.com/CodisLabs/codis.git -b release3.2
cd $GOPATH/src/github.com/CodisLabs/codis
make
# make时同时会进行安装,安装完成后检查文件

[root@Codis01 codis]# ls bin/
assets       codis-dashboard  codis-ha     codis-server     redis-cli       version
codis-admin  codis-fe         codis-proxy  redis-benchmark  redis-sentinel

[root@Codis01 codis]# cat bin/version
version = 2017-09-18 09:30:50 +0800 @f8bc4e320e6dd58b09f3f01bd8f1489a7be9f78c @3.2.0-21-gf8bc4e3
compile = 2017-09-24 01:02:54 -0400 by go version go1.8.3 linux/amd64

# 修改集群名称(这两个名字要保持一致)
sed -i 's/product_name = "codis-demo"/product_name = "Codis-xxx"/' $GOPATH/src/github.com/CodisLabs/codis/config/dashboard.toml
sed -i 's/product_name = "codis-demo"/product_name = "Codis-xxx"/' $GOPATH/src/github.com/CodisLabs/codis/config/proxy.toml

# 启动服务,要按顺序启动,依次运行脚本,开启服务,为了方便,下面写成启动脚本。
codis-dashboard-admin.sh start
codis-proxy-admin.sh start
codis-server-admin.sh start
codis-fe-admin.sh start

# 启动脚本
cd ~
ln -s $GOPATH/src/github.com/CodisLabs/codis codis

vim codis.sh
case $1 in
start)
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-dashboard-admin.sh start
    sleep 5
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-proxy-admin.sh start
    sleep 10
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-server-admin.sh start
    sleep 5
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-fe-admin.sh start
    sleep 5
    netstat -lntp
    echo "已开启Codis服务"
    ;;
stop)
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-dashboard-admin.sh stop
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-proxy-admin.sh stop
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-server-admin.sh stop
    $GOPATH/src/github.com/CodisLabs/codis/admin/codis-fe-admin.sh stop
    echo "已关闭Codis服务"
    exit 0
    ;;
restart)
    shift
    "$0" stop
    sleep 3
    "$0" start
    ;;
*)
    echo "Usage: $0 {start|stop|restart}" >&2

esac


chmod +x codis.sh

# 防火墙放行端口
firewall-cmd --add-port=9090/tcp --permanent
firewall-cmd --add-port=19000/tcp --permanent
firewall-cmd --add-port=11080/tcp --permanent
firewall-cmd --add-port=18080/tcp --permanent
firewall-cmd --reload

看到有如下端口,说明正常启动了,浏览器访问:IP:9090即可访问。

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      1489/codis-server 1 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      920/sshd            
tcp        0      0 0.0.0.0:19000           0.0.0.0:*               LISTEN      1472/codis-proxy     
tcp6       0      0 :::22                   :::*                    LISTEN      920/sshd       
tcp6       0      0 :::18080                :::*                    LISTEN      1457/codis-dashboar 
tcp6       0      0 :::9090                 :::*                    LISTEN      1496/codis-fe       
tcp6       0      0 :::11080                :::*                    LISTEN      1472/codis-proxy    

参考:
http://www.360doc.com/content/16/0425/22/16915_553796395.shtml
https://www.cnblogs.com/chenny7/p/5063368.html
http://blog.csdn.net/wych1981/article/details/43274403
http://blog.csdn.net/qifengzou/article/details/72902503



Cachecloud(非代理)

是搜狐视频开源的redis集群解决方案,配置还是有点麻烦的,依赖的环境很多,启动特别慢;因为不是代理,所以后端可以是多种类型;通过API返回节点地址进行Redis的读写,客户端需要自己封装,并不是开箱即用。集体见博客。

项目地址:https://github.com/sohutv/cachecloud
相关视频http://pan.baidu.com/s/1c2mET5e
博客https://cachecloud.github.io/

安装Maven,JDK,MySQL5.5或5.6

yum install java-1.8.0-openjdk java-devel 
# Maven参考:https://www.leolan.top/index.php/posts/88.html
之后才是正式安装cachecloud。


Twemproxy(代理)

高可用:Redis一主多从(或者哨兵模式),Redis节点可跨机房;Twemproxy做keepalived或加haproxy。

项目地址https://github.com/twitter/twemproxy
由Twitter开源,但是扩容基本是个致命伤。

安装参考:http://www.cnblogs.com/gomysql/p/4413922.html



Redis Cluster集群(非代理)

Redis Cluster集群是官方出的,在Redis3.0后加入了集群功能。存取需要支持的客户端,一般配合代理或其他管理工具一起使用。

基础环境配置

# 关闭SELinux
vi /etc/sysconfig/selinux
SELINUX=disabled

setenforce 0

# 安装开发包
yum install openssl* openssl-devel zlib-devel make autoconf readline-devel curl-devel expat-devel gettext-devel -y

yum install gcc glibc gcc-c++ automake cmake libtool bison flex perl mercurial -y 

yum install readline-devel bzip2-devel zlib-devel libxml2-devel libxslt-devel openssl-devel kernel-devel pcre-devel boost-devel python-devel python-setuptools libpcap-devel -y 

yum install wget vim lsof tcpdump net-tools lsof screen mtr nc nmap zip dos2unix sysstat dstat setuptool system-config-* ntsysv mlocate telnet tree -y

先参考:http://blog.csdn.net/fengshizty/article/details/51368004

# 安装Redis
cd ~
wget http://download.redis.io/releases/redis-4.0.1.tar.gz
tar zxf redis-4.0.1.tar.gz
cd redis-4.0.1
make
make install PREFIX=/usr/local/redis-cluster

# 拷贝配置文件和集群脚本设定文件
cp redis.conf /usr/local/redis-cluster/bin
cp src/redis-trib.rb /usr/local/redis-cluster

# 修改以下部分,开启集群配置,业务上要用的配置最好也现在修改好
vim /usr/local/redis-cluster/bin/redis.conf

daemonize yes #后台启动
port 7001 #修改端口号,从7001到7006
cluster-enabled yes #开启cluster,去掉注释
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

# 修改IP,对外的IP,如果是127.0.0.1的话外部机器无法访问,只能本机通过127.0.0.1访问。
sed -i 's/bind 127.0.0.1/bind 192.168.18.36/' /usr/local/redis-cluster/bin/redis.conf

# 拷贝5份
cd /usr/local/redis-cluster/
mv bin redis01
cp -r redis01 redis02
cp -r redis01 redis03
cp -r redis01 redis04
cp -r redis01 redis05
cp -r redis01 redis06

# 修改端口
sed -i 's/port 7001/port 7002/' /usr/local/redis-cluster/redis02/redis.conf
sed -i 's/port 7001/port 7003/' /usr/local/redis-cluster/redis03/redis.conf
sed -i 's/port 7001/port 7004/' /usr/local/redis-cluster/redis04/redis.conf
sed -i 's/port 7001/port 7005/' /usr/local/redis-cluster/redis05/redis.conf
sed -i 's/port 7001/port 7006/' /usr/local/redis-cluster/redis06/redis.conf


############################################################
# 启动脚本,之后redis节点要是挂了就要进入节点的目录去执行才会启动并加入集群,
# 单独启动(和脚本中的路径不同的话是无法加入集群的,ps aux|grep redis能看到区别)
# 多个节点挂掉了可以直接运行一次脚本,就会重新启动了。
cd ~
vim start-all-redis.sh

#!/bin/bash

cd /usr/local/redis-cluster/redis01
./redis-server redis.conf

cd /usr/local/redis-cluster/redis02
./redis-server redis.conf

cd /usr/local/redis-cluster/redis03
./redis-server redis.conf

cd /usr/local/redis-cluster/redis04
./redis-server redis.conf

cd /usr/local/redis-cluster/redis05
./redis-server redis.conf

cd /usr/local/redis-cluster/redis06
./redis-server redis.conf

chmod +x start-all-redis.sh

############################################################
# 安装Ruby环境,详情、报错参考:www.leolan.top/index.php/posts/80.html
wget https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.gz
tar zxf ruby-2.4.1.tar.gz
cd ruby-2.4.1
./configure --enable-shared --enable-pthread --prefix=/usr/local/ruby
make && make install

# 添加环境变量
echo "PATH=$PATH:/usr/local/ruby/bin;export PATH" >> /etc/profile
source /etc/profile

# 测试
ruby -v
gem --version

# 安装支持工具
gem install redis


############################################################
# 创建集群
cd ~
./start-all-redis.sh
ps aux |grep redis      #可以看到redis都启动了。

cd /usr/local/redis-cluster/
./redis-trib.rb create --replicas 1 192.168.18.36:7001 192.168.18.36:7002 192.168.18.36:7003 192.168.18.36:7004 192.168.18.36:7005 192.168.18.36:7006

注:使用create命令 --replicas 1 参数表示为每个主节点创建一个从节点,其他参数是实例的地址集合。
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.18.36:7001
192.168.18.36:7002
192.168.18.36:7003
Adding replica 192.168.18.36:7004 to 192.168.18.36:7001
Adding replica 192.168.18.36:7005 to 192.168.18.36:7002
Adding replica 192.168.18.36:7006 to 192.168.18.36:7003
M: f326cf6fc9a25a11c9a02e0311e649974c73a092 192.168.18.36:7001
   slots:0-5460 (5461 slots) master
M: bd0775f90610886d9afc8a6c24f6139a07cc6591 192.168.18.36:7002
   slots:5461-10922 (5462 slots) master
M: ad6a501622096b7a70253131e8b79bee4eb1cfdb 192.168.18.36:7003
   slots:10923-16383 (5461 slots) master
S: 0881a1e84f949f20ac1f8d91568a47b5ba83b70b 192.168.18.36:7004
   replicates f326cf6fc9a25a11c9a02e0311e649974c73a092
S: 0acd33304cb91879017d5358942437f73d5c2d9a 192.168.18.36:7005
   replicates bd0775f90610886d9afc8a6c24f6139a07cc6591
S: 7a2eac6aebaab5ca18bab27857f8e030f3e9d55d 192.168.18.36:7006
   replicates ad6a501622096b7a70253131e8b79bee4eb1cfdb
Can I set the above configuration? (type 'yes' to accept): yes  #输入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.18.36:7001)
M: f326cf6fc9a25a11c9a02e0311e649974c73a092 192.168.18.36:7001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 7a2eac6aebaab5ca18bab27857f8e030f3e9d55d 192.168.18.36:7006
   slots: (0 slots) slave
   replicates ad6a501622096b7a70253131e8b79bee4eb1cfdb
S: 0acd33304cb91879017d5358942437f73d5c2d9a 192.168.18.36:7005
   slots: (0 slots) slave
   replicates bd0775f90610886d9afc8a6c24f6139a07cc6591
S: 0881a1e84f949f20ac1f8d91568a47b5ba83b70b 192.168.18.36:7004
   slots: (0 slots) slave
   replicates f326cf6fc9a25a11c9a02e0311e649974c73a092
M: bd0775f90610886d9afc8a6c24f6139a07cc6591 192.168.18.36:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: ad6a501622096b7a70253131e8b79bee4eb1cfdb 192.168.18.36:7003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.


# 检查
./redis-trib.rb check 192.168.18.36:7002   #端口号只表示是哪一个网络,7001-7006任意一个都可以

# 进入任意一个节点目录
./redis-cli -c -p 7001
#任意一个端口号都可以,连接后set key后get key会自动跳转。详细测试见文章开头参考链接。

# 最后注意开放防火墙访问
firewall-cmd --zone=public --add-port=7001-7006/tcp --permanent
firewall-cmd --reload

Pegasus(代理)

Pegasus 是小米云存储团队开发的一个分布式 Key-Value 存储系统,最初的动机是弥补 HBase 在可用性和性能上的不足。Pegasus 系统的 Server 端完全采用 C++ 语言开发,使用 PacificA 协议支持强一致性,使用 RocksDB 作为单机存储引擎,降低了存储成本。
Github:https://github.com/XiaoMi/pegasus


Redis主从配置

原理参考(含数据恢复):
https://www.cnblogs.com/kevingrace/p/5685332.html
https://www.cnblogs.com/lukexwang/p/4711977.html

# 主服务器
Port 6379                  #端口视情况修改
requirepass yourpassword   #设置redis密码(供客户端连接,从服务器也可视为客户端)
bind 0.0.0.0               #开启任何主机可访问
protected-mode no          #关闭保护模式,开启也可以,可能会遇到客户端无法连接的问题。
# 持久化最少开启save或者快照其中一项;否则redis(崩溃重启机制)会导致重启后空数据集被同步到从节点,导致所有数据丢失!!!
save 900 1        #900秒内如果超过1个key被修改,则发起快照保存
save 300 10       #300秒内容如超过10个key被修改,则发起快照保存
save 60 10000     #60秒内容如超过10000个key被修改,则发起快照保存
保存配置,然后重启redis

# 从服务器
slaveof [主服务器IP] [主服务器端口]
masterauth [主服务器连接密码]
requirepass yourpassword   #本机连接密码(可以和主服务器不一样,供客户端连接)
bind 0.0.0.0               #开启任何主机可访问
protected-mode no          #关闭保护模式,开启也可以,可能会遇到客户端无法连接的问题。
保存配置,然后重启redis

# 检查
在主从服务器都执行以下命令
redis-cli
auth [密码]
info
可以在#Replication一栏看到;
主服务器显示slaves:1(有一个从节点)
从服务器master_link_status:up(连接主服务器成功,如果为down,请检查日志)

在主服务器set,在从服务器get,正常!配置完成。
#重启故障报错,参考配置
client-output-buffer-limit normal 0 0 0
#client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit slave 512mb 256mb 300
client-output-buffer-limit pubsub 32mb 8mb 60

报错参考:
http://blog.51cto.com/lee90/1871638
(●゚ω゚●)