• Redis复制
  • 介绍
  • 架构
  • 部署
  • 验证
  • Redis哨兵
  • 介绍
  • 架构
  • 部署
  • 验证
  • Redis集群
  • 介绍
  • 架构
  • 部署
  • 验证
  • Codis集群
  • 介绍
  • 架构
  • 部署
  • 验证



Redis复制

介绍

单台Redis服务器基本可以满足小型项目的应用。可是单台服务器要承受所有的请求负载,同样内存的使用也会造成瓶颈。
为解决这些问题,Redis提供了复制功能。当数据库数据更新后,会自动将数据同步到其他数据库节点中。在不同的服务器上部署多个Redis副本,即使有一台服务器出现故障,其他服务器依然可以继续提供服务。

架构


复制节点

操作

配置规则

Master

读写

Master可以拥有多个Slave

Slave


Slave只能拥有一个Master

redis EVAL 被重命名了_redis EVAL 被重命名了

说明:为了简化操作在一台服务器上启动三个Redis实例来实现上图的复制架构

部署


下载,解压缩和编译安装Redis:

# yum install gcc gcc-c++ -y
# wget http://download.redis.io/releases/redis-4.0.11.tar.gz
# tar xzf redis-4.0.11.tar.gz -C /usr/local 
# mv /usr/local/redis-4.0.11 /usr/local/redis
# cd /usr/local/redis
# make

创建三个目录,复制配置文件到三个目录中。代表三个Redis实例的配置文件

# mkdir /usr/local/redis/700{1..3}
# cp /usr/local/redis/redis.conf /usr/local/redis/7001/
# cp /usr/local/redis/redis.conf /usr/local/redis/7002/
# cp /usr/local/redis/redis.conf /usr/local/redis/7002/

修改配置文件

# vim /usr/local/redis/7001/redis.conf
port 7001
daemonize yes
pidfile /var/run/redis_7001.pid

# vim /usr/local/redis/7002/redis.conf
port 7002
daemonize yes
pidfile /var/run/redis_7002.pid
slaveof 127.0.0.1 7001

# vim /usr/local/redis/7003/redis.conf
port 7003
daemonize yes
pidfile /var/run/redis_7003.pid
slaveof 127.0.0.1 7001

分别启动三个 Redis实例

# /usr/local/redis/src/redis-server /usr/local/redis/7001/redis.conf
# /usr/local/redis/src/redis-server /usr/local/redis/7002/redis.conf
# /usr/local/redis/src/redis-server /usr/local/redis/7003/redis.conf
# ps -ef | grep redis
root      16908      1  0 01:06 ?        00:00:00 /usr/local/redis/src/redis-server 127.0.0.1:7001
root      16914      1  0 01:07 ?        00:00:00 /usr/local/redis/src/redis-server 127.0.0.1:7002
root      16920      1  0 01:07 ?        00:00:00 /usr/local/redis/src/redis-server 127.0.0.1:7003
root      16928  12651  0 01:08 pts/1    00:00:00 grep --color=auto redis

验证


登录7001监听端口Redis_Master
# /usr/local/redis/src/redis-cli -p 7001
127.0.0.1:7001> set name redis
OK
分别登录7002和7003监听端口Redis_Slave
# /usr/local/redis/src/redis-cli -p 7002
127.0.0.1:7002> get name
"redis"
# /usr/local/redis/src/redis-cli -p 7003
127.0.0.1:7003> get name
"redis"

默认Slave是不可以写入数据的,可以在配置文件中改变slave-read-onlyno来实现。
Redis复制操作很简单,可以在Redis命令行来设定新的实例为其他实例的Slave,指令为:slaveof < Master IP> < Master Port >
slaveof no one 可以停止接收其他数据库的同步并转换成为Master。

Redis哨兵

介绍

架构

部署

验证

Redis集群

介绍

Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。

Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的错误。

Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。

Redis 集群提供了以下两个好处:
将数据自动切分(split)到多个节点的能力。
当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。
详细原理,请自行百度。

架构

服务器划分如下:

hostname

ip

soft

node1.com

2.2.2.133

Ruby RubyGem redis

node2.com

2.2.2.134

redis

部署

安装Ruby和RubyGem(node1操作)

