数据密集型应用 第二部分 分布式数据
复制
1 同步复制
优点: 从库与主库保持高度一致。 主库失效可以立即切换从库
缺点: 从库出现异常时 主库跟着嗝屁
2 异步复制
优点:不影响主库写入,
缺点:有时可能落后主库几分钟之久。例如:从库正在从故障中恢复、系统在性能瓶颈运行,或者节点间网络问题。
半同步
将所有从库都设置为同步的事不切实际的,任何一个节点的中断都会导致整个系统停止服务。如果启用同步复制,通常一个slave 是同步,其余异步方式。如果同步从库变得不可用或缓慢,则使一个异步从库同步。保证至少两个节点拥有最新的数据副本。
新从库过程
1 某个时刻获取主库一致性快照。而不必锁定整个数据库。 MySQL innobackupex
2 将快照复制到新的主从节点
3 从库连接到主库,并拉取快照之后发生的数据变更(MySQL 二进制日志坐标 binlog coordinates)
4 从库处理完快照之后积压的数据变更后赶上(caught up)主库。现在他可以继续处理主库产生的变化了。
处理节点宕机
1 从库失效:追赶恢复
从库崩溃、重启、主从网络中断。 从库从日志找到最后一个事物,请求数据变更。
2 主库失效:故障切换 故障切换会出现很多大满帆。 脑裂等、主从自增不一致等
其中一个从库需要被提升为新的主库,需要重新配置客户端,将他们的写操作发送给新主库。其他从库需要开始拉取来自新主库的数据变更。故障切换(failover)
容忍节点故障只是需要复制的一个原因。还有可扩展性、和延迟需求
读写分离 (查多偶尔写)
读库处理客户端请求。写库处理所有的写请求
如果用户写入后立刻查看数据,可能出现新数据未到达副本,看起来像是刚刚提交的数据丢失了,用户体验差。
读写一致性。
读用户可能已经修改过的内容时,都从主库读
如果应用大部分内容被编辑。 切换至从库读。
客户端记住最近一次写时间,当从库不够新,从另一个从库读,或等待后读
单调读
用户先从新副本读取,然后又去旧副本读取。 产生时光倒流 (moving backward in time)
单调读是确保每个用户总是从同一个副本进行读取。
从库读顺序一致性
确保任何因果相关的写入到相同的从库(分区) 类似kafka 分区一致性问题
多 leader
多数据中心 多主复制
性能
容忍数据中心停机
数据中心之间的网络问题
离线数据库
写入冲突
同步与异步冲突检测。 即 等待写入被复制到所有副本,然后返回成功。 这样可以使用单主程序复制
缺点:放弃了多 leader 优势。这种应该使用单主
避免冲突
特定记录写入特定 leader
缺点:额外处理步骤
收敛至一致的状态 最后写入胜利
最后一个写操作确定该字段最终值。 每个写入唯一ID (时间戳)挑选最后者写入。丢弃其他修改。 最后写入胜利 (LWW, last write wins)
缺点:丢失记录数据
分区
分区目标是将数据和查询负载均衡。
极端情况所有负载压入一个分区,其余9节点空闲。不均衡导致分区热点
预分区
动态分区
分区增长超过配置大小(HBase 10G) 会被自动分成两个分区。每个分区占一半数据。 如果大量被删除优惠产生分区合并。
优点:动态适应。
缺点:大数据情况的IO风暴
事物
提交 commit 、 终止 abort、 回滚 rollback
ACID 原子性、一致性、隔离性、持久性
Read committed
1 读时,只看到已提交。没有脏读
2 写入,只覆盖已写入。没有脏写
快照隔离 一致快照
数据库必须保留一个对象的几个不同的提交版本。维护多个版本的对象。
实现快照隔离。 读不进行任何锁,写不锁。
串行执行
特定约束条件下,串行执行事物实现可序列化隔离等级的可行办法
每个事物必须小而快,一个缓慢全der
活跃数据被放入内存情况。很少磁盘交互。
写入吞吐量在单核 cpu 可以处理 或者 事物能划分至单个分区并且不需要跨分区协调
跨分区事物是可能的,但是限制很多。
两阶段锁定