Redis 主从,集群--实战

redis主从配置

1、架构

image.png

2Redis主从数据同步的步骤

image.png

 

3、安装部署

 

3.1 基本环境

两台Centos 6.5 操作系统 ,分别关闭selinux,以及防火墙。

master: 192.168.0.250

slave:  192.168.0.251

扫描二维码关注公众号,回复: 4945754 查看本文章

安装C语言编辑器

yum  install  gcc gcc-c++  -y 

 

 

4.2.下载编译

使用的版本是: redis-3.2.6

tar  zxvf  redis-3.2.6.tar.gz 

>cd redis-3.2.6

>make

>make PREFIX=/usr/local/redis install

 

4.3  创建redis后续使用的目录

mkdir  -p /usr/local/redis/{data,log,conf}

注:data是rdb文件保存位置,log是日志文件保存位置,conf是配置文件保存位置

拷贝配置文件

cp  /root/redis-3.2.6/sentinel.conf  /usr/local/redis/conf

cp  /root/redis-3.2.6/redis.conf  /usr/local/redis/conf

 

4.4修改配置文件

修改主服务器配置文件

vim redis.conf

bind  192.168.0.250 

daemonize yes

pidfile "/usr/local/redis/redis_6379.pid"

loglevel verbose

logfile "/usr/local/redis/log/redis.log"

dir "/usr/local/redis/data"

masterauth "zhangshuhao"

requirepass "zhangshuhao"

其余默认配置

修改从配置文件

vim redis.conf

bind  192.168.0.250 

daemonize yes

pidfile "/usr/local/redis/redis_6379.pid"

loglevel verbose

logfile "/usr/local/redis/log/redis.log"

dir "/usr/local/redis/data"

masterauth "zhangshuhao"

requirepass "zhangshuhao"

slaveof 192.168.0.250 6379

 

4.5 启动和测试

主机: redis-server ../conf/redis.conf

从机: redis-server ../conf/redis.conf

在主机上启动redis客户端:

redis-cli -h  192.168.0.250 

>set k1 v1

>get k1

"v1"

.登陆从机,并在从机上启动客户端:

redis-cli  -h  192.168.0.251 

>get k1

"v1"

 

开启哨兵机制:(我是在从节点开启的)

vim  /usr/local/redis/conf/sentinel.conf

sentinel monitor mymaster 192.168.0.251 6379 1

sentinel down-after-milliseconds mymaster 10000

sentinel auth-pass mymaster zhangshuhao

 

启动

./redis-sentinel  ../conf/sentinel.conf  >>/usr/local/redis/log/sentinel.log  & 

 

 

哨兵机制配置文件解释:

port 26379

 

#sentinel监控的redis的名字、IP和端口,最后一个数字是sentinel做决策的时候需要投赞同票的最少的sentinel的数量。

sentinel monitor mymaster 127.0.0.1 6379 1

 

#如果多久没联系上redis-servevr,认为这个redis-server进入到失效(SDOWN)状态。

sentinel down-after-milliseconds mymaster 10000

 

#可选的安全连接密码

#sentinel auth-pass mymaster xxx

 

#failover(提升一个slave成为master)过期时间,如果超过这个时间没触发成功failover,sentinel会认为failover失败。

sentinel failover-timeout mymaster 30000

 

#选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长。

sentinel config-epoch mymaster 2

 

#当failover时,可以指定一个“通知”脚本用来告知当前集群的情况。

#脚本被允许执行的最大时间为60秒,如果超时,脚本将会被终止(KILL)

#sentinel notification-script mymaster /var/redis/notify.sh

 

#failover之后重配置客户端

# sentinel client-reconfig-script <master-name> <script-path>

# Generated by CONFIG REWRITE

 

 

 

Redis的数据回写机制

Redis的数据回写机制分同步和异步两种,

  1. 同步回写即SAVE命令,主进程直接向磁盘回写数据。在数据大的情况下会导致系统假死很长时间,所以一般不是推荐的。

  2. 异步回写即BGSAVE命令,主进程fork后,复制自身并通过这个新的进程回写磁盘,回写结束后新进程自行关闭。由于这样做不需要主进程阻塞,系统不会假死,一般默认会采用这个方法。

个人感觉方法2采用fork主进程的方式很拙劣,但似乎是唯一的方法。内存中的热数据随时可能修改,要在磁盘上保存某个时间的内存镜像必须要冻结。冻结就会导致假死。fork一个新的进程之后等于复制了当时的一个内存镜像,这样主进程上就不需要冻结,只要子进程上操作就可以了。

在小内存的进程上做一个fork,不需要太多资源,但当这个进程的内存空间以G为单位时,fork就成为一件很恐怖的操作。何况在16G内存的主机上fork 14G内存的进程呢?肯定会报内存无法分配的。更可气的是,越是改动频繁的主机上fork也越频繁,fork操作本身的代价恐怕也不会比假死好多少。