Ruby是一种面向对象、命令式、函数式、动态的通用编程语言。
RubyGems是Ruby的一个包管理器,提供了分发Ruby程序和库的标准格式“gem”,旨在方便地管理gem安装的工具,以及用于分发gem的服务器。这类似于Python的pip。


rpm包的ruby版本过低,故删除ruby(如果已有)

# yum remove ruby ruby-devel -y

下载ruby源码包

# wget http://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2

安装开发工具包及依赖

# yum groupinstall "Development Tools" -y
# yum install openssl-devel -y

解压软件包并编译安装

# tar xf ruby-2.5.1.tar.bz2 -C /usr/src
# cd /usr/src/ruby-2.5.1
# ./configure
# make 
# make install

更新Rubygems 和 Bundler

# gem update --system
# gem install bundler

更新以原有老版本安装的Rubygems

# gem update

查看更新后的版本信息

# ruby -v
# gem -v

安装redis依赖

# gem install redis

安装Redis(两个节点上都操作)
下载Redis源码包并解压安装

# wget http://download.redis.io/releases/redis-4.0.11.tar.gz
# tar xf redis-4.0.11.tar.gz -C /usr/src/
# cd /usr/src/redis-4.0.11/
# make && make PREFIX=/usr/local/redis install

创建集群相关目录

# mkdir -p /usr/local/redis/redis_cluster/700{1..3}/data
# tree /usr/local/redis/
/usr/local/redis/
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof
│   ├── redis-check-rdb
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
└── redis_cluster
    ├── 7001
    │   └── data
    ├── 7002
    │   └── data
    └── 7003
        └── data

8 directories, 6 files

复制相关文件

# cp /usr/src/redis-4.0.11/src/mkreleasehdr.sh /usr/local/redis/bin/
# cp /usr/src/redis-4.0.11/src/redis-trib.rb /usr/local/redis/bin/
# cp /usr/src/redis-4.0.11/redis.conf /usr/local/redis/redis_cluster/7001/

修改配置文件

# vim /usr/local/redis/redis_cluster/7001/redis.conf
port 7001 # 每个redis节点的端口号
daemonize yes  # 后台守护模式
bind 2.2.2.133 # 当前机器IP
dir /usr/local/redis/redis_cluster/7001/data/ # 数据文件存放位置
pidfile /var/run/redis_7001.pid # pid 7001和port要对应
cluster-enabled yes # 启动集群模式
cluster-config-file nodes7001.conf # 9001和port要对应
cluster-node-timeout 15000
appendonly yes

另外两个redis节点直接复制过去,再修改,节点二也可以复制过去再修改相关参数

# cp /usr/local/redis/redis_cluster/7001/redis.conf /usr/local/redis/redis_cluster/7002/
# cp /usr/local/redis/redis_cluster/7001/redis.conf /usr/local/redis/redis_cluster/7003/

启动所有redis节点

# /usr/local/redis/bin/redis-server /usr/local/redis/redis_cluster/7001/redis.conf
# /usr/local/redis/bin/redis-server /usr/local/redis/redis_cluster/7002/redis.conf
# /usr/local/redis/bin/redis-server /usr/local/redis/redis_cluster/7003/redis.conf
# ps -ef | grep redis
root    42067    1  0 22:18 ?      00:00:00 /usr/local/redis/bin/redis-server 2.2.2.133:7001 [cluster]
root    42121    1  0 22:19 ?      00:00:00 /usr/local/redis/bin/redis-server 2.2.2.133:7002 [cluster]
root    42128    1  0 22:19 ?      00:00:00 /usr/local/redis/bin/redis-server 2.2.2.133:7003 [cluster]

创建集群

# /usr/local/redis/bin/redis-trib.rb create --replicas 1 2.2.2.133:7001 2.2.2.133:7002 2.2.2.133:7003 2.2.2.134:7001 2.2.2.134:7002 2.2.2.134:7003
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
2.2.2.133:7001
2.2.2.134:7001
2.2.2.133:7002
Adding replica 2.2.2.134:7003 to 2.2.2.133:7001
Adding replica 2.2.2.133:7003 to 2.2.2.134:7001
Adding replica 2.2.2.134:7002 to 2.2.2.133:7002
M: 96b602e1c54d2f60cd143673efe258fc7d9fddba 2.2.2.133:7001
   slots:0-5460 (5461 slots) master
