最近在工作中我需要把数据从公共的 Data Warehouse(数据仓库)导出来,放到属于我们 team 自己账号的云端存储资源中去,然后再在我们的应用中查询这样的资源。需要导出数据是因为直接从 Data Warehouse 查询数据是一个缓慢而且异步的过程,而我们的应用数据查询需要实时性。现在要解决这个问题有一些 AWS 的服务可供我们可以选择,基本上分成了两大类:
第一类是存储和内容分发(Storage & Content Delivery):
- CloudFront:CloudFront 是用于内容分发给不同地区用户的,它在全球设有数个 “edge”,作为临近网络访问数据的入口。就如同大网站建立的 CDN 设备一样。这显然不是我需要的。
- Glacier:Glacier 非常用来适合存储不常用的、压缩的和备份的海量文件数据,在集中文件存储的服务中,它是最便宜的。比如存储日志、备案资料等等。当然,它牺牲了数据传输的性能和一致性。显然它也不适合我的场景。
- S3:S3(Simple Storage Service)适合存储原始数据、大对象(单个上限 5Tb),费用比数据库服务低。如果我最终决定使用文件系统来存储数据,它是一个好的选择。另外,无论是 Glacier 还是 S3,层级概念上最大的以及都是地区级别的(在 Glacier 里面叫做 vault,在 S3 里面叫做 bucket,每个这样的单元都位于某一个地区,例如 Asin Pacific),因此如果需要全球多个节点访问同一份数据,需要额外把数据分发到各个地区去。
- Storage Gateway:Storage Gateway 是用于集成 IT 环境的内部部署的,它支持基于网关缓存的优化或者是网关存储的优化,便于本地和临近网络快速获取数据。它可以用于公司内部不同地理位置的文件共享、镜像或者备份,也不适合我这里的场景。
选择文件存储不能提供数据库的条件查询等功能,目前我的场景下并不需要,我只需要根据不同的区域和数据唯一键来获取数据集就可以了,否则,我需要考虑数据库服务:
- DynamoDB:DynamoDB 是挂在云上的 NoSQL 数据库服务,每一张表都需要指定一个 hash 的主键或者是 hash 加 range 两层的主键,同时,它的数据读取和存储的最小单位是 4KB,也就是说,存取 0.5KB 和 4KB 的数据,性能表现是几乎一样的。从数据量来看,如果选择数据库服务,它是最适合解决我的问题。
- SimpleDB:和 DynamoDB 相似,非关系型数据库,结构可随意变换,而且数据自动索引,所以查询是非常快的。它的数据容量小得多,有一个典型用法是使用 SimpleDB 来存储 S3 的文件地址,就像 “指针” 一样。但是它的容量限制需要考虑,每个 domain 只有 10G 的上限,可以建立多个 domain,但是那样就需要应用自己来路由选择 domain 了。关于一致性,它和 DynamoDB 一样,可以选择最终一致性和强一致性,当然,强一致性需要花费更多钱,还会降低吞吐量。
- ElastiCache:把 Memcached 或者 Redis 搬到了云上,这显然不是我需要的。
- RDS:RDS(Relational Database Service)相当于把关系型数据库搬到了云上,它和 DynamoDB 或者 SimpleDB 的区别,主要就是 RDB 和 NoSQL DB 的区别。
- RedShift:RedShift 是一个数据仓库服务,利用列式存储技术及节点间并行分布式查询,对于上 P 的数据访问做了优化。
在这里还可以找到这几个 AWS 上数据库服务的不同,用一表以蔽之:
If You Need | Consider Using | |
A relational database service with minimal administration |
Amazon RDS, a fully managed service that offers a choice of MySQL, Oracle or SQL Server database engines, scale compute & storage, Multi-AZ availability and more. |
|
A fast, highly scalable NoSQL database service |
Amazon DynamoDB, a fully managed service that offers extremely fast performance, seamless scalability and reliability, low cost and more. |
|
A NoSQL database service for smaller datasets |
Amazon SimpleDB, a fully managed service that provides a schemaless database, reliability and more. |
|
A relational database you can manage on your own |
Your choice of relational AMIs on Amazon EC2 and EBS that provide scale compute & storage, complete control over instances, and more. |
再有另一个技术选型的例子,在 web 容器中选择 Tomcat 还是 Jetty。Jetty 结构简单,容易定制其组件,也就是说,小和简单(这也是当初 Google 选择它作为 app 引擎的最重要原因),是它最大的优势。Jetty 在同时处理大量连接并且需要长时间保持这些连接的时候,性能上更有优势,因为它是基于 NIO,而不是 Tomcat 的 BIO 来处理请求的;但是我们也能找到很多性能测试的数据,在对于连接生命周期非常短而且非常频繁的请求,Tomcat 的性能要优于 Jetty。
以下摘选自 《Jetty VS Tomcat Performance Comparison》的二者比较:
Jetty Features and Powered:
- Full-featured and standards-based.
- Embeddable and Asynchronous.
- Open source and commercially usable.
- Dual licensed under Apache and Eclipse.
- Flexible and extensible, Enterprise scalable.
- Strong Tools, Application, Devices and Cloud computing supported.
- Low maintenance cost.
- Small and Efficient.
Tomcat Features and Powered:
- Famous open source under Apache.
- Easier to embed Tomcat in your applications, e.g. in JBoss.
- Implements the Servlet 3.0, JSP 2.2 and JSP-EL 2.2 support.
- Strong and widely commercially usable and use.
- Easy integrated with other application such as Spring.
- Flexible and extensible, Enterprise scalable.
- Faster JSP parsing.
- Stable.
在选择实现技术的时候经常会遇到这样或那样的选择题,上面的两个例子,都是相对理性地分析和比较的例子。我们考虑的内容往往包括功能、性能、社区支持、扩展性和定制性、已知问题和约束等等。
但是,具有讽刺意味的是,仔细想想,实际上我们选择某一项技术的最重要的原因,却远远不是那些 “理智的分析”,而是下面这些:
- “因为大家都在用它啊”,比如项目用 Java 或者 C++作为主要语言来实现,我想很多人和我一样,经常并没有经过太多思考,这似乎是一个思维惯性。
- “因为我没有用过这项技术,我感兴趣,我想学一下”,其实这也无可厚非,我以前也经历过一个项目组,大部分人(包括主管在内),都排斥使用新技术,原因是担心风险。我原则上认同风险一说,但是适度范围内给程序员选择技术的自由从长远看是有好处的,尤其是技术也是需要进步的。把所有问题都让 “工程商人” 来解决,只会让目光过于浅近。
- “因为我只知道它啊”,这种情况更多。你为什么选择 C3P0 连接池?因为那时候我不知道还有哪些别的数据库连接池……
工程师总会在技术选型的时候寻找某种平衡,纸面上未必会写这三条理由,但是心里面,有意识无意识地,一定会给向着这三条理由倾斜。
现在让我们退一步,倘若我们都非常理性地评估了类似技术的优缺点,但是在真正使用技术实现的时候,却发现,实际上这几条类似的技术都可以实现,选哪个关系并不大。因为数据规模、问题大小,都不足以到了非得区分类似技术优劣的地步。举例来说,持久层使用 MyBatis 还是 Hibernate,优秀的程序员可以说出二者各自的好处是什么,也许对于大型项目至关重要;但是也有程序员会吐槽,其实用哪个都可以啊,好处坏处的差异并没有那么明显,因为我的项目那么小,需要的数据库读写如此简单……
有人说,小项目可以帮助拓宽技术视野,但是只做小项目无法深入了解技术本身,因为你无从比较并理解类似技术的优劣。这也是 “玩具代码” 在学新东西的时候有成就感,也很适合技术分享的胶片之用,却无法带来工程师持续成长的原因。
你觉得是不是这样呢?
文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》
" 工程师的持续成长",能有空讲讲这块的内容吗,怎样才能算是持续的成长或者是真正的积累,如何突破“ 玩具代码” 的心态呢,有好玩的东西就尝试一下,感觉好像很有成就感,但实际上没有多少积累
对于 “工程师的持续成长”,我写过一两篇这方面文章,你可以到 “所有文章” 里面找一下;对于 “玩具代码”,我觉得只有真正做项目才会脱离它吧。