刚发现题主在别人答案下补充的那批 “闲置低性能” 电脑,128M 的内存,1G 都不到的主频...
下面提到的这些“低性能”,“闲置” 的电脑是相对于服务器来说的。五年内的没给坑的普通个人电脑,如果不想扔了,可以发挥一下余热。
具体配置,好歹内存 8G,硬盘几百G,CPU 至少得完爆树莓派之类的。
突然想起以前老板让我帮忙联系处理掉几十台塔机工作站,别在那儿占地方。我当年没听懂,说我能不能坑个 HDFS 好歹也废物利用下。当时我想的是,好几十万的工作站呢,就算过时了,攒个三五 T 的硬盘空间都是白捡的。岂不美哉。
到了库房,看那白白的全塔威武雄壮,三五台机器开起来就好像飞机起飞一样。激动地进了控制台。内存 4G,硬盘 64G。在 2000 年出头的时候的确还行吧。但 201X 年,感觉感动得要哭了...
这个还是需要限定下条件的:本文讨论的是目前多机横向扩展服务的实践如何。答案是毫秒级别的要求下,很多已经有很多成熟的服务可以帮忙构建一些 CPU,内存和硬盘比任何单机要高很多的服务。现在这些服务的开发和部署已经非常成熟了,构建集群的难度并不高。不过,就好像天河二并不适合挖矿一样,这个集群的主要能力在于处理大规模的数据和横向扩展(几乎线性的成本来完成容量增长的需求),而对游戏和小文本处理并没有多少裨益。
但是,它仍然并不是魔法,并不不能把比树莓派还弱功耗却高几百倍的机器也充分利用。
这几年单机性能增长已经放缓很多了,通过大量普通性能集群提供较为优良的访问已经有很多很好的实践。
看到居然没什么人回答,我就抛砖引玉下。
有个冷知识。你知道世界上吞吐量最高的信息传输方法是什么呢?
答案是装了一集装箱硬盘的卡车 :) AWS Snowmobile 数据传输服务_数据迁移方案-AWS云服务
一箱硬盘可以放 100PB 信息,然后卡车加船运虽然速度没有那么快,但是总量除以时间,其吞吐量和通过各种光缆传输的信道相比遥遥领先。
理解自己最需要什么是一件非常省钱的事情。
计算机技术很多都是妥协的结果。为什么要内存,为什么要高速缓存二级缓存?以前弄的那个什么南桥北桥那么复杂搞什么。
简单说,就是因为穷。因为穷,我们不得不作出一些妥协,让我们的钱花尽量有回报。
同样的,
因为穷,我们买一台戴尔插上 64 核 2T 内存基本得从 100 万往上找。所以我们考虑买几台 256G 内存,因为更低的总价却反而可以有更多 cpu cores。
因为穷,我们插满一个 1T 内存的机器,结果运营时候发现我们至少需要 3T 内存。擦,内存槽都满了哪里加?要不再花一百万买台机器还是把这一堆 3000+RMB 一根的内存条拔掉换一堆容量更大的条?不,我们还是想想怎么再买两台同样配置的机器,然后横向扩展试试看。
钱不够,我们不得不考虑下架构。比如我们有时候可以不需要同时访问全局内存的。比如我们可以多个硬盘分别存储东西,在对外的时候返回整体结果。
分布式集群是目前很常用的服务器系统组织形式。它主要想要复用每个节点的算力,内存和硬盘空间。
想要充分利用算力,那么就需要把任务分片,让每个局部的计算节点只使用一些局部的信息。后面的 mapreduce 以及一系列衍生的架构都是从这个思想考虑。
想要充分利用存储空间(内存和硬盘),由于低价的节点和网络的通讯意味着不稳定,我们就需要充分考虑一致性问题。比如后面的 TiDB,其底层的 TiKV 基于的 raft, 以及更早的 paxos 都是为了这个。
接下来本文主要是基于 Google 的三架马车。MapReduce, GFS 和 Bigtable。简单从原理介绍下实践的方向。和论文发布时候相比,现在有很多很好的开源实践了,感谢各位探索者的努力。
MapReduce 是一种并行化计算的模型。现在我们有一万条小数据,我们可以单机载入内存,然后一个一个处理完毕就好。但是,假如我们有几十亿条数据。显然的,我们不可能继续这么搞。简单抽象化一下,我们可以发现,其实很多时候我们在处理第 k 条数据的时候,我们可能并不关心第 k + n 条数据的内容。
因此我们可以设置这样一群专门计算的进程,每次丢进去那几十亿条数据中的一条,进程只管处理这一条,而然后把结果输出出去。最后我们把结果合并一下。这时候这个 "处理当前数据并输出结果" 就是 map,第 k 和第 k + 1 条操作返回一个结果,这个叫 reduce。
于是这个就算是 mapreduce 的基本原理。开源界的 hadoop 生态中有个组件可以把一堆性能低下并且单机容量较小的机器作为计算节点,然后可以轻松处理规模数十亿的数据集。
当然,它问题也很明显,就是抽象程度太低了。通常情况下,现在要是处理类似事情,我们应该用 Spark。Spark 是基于 scala 的一个 jvm 库。之所以用 scala,是因为 scala 本身就有很多类似思想。我们使用和 scala 本身非常相似的 api 构造出一个任务计划,程序内部根据我们的程序自动把任务划分为若干阶段,自动调用各个计算节点一起执行。
GFS 介绍了一种分布式的文件系统。其主要思想把文件分成很多小块(chunks)。每个节点开个块服务(chunkserver),你可以向这个服务发出读写请求。另外有个元数据服务(metadata),告诉你文件系统的结构,以及每个文件的数据你从哪里获取。
从实现上说,单个 chunkserver 就是一堆 kv storage,就是指定 id 读写结果。此外,每个小块在多个机器都准备了备份,因此即便某台机器挂了,也不会出问题。 顺便的,强烈推荐有兴趣的看看 leveldb 以及 rocksdb,作为一个嵌入的 kv store 简直神了。
目前开源实现中,除了较早的 HDFS,Ceph 和 GlusterFS 也都挺不错的。目前网上都能找到很多相关的详细说明,就不细说。个人而言,感觉 GlusterFS 的服务要求要少一点,多个小机器拼出一个大硬盘然后挂到一个目录下,用户不管登录到哪台服务器,都好像进自己家一样,速度貌似还不错。
此外,云服务 s3, 或者阿里的 oss 也应该是类似架构。
最后是 Bigtable 。前面提到的 GFS 从整体上说,我们可以看成是一个巨大的 kv store。就是我们面向整体,给一段文本作为 key,我们可以执行写入,读取,删除操作。内容是另一段文本。在 Bigtable 中,我们可以更加充分利用这个特性,作出更加高级的操作。
Bigtable 那篇论文中介绍了一个存储网页的数据库。当我们只是存储简单的数据似乎还不够的时候,我们可能需要一个更加高级点的文档。比如我们需要字段。在 BigTable 中介绍了我们可以使用 kv 实现一个数据库的方法。在那个 kv 里面,我们存放元数据,存放一条数据不同字段去哪里找等等。最后我们就能做出一个比较完善的类似关系数据库那样的前端。
实现有 HBase, Hive, PrestoDB, Cassandra 等等等。
现在,还有基于上面思想但更加严格的 TiDB, CockroachDB 等。他们在 kv 上面实现了一个关系数据库,而且分别支持了 mysql 协议和 psql 协议。
如果有非常多的廉价机器。一台一台安装环境,变更安装包等显然是一个非常让人头疼的事情。目前主要部署方法可以试试 kubernetes 。它可以很容易管理一堆部署在各个机器上的各种 docker 容器。而 docker 是一个基于 Linux 的 cgroup, aufs 等技术构造的一个非常轻量级的虚拟机。我们可以在开发机器上准备部署脚本,测试完毕后把整个环境变成一个 image 放到某个地方,然后让 kubernetes 随便找台机器就开始下载镜像完成部署。
参考:
2. The Google File System https://storage.googleapis.com/pub-tools-public-publication-data/pdf/035fc972c796d33122033a0614bc94cff1527999.pdf
3. Bigtable: A Distributed Storage System for Structured Data http://static.usenix.org/event/osdi06/tech/chang/chang.pdf
有的,云计算最初就是G家廉价机器集群搞出来的。G家当年穷买不起十八摸高大上的服务器,就发明了廉价机器分布式计算集群技术,也就是后来的云计算。所以你需要的技术就是云计算技术。
然后你要分清楚到底是闲置还是淘汰,目前市面上能买到的的个人电脑都是廉价的,管你矿机也好还是四路泰坦也好,在专业服务器面前都只能算是廉价机器。如果你所谓的计算机是三年内的主流配置,那么他们可以像G家当年一样组一个分布式计算集群出来。
但是如果你的计算机属于被淘汰的机器(五年前的产品),那么他们的能效比是非常不划算的,什么叫做能效比?就是所花费的能源和产生的效益的比例。或者讲的直白点儿就是电费都不划算……
不要对淘汰的电脑有任何幻想,卖给电脑城炼金是最合适的选择……