M: 3cbeb8625b56f751d8e47b8498f9c894eb34ae38 2.2.2.133:7002
   slots:10923-16383 (5461 slots) master
S: a52b207e351a88fe2eed2d04f94d2de76a90eb9f 2.2.2.133:7003
   replicates 356b4d683fd984b47804d1470a82f2c5590fd0b8
M: 356b4d683fd984b47804d1470a82f2c5590fd0b8 2.2.2.134:7001
   slots:5461-10922 (5462 slots) master
S: 2883da2f6182dcc9c3dcedd8d0e17cced12c77c0 2.2.2.134:7002
   replicates 3cbeb8625b56f751d8e47b8498f9c894eb34ae38
S: 63d59197786eb63023a52ad9819403470b21298f 2.2.2.134:7003
   replicates 96b602e1c54d2f60cd143673efe258fc7d9fddba
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 2.2.2.133:7001)
M: 96b602e1c54d2f60cd143673efe258fc7d9fddba 2.2.2.133:7001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 2883da2f6182dcc9c3dcedd8d0e17cced12c77c0 2.2.2.134:7002
   slots: (0 slots) slave
   replicates 3cbeb8625b56f751d8e47b8498f9c894eb34ae38
S: 63d59197786eb63023a52ad9819403470b21298f 2.2.2.134:7003
   slots: (0 slots) slave
   replicates 96b602e1c54d2f60cd143673efe258fc7d9fddba
M: 3cbeb8625b56f751d8e47b8498f9c894eb34ae38 2.2.2.133:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: 356b4d683fd984b47804d1470a82f2c5590fd0b8 2.2.2.134:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: a52b207e351a88fe2eed2d04f94d2de76a90eb9f 2.2.2.133:7003
   slots: (0 slots) slave
   replicates 356b4d683fd984b47804d1470a82f2c5590fd0b8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
  • 说明:
    replicas 1 表示一个主节点对应一个从节点
    M 为主节点
    S 为从节点

登录redis节点查看集群信息

# /usr/local/redis/bin/redis-cli -c -h 2.2.2.133 -p 7001
2.2.2.133:7001> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:391
cluster_stats_messages_pong_sent:386
cluster_stats_messages_sent:777
cluster_stats_messages_ping_received:381
cluster_stats_messages_pong_received:391
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:777
2.2.2.133:7001> cluster nodes
2883da2f6182dcc9c3dcedd8d0e17cced12c77c0 2.2.2.134:7002@17002 slave 3cbeb8625b56f751d8e47b8498f9c894eb34ae38 0 1535553262000 5 connected
63d59197786eb63023a52ad9819403470b21298f 2.2.2.134:7003@17003 slave 96b602e1c54d2f60cd143673efe258fc7d9fddba 0 1535553262548 6 connected
3cbeb8625b56f751d8e47b8498f9c894eb34ae38 2.2.2.133:7002@17002 master - 0 1535553263555 2 connected 10923-16383
356b4d683fd984b47804d1470a82f2c5590fd0b8 2.2.2.134:7001@17001 master - 0 1535553261000 4 connected 5461-10922
a52b207e351a88fe2eed2d04f94d2de76a90eb9f 2.2.2.133:7003@17003 slave 356b4d683fd984b47804d1470a82f2c5590fd0b8 0 1535553262000 4 connected
96b602e1c54d2f60cd143673efe258fc7d9fddba 2.2.2.133:7001@17001 myself,master - 0 1535553263000 1 connected 0-5460

验证

2.2.2.133:7001> set name redis
-> Redirected to slot [5798] located at 2.2.2.134:7001
OK
2.2.2.134:7002> get name
-> Redirected to slot [5798] located at 2.2.2.134:7001
"redis"

Codis集群

介绍

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 , 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。
Codis是豌豆荚的开源方案,目前在redis集群实现方式对比,codis集群比较稳定的方案,并且客户端不需要做任何修改,相对redis cluster兼容性更强,可节约大量开发成本并减少大量后期维护成本, 主要由以下特点:

  • 可以无缝迁移到codis,自带迁移工具,并且案例较多
  • 可以动态扩容和缩容
  • 多业务完全透明,业务不知道运行的是codis
  • 支持多核心CPU,twemproxy只能单核
  • codis是中心基于proxy的设计,是客户端像连接单机一样操作proxy
  • 有部分命令不能支持,比如keys *等
  • 支持group划分,组内可以设置一个主多个从,通过sentinel 监控redis主从,当主down了自动将从切换为主
  • 设置的进程要最大等于CPU的核心,不能超过CPU的核心数
  • 其依赖于zookeeper,里面保存的是key保存的redis主机位置,因此zookeeper要做高可用
  • 监控可以使用接口和dashboard

