Redis研究(十二)—数据复制

在上一节中我们写了Redis的数据持久化

http://blog.csdn.net/wtyvhreal/article/details/42916503

通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失)数据。但是由于数据是存储在一台服务器上的,如果这台服务器的硬盘出现故障,也会导致数据丢失。为了避免单点故障,我们希望将数据库复制多个副本以部署在不同的服务器上,即使有一台服务器出现故障其他服务器依然可以继续提供服务。这就要求当一台服务器上的数据库更新后,可以自动将更新的数据同步到其他服务器上,Redis提供了复制(replication
)功能可以自动实现同步的过程。

1.配置

同步后的数据库分为两类,一类是主数据库(master),一类是从数据库(slave)。主数据库可以进行读写操作,当发生写操作时自动将数据同步给从数据库。而从数据库一般是只读的,并接受主数据库同步过来的数据。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库。

在Redis中使用复制功能非常容易,只需要在从数据库的配置文件中加入“slaveof主数据库IP主数据库端口”即可,主数据库无需进行任何配置。为了能够更直观地展示复制的流程,下面将进行简单的演示。我们要在一台服务器上启动两个Redis实例,监听不同端口,其中一个作为主数据库,另一个作为从数据库。首先我们不加任何参数来启动一个Redis实例作为主数据库:

redis-server

该实例默认监听6379端口。然后加上slaveof参数启动另一个Redis实例作为从数据库,并让其监听6380端口:

redis-server --port 6380 --slaveof 127.0.0.1 6379

此时在主数据库中的任何数据变化都会自动同步到从数据库中。我们打开redis-cli实例A并连接到主数据库:

redis-cli

再打开redis-cli实例B并连接到从数据库:

redis-cli -p 6380

在实例A中使用SET命令设置一个键的值:

redis A>SET foo bar
OK

此时在实例B中就可以获得该值了:

redis B>GET foo
"bar "

但在默认情况下从数据库是只读的,如果直接修改从数据库的数据会出现错误:

redis B>SET foo hi
(error) 

可以通过设置从数据库的配置文件中的slave-read-only 为no以使从数据库可写,但是对从数据库的任何更改都不会同步给任何其他数据库,并且一旦主数据库中更新了对应的数据就会覆盖从数据库中的改动。

配置多台从数据库的方法也一样,在所有的从数据库的配置文件中都加上 slaveof参数指向同一个主数据库即可。

除了通过配置文件或命令行参数设置slaveof参数,还可以在运行时使用SLAVEOF命令修改:

redis>SLAVEOF  127.0.0.1 6379

如果该数据库已经是其他主数据库的从数据库了,SLAVEOF命令会停止和原来数据库的同步转而和新数据库同步。还可以使用SLAVEOFNO  ONE来使当前数据库停止接收其他数据库的同步转成主数据库。

2.原理

当一个从数据库启动后,会向主数据库发送SYNC命令,主数据库接收到SYNC命令后会开始在后台保存快照(即RDB持久化的过程),并将保存期间接收到的命令缓存起来。当快照完成后,Redi s会将快照文件和所有缓存的命令发送给从数据库。从数据库收到后,会载入快照文件并执行收到的缓存的命令。当主从数据库断开重连后会重新执行上述操作,不支持断点续传。

实际的过程略微复杂一些,由于Redi s服务器使用TCP协议通信,所以我们可以使用telnet工具伪装成一个从数据库来了解同步的具体过程。首先在命令行中连接主数据库(默认端口为6379,且没有任何从数据库连接):

telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected  to localhost.
Escape  cha acter  i s '^]' .

然后作为从数据库,我们先要发送PING命令确认主数据库是否可以连接:

PING
+PONG

主数据库会回复+PONG。如果没有收到主数据库的回复,则向用户提示错误。如果主数据库需要密码才能连接,我们还得发送AUTH命令进行验证。而后向主数据库发送REPLCONF命令说明自己的端口号(这里随便选择了一个):

REPLCONF  l istening-por t 6381
+OK

这时就可以开始同步的过程了:向主数据库发送SYNC命令开始同步,此时主数据库发送回快照文件和缓存的命令。目前主数据库中只有一个foo键,所以收到的内容如下(快照文件是二进制格式,从第三行开始):

SYNC
29
REDI S0006?foobar ?6_?"

从数据库会将收到的内容写入到硬盘上的临时文件中,当写入完成后从数据库会用该临时文件替换RDB快照文件(RDB快照文件的位置就是持久化时配置的位置,由dir和dbfilename两个参数确定),之后的操作就和RDB持久化时启动恢复的过程一样了。需要注意的是在同步的过程中从数据库并不会阻塞,而是可以继续处理客户端发来的命令。默认情况下,从数据库会用同步前的数据对命令进行响应。可以配置slave-serve-stale-data参数为no来使从数据库在同步完成前对所有命令(除了INFO和SLAVEOF)都回复错误:“SYNC
with  master in  progress.”

之后主数据库的任何数据变化都会同步给从数据库,同步的内容和Redis通信协议一样,比如我们在主数据库中执行SET foo hi,通过telnet我们收到了:

*3
$3
set
$3
foo
$2
hi

在复制的过程中,快照无论在主数据库还是从数据库中都起了很大的作用,只要执行复制就会进行快照,即使我们关闭了RDB方式的持久化(通过删除所有save参数)。更进一步,无论是否启用了RDB方式的持久化,Redis在启动时都会尝试读取dir和dbfilename两个参数指定的RDB文件来恢复数据库。

3.图结构

从数据库不仅可以接收主数据库的同步数据,自己也可以同时作为主数据库存在,形成类似图的结构,如图所示,数据库A的数据会同步到B和C中,而B中的数据会同步到D和E中。向B中写入数据不会同步到A或C中,只会同步到D和E中,

