<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Yisheng&#39;s Blog</title>
    <link>https://blog.yellowday.day/</link>
    <description>Recent content on Yisheng&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 15 Mar 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog.yellowday.day/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Context Engineering from the Inside Out</title>
      <link>https://blog.yellowday.day/posts/context_engineering_from_the_inside_out/</link>
      <pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/context_engineering_from_the_inside_out/</guid>
      <description>&lt;p&gt;AI agents live and die by their context windows. The system prompt, tool schemas, conversation history, retrieved documents — everything the model sees during a single request shapes what it does next. &lt;strong&gt;Context engineering&lt;/strong&gt; is the art of deciding what goes in, where it goes, and when it gets removed.&lt;/p&gt;&#xA;&lt;p&gt;Good context engineering makes agents more reliable, faster, and cheaper. This post explores the design philosophy behind features like CLAUDE.md, hooks, skills, subagents, and CLI vs MCP — and why KV cache hit rate is critical to agent system performance.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GPT-OSS Inference from Scratch</title>
      <link>https://blog.yellowday.day/posts/gpt_oss_from_scratch/</link>
      <pubDate>Tue, 03 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/gpt_oss_from_scratch/</guid>
      <description>&lt;p&gt;In this post, we implement GPT-OSS-20B inference from scratch in PyTorch. Building GPT-OSS shares a lot of common ground with building the Qwen3 family — if you haven&amp;rsquo;t read my &lt;a href=&#34;../qwen3_from_scratch/&#34;&gt;Qwen3 Inference from Scratch&lt;/a&gt; and &lt;a href=&#34;../qwen3_moe_from_scratch/&#34;&gt;Qwen3 MoE from Scratch&lt;/a&gt; posts, I recommend starting there.&lt;/p&gt;&#xA;&lt;p&gt;GPT-OSS is also a sparse MoE transformer with RMSNorm + GQA + RoPE + SwiGLU experts — the shared components work the same way. This post focuses on &lt;strong&gt;things GPT-OSS does differently&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Qwen3 MoE Inference from Scratch</title>
      <link>https://blog.yellowday.day/posts/qwen3_moe_from_scratch/</link>
      <pubDate>Fri, 27 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/qwen3_moe_from_scratch/</guid>
      <description>&lt;p&gt;In this post, we implement Qwen3 MoE inference from scratch in PyTorch. It builds on the Qwen3 dense architecture — if you haven&amp;rsquo;t read my &lt;a href=&#34;../qwen3_from_scratch/&#34;&gt;Qwen3 Inference from Scratch&lt;/a&gt; post, I recommend starting there, as it covers the full dense transformer pipeline (tokenizer, RMSNorm, RoPE, GQA, SwiGLU FFN, KV cache, generation). This post covers the key architectural advancement from dense to MoE: replacing the dense FFN with a &lt;strong&gt;Sparse Mixture of Experts&lt;/strong&gt; layer. MoE is a more efficient architecture — it achieves better performance by scaling total parameters while keeping compute low, activating only a small subset of weights per token. Everything else — attention, normalization, tokenizer, generation loop — is identical.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Qwen3 Inference from Scratch</title>
      <link>https://blog.yellowday.day/posts/qwen3_from_scratch/</link>
      <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/qwen3_from_scratch/</guid>
      <description>&lt;p&gt;Better late than never — I&amp;rsquo;ve started a repo called &lt;a href=&#34;https://github.com/gongyisheng/llm-from-scratch&#34;&gt;llm-from-scratch&lt;/a&gt;, where I reimplement popular open-source LLMs piece by piece, with a focus on making every component&amp;rsquo;s structure clear and easy to follow. It&amp;rsquo;s meant to be a hands-on tutorial for beginners and a personal reference for myself. The first entry is a from-scratch implementation of &lt;a href=&#34;https://huggingface.co/Qwen/Qwen3-0.6B&#34;&gt;Qwen3-0.6B&lt;/a&gt; in pure PyTorch — no Hugging Face &lt;code&gt;transformers&lt;/code&gt;, no &lt;code&gt;vllm&lt;/code&gt;, just raw tensor operations. This post walks through each core building block: tokenizer, RMSNorm, RoPE, FFN, GQA, transformer blocks, KV cache, prefill/decode, temperature sampling and batch processing — what each does, why it&amp;rsquo;s designed that way, and the non-obvious details I learned along the way.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Memorization vs Generalization</title>
      <link>https://blog.yellowday.day/posts/memorization_vs_generalization/</link>
      <pubDate>Fri, 12 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/memorization_vs_generalization/</guid>
      <description>&lt;p&gt;Today I revisit the classic LRU cache problem in my &lt;a href=&#34;https://github.com/gongyisheng/playground/blob/main/algorithm/lru.py&#34;&gt;playground&lt;/a&gt; repo. The standard answer comes to my mind immediately: HashMap + Doubly Linked List. Cool, I remember that. But then I ask myself, what about LFU, B+Tree, and other complex data structures? I can barely remember and have to look up the script I developed when I&amp;rsquo;m at school.&lt;/p&gt;&#xA;&lt;p&gt;Yeah, the real problem is that I&amp;rsquo;m memorizing the answer, not generalization. I suddenly realized that it&amp;rsquo;s also where LLMs suffer from: they are so good at memorizing answer, but not able to generalize.&lt;/p&gt;</description>
    </item>
    <item>
      <title>工作三年，许多想说</title>
      <link>https://blog.yellowday.day/posts/%E5%B7%A5%E4%BD%9C%E4%B8%89%E5%B9%B4%E8%AE%B8%E5%A4%9A%E6%83%B3%E8%AF%B4/</link>
      <pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/%E5%B7%A5%E4%BD%9C%E4%B8%89%E5%B9%B4%E8%AE%B8%E5%A4%9A%E6%83%B3%E8%AF%B4/</guid>
      <description>&lt;p&gt;最近读到laike9m &lt;a href=&#34;https://laike9m.com/blog/gong-zuo-san-nian-wo-xue-dao-liao-shi-yao,132/&#34;&gt;&amp;lt;工作三年我学到了什么&amp;gt;&lt;/a&gt;，听完那期捕蛇者说博客，觉得自己的视角下有许多不同，想也来写一写自己的感想。我毕业之后就一直在一家硅谷小厂工作，到今年6月也满三年了。前两年的角色大致是DE/SDE，最近一年在转向AI/LLM。这篇想把主题扩展到工作之外，到生活，心态，团队，方方面面，也算一个阶段性的记录。&lt;/p&gt;&#xA;&lt;h2 id=&#34;换方向是常有的事&#34;&gt;换方向是常有的事&lt;/h2&gt;&#xA;&lt;p&gt;换方向是常有的事，在小公司里更是。我刚进公司的时候是做维护data pipeline，花了6个月做了一次AWS EMR到databricks的迁移，稳定之后就几乎不需要时间维护了。随后便去接手了后端服务的性能优化，以这个契机接触了python / redis / mysql / elasticsearch后端技术栈，有段时间还去做了一些k8s hpa的调研。然后就是从一年前的夏天开始做AI一直到现在，现在也逐渐走上正路。如果在大公司里，这算不算三年换了两次组呢？我不太知道。但总体来说，我觉得十分满足，给了我太多跨领域学习的机会。&lt;/p&gt;&#xA;&lt;p&gt;我现在不太会想这样的经历会不会不专注，这是从后视镜看到的看法。在那个当下，我能看到的只是：面前有一个机会，我要不要抓住它？能在某个领域一直做很久并成为那个领域的专家，是一件幸运的事，但在目前的公司里我不太能看到这种可能。这个时代本身就是在变化的，所以我更多把换方向看作为一种常态，毕竟在科技行业，变化是一定会发生的事，我们谁也不敢说能依靠现在的技术栈一直工作到退休。&lt;/p&gt;&#xA;&lt;h2 id=&#34;playground是我的工具箱&#34;&gt;playground是我的工具箱&lt;/h2&gt;&#xA;&lt;p&gt;在小公司一个比较大的问题是技术栈比较简单，使用的技术一般比较成熟，甚至老旧。带来的问题就是视野和发展受限，“在工作中学习”是一种奢望，很容易处于一种“好像没什么再可以学的”状态，但是回归到人才市场时，却发现自己一无所长。我慢慢想出了一种变通解决的方法，叫做“在工作外学习，在工作中实践”，即选定一些自己感兴趣的知识和领域，慢慢了解它、学习它，并在工作中尝试运用它。一般来说，老板对新技术的采用抱开放态度（毕竟能提升性能或者省钱，都是看得见的成果），至少能申请一些做实验的机会，如果能上到生产环境那就是一次从0到1使用的经验，即使不采纳，也可以为以后的工作做铺垫。我发现在小公司里这样的机会还真不少，如果能证明有显著提升，最终能上到生产环境的概率很高，比如这几年我做了：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;[Y] (llm) ReAct agent&lt;/li&gt;&#xA;&lt;li&gt;[N] (benchmark) valkey vs redis&lt;/li&gt;&#xA;&lt;li&gt;[N] (benchmark) postgresql vs mysql&lt;/li&gt;&#xA;&lt;li&gt;[Y] (full stack) 带计费功能的openai api proxy&lt;/li&gt;&#xA;&lt;li&gt;[Y] (redis - client tracking) redis客户端缓存&lt;/li&gt;&#xA;&lt;li&gt;[Y] (redis - redis stream) 基于redis的可靠消息队列&lt;/li&gt;&#xA;&lt;li&gt;[Y] (mysql - replication) 基于mysql binlog的变动数据捕获 (change data capture)&lt;/li&gt;&#xA;&lt;li&gt;[Y] (k8s - keda) 基于keda的k8s HPA&lt;/li&gt;&#xA;&lt;li&gt;[N] (python - cpp extension) 用cpp写的trietree包，加速字符串匹配&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;有idea了，就花时间自己动手探索一下，在我的playground repo把教程跑一遍，或者做一个原型prototype看看情况，效果好的可以直接进行展示，效果不好也积累了知识。基本原则是小量试错，不花太多的时间就能得到初步结论，做一些笔记，然后拿着结论决定是否需要深入研究。这样长久积累下来我的playground repo就变成了一个大工具箱，里面有我的所有学习笔记和测试代码，可以随时clone下来作为知识库搜索。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis vs Valkey</title>
      <link>https://blog.yellowday.day/posts/redis_vs_valkey/</link>
      <pubDate>Fri, 23 May 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/redis_vs_valkey/</guid>
      <description>&lt;h3 id=&#34;background&#34;&gt;Background&lt;/h3&gt;&#xA;&lt;p&gt;过去一年各大云服务厂商在Redis换license之后，力推使用Valkey代替Redis作为kv内存数据库的使用方案。Valkey作为Redis 7.2.4 fork，不仅兼容redis各个语言的client库，也解决了Redis目前存在的单线程性能瓶颈和内存占用问题，不禁好奇其性能有多大提升，周末找了个时间进行了性能benchmark。&lt;/p&gt;&#xA;&lt;p&gt;已有youtube博主进行过benchmark，但由于方法不同结果仅供参考，可以与本文结果进行互相比较&lt;/p&gt;&#xA;&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;&#xA;      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/9hDvWVJtljE?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;&#xA;    &lt;/div&gt;&#xA;&#xA;&lt;p&gt;关于Valkey相较于Redis的改进，主要有两个，一个是io-thread, 另一个是数据结构内存优化, 可以参见以下两篇blog post:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://valkey.io/blog/unlock-one-million-rps/&#34;&gt;Unlock 1m rps - part1&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://valkey.io/blog/unlock-one-million-rps-part2/&#34;&gt;Unlock 1m rps - part2&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;其中io-thread是最重要的改进，支持了Epoll job并行执行，建议配置&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;io-thread=&amp;lt;核心数&amp;gt;&#xA;events-per-io-thread=2 (default)&#xA;io-threads-do-reads=yes (default)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&#34;./images/io-thread.png&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;另外，需要注意Redis 7.2.4 之后引入的 feature 如 time series, vector db, valkey 可能没有很好的支持，参考Redis方面的&lt;a href=&#34;https://redis.io/blog/what-is-valkey/&#34;&gt;post&lt;/a&gt;&lt;br&gt;&#xA;Valkey实验版本支持了RDMA，不经过OS和CPU直接进行数据读取，继续提升性能，参考以下两篇:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://valkey.io/topics/RDMA/&#34;&gt;RDMA official document&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/valkey-io/valkey/pull/477#issuecomment-2119785640&#34;&gt;RDMA github pull request&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;method&#34;&gt;Method&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;instance: RaspberryPi 5b, 4vcore 8GiB&#xA;kennel: linux 6.14.0-1005-raspi&#xA;redis: 8.0.0&#xA;valkey: 8.1.0&#xA;command: `redis-benchmark -h &amp;lt;host&amp;gt;`&#xA;client number: 50 (default)&#xA;request number: 100000 (default)&#xA;&#xA;valkey单核: io-threads=1&#xA;valkey多核: io-threads=4&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;result&#34;&gt;Result&lt;/h3&gt;&#xA;&lt;p&gt;Redis 8.0&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why MySQL replication is lagging</title>
      <link>https://blog.yellowday.day/posts/why_mysql_replication_is_lagging/</link>
      <pubDate>Tue, 09 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/why_mysql_replication_is_lagging/</guid>
      <description>&lt;h3 id=&#34;background&#34;&gt;Background&lt;/h3&gt;&#xA;&lt;p&gt;Our team planned to upgrade one of our MySQL instance from 8.0.28 to 8.0.36 through AWS RDS blue/green deployment. The whole process includes 4 steps:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;set up a new MySQL 8.0.36 instance (slave), recover data from snapshot&lt;/li&gt;&#xA;&lt;li&gt;new MySQL instance (8.0.36) subscribe to old MySQL instance (8.0.28)&lt;/li&gt;&#xA;&lt;li&gt;once there’s no replication lags, do switch-over. The downtime is usually &amp;lt; 10s.&lt;/li&gt;&#xA;&lt;li&gt;check online service. shutdown old instance after checking everything is good.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;However, We stuck at step 2. The replication lag kept growing and it seemed never to decrease, which made it impossible to start switch-over.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lost connection error with aiomysql</title>
      <link>https://blog.yellowday.day/posts/lost_connection_error_with_aiomysql/</link>
      <pubDate>Tue, 16 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/lost_connection_error_with_aiomysql/</guid>
      <description>&lt;h3 id=&#34;background&#34;&gt;Background&lt;/h3&gt;&#xA;&lt;p&gt;When I tried to run a big range query on mysql using &lt;code&gt;aiomysql&lt;/code&gt;‘s &lt;code&gt;SSDictCursor&lt;/code&gt;, everything looks fine at first but after a period of time (15min to 20min), the query stopped with error.&#xA;The error message is:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Error Code 2013: Lost connection to MySQL server during query.&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Environment&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Database&#xA;MySQL version: 8.0.29&#xA;connect_timeout=10&#xA;net_read_timeout=30&#xA;net_write_timeout=60&#xA;&#xA;Test Client&#xA;Linux kernal version: 6.1&#xA;Instance type: AWS t2.micro (1 vCPU, 1GiB RAM)&#xA;Python: 3.8.10&#xA;aiomysql: 0.1.1&#xA;PyMySQL: 1.1.0&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;observation&#34;&gt;Observation&lt;/h3&gt;&#xA;&lt;p&gt;What the code is doing is like&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spark executor OOM: not enough memory to build hash map</title>
      <link>https://blog.yellowday.day/posts/spark_executor_oom_not_enough_memory_to_build_hash_map/</link>
      <pubDate>Tue, 08 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/spark_executor_oom_not_enough_memory_to_build_hash_map/</guid>
      <description>&lt;h3 id=&#34;background&#34;&gt;Background&lt;/h3&gt;&#xA;&lt;p&gt;One of the pipelines I maintained failed last week. The first try failed but the second try was successful. The pipeline’s structure is quite simple, it contains 3 steps, like most of the ETL pipelines:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Load data from database&lt;/li&gt;&#xA;&lt;li&gt;Boardcast join a 2GiB dataset&lt;/li&gt;&#xA;&lt;li&gt;Write to delta table&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Error message is &lt;code&gt;There is not enough memory to build the hash map&lt;/code&gt;. It happened in step 2.&lt;/p&gt;&#xA;&lt;h3 id=&#34;environment-details&#34;&gt;Environment Details&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Databricks Runtime: 11.3 LTS, Scala 2.12, Spark 3.3.0&#xA;Cluster: (AWS EC2 instances)&#xA;Driver: r5.xlarge · (32GiB memory, 4 vcores)&#xA;Workers: i3en.xlarge · 4 workers (32GiB memory, 4 vcores)&#xA;Spark config (selected):&#xA;spark.driver.memory 24g&#xA;spark.driver.maxResultSize 12g&#xA;spark.executor.cores 2&#xA;spark.executor.memory 12g&#xA;spark.executor.memoryOverhead 2048&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;observation&#34;&gt;Observation&lt;/h3&gt;&#xA;&lt;p&gt;Detailed error log and traceback:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nginx reuseport导致偶发性卡顿</title>
      <link>https://blog.yellowday.day/posts/nginx_reuseport_cause_occasional_lag/</link>
      <pubDate>Mon, 05 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/nginx_reuseport_cause_occasional_lag/</guid>
      <description>&lt;h3 id=&#34;背景&#34;&gt;背景&lt;/h3&gt;&#xA;&lt;p&gt;摘抄自plantegg的blog&lt;/p&gt;&#xA;&lt;p&gt;从2018年开始，我们有个业务陆续接到反馈 Nginx 线上集群经常出现不响应或者偶发性的“超慢”请求。这种卡顿每天都有少量出现。而只有多个集群中的一个出现，其他压力更大的集群皆未出现。&lt;/p&gt;&#xA;&lt;p&gt;业务结构比较简单：LVS-&amp;gt;Nginx-&amp;gt;后端，如图&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;./images/architecture.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;观察到的现象：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;出问题前不久升级 Nginx 配置，打开了 reuseport 功能&lt;/li&gt;&#xA;&lt;li&gt;在压力大的后端（upstream）服务环境不容易出现，后端压力轻对应的Nginx卡顿概率更高&lt;/li&gt;&#xA;&lt;li&gt;关闭 reuseport 后 问题少了很多&lt;/li&gt;&#xA;&lt;li&gt;失败的请求响应时间都是 0ms（Nginx日志不靠谱了）&lt;/li&gt;&#xA;&lt;li&gt;从 Nginx 日志上看，所有失败的健康检查请求都是0ms 的499 错误码（健康检查设置超时是2秒），但实际出问题的时候有5s-2分钟没有任何日志输出（Nginx卡了这么久）要么是Nginx卡住没去accept，要么是accept了没响应&lt;/li&gt;&#xA;&lt;li&gt;所有超时来自同一个worker(一个Nginx服务一般按照机器核数开启多个worker)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;并且已知，卡顿的原因是打开 reuseport 后，新进来的请求可以由内核 hash 派发给一个 Nginx woker ，避免了锁争抢以及惊群。但如果网络条件足够好，压力足够低，Nginx worker 一直来不及读完 receive buffer 中的内容时，就无法切换并处理其他的 request，于是在新请求的客户端会观测不间断的卡顿，而压力大的后端由于网络传输慢，经常卡顿，Nginx worker 反而有时间能处理别的请求。在调小 receive buffer 人为制造卡顿后该问题得以解决。&lt;/p&gt;&#xA;&lt;h3 id=&#34;目标&#34;&gt;目标&lt;/h3&gt;&#xA;&lt;p&gt;由于所述场景比较复杂，缺乏直接证据，我打算通过构造一个较简单的环境来复现这个问题，并且在这个过程中抓包、观测 Nginx worker 的具体行为，验证这个假设。&lt;/p&gt;&#xA;&lt;h3 id=&#34;术语&#34;&gt;术语&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;快连接和慢连接&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;短连接：通常是传输时间短、传输量小的连接，耗时通常是ms级别&lt;/li&gt;&#xA;&lt;li&gt;长连接：通常是传输时间长、传输量大的连接，可以维持传输状态一段时间（如30s, 1min）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;在本次场景复现过程中，这两种连接都是短连接，每次请求开始前都需要三次握手建立连接，结束后都需要四次挥手销毁连接&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Epoll&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Nginx使用了epoll模型，epoll 是多路复用的一种实现。在多路复用的场景下，一个task（process）会批量处理多个socket，哪个来了数据就去读那个。这就意味着要公平对待所有这些socket，不能阻塞在任何socket的”数据读”上，也就是说不能在阻塞模式下针对任何socket调用recv/recvfrom。&lt;/p&gt;&#xA;&lt;p&gt;epoll 每次循环为O(1) 操作，循环前会得到一个就绪队列，其中包含所有已经准备好的 socket stream（有数据可读），不需要循环全部 socket stream 读取数据，在循环后会将被读取数据的 stream 重新放回睡眠队列。睡眠队列中的 socket stream 有数据可读时，再唤醒加入到 就绪队列中。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Avoid using big strings as MySQL index key</title>
      <link>https://blog.yellowday.day/posts/aviod_string_as_index/</link>
      <pubDate>Sat, 27 May 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/aviod_string_as_index/</guid>
      <description>&lt;h3 id=&#34;background&#34;&gt;Background&lt;/h3&gt;&#xA;&lt;p&gt;As what is explained in &lt;a href=&#34;https://blog.yellowday.day/posts/is_20m_rows_still_a_soft_limit_of_mysql_table_in_2023/&#34;&gt;my pervious post&lt;/a&gt;, B+ tree depth decides the worst case of MySQL’s query performance, only considering those use index. And with the help of SSD, that should be fine to have a B+ tree deeper than 4 layers.&lt;/p&gt;&#xA;&lt;p&gt;So the next question is: how bad the performance is possible to be? Here I intentionally design a table using very long string as primary key and index, which results in very deep B+ trees, up to 9 layers, to test its worst performance on SSD, which you are not expected to deal with in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Is 20M rows still a soft limit of MySQL table in 2023?</title>
      <link>https://blog.yellowday.day/posts/is_20m_rows_still_a_soft_limit_of_mysql_table_in_2023/</link>
      <pubDate>Mon, 22 May 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/is_20m_rows_still_a_soft_limit_of_mysql_table_in_2023/</guid>
      <description>&lt;h3 id=&#34;rumor&#34;&gt;Rumor&lt;/h3&gt;&#xA;&lt;p&gt;There&amp;rsquo;s rumor around the internet that we should avoid having &amp;gt; 20M rows in a single MySQL table. Otherwise, the table&amp;rsquo;s performance will be downgraded, you will find SQL query much slower than usual when it&amp;rsquo;s above the soft limit. These judgements were made on HDD many years ago. I&amp;rsquo;m wondering if it&amp;rsquo;s still true for MySQL on SSD in 2023, and if true, why is that?&lt;/p&gt;&#xA;&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;— Database  &#xA;MySQL version: 8.0.25  &#xA;Instance type: AWS db.r5.large (2vCPUs, 16GiB RAM)  &#xA;EBS storage type: General Purpose SSD (gp2)  &#xA;— Test Client  &#xA;Linux kernal version: 6.1  &#xA;Instance type: AWS t2.micro (1 vCPU, 1GiB RAM)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;experiment-design&#34;&gt;Experiment Design&lt;/h3&gt;&#xA;&lt;p&gt;Create tables with same schema but different in size. I created 9 tables with 100k, 200k, 500k, 1m, 2m, 5m, 10m, 20m, 30m, 50m, 60m of rows respectively.&lt;/p&gt;</description>
    </item>
    <item>
      <title>为什么我的网络传输速度下降了</title>
      <link>https://blog.yellowday.day/posts/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%9A%84%E7%BD%91%E7%BB%9C%E4%BC%A0%E8%BE%93%E9%80%9F%E5%BA%A6%E4%B8%8B%E9%99%8D%E4%BA%86/</link>
      <pubDate>Sat, 06 May 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%9A%84%E7%BD%91%E7%BB%9C%E4%BC%A0%E8%BE%93%E9%80%9F%E5%BA%A6%E4%B8%8B%E9%99%8D%E4%BA%86/</guid>
      <description>&lt;h3 id=&#34;背景&#34;&gt;背景&lt;/h3&gt;&#xA;&lt;p&gt;这个问题一开始是在进行RDS实验的时候发现的。最初的情景是，多台机器同时对数据库进行select和insert操作时，会发现insert操作会造成select操作qps大幅下降，且insert操作结束之后select操作的qps仍不能回升。起初以为是RDS的问题，但是在复现问题、监控RDS之后发现RDS的压力其实很小。于是开始怀疑是网络的问题，在简化了场景和操作之后，发现能在过去做tcp实验的机器上复现，于是用这个更简单的场景进行问题复现和分析。&lt;/p&gt;&#xA;&lt;h3 id=&#34;环境&#34;&gt;环境&lt;/h3&gt;&#xA;&lt;p&gt;linux kernal version: 6.1&lt;br&gt;&#xA;linux image: amazon/al2023-ami-2023.0.20230419.0-kernel-6.1-x86_64&lt;br&gt;&#xA;instance type: AWS t2.micro (1 vCPU, 1GiB RAM)&lt;br&gt;&#xA;tc qdisc: fq_codel&lt;/p&gt;&#xA;&lt;p&gt;无网络流量情况下：&lt;br&gt;&#xA;network rtt: 0.5 ms&lt;br&gt;&#xA;network bandwidth: 60 MB/s&lt;/p&gt;&#xA;&lt;h3 id=&#34;操作&#34;&gt;操作&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;开三台 t2.micro 机器，一台做 server，两台做client，在server上放一个 2GB 大小的文件&lt;/li&gt;&#xA;&lt;li&gt;client1 通过 curl get server 文件&lt;/li&gt;&#xA;&lt;li&gt;等待一段时间（约20s），client1网速稳定后，client2 通过 curl get server 文件&lt;/li&gt;&#xA;&lt;li&gt;可以观察到两种情况（如果无法复现请多试几次，就能复现）&lt;br&gt;&#xA;正常情况：两个 client 速度稳定在30MB/s左右&lt;br&gt;&#xA;降速情况：两个 client 速度降低到3.5MB/s左右&lt;/li&gt;&#xA;&lt;li&gt;关掉client2，观察到client1恢复到7-8MB/s，但是远低于60MB/s的带宽上限&lt;/li&gt;&#xA;&lt;li&gt;降速情况发生之后，client1/2重新通过curl 下载 server文件，就会出现起初网络速度在30-50MB/s，但10s后会降速7-8MB/s的情况，需要重启server才能恢复到60MB/s&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;分析&#34;&gt;分析&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;抓包&lt;/p&gt;&#xA;&lt;p&gt;通过tcpdump抓包，获得了完整的降速过程中，server和两个client的网络包的传输情况，pcap文件已上传到&lt;a href=&#34;https://github.com/gongyisheng/playground/tree/main/network/throughput_drop_case&#34;&gt;Github&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;./images/rtt_server_to_client1_serverside.png&#34; alt=&#34;img&#34;&gt;&#xA;&lt;img src=&#34;./images/rtt_server_to_client1_clientside.png&#34; alt=&#34;img&#34;&gt;&#xA;&lt;img src=&#34;./images/rtt_server_to_client2_serverside.png&#34; alt=&#34;img&#34;&gt;&#xA;&lt;img src=&#34;./images/rtt_server_to_client2_clientside.png&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;可以观察到：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;rtt有明显上升，rtt从降速前的小于1ms上升到降速后的50-100ms&lt;/li&gt;&#xA;&lt;li&gt;两边rtt不对等，在降速后关掉client2, server-&amp;gt;client1 tcp stream的rtt在server端和client端差异很大&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;猜测A：bufferbloat&lt;/p&gt;</description>
    </item>
    <item>
      <title>Packet capture experiment 2</title>
      <link>https://blog.yellowday.day/posts/packet_capture_experiment_2/</link>
      <pubDate>Sat, 15 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/packet_capture_experiment_2/</guid>
      <description>&lt;h2 id=&#34;sendreceive-buffer&#34;&gt;send/receive buffer&lt;/h2&gt;&#xA;&lt;h3 id=&#34;goal&#34;&gt;Goal&lt;/h3&gt;&#xA;&lt;p&gt;Get a better understanding of how send/receive buffer size may affect the network rtt and throughput. Usually send/receive buffer size is managed by kernal and application should not hardcode these values. However, real world cases are more rare and complicated. Inapporiate buffer size may be the root case of some network issues. Rare but possible.&lt;/p&gt;&#xA;&lt;h3 id=&#34;method&#34;&gt;Method&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Instance&lt;/p&gt;&#xA;&lt;p&gt;Instance provider: AWS&lt;br&gt;&#xA;Instance type: t2.micro, 1vCPU, 1GiB memory, Low to Moderate network&lt;br&gt;&#xA;Region: us-east-1b&lt;br&gt;&#xA;OS: Amazon Linux 2023 AMI&lt;br&gt;&#xA;Python: 3.9&lt;/p&gt;</description>
    </item>
    <item>
      <title>Packet capture experiment 1</title>
      <link>https://blog.yellowday.day/posts/packet_capture_experiment_1/</link>
      <pubDate>Tue, 11 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/packet_capture_experiment_1/</guid>
      <description>&lt;h2 id=&#34;packet-delay-loss-duplicate-corrupt-out-of-order-and-bandwidth-limit&#34;&gt;packet delay, loss, duplicate, corrupt, out-of-order and bandwidth limit&lt;/h2&gt;&#xA;&lt;h3 id=&#34;goal&#34;&gt;Goal&lt;/h3&gt;&#xA;&lt;p&gt;The goal of packet capture experiment here is to get a better understanding of TCP protocol. Besides, by reproducing the common network issues in the real world like packet delay, loss, out-of-order and brandwidth limit and saving a snapshot of packet capture result of circumstances above, we can identify and solve these problems more quickly next time.&lt;/p&gt;&#xA;&lt;h3 id=&#34;method&#34;&gt;Method&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Instance&lt;/p&gt;&#xA;&lt;p&gt;Instance provider: AWS&lt;br&gt;&#xA;Instance type: t2.micro, 1vCPU, 1GiB memory, Low to Moderate network&lt;br&gt;&#xA;Region: us-east-1b&lt;br&gt;&#xA;OS: Amazon Linux 2023 AMI&lt;br&gt;&#xA;Python: 3.9&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spot termination makes runtime unstable</title>
      <link>https://blog.yellowday.day/posts/spot_termination_makes_runtime_unstable/</link>
      <pubDate>Sat, 18 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/spot_termination_makes_runtime_unstable/</guid>
      <description>&lt;h3 id=&#34;observation&#34;&gt;Observation&lt;/h3&gt;&#xA;&lt;p&gt;Spark Job runtime is not stable&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;./images/spot-instance-1.png&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;As what can see from the screenshot, the pipeline (spark job) runtime is not quite stable. However, the pipeline deals with almost fixed amount data everyday, the runtime should not be so quite unstable like this.&lt;/p&gt;&#xA;&lt;p&gt;Besides, the pipeline runtime is quite stable at around 15min before migration to databricks.&lt;/p&gt;&#xA;&lt;h3 id=&#34;analysis&#34;&gt;Analysis&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Spark driver log&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;23/03/16 19:04:26 INFO StandaloneAppClient$ClientEndpoint: Executor updated: app-20230316185728-0000/2 is now EXITED (Worker shutting down)&#xA;23/03/16 19:04:26 WARN DLTDebugger: Failed to talk to RPC endpoint: dlt-debugger&#xA;org.apache.spark.SparkException: Exception thrown in awaitResult: &#xA;    at org.apache.spark.util.ThreadUtils$.awaitResult(ThreadUtils.scala:454)&#xA;    at org.apache.spark.rpc.RpcTimeout.awaitResult(RpcTimeout.scala:75)&#xA;    at org.apache.spark.rpc.RpcEnv.setupEndpointRefByURI(RpcEnv.scala:102)&#xA;    at org.apache.spark.rpc.RpcEnv.setupEndpointRef(RpcEnv.scala:110)&#xA;    at org.apache.spark.util.RpcUtils$.makeDriverRef(RpcUtils.scala:46)&#xA;    at org.apache.spark.debugger.DLTDebugger$.liftedTree1$1(DLTDebugger.scala:258)&#xA;    at org.apache.spark.debugger.DLTDebugger$.getDebuggerRef(DLTDebugger.scala:257)&#xA;    at org.apache.spark.debugger.DLTDebugger$.report(DLTDebugger.scala:341)&#xA;    at org.apache.spark.deploy.client.StandaloneAppClient$ClientEndpoint$$anonfun$receive$1.$anonfun$applyOrElse$5(StandaloneAppClient.scala:188)&#xA;    at scala.runtime.java8.JFunction1$mcVI$sp.apply(JFunction1$mcVI$sp.java:23)&#xA;    at scala.Option.foreach(Option.scala:407)&#xA;    at org.apache.spark.deploy.client.StandaloneAppClient$ClientEndpoint$$anonfun$receive$1.applyOrElse(StandaloneAppClient.scala:184)&#xA;    at org.apache.spark.rpc.netty.Inbox.$anonfun$process$1(Inbox.scala:115)&#xA;    at org.apache.spark.rpc.netty.Inbox.safelyCall(Inbox.scala:213)&#xA;    at org.apache.spark.rpc.netty.Inbox.process(Inbox.scala:100)&#xA;    at org.apache.spark.rpc.netty.MessageLoop.org$apache$spark$rpc$netty$MessageLoop$$receiveLoop(MessageLoop.scala:75)&#xA;    at org.apache.spark.rpc.netty.MessageLoop$$anon$1.run(MessageLoop.scala:41)&#xA;    at org.apache.spark.util.threads.SparkThreadLocalCapturingRunnable.$anonfun$run$1(SparkThreadLocalForwardingThreadPoolExecutor.scala:110)&#xA;    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)&#xA;    at com.databricks.unity.UCSEphemeralState$Handle.runWith(UCSEphemeralState.scala:41)&#xA;    at org.apache.spark.util.threads.SparkThreadLocalCapturingHelper.runWithCaptured(SparkThreadLocalForwardingThreadPoolExecutor.scala:74)&#xA;    at org.apache.spark.util.threads.SparkThreadLocalCapturingHelper.runWithCaptured$(SparkThreadLocalForwardingThreadPoolExecutor.scala:60)&#xA;    at org.apache.spark.util.threads.SparkThreadLocalCapturingRunnable.runWithCaptured(SparkThreadLocalForwardingThreadPoolExecutor.scala:107)&#xA;    at org.apache.spark.util.threads.SparkThreadLocalCapturingRunnable.run(SparkThreadLocalForwardingThreadPoolExecutor.scala:110)&#xA;    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)&#xA;    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)&#xA;    at java.lang.Thread.run(Thread.java:750)&#xA;Caused by: org.apache.spark.rpc.RpcEndpointNotFoundException: Cannot find endpoint: spark://dlt-debugger@10.241.97.77:45081&#xA;    at org.apache.spark.rpc.netty.NettyRpcEnv.$anonfun$asyncSetupEndpointRefByURI$1(NettyRpcEnv.scala:175)&#xA;    at org.apache.spark.rpc.netty.NettyRpcEnv.$anonfun$asyncSetupEndpointRefByURI$1$adapted(NettyRpcEnv.scala:171)&#xA;    at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:307)&#xA;    at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:41)&#xA;    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)&#xA;    at org.apache.spark.util.ThreadUtils$$anon$1.execute(ThreadUtils.scala:105)&#xA;    at scala.concurrent.impl.ExecutionContextImpl$$anon$4.execute(ExecutionContextImpl.scala:138)&#xA;    at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:72)&#xA;    at scala.concurrent.impl.Promise$DefaultPromise.dispatchOrAddCallback(Promise.scala:316)&#xA;    at scala.concurrent.impl.Promise$DefaultPromise.onComplete(Promise.scala:307)&#xA;    at scala.concurrent.impl.Promise.transformWith(Promise.scala:40)&#xA;    at scala.concurrent.impl.Promise.transformWith$(Promise.scala:38)&#xA;    at scala.concurrent.impl.Promise$DefaultPromise.transformWith(Promise.scala:187)&#xA;    at scala.concurrent.Future.flatMap(Future.scala:306)&#xA;    at scala.concurrent.Future.flatMap$(Future.scala:306)&#xA;    at scala.concurrent.impl.Promise$DefaultPromise.flatMap(Promise.scala:187)&#xA;    at org.apache.spark.rpc.netty.NettyRpcEnv.asyncSetupEndpointRefByURI(NettyRpcEnv.scala:177)&#xA;    ... 25 more&#xA;23/03/16 19:04:26 INFO StandaloneSchedulerBackend: Executor app-20230316185728-0000/2 removed: Worker shutting down&#xA;23/03/16 19:04:26 INFO StandaloneAppClient$ClientEndpoint: Executor added: app-20230316185728-0000/4 on worker-20230316185728-10.241.99.108-43045 (10.241.99.108:43045) with 4 core(s)&#xA;23/03/16 19:04:26 INFO StandaloneSchedulerBackend: Granted executor ID app-20230316185728-0000/4 on hostPort 10.241.99.108:43045 with 4 core(s), 12.0 GiB RAM&#xA;23/03/16 19:04:26 INFO StandaloneAppClient$ClientEndpoint: Executor updated: app-20230316185728-0000/4 is now FAILED (java.lang.IllegalStateException: Shutdown hooks cannot be modified during shutdown.)&#xA;23/03/16 19:04:26 INFO StandaloneSchedulerBackend: Executor app-20230316185728-0000/4 removed: java.lang.IllegalStateException: Shutdown hooks cannot be modified during shutdown.&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Spark log4j-active log shows that there’s excutor exit. But no reason for that.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spark driver OOM: Broadcast variable is too big</title>
      <link>https://blog.yellowday.day/posts/spark_driver_oom_broadcast_variable_is_too_big/</link>
      <pubDate>Wed, 15 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/spark_driver_oom_broadcast_variable_is_too_big/</guid>
      <description>&lt;h3 id=&#34;observation&#34;&gt;Observation&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Spark cluster master node OOM&lt;/p&gt;&#xA;&lt;p&gt;Master node shutdown due to OOM. Error log:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;INFO Data stored in hdfs:///XXXX&#xA;INFO XXXXX updated&#xA;INFO Data has XXXXX records&#xA;INFO Data stored in hdfs:///XXXX&#xA;INFO XXXXX updated&#xA;#&#xA;# java.lang.OutOfMemoryError: Java heap space&#xA;# -XX:OnOutOfMemoryError=&amp;#34;kill -9 %p&amp;#34;&#xA;#   Executing /bin/sh -c &amp;#34;kill -9 *****&amp;#34;...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Spark cluster worker node shutdown&lt;/p&gt;&#xA;&lt;p&gt;Worker nodes worked well until driver shutdown. Error log:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ERROR YarnCoarseGrainedExecutorBackend: Executor self-exiting due to : Driver ip-***-***-***-***.ec2.internal:***** disassociated! Shutting down.&#xA;INFO MemoryStore: MemoryStore cleared&#xA;INFO BlockManager: BlockManager stopped&#xA;ERROR CoarseGrainedExecutorBackend: RECEIVED SIGNAL TERM&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;analysis&#34;&gt;Analysis&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Look up driver log&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis OOM due to big keys</title>
      <link>https://blog.yellowday.day/posts/redis_oom_due_to_big_keys/</link>
      <pubDate>Thu, 16 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/redis_oom_due_to_big_keys/</guid>
      <description>&lt;h3 id=&#34;observation&#34;&gt;Observation&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Queue client performance went down&lt;/p&gt;&#xA;&lt;p&gt;Everything worked well in the morning until we got monitoring alarm at 12:45 PM EST: &lt;code&gt;&amp;lt;topic_name&amp;gt; Queue lag is too big&lt;/code&gt;. The issue happened in a service which is responsible for consuming message from message queue, processing message and writing it to database. The service also uses Redis to cache some objects which can be reused every time it processes the message. Auto-scaling rule is applied to the service so there’ll be tens to hundreds of pods running under heavy workload. We observed that the consumer speed went down by 50%, causing messages to be backlogged in the queue.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL connection deadlock</title>
      <link>https://blog.yellowday.day/posts/mysql_connection_deadlock/</link>
      <pubDate>Fri, 10 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/mysql_connection_deadlock/</guid>
      <description>&lt;h3 id=&#34;observation&#34;&gt;Observation&lt;/h3&gt;&#xA;&lt;h4 id=&#34;cronjob-is-taking-more-than-1h-to-complete&#34;&gt;CronJob is taking more than 1h to complete&lt;/h4&gt;&#xA;&lt;p&gt;My colleagues told me that one of the cron job stuck in the middle after a random day. They received the warning: CronJob is taking more than 1h to complete. And the pod kept stucking there after a day, which is abnormal. However, another cron job which almost uses the same code works well. No database failure was reported during the period of time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why signal file is a bad idea</title>
      <link>https://blog.yellowday.day/posts/why_signal_file_is_a_bad_idea/</link>
      <pubDate>Fri, 13 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/posts/why_signal_file_is_a_bad_idea/</guid>
      <description>&lt;h3 id=&#34;observation&#34;&gt;Observation&lt;/h3&gt;&#xA;&lt;p&gt;Signal file is widely used in Hadoop ecosystem. If you have experience with MapReduce, you’ll notice that by default MapReduce runtime writes an empty _SUCCESS file to mark successful completion of a job to the output folder. AWS DataPipeline and Databricks also support “file arrival” to trigger a downstream job.&lt;/p&gt;&#xA;&lt;h3 id=&#34;question&#34;&gt;Question&lt;/h3&gt;&#xA;&lt;p&gt;Is signal file a good architecture design?&lt;/p&gt;&#xA;&lt;p&gt;Can I use _SUCCESS created by MapReduce as signal file to trigger downstream job?&lt;/p&gt;</description>
    </item>
    <item>
      <title>About Me</title>
      <link>https://blog.yellowday.day/about_me/</link>
      <pubDate>Sun, 01 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.yellowday.day/about_me/</guid>
      <description>&lt;figure&gt;&lt;img src=&#34;https://blog.yellowday.day/about_me/images/profile.jpg&#34;&#xA;    alt=&#34;Profile picture&#34; width=&#34;200px&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;My name is Yisheng Gong.&lt;/p&gt;&#xA;&lt;p&gt;Software Engineer@&lt;a href=&#34;https://www.yipitdata.com/&#34;&gt;YipitData&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Based in Santa Clara, California.&lt;/p&gt;&#xA;&lt;p&gt;Recently working on Agent / RL Infra&lt;/p&gt;&#xA;&lt;p&gt;I love open source and I&amp;rsquo;m a committer of &lt;a href=&#34;https://github.com/sgl-project/sglang&#34;&gt;sglang&lt;/a&gt;, &lt;a href=&#34;https://github.com/radixark/miles&#34;&gt;miles&lt;/a&gt; and &lt;a href=&#34;https://github.com/verl-project/verl&#34;&gt;verl&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;And here&amp;rsquo;s some personal projects I built during my spare time:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/gongyisheng/playground&#34;&gt;playground&lt;/a&gt; - Learning by breaking things&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/gongyisheng/llm-from-scratch&#34;&gt;llm-from-scratch&lt;/a&gt; - Build LLMs from scratch&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://writings.yellowday.day/&#34;&gt;writings&lt;/a&gt; - Short stories and poetry&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Find me here:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://x.com/Orange41324306&#34;&gt;Twitter&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/gongyisheng&#34;&gt;GitHub&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.linkedin.com/in/yisheng-gong1997/&#34;&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;mailto:yishenggong9437@gmail.com&#34;&gt;Email&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Hope you will love my posts&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