架构

redis EVAL 被重命名了_ruby_02

部署

这里简化操作全部部署在一台服务器上

Go安装


下载go二进制包

# wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
# tar xzvf go1.11.linux-amd64.tar.gz -C /usr/local/

zookeeper安装


下载jdk、zookeeper二进制包
jdk 安装略

# wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz
# tar xvzf zookeeper-3.4.13.tar.gz -C /usr/local/
# mv /usr/local/zookeeper-3.4.13/ /usr/local/zookeeper

添加环境变量

# vim /etc/profile
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=/usr/local/codis
JAVA_HOME=/usr/local/jdk
CLASS_PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$PATH:$GOROOT/bin:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin
# . /etc/profile

将Zookeeper的conf目录下zoo.sample.cfg复制保存为zoo.cfg文件

# cp /usr/local/zookeeper/conf/zoo_sample.cfg /usr/local/zookeeper/conf/zoo.cfg

启动zookeeper

# /usr/local/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

codis安装


下载codis二进制包

wget https://github.com/CodisLabs/codis/releases/download/3.2.2/codis3.2.2-go1.9.2-linux.zip

# unzip codis3.2.2-go1.9.2-linux.zip -d /usr/local/
# mv /usr/local/codis3.2.2-go1.9.2-linux/ /usr/local/codis

# cd /usr/local/codis
# mkdir conf logs

codis-dashboard配置启动
创建配置文件并修改

# /usr/local/codis/codis-dashboard --default-config > /usr/local/codis/conf/dashboard.toml

修改如下:

#coordinator_name = "filesystem"
#coordinator_addr = "/tmp/codis"
coordinator_name = "zookeeper"
coordinator_addr = "2.2.2.10:2181" # zookeeper IP和端口
#coordinator_auth = ""

# Set Codis Product Name/Auth.
product_name = "codis-demo" # Codis 项目的名字和密码
product_auth = ""

# Set bind address for admin(rpc), tcp only.
admin_addr = "2.2.2.10:18080" # admin IP和端口

启动dashboard

# nohup /usr/local/codis/codis-dashboard --ncpu=4 --config=/usr/local/codis/conf/dashboard.toml --log=/usr/local/codis/logs/dashboard.log --log-level=WARN &

关闭dashboard命令:
/usr/local/codis/codis-admin --dashboard=2.2.2.10:18080 --shutdown

codis-proxy配置启动

生成proxy配置文件

# /usr/local/codis/codis-proxy --default-config > /usr/local/codis/conf/proxy.toml

修改如下:

product_name = "codis-demo" # 与dashboard一致
product_auth = ""

admin_addr = "2.2.2.10:11080"   # 管理节点 IP和端口

proto_type = "tcp4"
proxy_addr = "0.0.0.0:19000"    # proxy IP和端口

jodis_name = "zookeeper"
jodis_addr = "2.2.2.10:2181"    # zookeeper IP和端口
jodis_auth = ""

启动proxy

# nohup /usr/local/codis/codis-proxy --ncpu=4 --config=/usr/local/codis/conf/proxy.toml --log=/usr/local/codis/logs/proxy.log --log-level=WARN &

关联proxy与dashboard

# /usr/local/codis/codis-admin --dashboard=2.2.2.10:18080 --create-proxy -x2.2.2.10:11080

Codis-FE配置启动
生成FE配置文件

# /usr/local/codis/codis-admin --dashboard-list --zookeeper=2.2.2.10:2181 > /usr/local/codis/conf/codis.json

启动codis-fe

nohup /usr/local/codis/codis-fe --ncpu=2 --log=logs/fe.log --log-level=WARN --dashboard-list=conf/codis.json --listen=2.2.2.10:8080 &

管理地址
http://2.2.2.10:8080
proxy地址
2.2.2.10:19000

验证