(译)Things I Wished More Developers Knew About Databases
翻译整理自 https://medium.com/@rakyll/things-i-wished-more-developers-knew-about-databases-2d0178464f78
You are lucky if 99.999% of the time network is not a problem.没有网络问题你就走大运了兄弟
一个数据,With 99.999% service availability, Google cites only 7.6% of Spanner (Google’s globally distributed database) issues are caused by networking even though it keeps crediting its dedicated networking as a core reason behind its availability.
ACID has many meanings. 正确理解ACID
ACID实现麻烦,NoSQL部分甚至没有ACID,在实现ACID上也有各种妥协,比如mongo的实现
提交落盘是个很重的操作,为了写性能高一些,就会牺牲一点D
Each database has different consistency and isolation capabilities. 每种数据库有自己的一致性和隔离策略
上面说了D,关于CI,实现也是各有取舍。根据CAP定律,C和A之间互有取舍(译者注:CAP的C和ACID的C不是一回事儿,但是这里说的consistency好像是一个事儿)
隔离级别实现程度不同,使用者按照自己的接受方案来做取舍
SQL标准的四个隔离级别,串行SI,可重复读RR,读提交RC,脏读RU,越严格代价约大,一般也就RC RR采用
https://github.com/ept/hermitage 这个文档介绍了不同隔离界别下数据库设计的实现场景
Optimistic locking is an option when you can’t hold a lock.当你拿不到所,就用乐观锁
数据库的锁是很重的,引入竞争,且要求数据一致性,排到锁所可能会受到网络分区的影响(译者注:为什么)也可能导致死锁,不好识别和解决,所以乐观锁就出现了,先更新,再检查版本,拿锁,拿不到,算了。
There are anomalies other than dirty reads and data loss. 有比脏读和丢数据更异常的场景
写偏序,没脏读,没数据丢失,但是结果就是不对
识别写偏序是很困难的。串行化,schema设计,数据库限制来约束写偏序
My database and I don’t always agree on ordering.数据库和我在时序上有不同的意见
用事务
Application-level sharding can live outside the application.应用级别分片可以脱离于应用本身
分片是水平扩展的放水阀,应用层分片也就是架构师/开发能预测数据怎么增长,能很好的水平扩展分片
其实想说就是分片在数据库上层,比如mycat这种,作者给的例子是vitess
AUTOINCREMENT’ing can be harmful. 自增ID可能有害
主键自增id在一些场景下的缺陷
- 分布式数据库系统,维护全局自增代价过高
- 根据主键做分片,自增id可能导致写偏序,热点分布不均匀
- 主键更有意义,更唯一话,击中更快一些(译者注?这个影响会很大吗?)
主键自增ID和UUID索引在某些场景下都是个坏主意,要注意
Stale data can be useful and lock-free.过期数据可能有用且无锁
这里指的MVCC以及对应的快照实现,轻便无锁
- 主动淘汰 vacuum
- spanner有gc (译者注:rocksdb也有gc)
Clock skews happen between any clock sources. 什么时钟源都会有时钟偏序
时间同步,ntp服务gps时钟原子钟等等
google spanner是怎么保持整体时间有序的? TrueTime
Latency has many meanings.延迟的多种含义
对于数据库来说,延迟包含两部分,数据库本身延迟和客户端网络延迟,分析延迟相关问题以及指标时,要注意这两种
Evaluate performance requirements per transaction. 评估tps性能
要从典型场景考虑,比如
- 插入一定条数数据的写吞吐和延迟
- 查表的延迟。。。
这属于POC了吧,总之要考虑性能能不能满足自身业务的需求,并且收集指标信息和日志来分析
关于延迟的一些诊断方法,见https://medium.com/observability/want-to-debug-latency-7aa48ecbe8f7
Nested transactions can be harmful. 嵌套事务有害
Transactions shouldn’t maintain application state. 事务不应该维护应用的状态
指的是事务和数据共享竞争导致的数据错误
Query planners can tell a lot about databases.查询计划告诉你数据库的信息
就是看是不是全表扫描还是索引扫描了 explain
Online migrations are complex but possible.在线迁移复杂但也不是不可能
- 双写数据库
- 两个db都可读
- 新db接管主要的读写
- 停止写入旧db,只读,这时在新db上的读可能失败,因为数据不全,有一部分新数据没有
- 同步所有数据,新写的新数据和旧数据
这是粗糙概括,参考文章https://stripe.com/blog/online-migrations
Significant database growth introduces unpredictability.数据库显著增长带来更多的不可预测问题
扩容了,即使你了解你的数据库,但还是可能会有不可预测的热点,不均匀的数据粉扑,硬件问题,增加的流量带来的网络分区问题等等,让你重新考虑你的数据模型,部署模型等等