身为开发人员,这些数据库合知识不掌握不合适( 三 )


身为开发人员,这些数据库合知识不掌握不合适

文章插图
如果要求原子性(完整提交或放弃所有操作),而且顺序很重要,那么操作T1和T2应该在同一个数据库事务中运行 。
7应用程序层的分片可能需要在应用程序之外实现分片是数据库水平扩展的一种方式 。尽管一些数据库能够自动实现水平扩展,但也有一些数据库不能,或者不擅长该功能 。如果数据架构师和开发者能够预测数据点访问方式,那么可以在用户的层次实现水平分片,而不是将该任务交给数据库 。这称为应用程序层的分片 。
“应用程序层分片”这个名字通常会带来错误的印象——分片存在于应用程序服务之间 。然而,分片功能可以实现为数据库之上的一层 。根据数据增长和数据结构的迭代方式,分片需求可能会变得非常复杂 。如果能迭代实现某些策略,而不需要重新部署应用程序服务器,是最理想的 。
身为开发人员,这些数据库合知识不掌握不合适

文章插图
应用程序服务器与分片服务解耦合的例子
将分片作为单独的服务可以提高迭代分片策略的能力,而不必重新部署应用程序 。应用程序级分片系统的此类示例之一是Vitess 。Vitess为MySQL提供了水平分片,并允许客户端通过MySQL协议连接到它,并且它在彼此不认识的各个MySQL节点上分片了数据 。
8  AUTOINCREAMENT可能有害AUTOINCREMENT是生成主键的常用方式 。利用它生成ID的情况数不胜数,但有些数据库也会使用专门的ID生成方式 。下面是使用自增和使用专用主键生成方式的一些优缺点:
  • 在分布式数据库系统中,自增可能会很困难 。需要全局锁才能生成ID 。如果生成UUID,则数据库的各个节点之间不需要任何合作 。带有锁的自增可能会导致数据冲突,可能会导致分布式下的插入操作产生严重的性能降级 。一些数据库如MySQL可能会要求特殊的配置,才能正确地在双主架构中实现自增 。这种配置很容易搞错,从而导致写操作失败 。
  • 一些数据库具有基于主键的分区算法 。顺序ID可能会导致无法预测的热点,并且可能会使某些分区不堪重负,而另一些分区则保持空闲状态 。
  • 访问数据库中行的最快方法是通过其主键 。如果有更好的方法来标识记录,则顺序ID可能会使表中最重要的列成为无意义的值 。请尽可能选择一个全局唯一的自然主键(例如用户名) 。
在采用自增ID或UUID作为索引、分区或分片时需要认真考虑哪种方式最合适 。
 
过时的数据可能有用且无锁多版本并发控制(MVCC)引入了许多我们上面谈过的一致性功能 。一些数据库(如Postgres,Spanner)使用了MVCC来保证每个事务都看到一个快照(数据库过去的某个版本) 。事务和快照依然可以序列化,以保证一致性 。在从旧的快照中读取时,你读到的是过时的数据 。
读取稍稍过时的数据可能很有用,例如从数据中生成分析报告,或者计算大致的聚合值 。
读取过时数据的第一个好处就是延迟(特别是当数据库分布在不同物理地区时) 。MVCC数据库的第二个好处就是,它允许只读事务无锁执行 。如果能够接受过时数据,那么在存在大量读取的应用程序中,无锁是最大的优势 。
身为开发人员,这些数据库合知识不掌握不合适

文章插图
即使太平洋另一侧的数据库中存在最新版本,应用程序服务器依然从本地副本中读取5秒之前的旧数据 。
数据库会自动清理旧版本,在某些情况下,你可以按需进行清理 。例如,Postgres允许用户按需使用VACUUM命令,同时也会每隔一段时间自动执行清理 。Spanner会定时执行垃圾回收来清理超过一个小时的旧版本 。
 
只要存在时钟,就会发生时钟偏斜计算中最隐秘的秘密就是所有时间的API都是谎言 。我们的机器无法准确知道当前时间 。我们的计算机都包含一个石英晶体,该石英晶体会产生一个计时信号 。但是石英晶体无法准确地计算时间,总会比实际的时钟快或慢 。每天的漂移可能长达20秒 。为了准确起见,我们的计算机上的时间需要不时地与实际时间同步 。
我们使用NTP服务器进行同步,但是同步本身可能出现网络延迟 。与同一数据中心中的NTP服务器同步可能需要一些时间,与公用NTP服务器同步可能会导致更多偏差 。
原子钟和GPS时钟是确定当前时间的更好来源,但是它们太昂贵,并且需要复杂的设置,因此无法安装在每台机器上 。考虑到这些限制,数据中心通常会使用多层方法 。原子钟或GPS时钟能够提供准确的计时,它们的时间会通过另一台服务器广播到其他机器 。这意味着每台机器都会在一定程度上偏离实际当前时间 。


推荐阅读