在redis的安装目录下首先启动一个redis服务,使用默认的配置文件,作为主服务

ubuntu@slave1:~/redis2$ ./redis-server ./redis.conf &

在home目录下创建一个redis2 工作目录,拷贝redis配置文件到该目录下,并修改一下配置项

port 6380
pidfile /var/run/redis_6380
dir ~/redis2
slaveof 127.0.0.1 6379

使用以上的配置文件再启动一个redis服务,就是master的从服务了

ubuntu@slave1:~/redis2$ ~/redis-server/redis-4.0.1/redis-soft/bin/redis-server ./redis.conf &

再打开两个窗口分别连接这两个实例:

master:

127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=1737,lag=1
master_replid:92daad4418492783bb39ab32f5fee57d06eba455
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1737
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1737
ubuntu@slave1:~/redis-server/redis-4.0.1/redis-soft/bin$ ./redis-cli -p 6379
127.0.0.1:6379> set "test" "a value"
OK

slave:

127.0.0.1:6380> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:1709
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:92daad4418492783bb39ab32f5fee57d06eba455
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1709
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1709
ubuntu@slave1:~/redis-server/redis-4.0.1/redis-soft/bin$ ./redis-cli -p 6380
127.0.0.1:6380> get "test"
"a value"

此时关闭slave,在操作master:

127.0.0.1:6379> set "test2" "another value"
OK
127.0.0.1:6379> set "test" "new value"
OK

再次连接slave,并读取数据

ubuntu@slave1:~/redis-server/redis-4.0.1/redis-soft/bin$ ./redis-cli -p 6380
127.0.0.1:6380> get "test"
"new value"
127.0.0.1:6380> get "test2"
"another value"

至此,主从复制配置并测试完毕。

相关原理:

我们在从节点的配置文件设置了从服务的监听端口是6380,并设置了 slave of 127.0.0.1 6379 。表示这个服务实例是master的一个从节点。当主从实例之间网络连接通畅并建立了主从复制关系之后,主实例会将其接受的写入命令转发给从实例,以实现主从实例之间的数据同步。

当从实例第一次与主实例连接时会发生什么?从实例在网络连接中断后会重新连接到主实例吗?

在redis的复制机制中,共有两种重新同步机制:部分重新同步和完全重新同步。当一个redis从实例启动后并连接到主实例时,从实例总是会尝试 通过发送(master_replid;master_repl_offest)请求主实例进行部分重新同步。其中master_replid;master_repl_offest 表示与主实例同步的最后一个快照。此时如果主实例接收部分同步的请求,那么它会从从实例停止时的最后一个偏移量开始增量的进行数据同步,否则的话,就要进行完全同步复制。当从实例第一次了解主实例时,总是完全同步复制的,在进行完全同步复制时,为了将所有的数据复制到从实例中,主实例需要将数据转存到一个RDB文件中,然后将这个RDB文件发送给从实例。从实例接收到RDB文件后,会将内存中的所有数据清除,再将RDB文件中的数据导入,主实例的复制过程是完全异步的,因此不会阻塞主实例处理客户端的请求。

更多细节:当一个从实例被提升为主实例时,其他的从实例必须与新主实例重新同步。在Redis4之前,这个过程是完全重新同步的,在4.0 之后,新的主实例会记录旧主实例的master_replid,offest.因此可以接受来自其他从实例的部分重新同步请求。

复制机制调优(参数配置:)

repl_backlog_size (主从网络断开时,主实例缓冲区中缓存命令的大小,默认是1MB;当主从网络恢复时,如果异步数据超出这个范围,那么会触发完全同步,否则就是部分同步。)。关于这个值的配置,原则是该值小于RDB快照大小。参考的计算公式:

T * (mster_repl_offest2 - master_repl_offest1) / (T2 - T1) 

-T 网络断开可能持续的时间

repl_backlog_ttl :如果所有的从实例与主实例的连接全部断开,主实例需要等待多久才释放缓存中的命令。

repl_disable_tcp_nodelay:设置为yes可以减少网络带宽。(将小包合并为一个包再发送)

repl_diskless_sync:主从复制不提供磁盘RDB文件直接发送。(实验阶段特性,不安全)

复制机制失效故障排查:

repl_ping_slave_period:从主实例的角度看,检查从实例是否存活的方式是在该参数的时间间隔内向从实例发送ping命令,默认是10秒。而从实例的角度,是每秒向主实例发送replconf ack{offest}来报告自己的复制偏移量。无论ping还是replconf ack,都是通过repl-timeout指定超时时间,默认是60秒,如果两次ping命令或者replconf ack之间的间隔时间超时了,或者repl-timeout期间主从实例没有数据流量,那么主从实例的复制连接就会断开,导致复制失效。

client-output-buffer-limit: slave 256MB 64MB 60 :当我们配置主从复制时,从实例第一次连接主实例,主实例会将命令转储到RDB文件中在发动给从实例,那么在从实例执行RDB文件中的命令同步数据时,主实例的实时写入命令是放在客户端缓冲区的,在从实例加载完RDB文件后,再将这些明命令发送给客户端。这个缓冲区的大小是有限制的,如果超出了这个限制,就会导致重新复制。256MB是硬性要求,一旦超出,立即关闭从实例的连接,64MB 60 是个整体的软性要求,意思是 缓冲区的大小超出64MB 持续60秒,主实例将关闭连接。

