Hyperloglog 算法简介
这个网站简单地介绍了 Hyperloglog 这个算法。该算法适用于非精确估计 count(distinct)
这种场景,它的优点是只用几KB内存就能处理上G的数据,而不像常规的 len(set(e for e in data))
这样耗内存或者上 map-reduce 那样架构复杂。
- 算法
- 添加一条记录:获得
hash(row)
, 将 hash 剩余的0计数,归纳进 hash 头几位标记的 bucket 中。 - 计数:找出 bucket 中最大的数,应用上纠正算法(例如 LinearCount,即可得到估计的数值,在示例的数据集上做实验,偏离率在 2% 左右。
- 添加一条记录:获得
- Redis 实现了 pfcount 算法,即是 …
Cloud Services are not MAGICAL
本文是 antirez 的一篇老文章,讲的是如果你用了云服务,也还是建议你能够做一个异地容灾。
- 比起 AWS 省下来的钱来说, Bare Metal 并不贵。完全可以做到整个 stack 运行在两台 bare metal 上。100 euros/month 就可以搞到两台 64G RAM + RAID disk 的服务器了。
- AWS EC2 出故障了,你固然可以跟老板说全美国的网站都崩溃了,不止咱家;但是在这种情况下,uptime percentage 毕竟是受到影响了。
衍生思考:有 Terraform 这种技术,还是蛮容易将整套服务迁移到 gke, digitalocean 等云服务去。
read moreKubernetes 时代怎么做监控
本文是 Datadog 工程博客的一篇监控的介绍,若对 Kubernetes 比较熟可跳过前半篇看后半部分的真正的内容。
- 在 Kubernetes 前的时代,监控按照 VM / Host 来做,现在呢,监控的玩法都要变了,如下:
- tags & labels 是必选项了。这些使监控可以更接近 app 层面,而不是在 host 层面。
- 有更多的组件要监控,以前只有 host+app,现在要 host+containers+containerized_app+kubernetes。
- 应用用完就扔了(delete pod), 监控总不能像以前一样死盯着一个应用。
- 应用甚至可能部署在多个 cloud providers 上。
衍生思考:这篇文章讲述挑战更多,解决方案更少。可以关注后续的文章。
read moreTimeout Retry Circuit Breaker 我该用哪个
本文是 @abrookins 做的一个实验,在他的实验中,他测试了诸如超时,重试,断路器等技巧对系统健壮性的影响。tldr, 结论:高并发带依赖的服务,不要重试,用尽可能短的 timeout,发请求时包在 circuit beaker 里面。
- 上游服务宕机
- API Gateway Only: 如果下游服务只是简单地在 Connection Error 的时候捕获错误做一些默认值的处理,那么,对系统处理能力影响几乎微乎其微。主要是因为 socket error 报错是实时的,这时断路器和超时用上了也没用。
- Circuit Breakers, 不设置超时,遇到了上游服务宕机,跟上面没差。
- 上游服务器宕机
- No Timeouts, No Circuit Breakers, Boom,系统处理能力直接降到十几个请求。这个很容易理解:当前服务所有的处理能力都卡在那少数的几个上游服务的请求,而这些请求就 Hang …
Netflix 如何使用 Kayenta 做 Canary 部署
本文是 Netflix 工程博客的一篇文章,简述了他们如何使用 Kayenta 做 Canary 部署。
- 基本概念介绍:上线切 1% 流量到 Canary 环境,出错就停止部署,一切正常就应用到所有生产环境的 instance 去。
- 一些额外的工作:
- 为了防止 long-running process 的影响,在 production cluster 外起 baseline cluster + canary cluster 用于对比。
- 系统自动分析 canary 的结果,基于httpcode, load avg, 错误,响应等指标。如果指标评估通过就自动应用,否则 abort 掉部署。
- 解决的痛点:Canary 部署后以前要人工观察日志,监控数据做出决定,一周只能做一两次 …
如何部署满是BUG的应用
本文是 Trello 的一篇工程博客,讲述了如果你发布了一个带有 bug 的程序去了生产环境那该怎么办?
- 最基本的,要做监控。知道什么时候上线的代码。你不能只是部署了代码就丢到一边去了。
- 发布的时候经历 alpha,beta,staged。特别是 staged,你可以上线时只导流 1% 的流量。真正出问题了,也只是那一点点,回滚去修复。
- 特性开关。真要碰上下几个月才能发布的代码,那就得上特性开关,不停地合代码但就是不起用。
- 不要在人不在的假期前部署,简直是在给整个团队诚心不好好过节。
- 应用有能力在最后关头按照 User-Agent 掐掉请求,这样真有紧急 bug 出现导致应用被 ddos 了,可以扛一会儿。
- 与其赶着投胎修 bug,不如慢一些,把问题确切地修好,修对了。
为什么 SQLite 选用 C 语言实现
本文介绍了 SQLite 为啥用 C 语言而不用像 Rust / Go 这些更现代的语言,原因:性能,兼容,依赖,稳定。
- C 就是快。任何宣称跟 C 一样快的语言都是在耍流氓,没一个够格。
- 几乎任何系统都能调用 C 的库,不管是在安卓上,电脑上,还是在 gameboy 上。
- SQLite 的依赖压榨到了极致,在最小配置中,它只需要 memcmp memcpy memmove memset strcmp strlen strncmp 这几个东东。在全构建中也只多引入了 malloc/free 加文件读写。
- C 敲级稳定!
- 很多人误解了面向对象以为什么东西都要面向对象,事实上面向对象只是一个理解问题的好方法但不是解决问题的好方法。有时候过程式的代码就是更简单更容易维护,以及 …
是否真的需要 WebSockets
本文介绍了 WebSockets 及它的一些备选技术选型,例如 SSE,Long Pooling,通过比较这些技术的特性我们可以针对场景给出更合理的选择。
- WebSockets 允许服务端和客户端随时互相通信。它使用 HTTP 握手,但随后转用 TCP 建立全双工的信道通信。几乎所有现代的浏览器都支持这项特性。由于连接是 sticky 的,所以它对负载均衡并不是很友好。作者对 WebSockets 的评价是适合用于聊天应用或者推送提醒,但对于很多其它场景杀鸡用了牛刀了:看你是否需要做全双工的通信,因为很多场景只是单纯的服务端推送啊!
- Server-sent events 可以在 HTTP octet stream 的基础上做服务端像客户端的单方面推送。好处就是负载均衡能发挥作用了,不太好的地方是它没法检测客户端是否掉线了(当然如果能容忍这种场景的话就无所谓了!
- Long polling: 每次客户端发送请求带上授权信息,服务端有数据则返回,无数据则hang住,直到客户端 timeout。好处是随便什么浏览器都能用,不太好的地方是负载均衡的压力也会变大。
简而言之:不需要实时发数据回服务端用SSE,否则用 …
read more