我是007 发表于 2018-11-2 13:41:21

Redis 主从,集群--实战

  redis主从配置
  1、架构

  2、Redis主从数据同步的步骤
  
  3、安装部署
  
  3.1 基本环境
  两台Centos 6.5 操作系统 ,分别关闭selinux,以及防火墙。
  master: 192.168.0.250
  slave:192.168.0.251
  安装C语言编辑器
  yuminstallgcc gcc-c++-y
  
  4.2.下载编译
  使用的版本是: redis-3.2.6
  tarzxvfredis-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
  bind192.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
  bind192.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 -h192.168.0.250
  >set k1 v1
  >get k1
  "v1"
  .登陆从机,并在从机上启动客户端:
  redis-cli-h192.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
  # Generated by CONFIG REWRITE
Redis的数据回写机制
  Redis的数据回写机制分同步和异步两种,

[*]  同步回写即SAVE命令,主进程直接向磁盘回写数据。在数据大的情况下会导致系统假死很长时间,所以一般不是推荐的。
[*]  异步回写即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参数的设置决定是否放行。

[*]  如果 vm.overcommit_memory = 1,直接放行
[*]  vm.overcommit_memory = 0:则比较 此次请求分配的虚拟内存大小和系统当前空闲的物理内存加上swap,决定是否放行。
[*]  vm.overcommit_memory= 2:则会比较进程所有已分配的虚拟内存加上此次请求分配的虚拟内存和系统当前的空闲物理内存加上swap,决定是否放行。
搭建redis分布式集群
  1、架构图

  蓝色的部分为redis集群中的每个node节点,节点之间通过ping命令,测试相互是否连接正常,普通集群没有主从区分,连接任何一个节点操作,都可以转发到其他任意一个节点
  1、          redis容错机制
  每个redis提供了节点之间相互发送ping命令,用于测试每个节点的健康状态,集群中连接正常的节点收到其他接节点发送的ping命令时,会返回一个pong字符串
  Redis投票机制:如果一个节点A给B发送ping没有得到pong返回,那么A就会通知其他节点在次给B发送ping,如果集群中超过一半的节点给B发送ping都没有得到返回,那么B就被坐实game over了,所以为了避免单点故障,一半都会为redis的每个节点提供了备份节点,B节点挂掉之后立马启动B的节点服务器。
  2、          集群存储的原理
  在集群当中每个节点上的数据都不一样,(一样就是主备了)把数据都分散存放到各个节点上进行存储。
  Redis中槽slof就用于圈定当前节点的存储范围,为分散存储使用hash算法,确定什么值放到哪个槽里
  3、Redis 持久化机制
  Redis提供了2中数据持久化方式:
  Snapshotting:定时的将Redis内存的当前状态保存到RDB文件中,持久化到硬盘。
  AOF(append-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.rbcreate --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
  yuminstallruby-y   在这里我使用yum安装
  6.2)在次执行
  ./redis-trib.rbcreate --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
  所以安装 yuminstallrubygems-y
  6.3)在次创建集群
  ./redis-trib.rbcreate --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 installredis –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.rbcreate --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会对集群进行测试,检查是否每个节点都按照原先的展示的配置设置好了
   All nodes agree about slots configuration.
  >>> Check for open slots...
  >>> Check slots coverage...
   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来进行测试
  # ./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方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序在将指令近行一遍

页: [1]
查看完整版本: Redis 主从,集群--实战