找到原因之后,直接修改/etc/sysctl.conf内核参数vm.overcommit_memory= 1

sysctl -p

Linux内核会根据参数vm.overcommit_memory参数的设置决定是否放行。

  1.  如果 vm.overcommit_memory = 1,直接放行

  2. vm.overcommit_memory = 0:则比较 此次请求分配的虚拟内存大小和系统当前空闲的物理内存加上swap,决定是否放行。

  3. vm.overcommit_memory= 2:则会比较进程所有已分配的虚拟内存加上此次请求分配的虚拟内存和系统当前的空闲物理内存加上swap,决定是否放行。

 

 

搭建redis分布式集群

1、架构图                                               

image.png

 

蓝色的部分为redis集群中的每个node节点,节点之间通过ping命令,测试相互是否连接正常,普通集群没有主从区分,连接任何一个节点操作,都可以转发到其他任意一个节点

1、          redis容错机制

每个redis提供了节点之间相互发送ping命令,用于测试每个节点的健康状态,集群中连接正常的节点收到其他接节点发送的ping命令时,会返回一个pong字符串

Redis投票机制:如果一个节点AB发送ping没有得到pong返回,那么A就会通知其他节点在次给B发送ping,如果集群中超过一半的节点给B发送ping都没有得到返回,那么B就被坐实game over了,所以为了避免单点故障,一半都会为redis的每个节点提供了备份节点,B节点挂掉之后立马启动B的节点服务器。

 

2、          集群存储的原理

在集群当中每个节点上的数据都不一样,(一样就是主备了)把数据都分散存放到各个节点上进行存储。

Redis中槽slof就用于圈定当前节点的存储范围,为分散存储使用hash算法,确定什么值放到哪个槽里

 

3Redis 持久化机制

Redis提供了2中数据持久化方式:

Snapshotting:定时的将Redis内存的当前状态保存到RDB文件中,持久化到硬盘。

AOFappend-only file):将所有的command操作保存到aof文件中,AOP使得同步频率很高,数据即便丢失,粒度也很小,但性能上有所牺牲。默认数据持久化会2s同步一次,也可以进行配置改变同步频率。

 

4、安装部署

1)环境三台服务器分别关闭iptables ,selinux centOS6.5操作系统(要让集群正常的工作至少需要三个主节点,在这里创建6个redis节点,其中三个为主节点,三个节点为从节点)

192.168.2.41:7000

192.168.2.41:7001

192.168.2.41:7002

192.168.2.41:7003

192.168.2.41:7004

192.168.2.41:7005

 

2)下载安装包并上传到服务器解压,编译

http://download.redis.io/releases/                在这里我使用的是redis 3.2.6

tar zxvf redis-3.2.6.tar.gz &&mv redis-3.2.6 /usr/local/redis3.0 &&cd  /usr/local/redis3.0 && make && make install

 

3)创建集群所需要的目录并进行拷贝

mkdir -p /usr/local/cluster
mkdir -p /usr/local/cluster/7000
mkdir -p /usr/local/cluster/7001
mkdir -p /usr/local/cluster/7002
mkdir -p /usr/local/cluster/7003
mkdir -p /usr/local/cluster/7004
mkdir -p /usr/local/cluster/7005
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7000/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7001/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7002/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7003/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7004/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7005/

 

4)修改配置文件redis.conf (针对不同的进程修改对应的端口号)

port 7000                                          
daemonize yes                                      #
在后台运行
cluster-enabled yes                                #打开服务器集群模式
cluster-config-file nodes.conf                     #redis集群配置文件(自动生成)
cluster-node-timeout 5000                          #节点连接超时时间
appendonly yes                                     #同时开启dump,以及AOF

requirepass zhangshuhao                                 #设置客户端访问密码

 

5)启动6个redis(启动成功之后 ps –ef |grep redis 查看)

cd /usr/local/cluster/7000/src
redis-server ../redis.conf
cd /usr/local/cluster/7001/src
redis-server ../redis.conf
cd /usr/local/cluster/7002/src
redis-server ../redis.conf
cd /usr/local/cluster/7003/src
redis-server ../redis.conf
cd /usr/local/cluster/7004/src
redis-server ../redis.conf
cd /usr/local/cluster/7005/src
redis-server ../redis.conf

 

6.1)创建集群

cd /usr/local/redis3.0/src
./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

在启动时会报错,因为执行的内容需要安装ruby环境

报错信息:error:/usr/bin/env: ruby: No such file or directory

yum  install  ruby  -y   在这里我使用yum安装

6.2)在次执行

./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