4.读写分离

通过复制可以实现读写分离以提高服务器的负载能力。在常见的场景中,读的频率大于写,当单机的Redis无法应付大量的读请求时(尤其是较耗资源的请求,比如SORT命令等)可以通过复制功能建立多个从数据库,主数据库只进行写操作,而从数据库负责读操作。

5.从数据库持久化

另一个相对耗时的操作是持久化,为了提高性能,可以通过复制功能建立一个(或若干个)从数据库,并在从数据库中启用持久化,同时在主数据库禁用持久化。当从数据库崩溃时重启后主数据库会自动将数据同步过来,所以无需担心数据丢失。而当主数据库崩溃时,需要在从数据库中使用SLAVEOF NO ONE命令将从数据库提升成主数据库继续服务,并在原来的主数据库启动后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可将数据同步回来。

时间: 2024-10-26 17:07:12

Redis研究(十二)—数据复制的相关文章

Effective C++读书笔记之十二:复制对象时勿忘其每一个成分

Item 12:Copy all parts of an object 如果你声明自己的copying函数,意思就是告诉编译器你并不喜欢缺省显示中的某些行为.而编译器会对"你自己写出copying函数"做出一种复仇的行为:既然你拒绝它们为你写出copying函数,如果你的代码不完全,它们也不会告诉你.结论很明显:如果你为class添加一个成员变量,你必须同时修改copying函数.如果你忘记,编译器不太可能提醒你. 一下提供一种正确的模版: class Date{...}; class

Redis教程(十二):服务器管理命令总结

转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/140.html 一.概述: Redis在设计之初就被定义为长时间不间断运行的服务进程,因此大多数系统配置参数都可以在不重新启动进程的情况下立即生效.即便是将当前的持久化模式从AOF切换到RDB也无需重启.    在Redis中,提供了一组和服务器管理相关的 ,其中就包含和参数设置有关的CONFIG SET/GET command. 二.相关命令列表: 命令原型 时间复杂度

Redis研究(二)—准备

 一.安装Redis 安装Redis请看这里:http://blog.csdn.net/wtyvhreal/article/details/40980167 二.启动和停止Redis Redis可执行文件说明: redis-server             Redis服务器 redis-cli                    Redis命令行客户端 redis-benchmark   Redis性能测试工具 redis-check-aof      AOF文件修复工具 redis-ch

Redis Cluster 集群数据分片机制

复制粘贴自: https://www.e-learn.cn/content/redis/2344485, 点击链接访问原文 仅供个人学习参考之用, 高级开发不得不懂的Redis Cluster数据分片机制 Redis 集群简介 Redis Cluster 是 Redis 的分布式解决方案,在 3.0 版本正式推出,有效地解决了 Redis 分布式方面的需求. Redis Cluster 一般由多个节点组成,节点数量至少为 6 个才能保证组成完整高可用的集群,其中三个为主节点,三个为从节点.三个主

redis之(十二)redis数据的持久化

[一]redis的数据为什么要持久化 --->redis的存取数据性能高,是由于将所有数据都存储在内存中.当redis重启的时候,存储在内存中的数据就容易丢失. --->把redis作为数据库使用. --->把redis作为缓存服务器,但缓存被穿透后会对性能造成很大的影响,所有缓存同时失效会导致缓存雪崩,从而使服务无法响应. --->因此我们希望redis能将数据从内存中以某种形式同步到硬盘,使得重启后可以根据硬盘中的纪录恢复数据,这一过程就叫做持久化 [二]redis的持久化,支

阿里,腾讯内部十二个大数据项目,你都有做过吗?

随着社会的进步,大数据的高需求,高薪资,高待遇,促使很多人都来学习和转行到大数据这个行业.学习大数据是为了什么?成为一名大数据高级工程师.而大数据工程师能得到高薪.高待遇的能力在哪?自然是项目经验.下面给大家大概介绍一下在阿里的"双11"."双12"."双旦"即将到来的"618"与腾讯大数据都用上的十二个大数据项目:阿里,腾讯内部十二个大数据项目,你都有做过吗?一个大数据分析项目关键构成如下: 信息采集组.数据清洗组.数据融合

[WebGL入门]十二,模型数据和顶点属性

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 顶点属性的意思 上次的文章中,介绍了一下从着色器的生成,编译,到程序对象的生成和着色器的连接.这次,简单的说一下模型数据的定义和顶点属性的处理.另外,介绍一下根据模型数据生成VBO的方法.VBO的使用要比生成难理解一些,但是不要担心,后面会慢慢说明.接下来看一下顶点属性.顶点属性,说的简单点,

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意

redis之(二十)redis的总结一

1 什么是Redis Redis(REmote DIctionary Server,远程数据字典服务器)是开源的内存数据库,常用作缓存或者消息队列. Redis的特点: Redis存在于内存,使用硬盘作为持久化:每秒十万读写. 具有丰富的数据结构,字符串.哈希表.列表.集合.有序集合:提供交集.并集.差集等操作. 设置TTL存活时间,到期自动删除. Redis单线程.Memcached多线程:对于一般的应用场景,单线程也足够使用,优势还是在于多数据类型.持久化. 可以将数据复制到任意数量的从服务

Android学习笔记(十二)——使用意图传递数据的几种方式

使用意图传递数据的几种方式 点此获取完整代码 我们除了要从活动返回数据,也常常要传递数据给活动.对此我们可以使用Intent对象将这些数据传递给目标活动. 1.创建一个名为PassingData的项目,在activity_main.xml文件中添加一个Button: <Button android:id="@+id/btn_SecondActivity" android:layout_width="fill_parent" android:layout_hei