《数据密集型应用系统设计》读书笔记

220 阅读3分钟

第五章 数据复制

概述

  • 数据复制的目的

  • 低延时

  • 高可用

  • 高吞吐

主从复制方式及故障恢复

  • 主从复制过程

  • 主节点:可读写

  • 从节点:只读

  • 日志从主节点同步到从节点

  • 复制方式(各自优缺点)

  • 同步复制

  • 异步复制

  • 半同步复制

  • 链式复制(待深入)

  • 增加从节点步骤:快照+append日志

  • 节点故障恢复

  • 主节点:选举

  • 从节点:日志

  • 问题

  • 脑裂

  • 选举的新主节点数据不全

  • 复制日志形式

  • 基于语句(缺点)

  • 基于行(binlog)

复制滞后(延迟)带来的问题

  • 写后(立即)读

  • 写入主节点,立即从从节点读。似乎数据丢失

  • 实际场景:用户编辑保存个人信息

  • 强一致性场景

  • 解决方案

  • 强制读主节点

  • 客户端记录更新时间戳,带入请求;从节点判断是否满足时间戳,否则转移给另一个节点处理

  • 单调读

  • 第一次读某节点有新数据,第二次读另一个节点没有新数据。似乎数据丢失

  • 实际场景:评论列表获取刷新,有评论消失

  • 一致性要求弱于写后读

  • 解决方案

  • 确保同一个用户固定读一个节点(基于userId哈希)

  • 前缀一致读

  • 实际场景:群聊消息顺序错乱

  • 解决方案:见后

主从架构

  • 单主节点(如上)

  • 多主节点

  • 优点

  • 高性能

  • 主节点切换方便

  • 缺点:写冲突问题(单主节点不会存在这种问题),两个存在冲突的写请求访问不同的主节点,写入都成功。如何处理写冲突

  • 避免冲突;同一个用户固定访问某个主节点(UserId哈希)(应用最多)

  • LWW:写请求时间戳,最后者获胜。会丢数据

  • 逻辑合并;用户提示

  • 自动冲突解决算法:CRDT、OT、MPD(待深入)

  • happen-before:

  • 服务端下发最新版本号

  • 客户端写请求前,必须先发送读请求

  • 覆盖低版本写入

  • 架构模式(各自缺陷)

  • 环形

  • 星形

  • 全拓扑(常用)

  • 日志覆盖顺序问题:版本向量

  • 无主节点

  • quorum

  • 原则:n个节点,写确认w个,读查询r个,则必有w+r>n

  • 缺陷:

  • sloppy

  • 时钟偏差

  • 写入失败,但已经写入的节点无法回滚。脏数据

第六章 数据分区

  • 分区和复制的结合图6-1:一个节点多个分区,其中有主副本分区和从副本分区

  • 唯一主键分区策略

  • 基于主键(关键字)

  • 优点:有序性,区间查询

  • 缺点:热点集中(如以时间戳为关键字)

  • 基于主键哈希

  • 特性和直接用主键相反

  • 折中:id+timestamp(Cassandra)

  • 二级索引分区

  • 基于唯一主键分区(ES,MongoDB)

  • 主键分片后,各自维护二级索引,广泛应用

  • 优点:写快

  • 缺点:读需要聚集,慢

  • 基于二级索引分区

  • 对二级索引值直接分片(直接法or哈希,类似主键分区)

  • 特性和唯一主键分区相反

  • 往往异步写操作

  • 分区平衡

  • 取模的问题:节点数变化,迁移量大

  • 固定分区法:分区数远大于节点数

  • 动态分区法

  • 多节点多分区路由请求策略(需要感知节点和分区映射关系,可能是客户端、路由、节点)

  • 客户端任意连节点,若该节点无目标分区则转发给下一个节点

  • 引入路由,客户端连路由,路由转发

  • 客户端感知分区和节点状态,直连目标节点

  • 维护节点和分区映射关系

  • 引入独立协调服务 zookeeper

  • 分布式协议,集群节点自同步。gossip