依然会报错,报错信息为:(他告诉你找不到rubygems,缺少rubygems组件)

./redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError)
from ./redis-trib.rb:24

所以安装 yum  install  rubygems  -y 

 

6.3)在次创建集群

./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

还会报错,提示缺少redis的接口,错误内容为:

/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from ./redis-trib.rb:25

在这里我安装gem install  redis –version 3.0.0 

ERROR:  Could not find a valid gem 'redis' (= 3.0.0) in any repository
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)

在安装时报错需要手动下载并安装:

wget https://rubygems.global.ssl.fastly.net/gems/redis-3.2.1.gem
gem install -l ./redis-3.2.1.gem

6.4)再次创建集群

./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

本次成功创建

>>> Creating cluster
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
>>> Performing hash slots allocation on 6 nodes...    
#首先尝试连接给定的六个节点,检查他们是否存在
Using 3 masters:
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002      
#在确定这些节点都连接成功之后,redistrib.rb,在将7000/7001/7002设置为主节点,而7003/7004/7005 则被自动设置为三个主节点的从节点
M: 2022f24d581b4a7c3342e3245c32927cbd5ec16d 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: 37b7008f80f8c21a698da8cb1f1b32db8c0c415c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
S: b5b76d70bbb0dbf3e7df8a38f1259e95e2054721 127.0.0.1:7003   
#对三个主节点,redis-trib.rb会分别为他们支配5461/5462/5461个槽(默认情况下使用平均分配)
   replicates 2022f24d581b4a7c3342e3245c32927cbd5ec16d
S: 6881f8fef9c25da486f320ebf2ead39c1502db4c 127.0.0.1:7004
   replicates 37b7008f80f8c21a698da8cb1f1b32db8c0c415c
S: f090526d32cced97731eef2a2e1722a7bac7d9ea 127.0.0.1:7005
   replicates ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd
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 127.0.0.1:7000)
M: 2022f24d581b4a7c3342e3245c32927cbd5ec16d 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: 37b7008f80f8c21a698da8cb1f1b32db8c0c415c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
M: b5b76d70bbb0dbf3e7df8a38f1259e95e2054721 127.0.0.1:7003
   slots: (0 slots) master
   replicates 2022f24d581b4a7c3342e3245c32927cbd5ec16d
M: 6881f8fef9c25da486f320ebf2ead39c1502db4c 127.0.0.1:7004
   slots: (0 slots) master
   replicates 37b7008f80f8c21a698da8cb1f1b32db8c0c415c
M: f090526d32cced97731eef2a2e1722a7bac7d9ea 127.0.0.1:7005
   slots: (0 slots) master
   replicates ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd

#redis-trib.rb会对集群进行测试,检查是否每个节点都按照原先的展示的配置设置好了
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.  
#如果整个集群数据库16384个槽都有节点在处理,那么集群就会进入线上状态,之后用户就可以开始想集群发送命令请求了

 

7)集群访问

目前最主要的redis集群客户端:

1、redis-rb-cluster:antirez 使用 Ruby 编写的 Redis 集群客户端,集群客户端的官方实现;

2、predis:Redis 的 PHP 客户端,支持集群功能;

3、jedis:Redis 的 JAVA 客户端,支持集群功能;

4、StackExchange.Redis:Redis 的 C# 客户端,支持集群功能;

5、内置的 redis-cli :在启动时给定 -c 参数即可进入集群模式,支持部分集群功能;

为了让实例保持简单,我们在这里使用集群模式的redis-cli来进行测试

[root@zsh src]# ./redis-cli -p 7000 -c

127.0.0.1:7001> auth zhangshuhao

OK

127.0.0.1:7001> set name zsh 

OK

127.0.0.1:7001> get name 

"zsh"

127.0.0.1:7001> keys * 

1) "name"

 

九、redis持久化方式

Redis持久化---两种方式

Redis提供了两种持久化的方式,分别是RDB(redis Database )和AOF (append Only File)

RDB:简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;

AOF:则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些指令从前到后在执行一遍就可以实现数据恢复了。

 

Redis持久化---RDB

RDB方式是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法。

Redis在进行数据持久化的过程中,会将数据写入到一个临时文件中,待持久或过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让我们可以随时随地进行备份,因为快照文件总是完整可用的。

对于RDB方式,redis会单独创建fork一个子进程来进行持久化,而主进程是不会进行任何io操作的,这样就确保了redis极高的性能

如果需要仅此能大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式就不太适合,因为即使每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失,所以热镀丝还提供了另一种持久化方式,那就是AOF

 

Redis持久化—AOF

AOF(Append Only File),即只允许追加不允许改写的文件。

AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序在将指令近行一遍

 

猜你喜欢

转载自blog.csdn.net/u012045045/article/details/86476772