系统设计中最重要的概念

原文:Ted Dziuba  编译:伯乐在线 – 唐尤华

大约在一年前,我的程序员生涯遇到了一次转折,起因是我阅读了Eric S. Raymond(后文简称ESR)写的《UNIX编程艺术》一书。虽然该书写作的时候Web应用程序还未开始流行,但是其中的原则至今仍然适用。ESR在书中试图以UNIX的设计思想与程序员交流,如果你读过之后能够理解,你会在那时发出“啊哈”的感叹,并且对所有的知识瞬间领悟。这种感觉就像你第一次使用烟雾弹发现所有人和物体都变成了微粒,或者像你第一次知道如何使用磁铁一样。

接下来,这种顿悟自然消失了,然后你花费很长时间试图重新找回这种感觉。

对于web程序员,如果你不喜欢阅读,你也可以直接采用 “Single Point of Truth”(后文简称SPOT)规则,即“在系统中每个概念都必须具有唯一的、没有歧义的、权威的表示“。如果你设计的系统违反了这条原则,你会使自己陷入无尽的麻烦和灾难中。

你需要避免的做法

在Web开发领域,有一些违反了SPOT规则的情形,它们基本上都来自对数据库概念的误解。不,等一下,我突然想到了。我看到的几乎所有违反SPOT的情形,几乎都是以某种方式使用MySQL时遇到的错误。事实上,几乎所有的NoSQL灾难都是向MySQL输入错误SQL造成的后果,但这不是我这里要说的重点。

系统设计中最重要的概念

1. 使用Solr来搜索数据库 / Using Solr to Search a Database

我敢说你们肯定有过这样的想法,而我不止一次想过这么做。当你需要在web网站后台数据库进行搜索时会决定使用Apache Solr。你会建立一个“索引管道”用做从数据库周期地提取信息并交给 Solr 处理,或者在为更新数据库建立“插入/更新”入口点的同时也为Solr提供一个入口点。

问题在于你的应用程序不知道到什么才是真实的数据。如果是 Solr 执行返回的结果,你会按照搜索索引的格式显示数据吗?你会用索引行ID查询数据然后显示数据库后台的数据吗?无论你如何试图解决这个问题,结果都是令人痛苦的。看在上帝的份上,如果你的索引连接程序发生错误结果又会怎样?你需要多长时间才能发现这样的错误已经发生在你的系统中呢?

解决办法:不要那么做。PostgreSQL本身就带有很好的全文搜索功能。你可以在此基础上根据你的要求进行调整;这并不违反SPOT规则。该死,如果 Solr 可以满足需求,你甚至可以将Solr作为数据库使用。

2. 将SQL查询结果预存到一个NoSQL系统 / Precaching SQL Results in a NoSQL System

这种情况不大常见,但还是会发生。你将一个很大的对象关系模型的所有数据存到了MySQL中,但是从你的Web应用程序查询这些数据需要3到4个JOIN操作,这会使MySQL遇到性能瓶颈。一直以来都没有好的解决办法。所以为了解决这个问题,你预先计算了一些数据结构并且存储在类似Memcached或者Redis这样的NoSQL系统。

如果数据发生变化要怎么办?你会在程序运行的同时重新计算这些数据结构吗?会在之后的某个时刻更新NoSQL以及SQL写操作队列吗?你可以通过配置来让这种机制奏效,但是当你的“同步”脚本失效的时候,你会发现事情搞糟了,因为你不能确定哪一种才是有效的数据表示。

解决办法:如果你授权的DB运行速度过于缓慢,请不要试图重新组织你的数据模型或者将数据库改变成需要的形式。如果你确实需要为你的应用程序添加一个数据缓冲层,最好加在Web服务器前面最外层。以我的经验来看,任何试图在表示层下面加上数据缓冲都会带来数据同步灾难。另外,在应用程序的边缘增加数据缓存也比较容易:你可以使用Squid或者某个商用的内容提交网络。

3.  Frankendatabases 问题

是的,我已经说了很多关于MySQL的事。最近我遇到了这样的设计难题:你希望在一个数据库中进行查询,但这些数据却分散在多个数据库中。如果你和老式系统打过交道,你应该能理解我在说什么。编写同步脚本实现从数据库A和数据库B中提取数据然后更新到你的数据库中,这样的工作只会让你的脾气变得糟糕。

你会让自己陷入这样的逻辑:

此外,这会给你带来数据一致性的梦魇。假设同步的脚本运行中断,诸如此类,这时你往数据库里写入新的记录,如果接下来有人需要做和你类似的事情,情况会变得更糟。当然,通常这会在数据更新时触发大批查询操作。

解决办法:你已经猜到了:请不要那么做。尽量规范地整理数据库。有些情况并不适合老式系统,所以请你尽可能地避免合并数据库–直接查询数据库A和数据库B。如果你不那么去做,那么就不要怕难堪。

事情已出错的迹象

总而言之,如果你发现自己在编写一些跨越多个应用层的代码,或者“更新”脚本,后者你的crontab脚本超过了10行代码,你很有可能已经犯了错误并且在架构的某个地方违反了SPOT规则。写出那样的代码是枯燥和痛苦的,这种痛苦往往预示着你不能再继续下去了。所以,停下来不要继续犯错。

 

原文:Ted Dziuba  编译:伯乐在线 – 唐尤华

【如需转载,请标注并保留原文链接、译文链接和译者等信息,谢谢合作!】

 

收藏 1 评论

关于作者:唐尤华

唐尤华:我喜欢程序员,他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其实我是一个程序员。 个人主页 · 我的文章 · 18 ·    

相关文章

可能感兴趣的话题



直接登录
最新评论
  • 第一条不敢苟同。PostgreSQL虽然有全文检索的功能,但是为什么还会有solr出现并且大行其道?在数据量达到一定规模的时候,数据库的全文检索就会变慢,从而不适用。

跳到底部
返回顶部