跳到主要内容

通过故障转移提高可用性

· 阅读需 2 分钟

冷备份:使用心跳或指标/警报来跟踪故障。当发生故障时,配置新的备用节点。仅适用于无状态服务。

热备份:保持两个活动系统承担相同的角色。数据几乎实时镜像,两个系统将拥有相同的数据。

温备份:保持两个活动系统,但第二个系统在故障发生之前不接收流量。

检查点(或类似于 Redis 快照):使用预写日志(WAL)在处理之前记录请求。备用节点在故障转移期间从日志中恢复。

  • 缺点
    • 对于大型日志来说耗时较长
    • 自上次检查点以来丢失数据
  • 使用案例:Storm、WhillWheel、Samza

主动-主动(或全活动):在负载均衡器后保持两个活动系统。它们并行处理。数据复制是双向的。

设计一个网址缩短器

· 阅读需 6 分钟

设计一个系统,将用户提供的网址转换为缩短的网址,并重定向回原始网址。描述系统的工作原理。你将如何分配缩短的网址?你将如何存储缩短网址与原始网址的映射?你将如何实现重定向服务器?你将如何存储点击统计数据?

假设:我通常不会在初始问题陈述中包含这些假设。优秀的候选人会在提出设计时询问规模。

  • 注册重定向网址的独特域名总数大约在数万左右
  • 新网址注册量约为 10,000,000/天(100/秒)
  • 重定向请求量约为 10B/天(100,000/秒)
  • 提醒候选人这些是平均数字 - 在高峰流量时(例如“人们下班回家时”或“超级碗期间”)可能会高得多。
  • 最近的统计数据(在当前日期内)应聚合并在 5 分钟延迟后可用
  • 长期回顾统计数据可以每天计算

假设

每天 1B 新网址,总共 100B 条目 越短越好 显示统计数据(实时和每日/月度/年度)

编码网址

http://blog.codinghorror.com/url-shortening-hashes-in-practice/

选择 1. md5(128 位,16 个十六进制数字,碰撞,生日悖论,2^(n/2) = 2^64)截断?(64 位,8 个十六进制数字,碰撞 2^32),Base64。

  • 优点:哈希简单且水平可扩展。
  • 缺点:太长,如何清理过期网址?

选择 2. 分布式序列 ID 生成器。(Base62:az,AZ,0~9,62 个字符,62^7),分片:每个节点维护一部分 ID。

  • 优点:易于淘汰过期条目,更短
  • 缺点:协调(zookeeper)

KV 存储

MySQL(10k qps,慢,无关系),KV(100k qps,Redis,Memcached)

优秀的候选人会询问别名的生命周期,并设计一个系统来清理过期的别名。

后续问题

问:如何生成缩短的网址?

  • 一个差的候选人会提出一个使用单一 ID 生成器的解决方案(单点故障)或一个在每个请求中需要协调 ID 生成器服务器的解决方案。例如,使用自增主键的单一数据库服务器。
  • 一个可接受的候选人会提出使用网址的 md5,或某种形式的 UUID 生成器,可以在任何节点独立完成。虽然这允许分布式生成不冲突的 ID,但会产生较大的“缩短”网址。
  • 一个优秀的候选人会设计一个解决方案,利用一组 ID 生成器,从中央协调器(例如 ZooKeeper)保留 ID 空间的块,并独立从其块中分配 ID,必要时刷新。

问:如何存储映射?

  • 一个差的候选人会建议使用单体数据库。这个存储没有关系方面。它是一个纯粹的键值存储。
  • 一个优秀的候选人会建议使用任何轻量级的分布式存储。MongoDB/HBase/Voldemort 等等。
  • 一个优秀的候选人会询问别名的生命周期,并设计一个系统来==清理过期的别名==。

问:如何实现重定向服务器?

  • 一个差的候选人会从头开始设计某种东西来解决一个已经解决的问题。
  • 一个优秀的候选人会建议使用现成的 HTTP 服务器,配备一个插件,解析缩短的网址键,在数据库中查找别名,更新点击统计并返回 303 到原始网址。Apache/Jetty/Netty/tomcat 等等都可以。

