早在1978年,当我开始我的第一份工作编程时,它就是建立一个数据库系统。 22岁那年,我不知道那是什么,但这并不重要。我需要这份工作。那家初创公司最终成为一家关机公司.1982年,我去Tandem Computers工作,从事基础架构的工作,几年后成为Tandem的NonStop SQL。
在Tandem,我了解到支持公司业务的数据库是一个复杂而复杂的生物。它不仅需要提供对客户数据的访问,还需要在线DDL,高可用性,存档,异地磁带轮换和管理,在线备份,访问控制,监视和操作支持,甚至复制到远程数据中心。我称这为最后一个功能地质容错。
数据库庞大,功能强大且昂贵。您很幸运拥有一家,而且只有最大的企业集团能够负担得起不止一家。此外,大型主机计算机系统及其数据库非常昂贵,因此聘请数十名程序员来构建能够完全满足您需求的应用程序是非常实际的。
这导致大多数拥有闪亮的新的昂贵数据库的公司出现了一些重复出现的模式:
将非关系不可变文档,照片,音频文件,电影和其他无生命的对象填充到您无辜且未经准备的关系数据库中。
一旦您的公司收购了一个数据库,一个或多个DBA(数据库管理员)以及一个数据中心中的设置,公司中的每个新应用程序也都希望使用您的数据库!这是合理的,因为该公司确实买不起另一个主机。您确实应该分享自己的一份。
很快,数据库被数据库大祭司所包围,他们不断地为表创建和管理表的架构,并且随着新功能和新应用程序被添加到共享系统中而不断发展。随着数据库对于公司运营变得越来越重要,它的任务至关重要。在保持数据库以24 x 7或尽可能接近的速度运行所需的所有方面上,都投入了越来越多的关注。当数据库关闭时,公司也关闭了,那不是一件好事。
公司数据的所有维护和提供很快都集中在核心企业数据库上。在数据库提供者和企业数据库所有者之间,确保数据安全所需的东西真该死。
最初,每个应用程序都使用自己的表,并确保考虑到自己的业务。最终,与协商如何使用消息或接口调用另一个应用程序相比,阅读另一个应用程序的表似乎更容易。有什么害处?
很快,一个确定的趋势增加了应用程序和表格的熵和相互缠绕。跨表为不同应用程序进行事务更新变得很普遍。
“卫生”被解释为“嗨,吉恩!”当您要求数据库管理员访问另一个应用程序的表时。
当其他类型的数据需要房屋时,这些数据的所有者非常合理地希望它获得数据库所提供的相同的关怀和保护。
这些珍贵的文物有时会很大,例如扫描文档,照片甚至是电影!由于SQL可以接受Blob,因此它们可以将大量数据存储在数据库的尘土飞扬的角落。这对人们存储资料有很大的好处,而对操作数据库的人则有很大的不利之处。
对数据库的使用者来说非常好!轻松,干净地存储您的随机数据,并具有备份,高可用性和神奇的存储容量。此外,数据可以与数据库中的其他内容进行事务性更新。不用担心,可以为您的数据提供最好的照顾!生活是美好的!
这是数据库管理员的噩梦!突然之间,您的数据库开始变得越来越胖。很快,您将购买更多法律允许的最昂贵的存储解决方案。诸如照片和文档图像之类的不可变数据共存于支持数据库的SAN(存储区域网络)上。这是低效的,因为SAN是设计用于就地更新的极其昂贵的高端硬件。将它们用作不可变材料的存储库就像使用精巧的劳力士手表作为镇纸一样。
从数据库中提取这些珍贵而庞大的数据项并不像看起来那样容易。扫描纸质文档和其他介质的一成不变性质具有巨大的帮助。您可以为文档分配128位UUID,并将文档存储在其他位置。然后,可以将该标识符保存在与某些关系记录关联的数据库中。
很快,您意识到,尽管这可以将存储容量转移到更便宜的存储介质上,但仍存在挑战:
系统更新是非事务性的。通常,您需要通过以下方式更新新的统一系统:
步骤1:在数据库上的transaction-T1中,更新关系系统,说您打算将具有UUID-X的对象插入应用程序可以理解的表的列中。另一列管理持有不可变对象的存储区中对象的状态。
步骤3:最后,在transaction-T2中,更新附加列中对象的状态,以便您知道应用程序可以使用该对象。
糟糕,稍后您会发现多步插入失败可能会导致问题。步骤1之后和步骤2之前的故障会导致放弃和不完整的插入,如在应用程序中查看表时所看到的。在第2步之后和第3步之前的故障使不可变存储中的废弃对象无用。
为了解决这个问题,您需要一个正在进行的插入和删除的边表。至少,这可以与应用程序表中的插入内容进行事务处理。
接下来,您会意识到也最好为正在进行的工作加上时间戳,以便您可以注意到什么时候旧的东西由于插入失败而足以进行清理。现在,您的系统相当稳定,并且您有一个团队聚会。
几个月或几年后,blob的不变存储已达到容量。现在,您需要另一个崩溃程序来更新关系系统中的所有表以包括商店ID。这样您就可以在许多商店中保存斑点。
那就是当您意识到不知道数据库中的所有表都保存不可变的Blob的时候。应用程序一直在不协调的情况下将blob添加到不可变存储中。废话!
必须添加新的间接级别,以将Blob的管理推到专用表中,并将更新封装到专用模块中。通常,应用程序会遵守此规则,但并非总是如此。引用第一个不可变商店的旧用法必须纳入系统,因为它几乎无法追踪并杀死它们。
使用这种新的间接级别,您可以更轻松地管理跨数据中心的复制,甚至可以将不可变的Blob存储迁移到新的数据中心。
我非常喜欢“劈开”一词,因为它是它自己的反义词。如果你自相矛盾,你不会全都坏!
软件工程中最大的问题之一是解开泥泞的大球。这些相互交织,相互依存的大量代码有时可能包含由成千上万的软件工程师策划的数千万行代码。
不幸的是,很多时候,共享宝贵的数据库所带来的社会和经济压力造成了您自己的大泥潭。一旦应用程序文化鼓励不受限制地访问任何表,就很难更改。在文化上很难,并且很难进行软件工程来完成更改。
要祈祷改变这一点,它必须是渐进的。您必须同时驾驶胡萝卜和棍子。这可以通过以下方法演变成实现解纠缠的新方法:
有时人们登台表的只读副本。这些是从权威拥有的应用程序异步更新的。然后,其他应用程序“拥有”其应用程序表集中的只读副本。
通过这种方式,有时需要多年的成功投资才能摆脱困境。
通常,这些努力是由扶手椅式企业架构师推动的,这些企业架构师数十年来没有编写代码,吐出哲学格言并绘制漂亮的图画。哦……等等……就是我!自1988年以来我就没有编码,从不闭嘴,并且喜欢将笔记本电脑放在大腿上的安乐椅上。我会画漂亮的图画!嘘!
这些建筑项目常常被象牙塔思维者(像我这样)和需要做真实工作的人们之间的自然文化冲突所困扰。解开大型系统的最成功的努力只是部分成功。当他们成为现实时,是因为他们引起了人们对文化挑战的极大关注,在达成目标时成功地给予了公平和周到的补偿,优先考虑了对新功能的了解,并避免了它们与我们的团队动力。这需要真正的领导。祝你好运。
在某些方面,将一个巨大的应用程序分开比将具有不同传统的两个应用程序分开要容易得多。当您收购另一家公司时,他们的应用程序基于完全不同的公司文化,对最简单概念(例如“客户”)的不同理解,以及它们的元数据与您的元数据相结合的混乱局面。
分割巨大的应用程序就像拉直波士顿市中心的街道一样,以在1630年代基于母牛的路径创建城市地图而臭名昭著。如果没有摩天大楼,拉直街道本来会更容易。
您拔出了不可变的Blob,但在区分不同的应用程序方面仅取得了一定的成功。因此,它们仍然都需要位于SAME数据库中。
扩大规模:您非常努力地扩大数据库规模。购买更大更好的硬件可能会走很长一段路。
向外扩展:接下来,您尝试向外扩展数据库,希望使用集群中的多台计算机来获得更大的数据库。
应用程序总是与其平台紧密结合而开发的。在这种情况下,该平台的主要部分是数据库。将现有的大型应用程序迁移到新数据库可能比同时获得一份新工作,迁移到新城镇,与配偶离婚并在前一天晚上遇到的拉斯维加斯结婚要痛苦得多。它通常具有大约相同的成功率。
数据库中有许多微妙的方面,这些方面肯定会影响数百万行代码应用程序中的很多部分。其中一些是:
使用非标准数据库功能。每个数据库供应商都有很棒的很棒的非标准内容。大多数时候,这些秘诀的使用已经深深扎根于代码库中,因为它们早已由程序员添加了。
并发语义。 MVCC(多版本并发控制)与可序列化性与可重复读取与已提交读取的精妙之处并不在于胆小。我保证它们很少是第一次讨论的好话题!我还保证在现有的大型应用程序下滑动不同的并发语义是一个愚蠢的事情。
乐观与悲观并发控制。在乐观并发控制中,在确保您不会遇到其他交易更新之前,已完成交易的工作。如果发生冲突,事务将中止。它通常(但不总是)更有效率。在悲观并发控制中,资源被锁定以确保完成时不会失败。尽管通常比较昂贵,但是当乐观并发由于冲突而反复提交失败时,它可以防止陷入困境。虽然在乐观和悲观之间进行选择实际上不会影响应用程序所做更改的正确性,但将数据库行为更改为超出应用程序预期的范围可能会轻易导致许多性能问题,而应用程序则无用。
将申请从一组期望转移到另一个期望,就像将90多岁的祖父母从一个国家带到另一个国家一样。充其量是不容易的!
此外,即使您将同一数据库从集中式系统转移到分布式系统,几乎可以肯定的是,在获得一定程度的扩展的同时,应用程序的性能肯定会受到某些影响。协调锁和并发将面临不同的性能挑战,并且过渡最多将是一条艰难的路。将应用程序调整到分布式数据库需要耐心和洞察力。
应用程序深知其数据库的特性和怪癖。仅仅让一个服务器运行经过一定数量的节点就可以向外扩展的分布式数据库很难,而且常常是不可能的。使它以较低的延迟快速运行更加困难。
数据库是特殊而奇怪的生物。我爱他们,并且绝对认为他们是痛苦的。甚至更低。
公司中拥有许多数据库既烦人又昂贵,特别是在操作数据库方面遇到的挑战。我可以给数据库用户的最佳建议是谨慎谨慎地使用它。如果可能的话:
管理Blob。创建一种规范化的机制来处理Blob,即使您将它们在短期内保留在数据库中,之后再将其移至其他位置,
在应用程序之间使用消息传递。将应用程序与某种形式的异步消息连接起来,即使该消息只是简单地实现为在单独事务中排队和出队的数据库表中的行。结合隔离应用程序,可以使向多个数据库的迁移变得切实可行。
当然,这需要纪律。纪律是我严重缺乏的东西,所以我不会指责。
关系数据库的哪些方面使其具有更大的工业实力并能够支持关键任务应用程序?这是关系模型所固有的,还是仅仅是迄今为止对数据库系统的大量管理和运营投资的结果?
这些是技术挑战还是社会挑战?有区别吗?您如何分辨差异?
这些问题是否仅仅是由于早先的(非常合理的)假设已经不适用而造成的?这仅仅是我们在这里做事的方式,使我们陷入这种泡菜吗?