2026 年 05 月 23 日
市面上各种 agent 用过不少,cursor、claudecode、codex、opencode、trae、openclaw、pi……其实也没感觉哪个对其他有降维打击,反而各有各的不爽: 要么有模型限制,换别的兼容接口要各种转接,运行过程不透明——之前做了 linko,初衷也是为了搞清楚各种 agent 都在干嘛。 要么天天升级弄出各种奇怪 bug,要么过度臃肿,要配各种看着有用实际用起来又没什么卵用的插件。
所以,在 2026 年这个时间点,自己从 0 开始做一个 agent 到底有门槛吗(不限于 coding)?于是 4 月的时候开始做了 tachi。 结论是:做一个匹配个人需求和工作流 …
2026 年 02 月 15 日
做了个新玩具 linko, 本质上是个透明 mitm proxy, 但给他加上了可视化 ai agent 和 llm api 之间对话的能力.
限制:
目前只支持 MacOS (透明代理的实现用了MacOS 上的pfctl, linux 的支持很简单, 有空可以加下) 支持的 llm api 只有 anthropic 的接口格式, 任意兼容的第三方接口应该都可以(测试过minimax 和 deepseek) 原理上和 charles 之类的工具的主要区别在"透明", 不需要客户端指定http_proxy(有些工具不支持), 通过防火墙强行劫持https流量, 来做流量解密. …
2025 年 03 月 30 日
几年前写过个工具 gospy, 用于从旁路 dump 一个 golang 进程的 runtime 信息(包括 goroutine, memory 等), 大致原理见以前的文章.
基本功能能用, 但没继续做下去, 除了没时间外, 其他还有几个问题:
不支持 MacOS (主要是没搞懂 MacOS 下怎么读取进程内存). DWARF 解析写的过于繁琐, golang 版本更新时, 解析逻辑很难调整. 对写 UI (包括 terminal UI 和前端) 实在没兴趣, 不写又没法暴露功能, 也懒得去做通过 http 接口暴露数据. 前阵子试了下通过 aider 来写代码, 效果非常惊艳, 对我来说, …
2023 年 04 月 12 日
产品里用了一年多的 etcd, 碰到过一些 bug, 整理下,其中用些在最新版本里已经修复了, 会标注下.
添加 etcd 节点相关 bug 添加 etcd 节点的过程一般是先 member add, 然后启动新节点上的 etcd,这样的问题是在 member add 和新 etcd 启动 之间整个 etcd 集群处于 quorum - 1 的状态, 此过程增加了集群的不稳定性,如果新节点由于配置错误起不来,现存节点再挂一个 就可能导致整个集群不可用.
从 3.4 开始 etcd 引入了 learner 的概念, member add –learner, 可以将新节点添加成 …
2022 年 01 月 26 日
patroni 的安装跳过, 它只是个 python 包, 把依赖装好就行, 同时要求装好 postgres-server, patroni 运行过程中会调用 pg_ctl 等命令: https://patroni.readthedocs.io/en/latest/README.html 每个 patroni 管理一个 pg 实例, 两者必须部署在同一节点上, patroni 需要能:
访问 pg 的监听端口 读写 pg data dir (patroni 会重写 postgres.conf, pg_hba.conf 等文件) 配置文件 配置文件是yaml 格式, 具体见 …
2021 年 04 月 01 日
EKS control plane 的升级是比较简单的, 直接在 aws console 上点下就可以了, 但 worker node 是自己用 asg(autoscaling group) 管理的, 升级 worker node 又不想影响业务是有讲究的.
跑在 EKS 里, 且希望不被中断 traffic 的有:
stateless 的 api server, queue consumer 被 redis sentinel 监控着的 redis master/slave 用于 cache 的 redis cluster 写了个内部工具, 把下面的流程全部自动化了. 这样升级 eks 版本, …
2020 年 12 月 04 日
k8s 1.20 的 release note 里说 deprecated docker: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation
对 docker 和 k8s 关系比较了解的人一看就知道是废弃 dockershim, 正常操作, 具体有什么影响, 建议阅读:
https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/ …
2020 年 12 月 02 日
天气渐凉, 无奈得拿出了秋裤. 偷懒好久没写博客了, 回顾下这阵子做了什么.
工作 年底打算把之前用的 dedicated ec2 instance 全部换掉, 几年前为了 HIPAA 合规做的, 但 AWS 的 BBA 里后来不要求 dedicated instance 了, 换成普通的, 可以省掉每月1400多刀的固定 dedicated fee, 同类型的 ec2 instance 可以再省10%左右. 为了这个, 打算把部分遗留在 vm 上的东西迁移到 k8s 里, 减少之后更换 instance 的工作量.
cronjob 尝试用 argo 来调度 cronjob.
还是有不少坑的: …
2020 年 08 月 04 日
在 k8s 上部署 redis cluster 后, 感觉 redis-cli 管理 redis cluster 非常别扭, 写了个 kubectl 的插件 kubectl-rc 来辅助管理 redis-cluster.
redis-cli 难用在哪 不直观 & 不统一 部分 cluster 信息是直接通过 redis protocol 获得的, 比如 cluster nodes, cluster slots, 但部分管理命令又是通过 redis-cli --cluster 执行的.
cluster nodes, cluster slots 这些命令输出的又是 ip 和 node …
2020 年 06 月 30 日
从 0.10.0 版本开始给 snet 加了 stats api 来暴露内部的一些统计数据.
设置 "enable-stats": true 开启, 默认监听 8810 端口, curl http://localhost:8810/stats
{ "Uptime": "26m42s", "Total": { "RxSize": 161539743, "TxSize": 1960171 }, "Hosts": [ { "Host": …
2020 年 06 月 16 日
最近开始把线上的 k8s 从 1.15 升级到 1.16, 1.16 里有一些 api verison 被彻底废弃, 需要迁移到新的 api version, 具体有: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.16.md#deprecations-and-removals
有两个问题:
集群中使用的一些第三方 controller(nginx-ingress, external-dns-controller…), 调用的 apiVersion 需要升级. 已存在集群中的 …
2020 年 04 月 16 日
在代码中调用 aws api 的时候常用两种方法:
直接传入 aws accessKey/secretKey 使用 instance profile 前者一般是创建一个 IAM 用户, 绑定对应权限, 生成 keypair, 在 k8s 环境里, 把 keypair 放在 Secrets 里, 或通过环境变量注入. 好处是可以每个应用单独设置, 但需要自己管理 keypair.
后者创建一个 IAM role, 绑定对应权限, 创建 ec2 的时候选择对应的 role. 跑在该 ec2 instance 上的程序自动能拿到对应的 IAM 权限. 好处是不必自己管理 keypair, 缺点是跑在 …
2020 年 04 月 07 日
最近对业务里发送 apple APNS, google FCM 部分的代码进行了重构, 抽出了一个单独的 service, 本文记录下整个过程.
存在的问题 我们有好几个 mobile app, 每个 app 会有一套对应的 server 端 service 做业务逻辑, 因为历史原因, 每个 service 里面其实有很多重复代码, 大多只是一些配置和错误处理上有差异. 给 app 发推送是个典型, 原来的做法是当要发推送的时候, 往 python 的 celery 队列里扔一个 task, 由 celery 异步得去发.
有如下问题:
celery 性能不佳, worker class 用 …
2020 年 02 月 18 日
这几天测试了下 aws 的 personalize service, 看看能不能替换掉产品里现有的一些推荐逻辑.
大致的流程:
导入数据 选择 recipe 进行 training, 得到一个 solution version 选择最佳 solution version 创建 compaign 调用 api, 根据 compaign 得到 recommendations 一些 iam 权限相关的设置就不写了, 具体看文档吧, 这里只记录下主要步骤.
导入数据 首先需要准备用来 training 的数据, 分成三种数据集:
User Item User-Item interaction 其中 …
2020 年 01 月 18 日
成功的经验总是带有点运气成份, 失败则是必然的:). 工作中, 线上环境的问题千奇百怪, 有的来自自己代码 bug, 有的是配置错误, 有时候是第三方的 vendor 成了猪队友. 对于一些排查过程比较困难或具有代表性的问题, 需要记录下来, 一般把这个过程叫做 postmortem(验尸).
这篇写一下自己做 postmortem 的过程, 并记录一个最近处理的故障.
Postmortem process 我大体分以下几个部分:
用尽量简练的语句描述清楚在什么时间发生了什么,谁参与了问题的处理(when, what, who)? 详细描述解决问题的过程, 包括但不限于: debug 的过程, …
2019 年 12 月 30 日
网上经常有人诟病 AWS 的计费模式复杂, 喜欢国内那种打包式的售卖方式, 这个可能受限于每个公司的财务流程, 预算制定方式, 合不合国情,本文不讨论. 仅从开发者的角度介绍下 AWS 部分常用 service 的计费方式.
PS: 那些为了蹭一年 free plan 然后抱怨什么偷跑流量, 偷偷扣费的大哥就省省吧, AWS 根本不是给个人用的, 老老实实用 lightsail 得了.
EC2 EC2 的价格是最复杂的, 一台 EC2 instance 的价格组成:
instance fee, 实际支付的是 CPU+RAM 的费用 EBS fee, server 的根分区都是 EBS …
2019 年 11 月 29 日
snet: 0.5 ~ 0.6.1, 整理从上一篇以来的一些更新.
新增选项 proxy-scope, 默认 bypassCN, 可选 global. bypassCN 会做国内外分流, global 直接让所有流量去往国外.
host-map, 为域名指定 ip. 之前在测试一个功能的时候需要在内网让手机对某个域名的解析切换到我的测试 ip 上, 坑爹的是公司的路由器竟然没这功能, 索性在 snet 里写了这个功能, 让我的台式机发射 wifi, 手机连上来, snet 的 mode 切换成 router, listen-host 改为 0.0.0.0 就好了.
block-hosts, 因 …
2019 年 11 月 15 日
之前用过 datadog 的 tracing 功能, 非常好用, 但是很贵(单台30$), 迁移到 k8s 后, 监控迁移到了 prometheus, 也把 datadog 的 tracing 去掉了.datadog 的 tracing 也是 opentracing 的一种实现, 索性就换上开源实现.
tracing 系统是分布式系统中很好用的 performance tuning 工具, opentracing 只是一个标准,里面定义了 span, scope, tracer 等概念,但不规定 tracing 数据应该怎么 encoding, 怎么存储, 跨进程的 span 数据怎么串起来. …
2019 年 10 月 31 日
这两天在调试代码的时候, 发现 db 层的代码在每次把 connection 放回 db pool 的时候,即使之前执行的是 select 语句,也会 rollback 一下, 这代码很古老, 我也不知道为啥, 尝试把 rollback 去掉, 结果单元测试挂了一堆, 大多都是数据不一致的问题, debug 了一下, 最后发现这坑还挺大的.
为什么去掉 select 的 rollback 后会出现数据不一致?
pymysql 默认关闭了 autocommit, connection A 进行 select 之后, 其实 MySQL 内部为 select 也开启了一个 …
2019 年 09 月 29 日
前文讲了下 gospy 的大致用法, 这篇记录具体实现和过程中碰到的一些问题.
原理 要从外部获取 golang 进程的 runtime 信息, 需要做得是从进程的 binary 中的 debug 信息里 parse 出需要的一些变量的虚拟内存地址, 读取目标进程的内存, 得到相应的数据, 将两者映射起来就好了.只支持了 linux 上的 ELF 格式 binary, debug 信息是 go 在编译时候弄进去的, 格式是通用的 DWARF.
ELF 和 DWARF 格式本身不细究(汗, 文档几百页也实在看不动), go 标准库里自带相应的 parser: debug/elf, …
2019 年 09 月 20 日
go 自带的 profiling 工具很强大(pprof, trace, GODEBUG …), 但有时我还是想不修改目标进程的源码获取它的一些 runtime 信息, 最近研究了一下 py-spy 和 delve, 发现还是可实现的, 就做了个小东西gospy.
用法 目前就两个命令: gospy summary 和 gospy top
sudo ./gospy summary --pid 1234, 可以 dump 目标进程的一些信息和当前活动 goroutine 正在执行的函数信息, 比如对一个 prometheus 进程做一次 snapshot:
bin: …
2019 年 08 月 16 日
随记.
Life <火焰文章-风花雪月> 流程过半, 这一作难度确实低, 怂如我玩的又是不死人模式, 即使是困难难度, 到后面也是切菜. 流程里学生们 seisei 得喊, 想到后面要把他们一个个干掉, 心情挺复杂得… 风花雪月这个副标题, 玩着玩着也有点明白意思了, 美版竟然叫 <Three houses>, 老外神经果然傻大粗啊…
西泽保彦的高千和千晓系列看完了好几本, 还剩下<依存> 和 <啤酒之家的冒险>. 昨晚读完了 <苏格兰游戏>, 剧情高开低走, 前半段的迷题和悬念设置堪称系列之最, 我都想大 …
2019 年 08 月 02 日
追了一下 kube-scheduler 的源码, 记录一点, 基于 tag v1.16.0-alpha.2.
一句话概括 kube-scheduler 的职责是: 找到 pending 的 pod, 挑选一个合适的 node, 将 pod bind 上去.
Get pending pod 在 scheduler 的初始化过程中给 pod/node/pv/pvc/service/storageClassInformer 添加回调函数, 功能大致都是在这些资源发生变化时更新本地的 cache 和 ScheduleQueue scheduler.go:New.
ScheduleQueue 是关键, …
2019 年 07 月 28 日
pyflame 可以比较方便得生成 python 进程的调用函数栈火焰图, 来 debug 一些性能瓶颈, 做了个 kubectl 的小插件, 来方便得对 k8s pod 中的 python 进程进行 debug: https://github.com/monsterxx03/kube-pyflame 直接把 svg 文件下载到本地.
要对 pod 中的 python 进程进行 profiling, 大致思路有两种:
直接在 container 内使用 pyflame, 但这样要把 pyflame 做到所有的 base 镜像里去, 而且目标 container要在 …
2019 年 07 月 23 日
开始把线上流量往 k8s 集群里面导了, 中间碰到了茫茫多的问题 …… 记录一下(大多都不是 k8s 的问题).
nginx ingress controller 的问题 zero-downtime pods upgrade 默认配置下, nginx ingress controller 的 upstream 是 service 的 endpoints, 在 eks 里, 就是 vpc cni plugin 分配给 pod 的 vpc ip(不是 cluster ip), 和直接使用 service cluster ip 比, 好处是:
可以支持 sticky …
2019 年 06 月 30 日
准备工作都差不多了, 没意外下周就该开始把线上的服务往 k8s 上迁移了. 记录几个问题,暂时不 block 我的迁移进程, 但需要持续关注.
DNS timeout and conntrack 看到有个关于 DNS 的issue: #56903
现象是 k8s cluster 内部 dns 查询间歇性会 5s 超时, 大致原因是 coredns 作为中心 dns 的时候, 要通过 iptables 把 coredns 的 cluster ip, 转化到它真实的可路由 ip, 中间需要 SNAT, DNAT, 并在 conntrack 内记录映射关系.
这可能会带来两个问题: …
2019 年 06 月 20 日
这两天得了空, 让 snet 支持了下 MacOS.
snet 的大致原理是通过系统防火墙的流量重定向功能,将所有去往国外的流量导到 snet 监听的端口, 在程序内部 将流量传递给上游的 proxy server(ss, http), 拿到响应后再回给客户端.
实现关键是要在 snet 内部获取到流量的原目标地址, 因为重定向之后 tcp connnection 的目标地址变成了 snet 监听 的地址.
Linux 上的实现,以前讲过: https://blog.monsterxx03.com/2019/03/31/snet-transparent-ss-proxy-on-linux/ 是 …
2019 年 05 月 30 日
Just some random complains and notes about server infra management. I think those are my motivations to move to kubernetes.
Won’t explain k8s or docker in detail, and how they solve those problems in this post.
Infrastructure level(on AWS) We use following services provided by AWS.
Compute: …
2019 年 05 月 26 日
搞定了监控, 下一步在 k8s 上要做的是中心化日志, 大体看了下, 感兴趣的有两个选择: ELK 套件, 或fluent-bit + fluentd.
ELK 那套好处是, 可以把监控和日志一体化, filebeat 收集日志, metricbeat 收集 metrics, 统一存储在 ElasticSearch 里, 通过第三方项目elastalert 可以做报警,也能在 kibana 里集成界面. 坏处是 ElasticSearch 存储成本高, 吃资源. 我们对存储的日志使用需求基本就是 debug, 没有特别复杂的BI需求, 上一整套 ELK 还是太重了.
选择 fluent-bit …
2019 年 05 月 14 日
Why move to prometheus? 把生产环境迁移到 k8s 的第一步是要搞定监控, 目前线上监控用的是商业的 datadog, 在 container 环境下 datadog 监控还要按 container 数目收费, 单 host 只有 10 个的额度, 超过要加钱, 高密度部署下很不划算. 一个 server 跑 20 个以上 container 是很正常的事情, 单台 server 的监控费用立马翻倍.
tracing 这块之前用的也是 datadog, 但太贵了,一直也想换开源实现, 索性监控报警也换了, 踩一把坑吧.
vendor lock 总是不爽的… …
2019 年 05 月 07 日
我有两个 EKS 集群 (sandbox + production), 这两个集群分处两个 aws 帐号中. 所以管理的时候也需要两套 aws credential.
同时我用 helm-secrets 来管理 helm charts 中需要加密的一些配置. helm-secrets 只是 sops 的一个 shell wrapper, 实际加密是通过 sops 进行的.
sops 支持 aws KMS, gcp KMS, azure key vault.. 等加密服务. 我用的是 aws KMS, 在 KMS 里创建一个 key, 授权允许我这个 iam 帐号能用它来进行加解密.
这带来了一 …
2019 年 04 月 29 日
最近在把 jenkins 迁移到 k8s, 具体怎么 setup 的不赘述了(helm chart, jenkins home 目录挂pvc, jenkins kubernetes-plugin).
jenkins 跑 k8s 好处是可以方便得做分布式 build, 每次 trigger 一个 job 的时候自动起一个 pod 作为 jenkins slave agent, 结束了自动删掉. 在 aws 上结合 cluster-autoscaler 可以极大得扩展 ci 的并行能力, 降低成本.
记录一点过程中的坑.
装上 kubernetes-plugin 后,要想让 jenkins 的 …
2019 年 04 月 12 日
从 k8s 1.8 开始支持 PersistentVolumeClaimResize. 但 api 是 alpha 状态, 默认不开启, eks launch 的时候版本是 1.10, 因为没法改 control plane, 所以没法直接在 k8s 内做 ebs 扩容. 后来升级到了 1.11, 这个 feature 默认被打开了, 尝试了下直接在 EKS 内做 ebs 的扩容.
注意:
这个 feature 只能对通过 pvc 管理的 volume 做扩容, 如果直接挂的是 pv, 只能自己按传统的 ebs 扩容流程在 eks 之外做. 用来创建 pvc 的 storageclass 上必 …
2019 年 04 月 10 日
完成 SNET 初版后又做了些后续更新, 记录一点.
支持 http tunnel 配置文件里增加一个 proxy-type 选项, 默认为 ss, 可改成 http, 这样可以将 支持 http tunnel 的代理服务器作为 upstream(例如 squid). 填上 http-proxy- 开头 的选项就行.
实现上 client 端要对接 http tunnel 非常简单:
client 发送请求: Connect tgt-host:tgt-port HTTP/1.1 server response: HTTP/1.1 200, 即表示 server 端支持 http tunnel …
2019 年 03 月 31 日
日常使用 Linux 工作, Linux 下实现全局透明代理可以用 iptables + ss-redir, 要有比较好的上网体验还需要 ChinaDNS 配合 dnsmasq, 这一整套在路由器上搞一遍就算了, 在本地太麻烦了. 仔细想想这几个加起来的功能实现起来也并不复杂, 前阵子就写了个小东西, 用一个进程完成全局透明代理 + ChinaDNS + 国内外分流: https://github.com/monsterxx03/snet
目前的限制:
不支持 ipv6 只支持 tcp (因为我的测试服务器不支持 udp, 以后再加上吧) 上游 server 只支持 ss 目的是一个进程 + …
2019 年 03 月 28 日
之前用 celery 做的 task 都是一些很简单轻量级的 task, 从来没触发过 timeout, 最近加入了一些复杂很耗时的 task, 碰到一些 time limit 的坑.
celery 中 time limit 有两种, soft_time_limit 和 hard_time_limit, 区别是 soft_time_limit 会在内部抛一个 Exception, task 可以 catch 自行处理. hard time limit 没法被 catch.
使用如下:
from myapp import app from celery.exceptions import …
2019 年 02 月 12 日
最近在看 google 的 <The Site Reliablity Workbook>, 其中有一章是"Manage load", 内容还挺详细的, 结合在 aws 上的经验做点笔记.
Load Balancing 流量的入口是负载均衡, 最最简单的做法是在 DNS 上做 round robin, 但这样很依赖 client, 不同的 client 可能不完全遵守 DNS 的 TTL, 当地的 ISP 也会有缓存.
google 用 anycast 技术在自己的网络中通过 BGP 给一个域名发布多个 endpoint, 共享一个 vip(virtual …
2018 年 12 月 29 日
去年对线上业务做了一些性能优化, 当时把 http client 从 requests 换成了 geventhttpclient , 上线后发起 rpc 调用的 server 整体负载低了很多, 但 client 端 latency 却高了很多, 经过 debug 觉得问题是 geventhttpclient 把 header 和 body 通过两次 sock send 发出的额外开销造成的, 尝试 修改成一次 send 后 latency 就恢复了: https://github.com/gwik/geventhttpclient/pull/85
最近在调试 gunicorn 的代码时候, …
2018 年 12 月 16 日
定义 pod 的时候通过添加 node selector 可以让 pod 调度到有特定 label 的 node 上去, 这是最简单的调度方式. 其他还有更复杂的调度方式: node-taints/tolerations, node-affinity, pod-affinity, 来达到让某些类型的 pod 调度到一起, 让某些类型的 pod 不跑一起的效果.
Taints and Tolerations 如果 node 有 taints, 那只有能 tolerate 这些 taints 的 pod 才能调度到上面.
taint 的基本格式是: …
2018 年 12 月 03 日
This post will show several commands used for debugging on linux server, all examples are tested on ubuntu 18.04, some tools are not installed by default, you can installl by sudo apt install xxx. Some commands must be used via sudo.
System resources can be classified in three main categories: …
2018 年 11 月 17 日
之前产品里有一个功能是每天给用户推荐一批文章,要保证最后推给用户的文章每天不重复. 原先的实现很直接, 每次推送时候记录下用户 id 和 topic id 的键值对, 拿到新 topic 列表后,取出曾经给该用户推送过的文章列表, 两个 set 去重.
这个实现的问题很明显, 存储空间量太大(M * N), user id (int64) + topic id (int64) = 16 bytes, 1 million 的用户, 每天给用户推送10篇文章, 一年要存储: 16 * 10 * 365 * 1M = 54.4GB. 查询效率也很低,要么一次取所有已读 topic id, 要么把要推 …
2018 年 10 月 31 日
最近在把部分用 RDS 的 MySQL 迁移到 aurora 上去, 读了下 aurora 的 paper, 顺便和 RDS 的架构做些对比.
Paper notes 存储计算分离 redo log 下推到存储层 副本: 6 副本 3 AZ(2 per az), 失去一个 AZ + 1 additoinal node 不会丢数据(可读不可写). 失去一个 AZ (或任意2 node) 不影响数据写入. 10GB 一个 segment, 每个 segment 6 副本一个 PG (protection group), 一 AZ 两副本. 在 10Gbps 的网络上, 修复一个 10GB 的 …
2018 年 10 月 15 日
通常我们使用云服务的时候, 服务提供商会提供 SLA(Service Level Aggrement),作为他们提供的服务质量的标准(常说的几个9),达不到会进行赔偿. 比如 AWS 的计算类服务: https://aws.amazon.com/compute/sla/ .
对公司自己 host 的 service, 我们内部也需要一些技术指标来 track 我们为客户提供的服务质量如何, 这个叫做 SLO(Service Level Objective). 也可以把他当成一个对内的,没有赔偿协议的SLA.
定义指标 我主要 track 两个指标:
Availability (服务的可用性) …
2018 年 10 月 12 日
p95 latency 的定义: 把一段时间的 latency 按照从小到大排序, 砍掉最高的 %5, 剩下最大的值就是 p95 latency. p99, p90 同理.
p95 latency 表示该时间段内 95% 的 reqeust 都比这个值快.
一般我直接看 CloudWatch, 和 datadog 算好的 p95 值. 这次看看怎么从 access log 里直接计算 p95 latency.
假设在 redshift 中有一张表存储了应用的 access log, 结构如下:
CREATE TABLE access_log ( url string, time string, …
2018 年 09 月 26 日
这篇记录对 ingress 的测试.
ingress 用来将外部流量导入 k8s 内的 service. 将 service 的类型设置为 LoadBalancer / NodePort 也可以将单个 service 暴露到公网, 但用 ingress 可以只使用一个公网入口,根据 host name 或 url path 来将请求分发到不同的 service.
一般 k8s 内的资源都会由一个 controller 来负责它的状态管理, 都由 kube-controller-manager 负责, 但 ingress controller 不是它的一部分,需要是视情况自己选择合适的 …
2018 年 09 月 21 日
上文测试了一下 EKS 和 cluster autoscaler, 本文记录对 persisten volume 的测试.
PersistentVolume 创建 gp2 类型的 storageclass, 并用 annotations 设置为默认 sc, dynamic volume provision 会用到:
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: gp2 annotations: storageclass.kubernetes.io/is-default-class: …
2018 年 09 月 11 日
EKS 正式 launch 还没有正经用过, 最近总算试了一把, 记录一点.
Setup AWS 官方的 Guide 只提供了一个 cloudformation template 来设置 worker node, 我喜欢用 terraform, 可以跟着这个文档尝试:https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html 来设置完整的 eks cluster 和管理 worker node 的 autoscaling group.
设置完 EKS 后需要添加一条 ConfigMap: …
2018 年 09 月 03 日
Miscellaneous notes when reading <Kubernetes in Action>.
api group and api version core api group need’t specified in apiVersion field.
For example, ReplicationController is on core api group, so only:
apiVersion: v1 kind: ReplicationController ... ReplicationSet is added later in app …
2018 年 06 月 22 日
在把代码往 python3 迁移的过程中需要升级一些第三方库, 升级了 gevent 后发现 celery 有问题, 于是尝试把 celery 从3.1.25 升级到 4.2.0, 中间碰到了很多问题, 记录一点.
配置的变化 CELERY_ACCEPT_CONENT 之前默认是都允许的, 4.0 开始默认值只允许 json, 因为我用的是msgpack, 所以需要修改这个配置让它接受 msgpack.
CELERY_RESULT_SERIALIZER 之前默认是pickle, 现在默认也变成了json, 如果task 的返回结果是 binary 的话, json 无法处理,要么把结果 …
2018 年 06 月 16 日
上一篇 里简单得提了一点开始做 python 2 到 python3 迁移时候碰到的问题, 和工具的选择(推荐用 six).这篇讲下编写 python 2 / 3 兼容代码要注意的事情.
_future_ python2 里自带的向后兼容模块,将 python3 的一些语法行为 backport 到 python2 里, 使用的时候需要在文件头部声明, 作用域只在当前文件.
首先是几个在 python 2.7 里不用特意写,已经默认开启的特性:
from __future__ import nested_scopes 2.2 开始就默认开启了,用于修改嵌套函数内的变量搜索作用域, 在此之前, …
2018 年 06 月 07 日
This article won’t provide perfect guide for porting py2 code to py3, just list the solutions I tried, the problems I come to, and my choices. I haven’t finished this project, also I haven’t gave up so far :).
Won’t explain too much about the differences between py2 and py3, …
2018 年 06 月 01 日
最近着手准备从 python2.7 迁移到 python3.7, 还没开始就碰到一个问题. 老系统里有一部分竟然是将 python 内置 hash 函数的结果存进了数据库, 这个做法绝对是错的, hash 的结果本来就没有保证过在各个版本的 python 中保证一致. 而且 python3 中算法完全变了, 默认在进程初始化的时候会用随机种子加进 hash 过程, 所以python 进程 一重启结果就不一样了. 木已成舟, 目前看将数据库里的值全部改掉是不可能了, 只能在 python3 中重新实现一下这个算法.
python2.7 中的hash 算法是 fnv (有修改), python3 …
2018 年 05 月 23 日
Recently, we build pub/sub system based on AWS’s SNS & SQS service, take some notes.
Originally, we have an pub/sub system based on redis(use BLPOP to listen to a redis list). It’s really simple, and mainly for cross app operations. Now we have needs to enhance it to support more …
2018 年 05 月 20 日
最近把公司 db 层的封装代码基于 sqlalchemy 重写了, 记录一些.
原来的 db 层代码历史非常古老(10年以上…), 最早写代码的人早就不在了, 问题很多:
完全没有单元测试. 暴露出的接口命名很混乱, 多数是为了兼容一些历史问题. 里面带一套 client 端 db sharding 的逻辑, 但在新项目里完全用不到, 还导致无法做 join, 无法子查询, 很不方便. 老的 db 代码没有 model 层, 和 db migration 通过一种很 trick 的方式绑定在一起实现的, 导致开发时候对着代码完全无法知道数据库表结构,只能直接看数据库. 重写时候要 …
2018 年 04 月 09 日
EKS 还没有 launch, 但 AWS 先开源了自己的 CNI 插件, 简单看了下, 说说它的实现和其他 K8S 网络方案的差别.
K8S 集群对网络有几个基本要求:
container 之间网络必须可达,且不通过 NAT 所有 node 必须可以和所有 container 通信, 且不通过 NAT container 自己看到的 IP, 必须和其他 container 看到的它的 ip 相同. Flannel in VPC flannel 是 K8S 的一个 CNI 插件, 在 VPC 里使用 flannel 的话, 有几个选择:
通过 VXLAN/UDP 进行封包, 封包影响网络性能, …
2018 年 03 月 23 日
这几年吹 serverless 的比较多, 在公司内部也用 lambda , 记录一下, 这东西挺有用, 但远不到万能, 场景比较有限.
lambda 的代码的部署用的 serverless 框架, 本身支持多种 cloud 平台, 我们就只在 aws lambda 上了.
我基本上就把 lambda 当成 trigger 和 web hook 用.
和 auto scaling group 一起用 线上所有分组的机器都是用 auto scaling group 管理的, 只不过 stateless 的 server 开了自动伸缩, 带状态的 (ElasticSearch cluster, …
2018 年 03 月 17 日
一叶障目, 不见泰山. 前阵子一直在排查一个性能问题, 结果由于一些惯性思维, 费了好大劲才弄明白原因, 而且原因非常简单….把这事记录下来,免得以后再掉坑里去.
现象是到了晚上10点多, server lantency 突然一瞬间变高, 但持续时间很短,马上就会恢复, timeout 的请求也不多,影响不大.问题其实从蛮久前就出现了, 但一直也没很重视, 因为持续时间短,影响也不大,简单看了下也没看出明显的问题, 就一直搁置着. 直到最近,觉得问题变严重了, latency 变的更高了,而且在10~11点间多次变高, 开始认真看为什么.
2018 年 02 月 28 日
AWS lambda is convenient to run simple serverless application, but how to access sensitive data in code? like password,token…
Usually, we inject secrets as environment variables, but they’re still visable on lambda console. I don’t use it in aws lambda.
The better way is use aws …
2018 年 02 月 23 日
Glow data infrastructure 的演化 Glow 一向是一个 data driven 做决策的公司,稳定高效的平台是必不可少的支撑, 本文总结几年里公司 data infrastructure 的演进过程.
结合业务特点做技术选型和实现时候的几个原则:
real time 分析的需求不高,时间 delta 控制在1 小时以内可接受 . 支持快速的交互式查询. 底层平台尽量选择 AWS 托管服务, 减少维护成本. 遇到故障, 数据可以 delay 但不能丢. 可回溯历史数据. 成本可控. 用到的 AWS 服务:
数据存储和查询: S3, Redshift (spectrum), …
2018 年 02 月 01 日
If you run a webserver on AWS, get real client ip will be tricky if you didn’t configure server right and write code correctly.
Things related to client real ip:
CloudFront (cdn) ALB (loadbalancer) nginx (on ec2) webserver (maybe a python flask application). Request sequence diagram will be …
2017 年 12 月 15 日
DynamoDB 是 AWS 的托管 NoSQL 数据库,可以当作简单的 KV 数据库使用,也可以作为文档数据库使用.
Data model 组织数据的单位是 table, 每张 table 必须设置 primary key, 可以设置可选的 sort key 来做索引.
每条数据记作一个 item, 每个 item 含有一个或多个 attribute, 其中必须包括 primary key.
attribute 对应的 value 支持以下几种类型:
Number, 由于 DynamoDB 的传输协议是 http + json, 为了跨语言的兼容性, number 一律会被转成 string …
2017 年 12 月 10 日
A few weeks ago, production environment came to an outage, solve it cost me 8 hours (from 3am to 11am) although total down time is not long, really a bad expenrience. Finally, impact was mitigated, and I’m working on a long term solution. I learned some important things from this accident.
The …
2017 年 10 月 14 日
AWS’s DMS (Data migration service) can be used to do incremental ETL between databases. I use it to load data from RDS (MySQL) to Redshift.
It works, but have some concerns. Take some notes when doing this project.
Prerequisites Source RDS must:
Enable automatic backups Increase binlog remain …
2017 年 09 月 29 日
I use autoscaling group to manage stateless servers. Servers go up and down every day.
Once server is up, I will add a PTR record for it’s internal ip. But when it’s down, I didn’t cleanup the PTR record. As times fly, a lot of invalid PTR records left in Route53.
To cleanup those PTR records …
2017 年 08 月 19 日
Build static website on S3 is very easy, but by default, it can be accessed by open internet.It will be super helpful if we can build website only available in VPC. Then we can use it to host internal deb repo, doc site…
Steps are very easy, you only need VPC endpoints and S3 bucket policy.
AWS api …
2017 年 07 月 21 日
使用 redshift spectrum 查询 S3 数据 通常使用 redshift 做数据仓库的时候要做大量的 ETL 工作,一般流程是把各种来源的数据捣鼓捣鼓丢到 S3 上去,再从 S3 倒腾进 redshift. 如果你有大量的历史数据要导进 redshift,这个过程就会很痛苦,redshift 对一次倒入大量数据并不友好,你要分批来做。
今年4月的时候, redshift 发布了一个新功能 spectrum, 可以从 redshift 里直接查询 s3 上的结构化数据。最近把部分数据仓库直接迁移到了 spectrum, 正好来讲讲。
动机 Glow 的数据仓库建在 redshift …
2017 年 07 月 15 日
Coredump file is useful for debuging program crash. This post will show several settings related to coredump.
Enable coredump If you run program from shell , enable coredump via unlimit -c unlimited, then check unlimit -a | grep core, if it shows unlimited, coredump is enabled for your current …
2017 年 07 月 01 日
Python web 应用性能调优 为了快速上线,早期很多代码基本是怎么方便怎么来,这样就留下了很多隐患,性能也不是很理想,python 因为 GIL 的原因,在性能上有天然劣势,即使用了 gevent/eventlet 这种协程方案,也很容易因为耗时的 CPU 操作阻塞住整个进程。前阵子对基础代码做了些重构,效果显著,记录一些。
设定目标:
性能提高了,最直接的效果当然是能用更少的机器处理相同流量,目标是关闭 20% 的 stateless webserver. 尽量在框架代码上做改动,不动业务逻辑代码。 低风险 (历史经验告诉我们,动态一时爽,重构火葬场….) 治标 常见场景 …
2017 年 06 月 23 日
I’m lazy, I don’t want to be deb/rpm expert, I don’t want to maintain repo server. I want as less maintenance effort as possible. 🙂
Combine tools fpm, aptly with aws s3, we can do it.
Use fpm to convert python package to deb fpm can transform python/gem/npm/dir/… to deb/rpm/solaris/… packages …
2017 年 06 月 05 日
pyflame is an opensource tool developed by uber: https://github.com/uber/pyflame
It can take snapshots of running python process, combined with flamegraph.pl, can output flamegraph picture of python call stacks. Help analyze bottleneck of python program, needn’t inject any perf code into your …
2017 年 05 月 17 日
Chapter 4, 5, 6
Encoding formats xml, json, msgpack are text based encoding format, they can’t carry binary bytes (useless you encode them in base64, size grows 33%). And they cary schema definition with data, wast a lot of space.
thrift, protobuf are binary format, can take binary bytes, only carry …
2017 年 05 月 04 日
Notes when reading chapter 2 “Data models and query languages”, chapter 3 “Storage and retrieval”
2017 年 04 月 21 日
Create virtual resource on AWS is very convenient, but how to manage them will be a problem when your size grow.
You will come to:
How to explain the detail online settings for your colleagues (like: how our prod vpc is setup?what’s the DHCP option set?), navigate around AWS console is okay, but not …
2017 年 04 月 19 日
A few notes taken when reading
2017 年 04 月 05 日
Overview MySQL has buildin partition table support, which can help split data accross multi tables,
and provide a unified query interface as normal tables.
Benefit:
Easy data management: If we need to archive old data, and our table is partitioned by datetime, we can drop old partition directly. …
2017 年 03 月 22 日
In this article, let’s talk about ElasticSearch’s cluster mode, which means multi nodes ElasticSearch.
Basic concepts cluster: A collection of server nodes with same cluster.name settings in elasticsearch.yaml
primary shards: Divide a index into multi parts(by default 5), shards of an index can be …
2016 年 12 月 11 日
杂乱笔记,辅助读paper.
2016 年 11 月 19 日
看了下很久前 google 的 GFS 论文, 做点笔记。
2016 年 10 月 28 日
最近公司在做 HIPAA Compliance 相关的事情,其中要求之一是所有db需要开启encryption.
比较麻烦的是rds 的encryption 只能在创建的时候设定,无法之后修改, 所以必须对线上的db 做一次 migration.
2016 年 07 月 26 日
什么是索引,索引怎么建这些基本的就跳过不谈了,整理一些前段时间优化线上 SQL 查询时碰到的一些问题. 主要解决下面几个问题:
建立索引怎样选择合适的列. 怎样让 SQL 能有效利用索引. 如果对 SQL 效率进行评估(即设置索引前后是否真的有性能提升).
2016 年 07 月 16 日
Glow 的 server infrastructure 全部搭建在 AWS 上,一般要选择一些基础服务的时候,总是先看 AWS, 只要功能和成本符合要求,不会特意选择开源方案。
数据仓库我们选择了 AWS 的 Redshift.
在一年多的使用过程中 Redshift 的性能和稳定性都不错, 当然也有一些坑, 这里整理下在使用 redshift 的过程中的一些经验和遇到的坑.
2016 年 07 月 16 日
最近在对公司的 MySQL 服务器做性能优化, 一直对 innodb 的内存使用方式不是很清楚, 乘这机会做点总结.
在配置 MySQL 的时候, 一般都会需要设置 innodb_buffer_pool_size, 在将 MySQL 设置在单独的服务器上时, 一般会设置为物理内存的80%.
之前一直疑惑 MySQL 是怎么缓存数据的(不是指query cache), 直觉应该是LRU, 但如果 query 一下从磁盘上读取大量的数据的话(全表扫描或是 mysqldump), 是不是很容易就会把热数据给踢出去?