多机数据系统的正确性与一致性

Tags: 系统设计 

本篇目录

什么是数据系统?

凡是需要在「本地」保存数据,并对外开放「读写」功能的系统,都是数据系统。套用微服务里的概念,数据系统都属于「有状态服务」,与之相对纯粹负责计算的系统属于「无状态服务」。典型的 Mysql 数据库、Redis 都是有状态的数据系统。

按照组成系统的机器数量,数据系统又可以分为「单机数据系统」和「分布式数据系统」。

一台 MySQL 属于单机数据系统,如果:

  1. 增加了一台 MySQL 作为备份机,实现读写分离后,这两台 MySQL 构成了一个分布式数据系统
  2. 增加了一台 MySQL,把当前 MySQL 上的一些表迁移到了新 MySQL 上,这两台 MySQL 构成了一个分布式数据系统。

1 和 2 是分布式数据系统的中两种截然不同的情况,需要解决的问题也是不同的,后面阐述。

单机数据系统和分布式数据系统有各自需要解决的但是又非常类似的问题,简单说就是:

  1. 数据正确性问题
  2. 读写一致性问题

单机的数据正确性

单机数据系统实现时可能要解决各种各种的问题,但是很多问题都可以转换为一个问题:

  • 如果机器突然断电了,怎么办?

机器突然断电时,数据可能没写入磁盘、写了一半到磁盘、全部写入了磁盘,要怎么对待「处于中间状态」的数据,它们是可信的还是不可信的?后续的操作能不能使用它们?

个人认为这个问题是「数据的正确性」问题,磁盘上有不可信的数据,或者说脏数据。

数据库系统的处理方法是:

  • 提供原子操作。在操作系统的磁盘与用户之间增加一层,在这一层中通过 binlog、redolog 的各种技术手段,让用户的数据提交动作,要么成功,要么失败,对用户而言不存在中间态,从而保证用户读写的数据是正确的,不是脏的。

ACID 原子、一致、隔离、持久,可以认为 A、C、D 都在解决正确性。

ACID中C的定义无论是维基百科还是数据库教材都没有一个特别明确的说明,所以我们采用最广泛使用的 MySQL 数据库对 C 的定义 https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_acid

The database remains in a consistent state at all times — after each commit or rollback, and while transactions are in progress. If related data is being updated across multiple tables, queries see either all old values or all new values, not a mix of old and new values.

即数据状态始终是一致的,在事务的任何阶段,要么读到的都是旧数据、要么读到的都是新数据,读到的数据不能是「新旧混合」的。我更倾向于这是「正确性」,以和后面的「并发读写一致性」、「多副本场景的一致性」区别开。

撇开数据库,我们可以继续探讨,往单实例的 redis 中写数据到一半时,如果断电会怎样?

通过研究不同系统的处理方案,可以知道它们分别提供了怎样的保障,各自的优缺点以及适用场景。

单机的并发读写一致性

单机数据系统面临的另一个问题是:并发读写同一份数据时,读操作看到的应该是哪一份数据?写之前的、写了一半的、还是写完以后的?

单机并发读写一致性应该怎样?这是一个没有答案的问题! 因为并发行为的结果是什么,纯粹是一个「怎样约定规则」的问题,规则本身没有对错。

数据库的做法是:定义了读未提交、读已经提交、可重复读、串行化,4种行为规范。数据库说:反正这四种行为规范,我都能遵守,并且只能遵守一个,至于需要我遵守哪个,那就是你的问题了。

并发读写一致性的规则制定思路时,以「并发读写操作」等价于「串行读写」为最严格的一致性规则,然后在性能与严格之间进行协调,为了性能而妥协。

多机的数据正确性

多机数据系统通常构建在单机数据系统之上,组成多机系统的每台机器对外承诺「单机数据的正确性」和「单机并发读写的一致性」。但是只有单机的承诺是不够的,因为多机系统中的数据是分散在每台单机上的:

多机数据系统

如上图所示,多机数据系统的「一份数据」被分成两段,存放在两台机器上(注意和数据多副本区别开,这里讨论的是没有数据备份的场景)。用户的一次操作,可能既要改前半段,又要改后半段。这意味着对用户而言的一次操作,实际要发送到两台机器上分别执行。

那么问题来了:两台机器中一台故障了怎么办?这个问题和单机的数据正确性,何其类似!一个是单机上操作了一半,一个是多机中部分机器完成操作部分未完成。类似的问题有类似的解决方法,即分布式事务,具体的实现方案譬如 2pc/tcc等,不是非常了解也就不展开了。。!@#¥%……&*.

多机的并发读写一致性

和单机类似,多机系统中也有并发读写的问题。多机中的并发读写行为如何约定?

