系统设计中最重要的概念
大约在一年前,我的 程序员生涯遇到了一次转折,起因是我阅读了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中提取数据然后更新到你的数据库中,这样的工作只会让你的脾气变得糟糕。
你会让自己陷入这样的逻辑:
my_record = query("SELECT * FROM records WHERE id = x") if not my_record: insert_into_my_db(their_record) elif their_record != my_record: update_my_db(their_record)
此外,这会给你带来数据一致性的梦魇。假设同步的脚本运行中断,诸如此类,这时你往数据库里写入新的记录,如果接下来有人需要做和你类似的事情,情况会变得更糟。当然,通常这会在数据更新时触发大批查询操作。
解决办法:你已经猜到了:请不要那么做。尽量规范地整理数据库。有些情况并不适合老式系统,所以请你尽可能地避免合并数据库–直接查询数据库A和数据库B。如果你不那么去做,那么就不要怕难堪。
事情已出错的迹象
总而言之,如果你发现自己在编写一些跨越多个应用层的代码,或者“更新”脚本,后者你的crontab脚本超过了10行代码,你很有可能已经犯了错误并且在架构的某个地方违反了SPOT规则。写出那样的代码是枯燥和痛苦的,这种痛苦往往预示着你不能再继续下去了。所以,停下来不要继续犯错。
原文: Ted Dziuba 编译: 伯乐在线 – 唐尤华
【如需转载,请标注并保留原文链接、译文链接和译者等信息,谢谢合作!】
相关文章
- 移动web设计和开发45个实用资源
- Web开发面临的挑战主要有哪些?
- Mozilla技术布道者给Web开发人员推荐的Firefox插件列表
- Firefox 10 测试版拥有更强大的Web开发工具
- NoSQL生态系统
- 11个面向文档的开源NoSQL数据库
- 关于Web开发,每个程序员都应了解的那些事
- 我为什么向后端工程师推荐Node.js
- Google网站管理员:提升移动Web性能的4个建议
- 软件系统设计的问题:没适应用户需求和环境
from 博客 – 伯乐在线 http://blog.jobbole.com/10084/?utm_source=rss&utm_medium=rss&utm_campaign=%25e7%25b3%25bb%25e7%25bb%259f%25e8%25ae%25be%25e8%25ae%25a1%25e4%25b8%25ad%25e6%259c%2580%25e9%2587%258d%25e8%25a6%2581%25e7%259a%2584%25e6%25a6%2582%25e5%25bf%25b5
您可能也喜欢: | |||
解剖Twitter:Twitter系统架构设计分析 |
检索系统的下游管理 |
建设一个靠谱的火车票网上订购系统 |
pc安装XP和MAC双系统 |
无觅 |