恒昌小额信贷管理系统统与小额贷款管理系统的区别

深入解析半同步与异步的MySQL主从复制配置
作者:张志亮
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了半同步与异步的MySQL主从复制配置,包括不同的连接方案的讨论,需要的朋友可以参考下
简单来讲MySQL的主从复制就是一个C/S架构的应用。master可以认为是我们通常意义上所认为的server,slave可以当作是一台client。slave上的I/O线程去请求master上数据,而master验证通过slave的信息后就允许slave接入,然后进行数据变化信息的发送。
一、MySQL主从复制原理
这里我以MySQL5.5为例来说一下MySQL的主从复制的原理:
首先由备节点的I/O线程负责向主节点请求数据,主节点验证通过以后会由dump线程把数据发送给备用节点。备用节点的I/O线程收到资源后会把把这些数据写入到中继日志,备节点的SQL线程检测到中继日志变更后会立刻根据中继日志的内容跟新备库的内容。这样就完成了同步的过程。
二、常见的复制模型
1、一主一从模型
这种架构的优点就是比较简单,搭建和维护都比较容易,成本也比较低。对于一些负载量不是特别大、可靠性要求不是特别高的场合,完全可以采用这种模型。但是对于一些负载比较大站点,和对可用性要求比较高的场合,这种架构就不太适用了。因为如果访问量比较大,Master节点的压力会比较的,另外如果Master崩溃,也会导致业务的终止。
2、一主多从模型
在绝大多数场景中,我们的应用都是读多写。我们使用这种架构,通过读写分离的技术,可以有效降低Master上读的压力。我们在后端的slave上可以做一些数据备份,数据挖掘等方面的工作。但是如果备库比较多,同时主库又要负责其他的请求时,主库的压力会明显增大,此时主库会成为整个系统的性能瓶颈。
&&& 当然,还有其他的复制模型,比如多级中继,和环状复制等,这些复制的基本原理都和上面的差不多,这里不再详细的解释了。
3、配置主从复制
(1)、异步复制
主从同步的条件:
&&&&&& a:启用二进制日志;
&&&&&& b:选择一个server-id
&&&&&& c:创建具有复制权限的用户
&&&&&& a:启用中继日志
&&&&&& b:选择一个唯一的server-id
&&&&&& c:连接主服务器,并开始复制数据
A、首先在主库上建立用于复制的最小权限的用户
mysql& grant replication slave,replication client on *.* to repl@'10.12.%'
-& identified by '123456';
Query OK, 0 rows affected (0.03 sec)
B、在从库上连接主库
mysql& CHANGE MASTER TO MASTER_HOST='10.12.128.19',MASTER_PORT=3306,MASTER_USER='repl',
MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=451;
#查看复制的状态
mysql& show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.12.128.19
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000006
Read_Master_Log_Pos: 1512
Relay_Log_File: relay_index.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000006
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1512
Relay_Log_Space: 452
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 3306
Master_UUID: 97f33396-ed12-11e4-921a-000c29e8ee06
Master_Info_File: /mydata/data5.
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave ha waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
1 row in set (0.00 sec)
C、然后再从库上执行:
&&& 也可以单独启动IO线程和SQL线程。
(如果从库的IO线程状态一直是connecting的状态,可能是防火墙的原因,一般来说关闭防火墙或者配置防火墙规则就可以了)
(2)、半同步复制
半同步复制是基于Google为MySQL开发的半同步复制的插件。半同步复制的原理是,一个事务在主服务器上执行完成后,必须至少确保至少在一台从服务器上执行完成后,事务才算提交成功。如果在一定时间内从服务器没有响应,则会自动降级为异步复制。
这个半同步复制是建立在异步复制的基础之上进行的。
首先需要安装Google的半同步插件:
install plugin rpl_semi_sync_master soname 'semisync_master.so';
install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
然后开启半同步的功能
set global rpl_semi_sync_master_enabled = 1;
set global rpl_semi_sync_master_timeout = 100; //以毫秒计算
set global rpl_semi_sync_slave_enabled = ON;
在从库上还需要重启IO线程:
stop slave IO_
start slave IO_
分别在主库和备库上查看半同步插件运行的状态:
mysql& show global status like 'rpl%';
+--------------------------------------------+-------+
| Variable_name
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients
| Rpl_semi_sync_master_net_avg_wait_time
| Rpl_semi_sync_master_net_wait_time
| Rpl_semi_sync_master_net_waits
| Rpl_semi_sync_master_no_times
| Rpl_semi_sync_master_no_tx
| Rpl_semi_sync_master_status
| Rpl_semi_sync_master_timefunc_failures
| Rpl_semi_sync_master_tx_avg_wait_time
| Rpl_semi_sync_master_tx_wait_time
| Rpl_semi_sync_master_tx_waits
| Rpl_semi_sync_master_wait_pos_backtraverse | 0
| Rpl_semi_sync_master_wait_sessions
| Rpl_semi_sync_master_yes_tx
+--------------------------------------------+-------+
14 rows in set (0.04 sec)
mysql& show global status like 'rpl%';
+----------------------------+-------+
| Variable_name
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.04 sec)
可以看到,主库和备库的半同步插件都已经处于启用状态。
至此,异步主从配置结束。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具高可用配置(异步复制跟同步复制)-metaq - 开源软件当前位置:& &&&高可用配置(异步复制跟同步复制)-metaq高可用配置(异步复制跟同步复制)-metaq&&网友分享于:&&浏览:3次高可用配置(异步复制和同步复制)-metaq
Meta相比于kafka的一个重要特性就是消息高可用方案的实现,我们称之为HA方案。消息在发送到broker之后立即写入磁盘才返回客户端告诉消息生产者消息发送成功,通过unflushThreshold和unflushInterval两个参数的控制,可以保证单机消息数据的安全性,只要机器的磁盘没有永久损坏,消息总可以在重启后恢复并正常投递给消费者们。但是,如果遇到了磁盘永久损坏或者数据文件永久损坏的情况,那么该broker上的消息数据将可能永久丢失。为了防止这种情况的发生,一个可行的方案就是将消息数据复制到多台机器,类似mysql的主从复制功能。
同步复制和异步复制
meta提供类似mysql主从复制的异步复制和同步功能,分别对应不同的可靠级别。理论上说同步复制能带来更高的可靠级别,异步复制因为延迟的存在,可能会丢失极少量的消息数据,相应地,同步复制会带来性能的损失,因为要同步写入两台甚至更多的broker机器上才算写入成功。
在实际实践中,我更推荐采用异步复制的架构,因为异步复制的架构相对简单,并且易于维护和恢复,对性能也没有影响。而同步复制对运维要求相对很高,机制复杂容易出错,故障恢复也比较麻烦。异步复制加上磁盘做磁盘阵列,足以应对非常苛刻的数据可靠性要求。
异步复制配置
假设你已经配置了一台broker服务器,并且配置了一个topic为test,现在你希望test能复制到另一台slave broker上来保证消息数据的高可用。你可以这样做:
1.首先,你需要部署一个新的broker,配置server.ini从master broker拷贝一份。
2.其次,配置slave文件。编辑conf/async_slave.properties:
#slave编号,大于等于0表示作为slave启动,同一个master下的slave编号应该设不同值.
#作为slave启动时向master订阅消息的group,如果没配置则默认为meta-slave-group
#不同的slaveId请使用不同的group
slaveGroup=meta-slave-group
#slave数据同步的最大延时,单位毫秒
slaveMaxDelayInMills=500
#是否自动从master同步server.ini, 1.4.2新增选项
#第一次仍然需要自己拷贝server.ini,后续可以通过设置此选项为true来自动同步
autoSyncMasterConfig=true
配置参数的含义请自己看注释。可见,一个master可以复制到多个slave。
3.执行下列命令启动slave:
bin/metaServer.sh start slave
4.第一次复制因为需要跟master完全同步需要耗费一定时间,你可以在数据文件的目录观察复制情况。
5.请注意,异步复制的slave将参与消费者的消费活动,消息消费者可以从slave中获取消息并消费,消费者会随机从master和slaves中挑选一台作为消费broker。
6.请注意,从1.4.2开始,可以通过autoSyncMasterConfig选项配置是否自动同步master的server.ini到异步复制的slave上,当master的server.ini文件变更并通过bin/metaServer.sh reload之后,slave将监控到这一变更并自动同步。
异步复制的局限
异步复制有延迟,虽然可以通过设定slaveMaxDelayInMills来控制延迟。
异步复制的故障处理
Master永久故障: 将slave作为master启动,去除启动参数中的slave即可,也就是metaServer.sh restart
Slave永久故障: 启动新的broker并配置作为master新的slave启动。
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有说说MySQL的半同步复制_数据库技术_Linux公社-Linux系统门户网站
你好,游客
说说MySQL的半同步复制
来源:Linux社区&
作者:lgdvsehome
MySQL Semisynchronous Replication
MySQL5.5 除了支持内置的异步复制机制,还提供了接口支持半同步复制的机制。
异步复制的缺点:
MySQL复制默认是异步复制,Master将事件写入binlog,但并不知道Slave是否或何时已经接收且已处理。在异步复制的机制的情况下,如果Master宕机,事务在Master上已提交,但很可能这些事务没有传到任何的Slave上。假设有Master-&Salve故障转移的机制,此时Slave也可能会丢失事务。
半同步复制的概念:i.当Slave主机连接到Master时,能够查看其是否处于半同步复制的机制。
ii.当Master上开启半同步复制的功能时,至少应该有一个Slave开启其功能。此时,一个线程在Master上提交事务将受到阻塞,直到得知一个已开启半同步复制功能的Slave已收到此事务的所有事件,或等待超时。
iii.当一个事务的事件都已写入其relay-log中且已刷新到磁盘上,Slave才会告知已收到。
iv.如果等待超时,也就是Master没被告知已收到,此时Master会自动转换为异步复制的机制。当至少一个半同步的Slave赶上了,Master与其Slave自动转换为半同步复制的机制。
v.半同步复制的功能要在Master,Slave都开启,半同步复制才会起作用;否则,只开启一边,它依然为异步复制。
同步,异步,半同步复制的比较:
同步复制:Master提交事务,直到事务在所有的Slave都已提交,此时才会返回客户端,事务执行完毕。缺点:完成一个事务可能会有很大的延迟。
异步复制:当Slave准备好才会向Master请求binlog。缺点:不能保证一些事件都能够被所有的Slave所接收。
半同步复制:半同步复制工作的机制处于同步和异步之间,Master的事务提交阻塞,只要一个Slave已收到该事务的事件且已记录。它不会等待所有的Slave都告知已收到,且它只是接收,并不用等其完全执行且提交。
半同步复制的控制变量,状态监控变量:
Variable Name
Variable Scope
Dynamic Variable
Effect Host
rpl_semi_sync_master_enabled
rpl_semi_sync_slave_enabled
rpl_semi_sync_master_timeout
rpl_semi_sync_master_enabled是控制Master是否开启半同步,开启或不开启,将其设置为ON或OFF(1or0).
rpl_semi_sync_master_timeout是控制Master等待多长时间被告知Slave已收到,也就是所谓的超时时间。
rpl_semi_sync_slave_enabled是控制Slave是否开启半同步,开启或不开启,将其设置为ON或OFF(1or0)。
监控半同步复制的状态变量(几个常用的)
Rpl_semi_sync_master_clients:查看有多少个开启半同步复制的插件的Slave
Rpl_semi_sync_master_status:查看在Master上半同步复制是否正在运行,其值为ON时,说明Master已启用半同步且已被告知有Slave收到;其值为OFF时,说明Master没启用半同步或是没被告知,由于timeout等原因。
Rpl_semi_sync_master_no_tx:查看有多少事务没有用半同步复制的机制进行复制。
Rpl_semi_sync_master_yes_tx:查看有多少事务是通过半同步复制机制成功复制。
Rpl_semi_sync_slave_status:查看Slave上半同步复制是否正常运行,其值为ON时,说明Slave正通过半同步复制且Slave I/O正在运行;为OFF时,反之。
说明关于其它的请参阅:
半同步复制的安装,配置
环境要求:i.MySQL5.5或以上版本
ii.在MySQL上安装插件需要数据库支持动态载入。检查是否支持,用如下检测:
mysql& show global variables like 'have_dynamic_loading';
+----------------------+-------+
| Variable_name& & & & | Value |
+----------------------+-------+
| have_dynamic_loading | YES&
+----------------------+-------+
1 row in set (0.00 sec)
iii.半同步复制是基于复制的环境。也就是说配置半同步复制前,已有复制的环境。
在Master上执行:
mysql& INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
各个Slave上执行:
mysql& INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
如果不清楚Plugin的目录,用如下查找:
mysql& show global variables like 'plugin_dir';
+---------------+----------------------------------+
| Variable_name | Value& & & & & & & & & & & & & & |
+---------------+----------------------------------+
| plugin_dir& & | /opt/usr/local/mysql/lib/plugin/ |
+---------------+----------------------------------+
检查Plugin是否已正确安装:
mysql& select * from information_schema.
在Master上执行:
mysql& SET GLOBAL rpl_semi_sync_master_enabled = 1;
mysql& SET GLOBAL rpl_semi_sync_master_timeout = N;
在Slave上执行:
mysql& SET GLOBAL rpl_semi_sync_slave_enabled = 1;
如果在一个正在运行的Slave上开启半同步复制的功能,必须先停止Slave I/O,将其启用半同步后,再开启Slave I/O.
mysql& STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
如果不这样做,Slave还是会以异步的方式进行复制。
正如大家所知,如果不将变量的设置写到配置文件,下次重启数据库,将失效。写入配置文件:
Master上:
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 1 second
rpl_semi_sync_slave_enabled=1
总结:半同步复制个人感觉是维持数据完整性,安全性的的一个策略,虽会损失一点性能,还是值得的。配置很简单,关键是理解其工作机制。
相关资讯 & & &
& (08月17日)
& (07月25日)
& (02月22日)
& (08月05日)
& (07月11日)
& (01/07/:39)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款谈谈复制_数据极客_传送门
复制几乎是构成分布式系统,尤其是分布式存储和分布式数据库的关键所在,那么本文就来综合谈论下复制技术。简单说复制本身可以分为同步复制和异步复制,两者的区别在于前者需要等待所有副本返回写入确认,而后者只需要一个返回确认即可。从用途上,复制可以分为两类,一类用于确保不同副本的表现行为一致(避免divergence),另一类则用于允许不同副本之间的数据差异(divergence不可避免,如Dynomo),先来看看前者。有若干种手段用于确保不同副本之间的状态一致:第一种叫主从复制。主从之间可以是异步复制,也可以是同步复制。例如MySQL,在默认情况下采用异步复制,异步复制容易引起数据丢失,比如主从结构中,主节点的写入请求还没有复制到从节点就挂了,当从节点被选为新的主节点之后,在这之前写入没有同步的数据就会被丢失。即便采用了同步复制,也只能提供相对较弱的基本保障,考虑如下情形:主接收写入请求然后发到从节点,从节点写入成功后并发送确认给主,如果此时主节点正准备发送确认信息给客户端时挂了,那么客户端就会认为提交失败,可是从节点已经提交成功了,如果这是从节点被提升为主,那么就出现问题了。在主从复制结构里,异步复制相比同步复制具备更高的吞吐量和更低延迟,因此,结合同步和异步复制是一个常见选项。比如Kafka,根据它的声称,这是一个CA系统,也就是同时达到数据一致和高可用。Kafka的复制设计同时包含异步复制和同步复制,同步复制节点组成的集合称为ISR(In-Sync
Replicas),只有ISR内的所有节点都对写入确认之后,才算做写成功。当一个节点失效,Leader会通过ZooKeeper感知并把它从ISR
中移除。不过Kafka有一个问题,因为它声称F个节点可以容忍F-1个节点失效,这跟其他系统不同,通常类似的设计只能容忍F/2-1个节点失效,也就是说要确保大多数节点都能正常运行,而Kafka这把这个条件弱化成为只有Leader运行也可以。这样做是有问题的:假设ISR只剩下一个Leader在运行,如果此时Leader跟ZooKeeper的网络连接中断,就会产生一次选举,让ISR之外的节点(那些异步复制节点)加入ISR,通常它会落后此前的Leader不少。当原先的Leader跟ZooKeeper网络连接恢复后,系统就产生脑裂,需要对2个Leader的数据做Merge或者舍弃,后者则会导致数据丢失。另一个例子来自数据库高可用设计,如下是Joyent的PostgreSQL高可用方案manatee,一个主节点带一个同步复制的从节点,以及若干异步复制从节点,当主节点挂了之后,同步复制节点被选举为主节点,异步复制节点选举一个提升为同步复制,而此前挂掉的节点恢复之后首先加入异步复制集群。另一个高可用设计MaxScale项目也是类似的设计,直接针对BinLog搭建Replication Proxy,该Proxy同时作为主节点的Slave,以及其他Slave的Master。因此可以看出,主从复制对于数据的保障不高,基于主从结构做高可用设计总是一件很困难的事情。第二种复制手段是通过两阶段提交来提供更高的保障。例如MySQL Cluster就是通过2PC来提供数据同步的。相比之下,主从复制可以看做一阶段提交,因为没有发生错误的回滚。由于2PC很容易因为参与者宕机导致一直阻塞,因此2PC用于复制并不常见。第三种则引入分区一致性算法Paxos,又叫复制状态机。复制状态机在数据库开发的很多领域都可以遇到,比如Google Megastore,针对不同分区的每次提交采用复制状态机来确保每个分区的全局事务提交时序;Google Spanner在单分区内也采用了类似的设计。复制状态机主要用于满足两点需求:客户端在面对任何一个副本时都具备完全一致的访问行为;每个副本在执行请求时都需要按照完全一致的顺序来进行。复制状态机通常都是基于复制日志实现的,每一个服务器存储一个包含一系列指令的日志,并且按照日志的顺序进行执行。每一个日志都按照相同的顺序包含相同的指令,所以每一个服务器都执行相同的指令序列。因为每个状态机都是确定的,每一次执行操作都产生相同的状态和同样的序列。保证复制日志相同就是一致性算法的工作了。在一台服务器上,一致性模块接收客户端发送来的指令然后增加到自己的日志中去。它和其他服务器上的一致性模块进行通信来保证每一个服务器上的日志最终都以相同的顺序包含相同的请求,尽管有些服务器会宕机。一旦指令被正确的复制,每一个服务器的状态机按照日志顺序处理他们,然后输出结果被返回给客户端。因此,服务器集群看起来形成一个高可靠的状态机。复制状态机如此重要,那么有没有独立的实现呢,ZooKeeper和Raft都是。以ZooKeeper为例,它实现了基于ZAB(ZooKeeper Atomic Broadcasting)协议的复制状态机。Leader产生状态变化后,跟随者产生相应的持久化日志并做确认。当从足够的副本(包含跟随者和Leader)获得ACK确认后,Leader通过发送提交信息进行一次提交。当某副本得到提交信息后,它应用到本地并进行相应的状态调整,所以,在ZooKeeper里进行一次状态确认需要两轮的消息传送,这是消耗很高的工作。除了在Spanner这种前卫数据库中见到的复制状态机,在常规数据库里我们能见到的很少(拿来做分布式协调者的不算),那么,我们通常见到的MariaDB Galera Cluster是否算复制状态机呢?Galera完全是多主同步复制,复制协议采用Atomic broadcast,而原子多播是复制状态机的一种实现[4]。Galera的复制工作如下:1. 事务在本地节点执行时采取乐观策略,成功广播到所有节点后再做冲突检测2. 检测出冲突时,本地事务优先被回滚3. 每个节点独立、异步执行队列中的Write Set4. 事务T在A节点执行成功返回客户端后,其他节点保证T一定会被执行,因此有可能存在延迟,即虚拟同步Galera是同步复制方案,事务在本地节点(客户端提交事务的节点)上提交成功时,其它节点保证执行该事务。在提交事务时,本地节点把事务复制到所有节点后,之后各个节点独立异步地进行certification
test、事务插入待执行队列、执行事务。然而由于不同节点之间执行事务的速度不一样,长时间运行后,慢节点的待执行队列可能会越积越长,最终可能导致事务丢失。Galera内部实现了flow control,作用就是协调各个节点,保证所有节点执行事务的速度大于队列增长速度,从而避免丢失事务。根据[2]的测试结果,Galera会导致stale read,也不能提供宣称的快照隔离事务级别,因此,选择的时候需要知道它的适用场景。此外,还有一种复制叫做链式复制,本号之前的文章有介绍,它是主从复制的变种,所有读请求都转发到尾部节点响应,所有的写入请求都从头部节点写入,因此所有写入请求都严格按照单一时序进行,而针对尾部的读请求可以做到强一致性。相比复制状态机,链式复制可以提供更高的容错性,因为Paxos是基于多数选举原则的算法,如果系统可以容纳F个节点错误,那么系统中需要有2F+1个副本存在,而链式复制只需要F+1个副本。跟主从复制相比,主从复制中的主节点的角色在简单链式复制中由2个副本承担:头节点负责写入请求的顺序化,尾节点负责响应。这种角色的分工可以产生更低的读延迟和开销,因为只有一个节点负责处理读请求,而且不用等待其余任何副本的写入请求,然而,链式复制的写入延迟会增加,因为需要链上的所有副本都串行写入成功后才可返回响应,这一点要大大低于主从结构。因此,简单链式复制适用于高吞吐量和强一致性要求的场景(高并发读,低延迟写属于被牺牲的方面)。再来看看第二种复制的用途——允许不同副本之间的数据差异。比如在Dynamo系统中,不同副本的数据并不总完全一致,可以按照R+W和N的关系进行Quorum选举。首先看看强Quorum,就是R+W>N的情况。这种情形是完全可以保证数据读写一致的,正如Amazon Dynamo那样。典型部署如下:在N个节点中,R=1,W=N,这是针对读优化的场景R=N,W=1,这是针对写优化的场景R=N/2,W=N/2+1,这是针对读写适中的场景例如默认情况下,Riak采用了N=3,R=2以及W=2的配置。当R+W<=N时,叫做Partial Quorum,通常用于低延迟的服务,此时,读取不一致数据的概率是:当N的值很大时,不一致的概率就会降低。2012年的文章PBS(Probabilistically Bounded Staleness)就是基于此提出的理论,旨在提供最终一致的程度,并在Cassandra数据库上进行了实现[3],根据测试,N=3时,从R=1, W=1变换到R=2, W=1时,数据不一致的窗口可以从1352 ms降低到202 ms,同时相比R=3,W=1的219ms延迟, R=2,W=1则可以降低到32ms。采用Quorum算法可以提供比Paxos更高的吞吐量,例如Apache BookKeeper项目,区别于ZooKeeper基于选举和一致性模块机制的复制状态机,BookKeeper可以服务高吞吐量的分布式日志系统。BookKeeper仍然依赖ZooKeeper作为一致性模块,这个项目已经很多年没有更新了,如果不是看到近期Twitter采用BookKeeper作为其分布式日志核心组件的介绍[1],也不会关注到。在BookKeeper中,引入一个概念叫Ledger,可以把它看作事务日志,对于每个Ledger,都只有唯一的写入者,写入者通过多个被称为Bookie的节点向Ledger同时写入,当大部分Bookie被写入,并且可以通过向不同组的Bookie写入不同数据提高写入并行度。然而对于需要读取的客户端来说,就存在困难,因为它无法知道这些写入的数据是否被正确地复制到了其他副本,所以需要从多个Bookie读取数据才能确保一致。此外,BookKeeper还引入了ZooKeeper来存放被正确复制的最后记录的ID,为避免过于频繁地向ZooKeeper写入数据,该操作仅在Ledger关闭时进行。通过一系列优化,尽管通过一致性模块进行协调,但BookKeeper仍然保持了非常高的吞吐量和低延迟---差不多可以达到百万TPS和10毫秒级别,非常适合作为分布式日志和消息队列,Yahoo的Cloud Message Service也基于它进行。关于复制还应当了解的一个话题叫做CRDT[5],全称叫做Convergent Replicated Data Type,目的是提供不用协调的收敛到一致的数据结构,因此又称为Conflict-free Replicated Data Type。分布式计数器是CRDT数据结构中最常见的一个例子:假设每个用户都能写入到自己的计数器中,当每个用户需要改变它的计数器数值时,它只改变自己的数值,这样就有了并发同时发生的数值增加。因此,这是个分布式系统,那么如何得到最后的整个计数器结果?只要将单独的这些计数器加起来即可—为了得到一个全局整体的计数器,每个节点用户都需要知道彼此另外节点上的计数器值,可以在节点间广播这些值。可是网络不是100%可靠,广播的消息有可能会丢失或延迟到达。解决消息丢失并不容易,让我们来看看如何解决:1. 在发送方,节点服务器规则地广播它们的状态。2. 在接收方,我们需要一种方式搞清楚发现消息的重复,节点服务器通过比较接受值和现有值,如果这两个值是相同的表示这是重复的消息,否则就是一个新的消息,更新原来的值即可。解决延迟消息投递问题需要另外的技巧:假设计算器总是不断向前增加,不允许减少。那么现在该发现当接受到消息应该怎么做了:只要选择接受值和现有值之间最大差值的那个值。这样,每个节点都知道接受到消息后该怎么做,我们有了最终强一致性,因为只要一个节点接受到所有广播消息事件(无论以任何顺序),它会知道计数器当前状态,每个节点的状态也是相同的,没有冲突,所有节点最终会汇聚到相同的值。这就是CRDT的分布式计数器。CRDT还有其他一些应用场景,具体可以看[5]的综述:支持加法和减法的计数器Last-Writer-Win注册器(一个注册器是一个能够存储对象和值的单元) – 基于时间戳mergeMulti-value 注册器 – 基于版本向量merge,如Amazon的DynamoGrow-only Set (支持新增和寻找). 这将会表明对于高级类型是有用的构建块。2P-Set (two-phase两段集合set), 其每个条目能被增加或可选移除,但是不会在其后再次增加U-Set, (unique set). 2P-Set的简化。Last-Writer-Wins element Set, 元素条目是有时间戳,有add-set 和 remove-setPN-Set 为每个元素保留计数器Observed-Remove SetRiak以及Akka都有支持CRDT数据结构的工具包[6][7]。复制的话题非常广泛,几乎涵盖了分布式系统设计的每个方面,下次本号再次涉及该话题时,将重点讲述复制状态机在新型数据库中的具体设计。[1] q.com/cn/news/2015/09/BookKeeper-Twitter[2] /posts/328-call-me-maybe-percona-xtradb-cluster[3] http://pbs.cs.berkeley.edu/
Probabilistically Bounded Stalenessfor Practical Partial Quorums[4] /?p=603[5] A Comprehensive Study of Convergent and Commutative Replicated Data Types[6] /riak/latest/theory/concepts/crdts[7] /jboner/akka-crdt
觉得不错,分享给更多人看到
数据极客 微信二维码
分享这篇文章
数据极客 最新头条文章
数据极客 热门头条文章

我要回帖

更多关于 小额信贷管理系统源码 的文章

 

随机推荐