1. 写后读问题
- 一般而言,写操作会发生在主库,读操作发生在从库。主从复制采用异步复制。所以可能会导致用户在主库写入后立即从从库读取最新的更改过程中,因为异步复制的延迟无法读取的最新的更新数据。
1.1 如何解决
- 从主库读取用户自己的档案,在从库中去取其他用户的档案
- 自己的档案自己可编辑,而其他人无法编辑
- 这种方式适合可编辑内容只有少数人能写而大多数人只能读的情况
- 客户端记住最近一次写入的时间戳,系统需要确保从库为该用户提供任何查询时,该时间戳前的变更已经传播到本从库中。否则就从主库读
- 时间戳可以是逻辑时间错,比如日志序列号,也可以是实际系统时钟
- 这种方式不适合同一个用户从多个设备请求服务。因为一台设备上运行的程序不知道另一台设备上发生了什么(是否更新了时间戳)。
2. 单调读问题
- 用户a向主库1写入数据,然后异步向从库2和从库3机型复制。
- 此时用户b向从库2读数据,假设从库2完成了复制,则用户b会从从库2里面读到用户a修改的数据。
- 然后用户b刷新了网页,导致再次读取数据库,但这次请求被路由从库3,而从库3还未完成数据复制,而导致用户b无法读到用户a修改的数据。
- 则对于用户b来说刚开始能读到,刷新后又读不到,让人头大,这就是为保证单调读的后果
3.1 如何保证单调读
- 保证每个用户总是从同一个副本进行读取,不同的用户可以从不同的副本读取。
- 可以基于用户ID的散列值来选择副本
3. 一致性前缀读
- 如果一系列的写入按照某个顺序发生,那么任何人读取这些写入时,也会看见它们以同样的顺序出现
3.1 如何保证一致性前缀读
- 一致性前缀读时分区数据库的一个特殊问题。许多分布式数据库中,不同的分区独立运行,因此不存在全局写入顺序:当用户从数据库中读取数据时,可能会看到数据库中的某些部分处于较旧的状态,而某些处于较新的状态
- 一种解决方法:确保任何因果相关的写入都写入相同的分区。