问:点击统计数据如何存储?

  • 一个差的候选人会建议在每次点击时写回数据存储。
  • 一个优秀的候选人会建议某种形式的==聚合层,接受点击流数据,聚合并定期写回持久数据存储==。

问:如何对聚合层进行分区?

  • 一个优秀的候选人会建议使用低延迟消息系统来缓冲点击数据并将其传输到聚合层。
  • 一个候选人可能会询问统计数据需要多频繁更新。如果是每日更新,将其存储在 HDFS 中并运行 map/reduce 作业来计算统计数据是一个合理的方法。如果是近实时的,聚合逻辑应计算统计数据。

问:如何防止访问受限网站?

  • 一个优秀的候选人可以回答通过在 KV 存储中维护一个主机名黑名单。
  • 一个优秀的候选人可能会提出一些高级扩展技术,如布隆过滤器。

Lambda 架构

· 阅读需 2 分钟

为什么选择 Lambda 架构?

为了解决大数据带来的三个问题

  1. 准确性(好)
  2. 延迟(快)
  3. 吞吐量(多)

例如,传统方式扩展页面查看服务的问题

  1. 你从传统关系数据库开始。
  2. 然后添加一个发布-订阅队列。
  3. 然后通过水平分区或分片进行扩展。
  4. 故障容错问题开始出现。
  5. 数据损坏发生。

关键点是 ==AKF 规模立方体 的 X 轴维度单独并不足够。我们还应该引入 Y 轴 / 功能分解。Lambda 架构告诉我们如何为数据系统做到这一点。==

什么是 Lambda 架构?

如果我们将数据系统定义为

查询 = 函数(所有数据)

那么 Lambda 架构是

Lambda 架构

批处理视图 = 函数(批处理作业执行时的所有数据)
实时视图 = 函数(实时视图,新数据)

查询 = 函数(批处理视图,实时视图)

==Lambda 架构 = CQRS(批处理层 + 服务层) + 快速层==

适用于大数据系统的 Lambda 架构

Lambda 架构

· 阅读需 2 分钟

为什么要使用lambda架构?

为了解决大数据所带来的三个问题

  1. 准确性(好)
  2. 延迟(快)
  3. 吞吐量(多)

例如:以传统方式扩展网页浏览数据记录的问题

  1. 首先使用传统的关系数据库
  2. 然后添加一个“发布/订阅”模式队列
  3. 然后通过横向分区或者分片的方式来扩展规模
  4. 容错性问题开始出现
  5. 数据损坏(data corruption)的现象开始出现

关键问题在于AKF扩展立方体中,==仅有X轴的水平分割一个维度是不够的,我们还需要引入Y轴的功能分解。而 lambda 架构可以指导我们如何为一个数据系统实现扩展==。

什么是lambda架构

如果我们将一个数据系统定义为以下形式:

Query=function(all data)

那么一个lamda架构就是

Lambda Architecture

