Redis 学习笔记(十二)Redis 复制功能详解 ----- (error) READONLY You can't write against a read only slave
Redis 复制(Replication)
1. 复制介绍
分布式数据库为了获取更大的存储容量和更高的并发访问量,会将原来集中式数据库中的数据分散存储到多个通过网络连接的数据存储节点上。Redis为了解决单点数据库问题,会把数据复制多个副本部署到其他节点上,通过复制,实现Redis的高可用性,实现对数据的冗余备份,保证数据和服务的高度可靠性。
2. 复制的建立
建立复制的配置方式有三种。
在redis.conf文件中配置slaveof <masterip> <masterport>选项,然后指定该配置文件启动Redis生效。
在redis-server启动命令后加上--slaveof <masterip> <masterport>启动生效。
直接使用 slaveof <masterip> <masterport>命令在从节点执行生效。
我们以最简单的一主一从模型,使用第2种方式建立复制。
首先先开启主节点master实例,端口8888
redis-server --port 8888
开启一个client
,连接上主节点服务器
./redis-cli -p 8888
127.0.0.1:8888> KEYS * //新开启的Redis服务器,没有键值对
(empty list or set)
接着开启从节点slave实例,端口9999
,并指定指定主节点。
redis-server --port 9999 --slaveof 127.0.0.1 8888
//命令行开启Redis服务器后,会打印如下日志信息,已经开启复制了
Connecting to MASTER 127.0.0.1:8888
MASTER <-> SLAVE sync started
Non blocking connect for SYNC fired the event.
Master replied to PING, replication can continue...
Partial resynchronization not possible (no cached master)
Full resync from master: 1aff09ecd70ca640e33083f8422018b29883b9d1:1
MASTER <-> SLAVE sync: receiving 76 bytes from master
MASTER <-> SLAVE sync: Flushing old data
MASTER <-> SLAVE sync: Loading DB in memory
MASTER <-> SLAVE sync: Finished with success
开启一个client
,连接上从节点服务器。
➜ ~ redis-cli -p 9999
127.0.0.1:9999> INFO replication
# Replication
role:slave //节点角色
master_host:127.0.0.1 //主节点的IP
master_port:8888 //主节点的端口
master_link_status:up //与主节点的连接状态
master_last_io_seconds_ago:0 //主节点最后与从节点的通信时间间隔,单位秒
master_sync_in_progress:0 //从节点是否正在全量同步主节点的RDB文件
slave_repl_offset:407 //复制偏移量
slave_priority:100 //从节点的优先级
slave_read_only:1 //从节点是否只读
connected_slaves:0 //连接从节点的个数
master_repl_offset:0 //当前从节点作为其他从节点的主节点时的复制偏移量
//以下四种信息为通用的配置
repl_backlog_active:0 //复制缓冲区的状态
repl_backlog_size:1048576 //复制缓冲区的大小
repl_backlog_first_byte_offset:0//复制缓冲区起始偏移量,标识当前缓冲区可用的范围
repl_backlog_histlen:0 //标识复制缓冲区已存在的有效数据长度
127.0.0.1:9999> KEYS * //由于主节点的键空间为空,所以从节点的键空间也为空。
(empty list or set)
此时,我们查看主节点的INFO replication
信息
//通过INFO replication命令可以查看当前的复制信息
127.0.0.1:6380> INFO replication
# Replication
role:master //节点角色
connected_slaves:1 //连接从节点的个数
slave0:ip=127.0.0.1,port=9999,state=online,offset=631,lag=0 //连接从节点的信息
master_repl_offset:631 //主节点的偏移量
//以下四种信息为通用的配置
repl_backlog_active:1 //复制缓冲区的状态
repl_backlog_size:1048576 //复制缓冲区的大小
repl_backlog_first_byte_offset:2 //复制缓冲区起始偏移量,标识当前缓冲区可用的范围
repl_backlog_histlen:630 //由于主节点的键空间为空,所以从节点的键空间也为空。
到此,一主一从模型的复制就建立成功了。我们可以在主节点建立一些新的键,然后查看从节点的键空间的变化
//根据端口区别主从节点
127.0.0.1:8888> HSET hash_key hello world
(integer) 1
127.0.0.1:9999> KEYS * //从节点的键空间已经更新
1) "hash_key"
我们在查看从节点的INFO replication
信息时,可以知道slave_read_only:1
,从节点默认只能读不能写,因此执行写命令会得到如下回复:
127.0.0.1:9999> SET key value
(error) READONLY You can't write against a read only slave.
只读模式由 redis.conf 文件中的 slave-read-only 选项控制,也可以通过 CONFIG SET命令来开启或关闭这个模式。
我们在查看从节点的INFO replication信息时,还发现有connected_slaves:0选项 ,说明Redis的复制拓扑结构支持单层或多层复制关系,从节点还可以作为其他从节点的主节点进行复制。
根据拓扑关系可以分为三种:
一主一从
- 一主多从
- 树型主从结构
3. 复制的断开
复制断开也是在从节点执行命令slaveof on one
来断开于主节点的复制关系。例如,将刚才端口为9999
的从节点断开复制:
127.0.0.1:9999> SLAVEOF no one
OK
//从节点服务器会打印如下日志
Connection with master lost.
Caching the disconnected master state.
Discarding previously cached master state.
MASTER MODE enabled (user request from 'id=3 addr=127.0.0.1:40218 fd=7 name= age=2218 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
//主节点服务器也会打印断开的信息
Connection with slave 127.0.0.1:9999 lost.
从节点服务器断开后,从节点会晋升为主节点。从日志中可以看到MASTER MODE enabled
,也可以从INFO
命令查看到
127.0.0.1:9999> INFO replication
# Replication
role:master //角色发生变化
......
4. min-slaves配置选项
Redis的min-slaves-to-write
和min-slaves-max-lag
两个选项可以防止主节点在不安全的情况下执行写命令。
min-slaves-to-write 3 //从节点数量少于3个,主节点拒绝执行写命令
min-slaves-max-lag 10 //3个从节点的延迟(lag)值,大于或等于10,主节点拒绝执行写命令
Redis 学习笔记(十二)Redis 复制功能详解 ----- (error) READONLY You can't write against a read only slave的更多相关文章
- python 学习笔记十四 jQuery案例详解(进阶篇)
1.选择器和筛选器 案例1 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- Redis学习笔记(二)-key相关命令【转载】
转自 Redis学习笔记(二)-key相关命令 - 点解 - 博客园http://www.cnblogs.com/leny/p/5638764.html Redis支持的各种数据类型包括string, ...
- python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL
python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...
- Go语言学习笔记十二: 范围(Range)
Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...
- IP地址和子网划分学习笔记之《IP地址详解》
2018-05-03 18:47:37 在学习IP地址和子网划分前,必须对进制计数有一定了解,尤其是二进制和十进制之间的相互转换,对于我们掌握IP地址和子网的划分非常有帮助,可参看如下目录详文. ...
- Java进阶(三十二) HttpClient使用详解
Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...
- 零拷贝详解 Java NIO学习笔记四(零拷贝详解)
转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...
- Redis学习笔记(二)Redis支持的5种数据类型的总结之String和Hash
引言 在Redis学习笔记(一)中我们已经会安装并且简单使用Redis了,接下来我们一起来学习下Redis支持的5大数据类型. 简介 Redis是REmote DIctionary Server(远程 ...
- Redis学习笔记(二) Redis 数据类型
Redis 支持五种数据类型:string(字符串).list(列表).hash(哈希).set(集合)和 zset(有序集合),接下来我们讲解分别讲解一下这五种类型的的使用. String(字符串) ...
随机推荐
- 深度学习原理与框架-Alexnet(迁移学习代码) 1.sys.argv[1:](控制台输入的参数获取第二个参数开始) 2.tf.split(对数据进行切分操作) 3.tf.concat(对数据进行合并操作) 4.tf.variable_scope(指定w的使用范围) 5.tf.get_variable(构造和获得参数) 6.np.load(加载.npy文件)
1. sys.argv[1:] # 在控制台进行参数的输入时,只使用第二个参数以后的数据 参数说明:控制台的输入:python test.py what, 使用sys.argv[1:],那么将获得w ...
- Linux网络编程学习(六) ----- 管道(第四章)
1.管道的定义 管道就是将一个程序的输出和另外一个程序的输入连接起来的单向通道,比如命令: ls -l|more,就建立了一个管道,获取ls -l的输出作为more的输入,数据就沿着管道从管道的左边流 ...
- MySQL的show profile(已过时)简介以及该功能在MySQL 5.7中performance_schema中的替代
本文出处:http://www.cnblogs.com/wy123/p/6979499.html show profile 命令用于跟踪执行过的sql语句的资源消耗信息,可以帮助查看sql语句的执行情 ...
- 23.Hibernate-基础.md
目录 1. ORM和Hibernare 2. 基本开发 2.1 lib 2.2 写对象和引入对象映射 2.2.1 写对象类文件 2.3 配置文件 2.3.1 配置加载映射文件 2.3.2 配置数据库连 ...
- 本学期c#学习总结
本学期c#学习总结 时间转瞬即逝,大一上半学期的学习生涯已经结束.虽然以前我没什么关于学习计算机的基础,但是经过了这几个月的学习我也还是有点收获的. 我发现c#语言的关键词有很多语言特性和固定的用法, ...
- java.lang.RuntimeException: Canvas: trying to draw too large(203212800bytes) bitmap.
https://www.cnblogs.com/spring87/p/7645625.html 今天我师父发现了一个问题:在更换登录页图片后,更新版本,部分手机打开会闪退.借了一个三星手机后,查看问题 ...
- 2. Go变量(Variables)
变量是什么,变量的命名规则,以及一些关于变量的基础没有必要再说了,我想学习Go语言的有很多都是从其他语言转过来的,那我们直接进入正题. 声明一个变量: var age int 给变量赋值: age = ...
- [leetcode]67. Add Binary 二进制加法
Given two binary strings, return their sum (also a binary string). The input strings are both non-em ...
- [leetcode]84. Largest Rectangle in Histogram直方图中的最大矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- node.js中通过stream模块实现自定义流
有些时候我们需要自定义一些流,来操作特殊对象,node.js中为我们提供了一些基本流类. 我们新创建的流类需要继承四个基本流类之一(stream.Writeable,stream.Readable,s ...