更多细节:repl_ping_slave_period的值必须小于repl_timeout的值,否则每次主实例之间没有流量就会造成复制超时。同时我们应该避免使用长时间阻塞的操作。

复制超时的触发条件:执行重新同步时主从实例之间没有数据传输,或者超时时间内主从实例无法接受ping/replconf ack .比如从实例加载RDB文件过长,导致实例写入命令在主实例缓冲区 超过64MB并持续60秒。在生产环境中我们可以使用命令: conf set 设置合适的值或者修改配置文件并重启redis:(一下设置意为:512MB硬性要求,128MB 持续120秒)

127.0.0.1:6379> CONFIG SET client-output-buffer-limit 'slave 536870912 134217728 120'
OK

多说一句:主从配置中,最好将从实例设置为 read only;主实例删除键时会同步删除从实例;如果我们在从实例中设置了键的过期时间,那么这个键将永远不过期。但是redis4.0解决了这个问题。

[redis]复制机制,调优,故障排查的更多相关文章

  1. redis复制机制

    摘自redis设计与实现 通过客户端,发送slave of xxx给redis从服务器,即可实现主从服务器之间的复制.如果主服务器设置了requirepass进行身份验证,从服务器需要设置master ...

  2. MySQL复制以及调优

    一. 简介 MySQL自带复制方案,带来好处有: 数据备份. 负载均衡. 分布式数据. 概念介绍: 主机(master):被复制的数据库. 从机(slave):复制主机数据的数据库. 复制步骤: (1 ...

  3. JVM原理讲解和调优

    一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...

  4. JDK记录-JVM原理与调优(转载)

    转载自<https://www.cnblogs.com/andy-zhou/p/5327288.html> 一.什么是JVM JVM是Java Virtual Machine(Java虚拟 ...

  5. JVM、垃圾回收、内存调优、常见參数

    一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写.JVM是一种用于计算设备的规范.它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...

  6. JVM调优2

    原文地址:https://blog.csdn.net/sun1021873926/article/details/78002118 一.什么是JVM  JVM是Java Virtual Machine ...

  7. Java 面试题 三 <JavaWeb应用调优线程池 JVM原理及调优>

    1.Java Web应用调优线程池 不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文由浅入深,介 ...

  8. Redis复制与可扩展集群搭建

    抄自:http://www.infoq.com/cn/articles/tq-redis-copy-build-scalable-cluster 讨论了Redis的常用数据类型与存储机制,本文会讨论一 ...

  9. JVM学习笔记(四)------内存调优【转】

    转自:http://blog.csdn.net/cutesource/article/details/5907418 版权声明:本文为博主原创文章,未经博主允许不得转载. 首先需要注意的是在对JVM内 ...

随机推荐

  1. 30-python3 中 bytes 和 string 之间的互相转换

    转自:http://www.jb51.net/article/105064.htm password = b'123456' 等价于: pw = '123456' password = pw.enco ...

  2. JS Code Snippet --- Cookie

    <a id="quitBtn" href="#" class="exit">Exit</a> <a id=&q ...

  3. Create Empty Project In Vs But Not Debug?

    问题描述 在使用VS创建一个空的项目管理,然后,添加项目.可是,这个时候,项目虽然可以运行,但是不能Debug进行调试. 解决方法 按照下面三张图像的设置即可.

  4. SystemTap 内核调试

    一.简介 Systemtap是一个Linux下的全新的调式.诊断和性能测量工具,是我目前所知的最强大的内核调试工具. 参考: http://m.blog.csdn.net/blog/hnllei/75 ...

  5. arean.c

    glibc-2.14中的arean.c源代码,供研究malloc和free实现使用: /* Malloc implementation for multiple threads without loc ...

  6. JavaScript语言精粹 笔记06 方法

    JS包含了少量可用在标准类型上的标准方法. ArrayFunctionNumberObjectRegExpString Array array.concat(item...) concat方法返回一个 ...

  7. ZOJ2748 Free Kick 2017-04-18 20:40 40人阅读 评论(0) 收藏

    Free Kick Time Limit: 2 Seconds      Memory Limit: 65536 KB In a soccer game, a direct free kick is ...

  8. MFC中的主窗口修改标题

    MFC中的主窗口修改标题 如何去掉“无标题”1.在主程序中的InitInstance(): m_pMainWnd->SetWindowText("你要显示的东西如果不想显示置空就行&q ...

  9. 用U盘安装Ubuntu主系统

    用U盘安装Ubuntu主系统 0. 学习Ubuntu系统的的动机 ubuntu系统的内核是linux系统,通过Ubuntu的学习,掌握lInux服务器搭建!!!! 硬件要求:闲置的笔记本  +  U盘 ...

  10. github的使用经历

    首先我打开百度搜索markdown,点击这个在线编辑器,开始编写,如下图: 预览效果如下: 然后打开github的网页登录后,点击下图这个标志: 然后给给要上传的一个命名: 然后选择README 确认 ...