batch view = function(all data at the batching job's execution time)
realtime view = function(realtime view, new data)

query = function(batch view. realtime view)

==lambda架构 = 读写分离(批处理层 + 服务层) + 实时处理层==

Lambda Architecture for big data systems

非暴力沟通(NVC)

· 阅读需 2 分钟

为什么要非暴力沟通?

通过==重视每个人的需求==来提高沟通质量。==而猜疑和暴力是没能满足需求的表现==。

NVC不是什么

  • 不是为了表现友善。
  • 不是为了让别人做我们想做的事情,这关乎于人与人之间的相互理解。

加强人与人之间联系和理解的方法

  1. 脆弱的表达出我们的感情和需求
    • 意识到持续的感情和需求
    • 暴露感情和需要的脆弱性
  2. 着重听取对方的感情和需求
    • 共情聆听的核心:存在、专注、空间与关怀,==以及对感觉和需求的言语表达==
    • 不提建议,不做处理,不安慰,不讲故事,不同情,不做分析,不做解释,......
    • 无论说的什么,关键是听取对方的感受,需求,意见和要求

例如:==因为你需要......所以你觉得......?==

做这些事会导致我们之间彼此疏远

  • 对他人做评价,做判断,打标签,做分析,批评,对比,等等。
  • 值得思考(即某些行为值得惩罚或奖励)
    • 要求(不接受他人的选择;想要惩罚那些不按照自己想法做的人)
    • 拒绝选择或承担责任(关键词:不得不,本应该,猜想会,他们让我做的,等等)

为什么买家画像很重要?

· 阅读需 3 分钟

KYC (了解你的客户)并不容易

==你多久才能有一次机会听你的客户描述他们遇到的问题?== 如果你是一家大公司的非市场部门雇员,答案是可能永远没有机会。

当然,如果你有机会,要知道在==买家人设核心概念==中有两个非常重要的部分

  1. 询问探索性问题
  2. 倾听

==KYC (了解你的客户)== 并不容易。例如:2008年,iPhone 3G在日本销售的情况不佳。而日本消费者习惯于用手机拍摄视频,用借记卡/火车通行证支付。

只拥有买家侧画是不够的

一份普通的买家侧画 (buyer profile) 无法让营销人员准确的了解买家决定是否购买。营销人员只是根据人口统计(如年龄,收入,婚姻状况,教育)或心理特征(个性,价值观,生活方式,意见)对买家进行猜测。

尽管如此,买家简介仍能给出一些显而易见的答案。例如,通过电子邮件活动联系到首席财务官(CFO)是很困难的。而对于一个只有时间养金鱼的女人来说,强调汽车的货物空间即使放上大型犬也是很宽敞是没用的。

建立买家角色模型最有效的方式可不是猜测,而是调查那些曾经权衡过他们的选择、考虑过或拒绝过提出的解决方案,并做出了类似于你想要影响的决定的买家。

买家画像 = 买家侧画 buyer profile(谁会购买)+ 买家洞见 buyer insights(何时/如何/为什么购买)

关系数据库简介

· 阅读需 2 分钟

关系数据库是大多数存储使用案例的默认选择,原因在于 ACID(原子性、一致性、隔离性和持久性)。一个棘手的问题是“一致性”——它意味着任何事务都会将数据库从一个有效状态转变为另一个有效状态,这与 CAP 定理 中的一致性不同。

模式设计和第三范式 (3NF)

为了减少冗余并提高一致性,人们在设计数据库模式时遵循 3NF:

  • 1NF:表格形式,每个行列交集只包含一个值
  • 2NF:只有主键决定所有属性
  • 3NF:只有候选键决定所有属性(且非主属性之间不相互依赖)

数据库代理

如果我们想消除单点故障怎么办?如果数据集太大,无法由单台机器承载怎么办?对于 MySQL,答案是使用数据库代理来分配数据,可以通过集群或分片

集群是一种去中心化的解决方案。一切都是自动的。数据会自动分配、移动和重新平衡。节点之间互相传递信息(尽管这可能导致组隔离)。

分片是一种集中式解决方案。如果我们去掉不喜欢的集群属性,分片就是我们得到的结果。数据是手动分配的,不会移动。节点之间互不知晓。

价值的要素

· 阅读需 1 分钟

当客户评估一个产品或者一个服务时,他们会权衡==感知价值==和==实际要价==。

以下是30个“价值的要素”。

Elements of Value

  1. 功能性价值

    • 节约时间
    • 简化流程
    • 获取收益
    • 降低风险
    • 组织
    • 整合
    • 连接
    • 减少付出
    • 避免麻烦
    • 减少开支
    • 质量
    • 多样性
    • 感官诉求(如:食物与饮料)
    • 报信
  2. 情感性价值

    • 减少焦虑
    • 回报
    • 怀旧
    • 设计/美学
    • 徽章价值
    • 健康
    • 治疗价值
    • 愉悦/娱乐
    • 吸引力
    • 提供方法
  3. 改变生活

    • 给予希望
    • 自我实现
    • 动力
    • 传家宝
    • 联系/附属
  4. 社会影响

    • 自我超越

四种 No-SQL

· 阅读需 4 分钟

在一个常规的互联网服务中,读取与写入的比例大约是 100:1 到 1000:1。然而,从硬盘读取时,数据库连接操作耗时,99% 的时间花费在磁盘寻址上。更不用说跨网络的分布式连接操作了。

为了优化读取性能,非规范化通过添加冗余数据或分组数据来引入。这四种 NoSQL 类型可以帮助解决这个问题。

键值存储

键值存储的抽象是一个巨大的哈希表/哈希映射/字典。

我们希望使用键值缓存的主要原因是为了减少访问活跃数据的延迟。在快速且昂贵的介质(如内存或 SSD)上实现 O(1) 的读/写性能,而不是在传统的慢且便宜的介质(通常是硬盘)上实现 O(logn) 的读/写性能。

设计缓存时需要考虑三个主要因素。

  1. 模式:如何缓存?是读透/写透/写旁/写回/缓存旁?
  2. 放置:将缓存放在哪里?客户端/独立层/服务器端?
  3. 替换:何时过期/替换数据?LRU/LFU/ARC?

现成的选择:Redis/Memcache?Redis 支持数据持久化,而 Memcache 不支持。Riak、Berkeley DB、HamsterDB、Amazon Dynamo、Project Voldemort 等等。

文档存储

文档存储的抽象类似于键值存储,但文档(如 XML、JSON、BSON 等)存储在键值对的值部分。

我们希望使用文档存储的主要原因是灵活性和性能。灵活性通过无模式文档实现,性能通过打破 3NF 来提高。初创公司的业务需求时常变化。灵活的模式使他们能够快速行动。

现成的选择:MongoDB、CouchDB、Terrastore、OrientDB、RavenDB 等等。

列式存储

列式存储的抽象就像一个巨大的嵌套映射:ColumnFamily<RowKey, Columns<Name, Value, Timestamp>>

我们希望使用列式存储的主要原因是它是分布式的、高可用的,并且针对写入进行了优化。

现成的选择:Cassandra、HBase、Hypertable、Amazon SimpleDB 等等。

图数据库

顾名思义,这种数据库的抽象是一个图。它允许我们存储实体及其之间的关系。

如果我们使用关系数据库来存储图,添加/删除关系可能涉及模式更改和数据移动,而使用图数据库则不需要。另一方面,当我们在关系数据库中为图创建表时,我们是基于我们想要的遍历进行建模;如果遍历发生变化,数据也必须随之变化。

现成的选择:Neo4J、Infinitegraph、OrientDB、FlockDB 等等。

买家角色为什么重要?

· 阅读需 2 分钟

KYC 并不容易

==您有多少机会听到客户描述他们的问题?== 如果您是大型公司的非营销部门员工,答案可能是从未。

如果您确实有机会,买家角色概念的核心有两点,==

  1. 提问
  2. 倾听

==KYC(了解您的客户)== 并不容易。例如,2008年,iPhone 3G在日本的销售情况不佳。日本客户习惯于使用手机拍摄视频/用借记卡芯片支付/使用通勤卡芯片。

买家档案很好,但还不够

一个通用的买家档案无法让营销人员准确了解决定买家购买决策的因素。营销人员只是根据人口统计信息(年龄、收入、婚姻状况、教育程度)或心理特征(个性、价值观、生活方式、观点)进行猜测。

不过,买家档案仍然可以提供一些明显的答案。例如,通过电子邮件活动联系首席财务官是非常困难的。强调汽车货舱的宽敞对于只养金鱼的忙碌女性来说并没有用处。

与其猜测,构建买家角色的最有效方法是采访那些之前权衡过选择、考虑或拒绝过解决方案并做出与您想要影响的决策相似的买家。

买家角色 = 买家档案(谁会购买) + 买家洞察(何时/如何/为什么购买)