目前还没找到阐述这个问题的资料,无法展开。。。

多机数据备份场景下的一致性

多机场景下,还有一个非常特殊的场景:数据备份。

多机数据系统

机器A副本完全镜像了机器A的数据,机器B副本完全镜像了机器B的数据。

数据从机器A同步到机器A副本是有延迟的,那么:

  1. 机器A副本要不要对外提供「读接口」,如果提供,用户会不会从机器A和机器A副本上读到两份不同的数据?
  2. 如果对机器A进行并发读写,这些读写操作是怎样同步到机器A副本上的,会不会有乱序?

这些问题总结为:多机数据备份场景下的读写一致性问题。

这是也是一个没有标准答案的问题,不同的系统提供不同的承诺。解决多机器数据备份场景问题的经典理论框架是 CAP。CAP 中的 C 指的是存在多副本情况的一种一致性约定。

多副本场景的下的一致性有很多种:譬如单会话单调写一致、单调读一直、自读自写,多会话的先读后写、线性一致性等。分布式数据库、redis集群、ES集群等等对外的承诺可能都是不同的,使用它们的时候首先要考虑它们承诺的是哪一种一致性。

授人以渔

以上内容都是从别的地方扒来的:

  1. 《分布式金融架构课》阅读笔记1:单机&多机并发/多副本读写正确性和一致性
  2. 《分布式金融架构课》阅读笔记2:线性一致的分布式数据系统的实现过程

强烈推荐这个专栏,微观上搞定操作系统,宏观上搞定分布式,就可以大胆闯荡江湖了。

参考

  1. 李佶澳的博客

系统设计

  1. 各大云厂商的 API 设计风格
  2. Google 是如何实践 RESTful API 设计的?
  3. Netflix 的异地多活设计: Active-Active for Multi-Regional Resiliency
  4. Facebook 的缓存系统实践经验《Scaling Memcache at Facebook》
  5. 多机数据系统的正确性与一致性
  6. 《大型网站技术架构: 核心原理与案例分析》阅读摘录
  7. 《分布式金融架构课》阅读笔记2: 线性一致的分布式数据系统的实现过程
  8. 《分布式金融架构课》阅读笔记1: 单机&多机并发/多副本读写正确性和一致性
  9. 《消息队列高手课》阅读笔记: Rabbit/Rocket/Kafka/模型/消息事务/保序等
  10. 《消息队列高手课》阅读笔记: Rabbit/Rocket/Kafka/模型/消息事务/保序等
  11. 《Redis核心技术与实践》阅读笔记: 数据类型/存储开销/Rehash/案例等
  12. 《Redis核心技术与实践》阅读笔记: 数据类型/存储开销/Rehash/案例等
  13. 《高并发系统设计40问》阅读笔记: 数据库/缓存/消息队列/分布式服务
  14. 《高并发系统设计40问》阅读笔记: 数据库/缓存/消息队列/分布式服务
  15. 《MySQL实战45讲》阅读笔记: 索引类型/数据可靠性/事务/间隙锁/临时表等
  16. 系统性能分析方法论: 统计图谱工具
  17. 张磊《深入剖析Kubernetes》专栏的阅读笔记
  18. 代理服务软件haproxy、nginx、envoy对比,以及开源的API网关项目对比
  19. 蓝绿部署、金丝雀发布(灰度发布)、A/B测试的准确定义
  20. 阿里巴巴的应用限流和服务降级是怎样实现的?|如何打造平台稳定能力
  21. 陈皓《左耳听风》专栏的阅读笔记(持续更新)
  22. 好雨云帮,一款不错的国产开源PaaS
  23. 怎样为软件的不同版本命名?
  24. 怎样选择开源项目的license?
  25. Glusterfs的架构
  26. 怎样设计一个企业级的PaaS平台?
  27. 几种常见的LDAP系统
  28. DNS SRV介绍(一种用DNS做服务发现的方法)
  29. DNS,DNS-Domain Name System
  30. 思科的网络设备
  31. 虚拟化技术汇总
  32. 认证与授权系统的汇总
  33. 高可用实现方法汇总
  34. 编译器汇总
  35. Linux系统的优化方法
  36. CentOS7的一些变化
  37. 分布式系统的一些知识
  38. 计算机编程语言的特性汇总
  39. 网络通信的一些基础知识
  40. PCIE总线的一些知识
  41. 操作系统的API
  42. 网卡的一些知识
  43. Linux系统的构建过程
  44. 数据结构与算法
  45. CPU的相关知识

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  李佶澳的博客  系统软件  程序语言  运营经验  关注方向  水库文集  网文收藏  网络课程  发现知识星球  百度搜索 谷歌搜索