直接构建数据库底层文件 , 就是一个 MapReduce 应用的绝佳案例:使用 Mapper 抽取 key,然后利用该 key 进行排序 , 已经覆盖了构建索引中的大部分流程 。由于大部 KV 存储都是只读的(通过批处理任务一次写入后,即不可变) , 这些存储的底层数据结构可以设计的非常简单 。例如,不需要 WAL(参见让 B 树更可靠) 。
当数据加载进 Voldemort 时 , 服务器可以利用老文件继续对外提供服务 , 新文件会从分布式文件系统中拷贝的 Voldemort 服务本地 。一旦拷贝完成 , 服务器可以立即将外部查询请求原子地切到新文件上 。如果导入过程中发生了任何问题,也可以快速地切回,使用老文件提供服务 。因为老文件是不可变的,且没有立即被删除 。
批处理输出的哲学本章稍早我们讨论过 Unix 的设计哲学,它鼓励在做实验时使用显式的数据流:每个程序都会读取输入,然后将输出写到其他地方 。在这个过程中,输入保持不变 , 先前的输出被变换为新的输出 , 并且没有任何其他的副作用 。这意味着,你可以任意多次的重新跑一个命令,每次可以对命令或者参数进行下微调,或者查看中间结果进行调试,而不用担心对你原来系统的状态造成任何影响 。
MapReduce 任务在处理输出时,遵从同样的哲学 。通过不改变输入、不允许副作用(比如输出到外部文件),批处理不仅可以获得较好的性能,同时也变得容易维护:
- 容忍人为错误 。如果你在代码中不小心引入了 bug,使得输出出错,你可以简单地将代码回滚到最近一个正确的版本,然后重新运行任务,则输出就会变正确 。或者 , 更简单地,你可将之前正确的输出保存在其他的文件夹 , 然后在遇到问题时简单的切回去即可 。使用读写事务的数据库是没法具有这种性质的:如果你部署了有 bug 的代码 , 并且因此往数据库中写入了错误的数据,回滚代码版本也并不能修复这些损坏的数据 。(从有 bug 的代码中恢复,称为容忍人为错误,human fault tolerance) 。这其实是通过牺牲空间换来的,也是经典的增量更新而非原地更新 。
- 便于敏捷开发 。相比可能会造成不可逆损坏的环境,由于能够很方便地进行回滚 , 可以大大加快功能迭代的速度(因为不需要进行严密的测试即可上生产) 。最小化不可逆性(minimizing irreversibility)的原则 , 有助于敏捷软件开发 。
- 简单重试就可以容错 。如果某个 map 或者 reduce 任务失败了,MapReduce 框架会自动在相同输入上对其重新调度 。如果失败是由代码 bug 引起的,在重试多次后(可以设置某个阈值),会最终引起任务失败;但如果失败是暂时的,该错误就能够被容忍 。这种自动重试的机制之所以安全,是因为输入是不可变的 , 且失败子任务的输出会被自动抛弃 。
- 数据复用 。同一个文件集能够作为不同任务的输入,包括用于计算指标的监控任务、评估任务的输出是否满足预期性质(如,和之前一个任务的比较并计算差异) 。
推荐阅读
- 使用旧域名创建新站点获取快速收录和排名的实践心得
- 办公风水技巧
- 为什么我每天睡够了8小时,黑眼圈和眼袋还是很重啊?
- 怎么区分土鸡蛋和饲料蛋,粮食鸡蛋和饲料鸡蛋的区别
- 防爆单反相机和防爆卡片相机有哪些区别呢
- 杨紫琼办婚宴,吕克贝松和何超琼到场,85岁母亲看着比女婿还年轻
- excel表格如何设置自动和
- “四川火锅”和“重庆火锅”区别大!别再以为是同一种了
- 如若一个女人和你分享这四种私人话题,暗示她已经爱上你了
- 57岁叶子楣复出!和男友未婚没有遗产,粉丝合影要红包