Redis 主从,集群--实战

redis主从配置node

1、架构linux

image.png

2Redis主从数据同步的步骤c++

image.png


3、安装部署redis

 

3.1 基本环境算法

两台Centos 6.5 操做系统 ,分别关闭selinux,以及防火墙。数据库

master: 192.168.0.250vim

slave:  192.168.0.251安全

安装C语言编辑器ruby

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命令,测试相互是否链接正常,普通集群没有主从区分,链接任何一个节点操做,均可以转发到其余任意一个节点

一、          redis容错机制

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

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

 

二、          集群存储的原理

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

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

 

3Redis 持久化机制

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

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

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

 

4、安装部署

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

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)启动6redis(启动成功以后 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"

 

9、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方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序在将指令近行一遍

相关文章
相关标签/搜索